我正在尝试将Dataset API集成到我的输入管道中。在进行此集成之前,该程序使用了tf.train.batch_join(),它已启用了动态填充。因此,这将对元素进行批处理并根据迷你批处理中最大的元素进行填充。
image, width, label, length, text, filename = tf.train.batch_join(
data_tuples,
batch_size=batch_size,
capacity=queue_capacity,
allow_smaller_final_batch=final_batch,
dynamic_pad=True)
但是,对于数据集,我无法找到确切的替代方法。我无法使用填充批处理,因为图像的尺寸没有设置的阈值。图像宽度可以是任何值。我和我的伴侣可以使用tf.contrib.data.bucket_by_sequence()解决此问题。这是摘录:
dataset = dataset.apply(tf.contrib.data.bucket_by_sequence_length
(element_length_func=_element_length_fn,
bucket_batch_sizes=np.full(len([0]) + 1, batch_size),
bucket_boundaries=[0]))
此操作基本上是因为边界设置为0,因此将所有元素都转储到溢出存储桶中。然后,由于存储桶根据最大的填充元素填充了存储桶,因此它从该存储桶中进行了批处理。
是否有更好的方法来实现此功能?
答案 0 :(得分:1)
我遇到了完全相同的问题。现在我知道如何解决这个问题。如果您的input_data
仅具有可变长度的一维,请尝试对tf.contrib.data.bucket_by_sequence_length
函数使用dataset.apply()
,使bucket_batch_sizes = [batch_size] * (len(buckets) + 1)
。就像@mrry在评论中所说的那样,还有另一种方法。
iterator = dataset.make_one_shot_iterator()
item = iterator.get_next()
padded_shapes = []
for i in item:
padded_shapes.append(i.get_shape())
padded_shapes = tf.contrib.framework.nest.pack_sequence_as(item, padded_shapes)
dataset = dataset.padded_batch(batch_size, padded_shapes)
如果张量形状中的一个尺寸为None或-1,则padded_batch
将在该尺寸上填充张量以达到批次的最大长度。
我的训练数据具有可变长度的两个特征,这种方法效果很好。