我使用datasetAPI在TF1.4.1中工作。我有两组输入数据,x
和{x
和y
,我有大的上下文数组context_x
和{
每个输入批处理的上下文都会有所不同(尽管一个批中的每个样本都是相同的),因此在输入管道中将它们链接在一起是有意义的。我不能存储图中所有批处理的所有上下文数组,然后再从中读取,因为从所需内存来看,静态地将所有这些数组存储在图中是不允许的。我可以为当前批处理输入一个上下文数组,我希望在输入管道中包含它。在
还请注意,在我的图中,上下文数组经过一些卷积层,这有效地将其缩小到一个可管理的大小,比原始数组小得多,这样我就可以使用批处理中特定于样本的其他特性对其进行处理,并继续执行剩下的任务。因此,即使我最终需要复制到批量大小,我也可以在从上下文数组中提取的特征向量上执行此操作,该数组的大小要小得多。在
我使用以下类型的代码来构建一个数据集,该数据集应将一批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]
复制大型上下文数组:
这将浪费大量内存,因为所有3210000
-by-10
片都是相同的!我应该如何使用Dataset API来避免这种不必要的上下文数组复制,并且为每个批处理获得一个输出,比如((32,), (1, 10000, 10))
?您可以将其视为混合批大小,32用于x
和{
好吧,这是我的初步解决方案。请注意,我假设您的数据是以某种方式排序的,这样当您构建}总是与当前批处理相关的。在
x
的批处理时,您所读取的下一个{在您的实现中,删除
dataset_context_* = dataset_context_*.repeat()
行。在您的管道的关键区别在于,我在使用上下文压缩它之前对
x
进行批处理,这样上下文就不会被复制。但是,这需要您在处理数据加载时要小心(因此我在上面假设)。在相关问题 更多 >
编程相关推荐