tensorflow学习笔记(四十一):control dependencies

tf.control_dependencies()设计是用来控制计算流图的,给图中的某些计算指定顺序。比如:我们想要获取参数更新后的值,那么我们可以这么组织我们的代码。

opt = tf.train.Optimizer().minize(loss)

with tf.control_dependencies([opt]):
  updated_weight = tf.identity(weight)

with tf.Session() as sess:
  tf.global_variables_initializer().run()
  sess.run(updated_weight, feed_dict={...}) # 这样每次得到的都是更新后的weight

关于tf.control_dependencies的具体用法,請移步官网https://www.tensorflow.org/api_docs/python/tf/Graph#control_dependencies,总结一句话就是,在执行某些op,tensor之前,某些op,tensor得首先被运行。

下面说明两种 control_dependencies 不 work 的情况

下面有两种情况,control_dependencies不work,其实并不是它真的不work,而是我们的使用方法有问题。

第一种情况:

import tensorflow as tf
w = tf.Variable(1.0)
ema = tf.train.ExponentialMovingAverage(0.9)
update = tf.assign_add(w, 1.0)

ema_op = ema.apply([update])
with tf.control_dependencies([ema_op]):
    ema_val = ema.average(update)

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for i in range(3):
        print(sess.run([ema_val]))

也许你会觉得,在我们 sess.run([ema_val])ema_op 都会被先执行,然后再计算ema_val,实际情况并不是这样,为什么? 有兴趣的可以看一下源码,就会发现 ema.average(update) 不是一个 op,它只是从ema对象的一个字典中取出键对应的 tensor 而已,然后赋值给ema_val。这个 tensor是由一个在 tf.control_dependencies([ema_op]) 外部的一个 op 计算得来的,所以 control_dependencies会失效。解决方法也很简单,看代码:

import tensorflow as tf
w = tf.Variable(1.0)
ema = tf.train.ExponentialMovingAverage(0.9)
update = tf.assign_add(w, 1.0)

ema_op = ema.apply([update])
with tf.control_dependencies([ema_op]):
    ema_val = tf.identity(ema.average(update)) #一个identity搞定

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for i in range(3):
        print(sess.run([ema_val]))

第二种情况: 这个情况一般不会碰到,这是我在测试 control_dependencies 发现的

import tensorflow as tf
w = tf.Variable(1.0)
ema = tf.train.ExponentialMovingAverage(0.9)
update = tf.assign_add(w, 1.0)

ema_op = ema.apply([update])
with tf.control_dependencies([ema_op]):
    w1 = tf.Variable(2.0)
    ema_val = ema.average(update)

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for i in range(3):
        print(sess.run([ema_val, w1]))

这种情况下,control_dependencies也不 work。读取 w1 的值并不会触发 ema_op, 原因请看代码:

#这段代码出现在Variable类定义文件中第287行,
# 在创建Varible时,tensorflow是移除了dependencies了的
#所以会出现 control 不住的情况
with ops.control_dependencies(None):
    ...      

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python研发

大话设计模式之简单工厂模式

  最近朋友推荐了一本书《大话设计模式》,此书刚刚到,博主也还没开始看,希望以博文的方式与大家一起分享,一起学习.

883
来自专栏我和未来有约会

(收藏)JS验证

1 /* 2 函数名:检验表单的函数 3 作者:xuwen 日期:2007-2-10 4 参数 _obj:验证的对象 ...

17610
来自专栏Android知识点总结

Android基于TCP的五子棋双人对战实现

802
来自专栏较真的前端

Chrome开发者工具还有这些功能,你知道吗?

2238
来自专栏原创

教你如何用AST语法树对代码“动手脚”

作为程序猿,每天都在写代码,但是有没有想过通过代码对写好的代码”动点手脚”呢?今天就与大家分享——如何通过用AST语法树改写Java代码。 先抛一个问题:如何将...

5286
来自专栏C/C++基础

C++注释风格建议

有个笑话,一位从不写注释的程序员在编写一段复杂的代码时,骄傲地认为这段代码只有自己和上帝知道它是干嘛的,等过了一段时间再回顾时,发现没有注释,感叹到这段代码现在...

1191
来自专栏java、Spring、技术分享

Redis设计与实现读书笔记

  Redis底层的数据库采用的就是这种结构,还有哈希键的底层实现之一也是采用HashMap这种结构。 哈希表的节点结构如下:

1192
来自专栏重庆的技术分享区

项目常用的less语法详解

1385
来自专栏三丰SanFeng

Linux64位程序移植

1 概述 Linux下的程序大多充当服务器的角色,在这种情况下,随着负载量和功能的增加,服务器所使用内存必然也随之增加,然而32位系统固有的4GB虚拟地址空间限...

1977
来自专栏向治洪

android应用资源预编译,编译和打包全解析

我们知道,在一个APK文件中,除了有代码文件之外,还有很多资源文件。这些资源文件是通过Android资源打包工具aapt(Android Asset P...

38110

扫码关注云+社区