我正在使用tf.data.dataset
/ iterator
机制并尝试提高数据加载性能。在我看来,从Python卸载整个minibatch循环可能会有所帮助。我的数据足够小,无法存储在CPU或GPU上。
那么,是否可以在调用session.run
的过程中将优化器节点循环到完整的miniatched epoch?
iterator.get_next()
返回的张量仅每session.run
递增一次,这似乎无法迭代微型数据集......但如果可以完成,我的CPU会每个纪元只需触摸一次Python线程。
更新:@ muskrat使用tf.slice
的建议可用于此目的。使用tf.while_loop
查看我的后续非答案,并使用其原理图实现。但是,问题是否可以使用数据集/迭代器来实现......我仍然想知道。
答案 0 :(得分:1)
从描述中可以看出,您已经将数据集预加载为CPU / GPU上的常量,如at this example。这当然是第一步。
其次,我建议使用tf.slice()
来复制minibatch操作的效果。换句话说,只需从预加载的常量(您的数据集)中手动切片小批量,您就应该获得所需的行为。例如,请参阅the slice docs或this related post。
如果这还不够详细,请编辑您的问题以包含代码示例(使用mnist或其他内容),我可以提供更多详细信息。
答案 1 :(得分:1)
这个"答案"是麝鼠的tf.slice
建议的实施,其中tf.while_loop
的详细信息已得到解决(在How to use tf.while_loop() in tensorflow和https://www.tensorflow.org/api_docs/python/tf/while_loop的帮助下)。
除非你的数据和模型足够小,以至于你被Python I / O(像我一样)瓶颈,否则这个解决方案可能是学术性的。
优点:
缺点:
feed_dict
奸诈。理解循环体内的操作被评估以及评估他们所依赖的操作时,尤其是(精简)官方文档和有限的Stack Overflow覆盖范围,这一点很有挑战性。tf.while_loop
缺少的文档是,循环体外的张量只评估一次,即使内部操作依赖于它们。这意味着优化,模型和丢失必须在循环中定义。如果你愿意,这会限制灵活性。能够在训练时期之间调用验证损失操作。据推测,这可以通过tf.while_loop
语句和通过tf.cond
传递的适当标志来完成。但不像feed_dict
中的数据集/迭代器机制那样灵活或优雅。这是我的原理图代码(为了简洁起见,我省略了变量和模型定义):
tf.data
答案 2 :(得分:0)
我实现了tf.slice()和tf.while_loop方法来矢量化上面建议的小批量生产。
在我的案例中,该性能比使用feed_dict的迷你批次快约1.86倍,但是我发现存在一个问题,即每个时期的损耗值都不稳定。
然后,我每次更改为tf.random_shuffle输入,此问题得到了很大缓解。 (性能提升降低到1.68倍)