我正在尝试将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.然后,它从该桶批处理它,因为桶按照最大的元素填充元素。
有没有更好的方法来实现此功能?
我遇到了完全相同的问题。现在我知道如何解决这个问题。如果你的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
会将该维度上的张量填充到批次的最大长度。
我的训练数据有两个可变长度的特征,这个方法工作正常。