如何在Tensorflow中使用变量的旧值和新值?

How to use the old value and the new value of a Variable in Tensorflow?

我想使用变量的旧值和新值。但我是 对何时应用 Assign Op 感到困惑。

这是一个简单的例子。 outputoutput2 的输出不同。

v = tf.Variable(0)
with tf.Session() as sess:
    sess.run(v.initializer)

    new_v = v.assign(v + 10)
    output = v + 0 # `v` is evaluated before the assignment ?
    output2 = v  # `v` is evaluated after the assignment ?

    print(sess.run([ output, output2, new_v])) 
    print(sess.run(output))

结果是

[0, 10, 10]

10

请告诉我使用变量的旧值和新值的正确方法是什么。谢谢。


根据chrisz的回答,我尝试tf.control_dependencies获取v的旧值。但是结果不是我所期望的。我仍然需要将 0 添加到 v 以获得旧值。

这是测试代码。然后我添加一个 0 以获得与上面相同的结果。否则,output_old 的结果将是 10

v = tf.Variable(0)
with tf.Session() as sess:
    sess.run(v.initializer)
    output_old = v + 0         # If I want the old value, this extra add is needed
    with tf.control_dependencies([output_old]):
        new_v = v.assign(v + 10)
        output_new = new_v

    print(sess.run([output_old, output_new, new_v])) 
    print(sess.run(output_old))

首先,当提取是独立的时,通常无法保证它们的计算顺序( 具有类似的情况)。

例如,如果您 运行 循环中的脚本,您可能偶尔会得到 [10, 10, 10],这意味着首先评估 new_v。在我的机器上,我无法使 output2 计算为 0,因此它很可能是实现功能,但如果它在不同平台或不同版本之间发生变化,我不会感到惊讶。唯一保证的值是 new_v,它永远是 10outputoutput2 都可以是 010.

要回答您的问题,同时获取两个值的最佳方法是添加另一个变量并使用 tf.control_dependencies 上下文:

v = tf.Variable(0)
tmp = tf.Variable(0)
with tf.Session() as sess:
    sess.run([v.initializer, tmp.initializer])
    saved_v = tmp.assign(v)
    with tf.control_dependencies([saved_v]):
      new_v = v.assign(v + 10)
      old_v = tf.identity(saved_v)
      # At this point, `new_v` is guaranteed to be 10, 
      # `old_v` and `saved_v` are guaranteed to be 0

请注意,如果没有 tf.control_dependencies,它通常不会工作,因为 old_vsaved_v 可以在 new_v 之后计算。你依赖 output_old = v + 0 的技巧也有效,但对我来说它看起来更像是一个 hack。无论如何,你无法避免 tf.control_dependencies.