Tensorflow 中 sess.run([op1, op2...]) 的顺序

Lon*_*gqu 6 python tensorflow

我想知道 sess.run(ops_list, ...) 中 op 列表的运行顺序是什么。例如:对于典型的分类场景:_, loss = sess.run([train_op, loss_op])如果train_op先运行,则损失是当前反向传播后的损失。但是如果loss先运行,那么损失就是当前反向传播之前的损失。有人帮我吗?谢谢。

jde*_*esa 6

loss将是由引起的更新损失的值train_op。请注意,这loss_op是优化器的输入,因此它必须train_op在图中“之前” 。在操作开始loss_op使用变量值计算。如果你想计算的损失,你能做到这一点,例如使用与优化块,并再次计算的损失,但在这种情况下,你会在每一步做模型的两个正向合格,相关的成本。通常,如果您只想绘制监控的损失或类似的东西,可以使用上一步中的值。run train_optf.control_dependencies

为了进一步说明,一般情况下,TensorFlow 操作的执行顺序仅在这些操作相互依赖的范围内得到保证,与传递给 的顺序无关run。在您的情况下,train_op取决于loss_op,因此loss_op必须先行。然而,在其他情况下,操作并不直接相互依赖,在这种情况下,顺序是不能保证的。很多时候这并不重要,但在某些情况下确实如此。考虑下一个例子:

import tensorflow as tf

v = tf.Variable(0)
v2 = 2 * v
v_update = v.assign(v + 1)
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    for i in range(5):
        print(sess.run([v_update, v2]))
Run Code Online (Sandbox Code Playgroud)

在我的电脑上运行产生了这个输出:

import tensorflow as tf

v = tf.Variable(0)
v2 = 2 * v
v_update = v.assign(v + 1)
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    for i in range(5):
        print(sess.run([v_update, v2]))
Run Code Online (Sandbox Code Playgroud)

如您所见,v2有时是更新值的两倍,有时是未更新值的两倍。例如,如果我们想确保我们可以做之前v2总是运行: v_update

import tensorflow as tf

v = tf.Variable(0)
v2 = 2 * v
with tf.control_dependencies([v2]):
    v_update = v.assign(v + 1)
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    for i in range(5):
        print(sess.run([v_update, v2]))
Run Code Online (Sandbox Code Playgroud)

始终如一地产生:

[1, 0]
[2, 2]
[3, 4]
[4, 8]
[5, 10]
Run Code Online (Sandbox Code Playgroud)