Tensorflow数据集API是否比队列慢?

y.s*_*hyk 6 performance tensorflow tensorflow-datasets

我用数据集API方法替换了项目中的CIFAR-10预处理管道,导致性能下降了大约10-20%.

预备是相当标准的: - 从磁盘读取图像 - 随机/裁剪和翻转 - 随机播放,批量 - 馈送到模型

总的来说,我看到现在的批处理处理速度提高了15%,但每隔一段时间(或者更确切地说,每当我重新初始化数据帧或预期重新洗牌时)批量被长时间(30秒)阻塞,这总计到了更慢的时代-per-epoch处理.

这种行为似乎与内部散列有关.如果我在ds.shuffle(buffer_size = N)中减少N,则延迟较短但比例更频繁.删除shuffle会导致延迟,就像buffer_size设置为数据集大小一样.

在阅读/缓存方面,有人可以解释数据集API的内部逻辑吗?是否有任何理由期望数据集API比手动创建的队列更快地工作?

我正在使用TF 1.3.

mrr*_*rry 10

如果使用API并使用队列实现相同的管道tf.data.Dataset,则数据集版本的性能应优于基于队列的版本.

但是,为了获得最佳性能,需要遵循一些性能最佳实践.我们在演出指南中tf.data收集了这些内容.以下是主要问题:

  • 预取很重要:默认情况下基于队列的管道预取,而数据集管道则不预取.添加dataset.prefetch(1)到管道的末尾将为您提供预取的大部分好处,但您可能需要进一步调整.

  • shuffle运算符在开头有一个延迟,而它填充缓冲区.基于队列的管道混合了所有历元的串联,这意味着缓冲区仅填充一次.在数据集管道中,这相当于dataset.repeat(NUM_EPOCHS).shuffle(N).相比之下,你也可以写dataset.shuffle(N).repeat(NUM_EPOCHS),但这需要在每个时代重新开始改组.后一种方法稍微优先(例如,对于SGD的定义更为真实),但如果您的数据集很大,则差异可能不明显.

    我们正在添加一个融合版本的shuffle-and-repeat,不会产生延迟,而TensorFlow的每晚构建将包括tf.contrib.data.shuffle_and_repeat()相当于dataset.shuffle(N).repeat(NUM_EPOCHS)但不会在每个时代开始时遭受延迟的自定义转换.

话虽如此,如果你使用的管道tf.data比队列慢得多,请提交一个GitHub问题详细说明,我们来看看吧!