什么是填充可变长度数据集以在Tensorflow中进行批处理的有效方法,而该数据集没有确切的

时间:2018-06-21 21:00:09

标签: tensorflow tensorflow-datasets

我正在尝试将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,因此将所有元素都转储到溢出存储桶中。然后,由于存储桶根据最大的填充元素填充了存储桶,因此它从该存储桶中进行了批处理。

是否有更好的方法来实现此功能?

1 个答案:

答案 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将在该尺寸上填充张量以达到批次的最大长度。

我的训练数据具有可变长度的两个特征,这种方法效果很好。