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

7

我想知道sess.run(ops_list, ...)中操作列表的运行顺序。例如:对于典型的分类场景:_, loss = sess.run([train_op, loss_op]),如果train_op先运行,则损失是当前反向传播后的损失。但是如果loss先运行,则损失是当前反向传播前的损失。

有人能帮我吗?谢谢。

1个回答

8
loss将是train_op引起更新之前的损失值。请注意,loss_op是优化器的输入,因此在图中它必须放在train_op之前。loss_op使用run操作开始时的变量值进行计算。如果您想计算train_op后的损失值,可以使用tf.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]))

我的电脑运行后产生了这个输出:
[1, 0]
[2, 2]
[3, 4]
[4, 8]
[5, 10]

正如您所看到的,v2 有时是更新值的两倍,有时是非更新值的两倍。例如,如果我们想确保在 v_update 之前始终运行 v2,可以执行以下操作:

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]))

它能持续产生:

[1, 0]
[2, 2]
[3, 4]
[4, 6]
[5, 8]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接