如果我使用tf.data.Dataset数据集中的多个元素来构建图形,然后稍后评估图形,那么数据集中的元素的顺序似乎是未定义的。例如,以下代码段
import tensorflow as tf
dataset = tf.data.Dataset.range(5)
iterator = dataset.make_one_shot_iterator()
print 'build graph and then eval'
keep = []
for i in range(5):
keep.append(iterator.get_next())
with tf.Session() as sess:
keep_eval = sess.run(keep)
print keep_eval
print 'eval each element'
with tf.Session() as sess:
for i in range(5):
print sess.run(iterator.get_next()),
将产生如下输出:
构建图表,然后是eval
[3 0 1 4 2]
评估每个元素
0 1 2 3 4
此外,每次运行都会产生不同的"构建图,然后是eval"。 我希望"建立图表然后评估"订购,以及"评估每个元素"。谁能解释为什么会这样?
答案 0 :(得分:2)
tf.data.Dataset
的顺序定义且具有确定性(除非您添加非确定性Dataset.shuffle()
)。
然而,你的两个循环构建了不同的图形,这说明了差异:
"构建图表,然后是eval" part创建一个包含五个iterator.get_next()
操作的列表,并行运行五个操作。由于这些操作并行运行,因此可能会以不同的顺序生成结果。
"评估每个元素" part还会创建五个iterator.get_next()
操作,但它会按顺序运行它们,因此您始终可以按预期顺序获取结果。
请注意,我们不建议在循环中调用iterator.get_next()
,因为它会在每次调用时创建一个新操作,该操作会添加到图形中,并占用内存。相反,当您遍历Dataset
时,请尝试使用以下模式:
dataset = tf.data.Dataset.range(5)
iterator = dataset.make_one_shot_iterator()
# Call `iterator.get_next()` once and use the result in each iteration.
next_element = iterator.get_next()
with tf.Session() as sess:
for i in range(5):
print sess.run(next_element)
答案 1 :(得分:1)
来自TensorFlow常见问题解答here
各个操作系统具有并行实现,在CPU中使用多个内核,或在GPU中使用多个线程。
所以你的"构建图表然后eval"对于列表中的每个元素,调用并行运行,这就是为什么数字是随机顺序的,而for循环强制一个调用在另一个之后运行,所以它的序列。你可以通过时间来验证,第一个应该是快速的,for循环会更慢。