我想知道sess.run(ops_list,...)中op列表的运行顺序是什么。例如:
对于典型的分类方案:_, loss = sess.run([train_op, loss_op])
,如果先运行train_op
,则损失为当前反向传播后的损失。但是,如果loss
首先运行,则损失为当前反向传播之前的损失。
有人帮我吗?谢谢。
答案 0 :(得分:2)
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
有时是更新值的两倍,有时是未更新值的两倍。例如,如果我们要确保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]))
始终产生:
[1, 0]
[2, 2]
[3, 4]
[4, 6]
[5, 8]