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

标签 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。

最佳答案

如果您实现 使用 tf.data.Dataset 的管道API 和使用队列,Dataset 版本的性能应该优于基于队列的版本。
但是,为了获得最佳性能,需要遵守一些性能最佳实践。我们已将这些收集在 performance guide for 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 issue详细信息,我们来看看!

    关于performance - Tensorflow 数据集 API 是否比队列慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47403407/

    相关文章:

    tensorflow - 在急切模式下对字符串张量调用 map 时,需要一个类似字节的对象,而不是 'Tensor'

    tensorflow - 在 Tensorflow 中通过数据集 API 处理批处理时,在字典中执行索引查找的推荐方法是什么?

    python-3.x - 使用 tensorflow 训练 CNN 时如何修复 'OutOfRangeError: End of sequence' 错误?

    performance - 等待 header 时超出客户端超时

    tensorflow - keras 中的自定义损失函数 - 使用 K.minimum 实现的问题

    python - 如何修复tensorflow.tools.api.generator.api.contrib'没有 'layers'成员?

    python - 如何使用 Keras RNN 模型预测 future 的日期或事件?

    mysql - 如何在mysql中获取这个特定的用户排名查询?

    php - 将 sql 查询写入文件而不是执行它的技术原因?

    c - -fPIcflags可以增加多少开销?