2017-07-29 67 views
2

我有一个TensorFlow深度学习工作流程,其中我有一个相当简单的数据读取和使用常规NumPy构建的饲料管道;但我看到TensorFlow提供了大量用于加载数据和构建数据管道的功能。我不知道这些目标是什么情况。这似乎有两个:各种TensorFlow数据加载成语应用的情景是什么?

  1. 学习,涉及到非常大的现实世界的数据集,并建立与与high-level TensorFlow API
  2. 网络。

看来,使用"reading" as opposed to "feeding"的好处(例如功能,如tf.train.shuffle_batch,但即使是简单的助手像tf.one_hot)适用于前者,而很多的文档为things like input functions,似乎独家后者的目标。

在我的情况下,我正在使用可以使用标准Python轻松读取的文件,并且可以高效地一次性将所有文件加载到内存中,只需使用np.array就可以很好地工作,其他方法或者看起来也很不错复杂的(读取管道;实际上很慢,我已经厌倦了他们)或不恰当的(“高级”API,因为我大多使用“低级”API)。

我的结论是正确的,鉴于我已经使用TensorFlow本身(而不是低级别的学习API)和喂养NumPy阵列满足我的需求,有没有很好的理由来打扰任何一种替代方法?说这些方法的预期目标与我的不同是否公平?

或者是否有另一种分类法能更好地分析各种TensorFlow数据加载成语以及它们所应用的场景?

回答

1

将数据作为numpy数组提供是官方API的一部分,因此可以依赖它。官方卷积MNIST example将数据作为numpy数组提供,并且在移动到队列时没有速度优势。这是添加到TensorFlow中的第一个数据加载语言。

Python运行时具有GIL和其他功能,使其在多核环境中表现不佳,并且成为大量数据摄取的瓶颈。这可以通过将Python位(即打开文件)移动到本地TensorFlow操作来解决,因此这些操作可以由并行TensorFlow运行时调度,而不是由Python运行时调度。

这种管道方法会将所有操作转移到TensorFlow操作中,通过“队列”阶段分离,并使用Python线程发出session.run调用来填充队列。这是添加到TensorFlow中的第二个数据加载成语。

这消除了很多Python位,但对于高性能应用程序,其余的Python零件仍然是瓶颈(即示例herehere),因此为了解决这些问题,引入了下一代操作系统(StageOp /数据集),它不需要额外的Python线程。这是最新推出的数据加载成语。

作为一个具体的例子,为了在ImageNet上的64个GPU上重现正式的60倍加速,你不得不使用最新一代的输入加载,但对于不太密集的任务,你可以使用第二代或第一代成语。

+0

这非常有帮助。你能链接到不同的方法吗?例如,我不确定我是否理解“StageOp/Dataset”操作在实际API方面与“队列”有何不同。另外,如果我已经使用“真实”TensorFlow,我认为“高级”API方法并不真正相关。 – orome

+0

这是我在队列中给出的教程中的[幻灯片](https://github.com/yaroslavvb/stuff/blob/master/queues_talk/slides.pdf),但还有其他几个。数据集在这里介绍https://github.com/tensorflow/tensorflow/blob/master/tensorflow/docs_src/programmers_guide/datasets.md。 StageOp记录在官方API /源注释 –

+1

中,我已经[发布了一个后续问题](https://stackoverflow.com/q/45399907/656912),介绍如何将现有的基于Feed的代码映射到Dataset。目前尚不清楚如何做到这一点,特别是对于我所做的日志记录和分析。 – orome

2

雅罗斯拉夫已经告诉过你关于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或数据集。

+0

使用具有中等大小数据集的数据集会带来性能上的好处或损失(例如,可能高达几十万张小图像,例如? – orome

+1

我已经[发布了后续问题](https://stackoverflow.com/q/45399907/656912)关于如何将我现有的基于feed的代码映射到Dataset。目前还不清楚如何做到这一点,特别是对于我的日志记录和分析。 – orome

+0

@raxacoricofallapatorius我还没有尝试过这样做(只有模式,我切换到数据集有数以百万计的例子),但我不明白为什么应该有速度损失。 –

相关问题