我有一个 TensorFlow 深度学习工作流程,其中我有一个使用常规 NumPy 构建的相当简单的数据读取和馈送管道;但我看到 TensorFlow 提供了大量用于加载数据和构建数据管道的功能。我想知道这些目标是什么场景。好像有两个:
- 学习涉及非常大的真实世界数据集,并且
- 使用 high-level TensorFlow API 构建的网络.
看来使用"reading" as opposed to "feeding"的好处(例如 tf.train.shuffle_batch 等函数,甚至像 tf.one_hot 这样的简单助手)也适用于前者,而 things like input functions 的大部分文档, 似乎专门针对后者。
在我的例子中,我使用的文件可以使用标准 Python 轻松读取,并且可以一次高效地加载到内存中,只需使用 np.arrays 就可以正常工作,和其他方法要么看起来太复杂(读取管道;实际上很慢,我已经厌倦了它们)要么不合适(“高级”API,因为我主要使用“低级”API ).
鉴于我已经正确使用 TensorFlow(不是低级学习 API)并且提供 NumPy 数组满足我的需求,我的结论是否正确,没有充分的理由为这两种替代方法烦恼?可以说这些方法的预期目标与我的不同吗?
或者是否有另一种分类法可以更好地考虑各种 TensorFlow 数据加载习语及其应用场景?
请您参考如下方法:
Yaroslav 已经告诉过你 feeding , queues并谈到了数据集。我的一些想法:
- 如果您只是想学习 TF 或想快速试验您的各种模型,
feed_dict为您提供了一种快速的方法。存在性能下降,这就是为什么存在队列 - 队列允许您指定绕过 python -> native_TF -> python 循环和 GIL 的 TF 操作。队列的最大问题是它们很难使用(在能够正确使用我的数据之前,我总是很费力)。许多其他人都在挣扎,你可以看到一些examples of problems here
新介绍Datasets (由于某些原因没有官网链接,可能会随着TF 1.3加入)解决了很多问题。它们非常易于使用(查看页面末尾的示例)并且代码非常简单和简短。这是一个例子:
def parser(record):
# parse the record with tf.parse_single_example
iterator = tf.contrib.data.TFRecordDataset(
glob.glob("data/tfrecords/training_shard_*.tfrecord")
).map(parser).batch(batch_size).shuffle(shuffle_num).repeat(repeat_num).make_initializable_iterator()
next_element = iterator.get_next()
...
with tf.Session() as sess:
sess.run(iterator.initializer)
for i in xrange(100000):
sess.run(next_element)
这几行能够用队列代替 X4 行。让它工作也比队列更容易(几乎和 feed_dict 一样简单)。所以现在我的意见是不再需要排队了。使用 feed_dict 或数据集。
