1

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

将产生如下输出:

构建图然后评估

[3 0 1 4 2]

评估每个元素

0 1 2 3 4

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

4

2 回答 2

3

a 的顺序是tf.data.Dataset 定义且具有确定性的(除非您添加非确定性的Dataset.shuffle())。

但是,您的两个循环构建了不同的图表,这说明了差异:

  • “构建图然后评估”部分创建一个包含五个iterator.get_next()操作的列表并并行运行五个操作。因为这些操作是并行运行的,所以它们可能会以不同的顺序产生结果。

  • “评估每个元素”部分还创建了五个iterator.get_next()操作,但它按顺序运行它们,因此您始终可以按预期顺序获得结果。

请注意,我们不建议iterator.get_next()在循环中调用,因为它会在每次调用时创建一个新操作,该操作会添加到图中并消耗内存。相反,当您遍历 a 时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) 
于 2017-12-12T21:16:47.493 回答
1

此处的 TensorFlow 常见问题解答

各个操作具有并行实现,在 CPU 中使用多个内核,或在 GPU 中使用多个线程。

因此,您的“构建图然后评估”调用为列表中的每个元素并行运行,这就是为什么数字是随机顺序的,而 for 循环强制一个调用一个接一个地运行,因此它是串行的。您可以通过定时来验证,第一个应该很快,for 循环会更慢。

于 2017-12-12T21:20:49.933 回答