张量流数据集顺序未定义?

tensorflow Dataset order undefined?

如果我使用 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()), 

将产生如下输出:

build graph and then eval

[3 0 1 4 2]

eval each element

0 1 2 3 4

此外,每个 运行 都会产生不同的“构建图然后评估”。 我希望像“评估每个元素”一样订购“构建图形然后评估”。谁能解释为什么会这样?

tf.data.Dataset的顺序是定义的和确定的(除非你添加一个非确定的Dataset.shuffle())。

但是,您的两个循环构建了不同的图形,这造成了差异:

  • "build graph and then eval" 部分创建了一个包含五个 iterator.get_next() 操作的列表,运行 并行创建了五个操作。因为这些操作 运行 是并行的,所以它们可能会以不同的顺序产生结果。

  • "eval each element" 部分还创建了五个 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) 

来自 TensorFlow 常见问题解答 here

The individual ops have parallel implementations, using multiple cores in a CPU, or multiple threads in a GPU.

所以你的 "build graph then eval" 为列表中的每个元素并行调用 运行s,这就是为什么数字是随机顺序的,而 for 循环强制一个调用是 运行 一个接一个,所以它是连续的。你可以通过两者的计时来验证,第一个应该快,for循环会慢一些。