首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何理解tf.control_dependencies?

如何理解tf.control_dependencies?
EN

Stack Overflow用户
提问于 2017-11-12 11:45:12
回答 1查看 1.5K关注 0票数 2

有一个非常奇怪的例子:

代码语言:javascript
复制
w = tf.get_variable("w", shape=(), dtype=tf.int32,
                    initializer=tf.constant_initializer(2))

reset = tf.assign(w, 0)
update = tf.assign(w, w + 3)
update = tf.Print(update, [update])
reset = tf.Print(reset, [reset])
def body(i,x):
    with tf.control_dependencies([update]):
        t = tf.identity(w)

    with tf.control_dependencies([reset]):
        y = tf.identity(t)
    return i+1, y
i, z = tf.while_loop(lambda i,z: i < 20, body, [0,0])
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    print(sess.run(z))

输出为5。但如何解释呢?正如我们所看到的,reset不被执行,而update只使用tf.Print执行一次。但是tf.while_loop将执行body 20次。所以这太神奇了。

更新

另一个奇怪的示例

代码语言:javascript
复制
import tensorflow as tf

x = tf.Variable(0, dtype=tf.int32)

old_val = tf.identity(x)
with tf.control_dependencies([old_val]):
    new_val = tf.assign(x, x + 1)


with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    print(sess.run([old_val, new_val, x]))

输出为[1,1,1]。在看完github的问题后,我也很困惑。sess.run()一个接一个地执行,这意味着它运行old_val,然后运行new_val,然后运行x

当它运行old_val时,它得到0,当它运行new_val时,它发现old_valnew_val的依赖项,但是old_val已经运行。所以它立即运行new_val,得到1,然后运行x,得到1

所以我认为它应该打印[0,1,1],那么有什么问题吗?

EN

回答 1

Stack Overflow用户

发布于 2017-11-12 19:22:14

以下是你为什么得到这个结果的解释:

让我们跟随您在会话中执行的节点上的图,看看会发生什么。

sess.run(z)

z是tf.while_loop的第二个返回变量,因此让我们看看执行tf.while_loop节点时会发生什么。

第一次迭代:

tf.while_loop执行body函数,直到谓词为真为止。因此,对于这第一次呼吁:

body(i,x)调用-> -- body函数的主体不引用x变量。因此

return i+1, y

while循环继续进行,现在在body调用中将y作为x传递。

第二次迭代:

body(i, x) = run(body(_,yvariable of the previous iteration))

现在,Tensorflow需要解析y变量。

  1. y变量是tf.identity(t)
  2. tf.identity(t)必须在reset = tf.assign(w,0)之后执行。
  3. tf.identity(t)引用t。在执行reset之后,我们必须解析t,对其进行评估,然后退出y

因此:只有在执行t = tf.identity(w) ->之后才能执行update

因此,按以下顺序执行:update -> t -> reset -> y

评价结果:w = w + 3 -> w = 5; t = 5; w = 0; y = t = 5; return 5.

副作用

updatereset节点在body函数之外声明,这意味着它们只是两个独立的节点,现在它们被标记为执行的(概念上的)。

第三次迭代

计算顺序与上一次迭代相同,但是:updatereset节点已经执行(因为存在已执行的标志),因此tf.control_dependencies跳过它们的执行,Tensorflow只执行ty

因此:t = 5; y = 5; return 5.

正如您所看到的,从现在开始,您将得到5作为结果,始终如此。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47248406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档