Session.run() 如何选择要 运行 的子图

How Session.run() chooses which sub-graph to run

我试图了解 Session.run() 在 Tensorflow 流中的工作原理。我知道 Session.run() 运行我们给它的 "fetch" 参数指定的子图。由于取决于先执行子图的哪一部分,我们可能会得到不同的结果,所以我想看看是否真的是这样。假设我们比较这段代码的输出:

import tensorflow as tf

x = tf.Variable(42)
assign1 = tf.assign(x, 13)
assign2 = tf.assign(x, 14)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    val1, val2, val3 = sess.run([x, assign1, assign2])
    print(val1, val2, val3)

使用此代码:

import tensorflow as tf

x = tf.Variable(42)
assign2 = tf.assign(x, 14)
assign1 = tf.assign(x, 13)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    val1, val2, val3 = sess.run([x, assign1, assign2])
    print(val1, val2, val3)

(唯一的变化是 14 在第二个代码中排在第一位)。我期待看到第一个代码产生输出 14、14、14,而第二个代码产生 13、13、13。

然而,结果是第一个产生了 13、13、13,而第二个产生了 14、14、14。

为什么会这样?


更新:遵循选择的答案:

我不太明白什么是独立的,什么不是。例如,在下面的代码中:

x = tf.Variable([1, 2, 3, 4, 5])

def foo():
    tmp_list = []
    assign = tf.assign(x[4], 100)
    for i in range(0, 5):
        tmp_list.append(x[i])
    return tmp_list

z = foo()

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    val1, val2 = sess.run([z, assign])
    print(val1, val2)

在我的 Session.run() 中,我同时拥有 z 和 assign。要获得 z,我需要 foo()。当 foo() 为 运行 时,assign = tf.assign(x[4], 100) 也为 运行。但是,输出是 [1, 2, 3, 4, 5] 13,我不知道 13 来自哪里。

无法保证首先执行哪个独立操作,因此在这两种情况下您都可以获得 13 或 14。你的结果是纯粹的运气。试试这个:

with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  for i in range(100):
    val1, val2, val3 = sess.run([x, assign1, assign2])
    print(val1, val2, val3)

... 你会看到 13 14 被打印出来。


后续问题更新:

z = foo()(只是 x 个切片的列表)不依赖于 assign。请注意 foo 在会话开始前只被调用一次。我认为,最好的方式是在 tensorboard 中可视化图形。

如果你说...

sess.run(z)

... tensorflow 不会 运行 assign,因为它没有 运行 一个 python 函数,它计算张量。并且张量 xx[i] 不依赖于操作 assign.

依赖性由使用张量执行的操作定义。所以如果你有...

y = x + 2

...这个一个依赖:为了评估y,tensorflow必须评估x。希望这能让它现在更清楚。