tf.数据:“混合”批次大小?

2024-04-26 22:32:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用datasetAPI在TF1.4.1中工作。我有两组输入数据,x和{},每一组都有相同数量的元素。对于xy,我有大的上下文数组context_x和{},比如大小为10000×10。在

每个输入批处理的上下文都会有所不同(尽管一个批中的每个样本都是相同的),因此在输入管道中将它们链接在一起是有意义的。我不能存储图中所有批处理的所有上下文数组,然后再从中读取,因为从所需内存来看,静态地将所有这些数组存储在图中是不允许的。我可以为当前批处理输入一个上下文数组,我希望在输入管道中包含它。在

还请注意,在我的图中,上下文数组经过一些卷积层,这有效地将其缩小到一个可管理的大小,比原始数组小得多,这样我就可以使用批处理中特定于样本的其他特性对其进行处理,并继续执行剩下的任务。因此,即使我最终需要复制到批量大小,我也可以在从上下文数组中提取的特征向量上执行此操作,该数组的大小要小得多。在

我使用以下类型的代码来构建一个数据集,该数据集应将一批x和{}样本及其上下文一起提供给我的图形:

import tensorflow as tf
import numpy as np

# Small data input
x = np.arange(100)
y = np.arange(100)

# Large context array for both x  and y
context_x = np.random.rand(1, 10000, 10)
context_y = np.random.rand(1, 10000, 10)

# Create datasets
dataset_x = tf.data.Dataset.from_tensor_slices(x)
dataset_y = tf.data.Dataset.from_tensor_slices(y)

# same context should be repeated for every data item
dataset_context_x = tf.data.Dataset.from_tensor_slices(context_x)
dataset_context_x = dataset_context_x.repeat()
dataset_context_y = tf.data.Dataset.from_tensor_slices(context_y)
dataset_context_y = dataset_context_y.repeat()

dataset = tf.data.Dataset.zip((dataset_x, dataset_context_x))
dataset = dataset.concatenate( tf.data.Dataset.zip((dataset_y, dataset_context_y)) )
dataset = dataset.batch(32)

iterator = dataset.make_initializable_iterator()
(x_iter, context_iter) = iterator.get_next()
with tf.Session() as sess:
    sess.run(iterator.initializer)
    while True:
        try:
            xi, ci = sess.run([x_iter, context_iter])
            print(xi.shape, ci.shape)
        except tf.errors.OutOfRangeError:
            break

输出指示为每个示例x[i]y[i]复制大型上下文数组:

^{pr2}$

这将浪费大量内存,因为所有3210000-by-10片都是相同的!我应该如何使用Dataset API来避免这种不必要的上下文数组复制,并且为每个批处理获得一个输出,比如((32,), (1, 10000, 10))?您可以将其视为混合批大小,32用于x和{},而1用于上下文数组。在


Tags: 数据fromdatatfasnpcontext数组
1条回答
网友
1楼 · 发布于 2024-04-26 22:32:59

好吧,这是我的初步解决方案。请注意,我假设您的数据是以某种方式排序的,这样当您构建x的批处理时,您所读取的下一个{}总是与当前批处理相关的。在

import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # running on CPU
import tensorflow as tf
import numpy as np

# Small data input
x = np.arange(100)
y = np.arange(100)

# Large context array for both x  and y
context_x = np.random.rand(1, 10000, 10)
context_y = np.random.rand(1, 10000, 10)

# Create datasets
dataset_x = tf.data.Dataset.from_tensor_slices(x).batch(32)
dataset_y = tf.data.Dataset.from_tensor_slices(y).batch(32)

# same context should be repeated for every data item
dataset_context_x = tf.data.Dataset.from_tensor_slices(context_x)
dataset_context_x = dataset_context_x.repeat() # here just for demonstration purposes. Ideally you'll have enough context data to match the batches
dataset_context_y = tf.data.Dataset.from_tensor_slices(context_y)
dataset_context_y = dataset_context_y.repeat() # here just for demonstration purposes. Ideally you'll have enough context data to match the batches

dataset = tf.data.Dataset.zip((dataset_x, dataset_context_x))
dataset = dataset.concatenate( tf.data.Dataset.zip((dataset_y, dataset_context_y)) ) # This stacks all 'x' samples on top of all 'y' samples. Is this really what you wanted?

iterator = dataset.make_initializable_iterator()
(x_iter, context_iter) = iterator.get_next()
with tf.Session() as sess:
    sess.run(iterator.initializer)
    while True:
        try:
            xi, ci = sess.run([x_iter, context_iter])
            print(xi.shape, ci.shape)
        except tf.errors.OutOfRangeError:
            break

在您的实现中,删除dataset_context_* = dataset_context_*.repeat()行。在

您的管道的关键区别在于,我在使用上下文压缩它之前对x进行批处理,这样上下文就不会被复制。但是,这需要您在处理数据加载时要小心(因此我在上面假设)。在

相关问题 更多 >