起因是看到了这么一个帖子:
http://www.cocoachina.com/cms/wap.php?action=article&id=86347
简短来说就是下面的代码 运行起来结果十分的怪异!!!
import tensorflow as tf a = tf.constant(1.) mean_a, mean_a_uop = tf.metrics.mean(a) with tf.control_dependencies([mean_a_uop]): mean_a = tf.identity(mean_a) sess = tf.InteractiveSession() tf.global_variables_initializer().run() tf.local_variables_initializer().run() for _ in range(10): print(sess.run(mean_a))
在CPU上运行:
第一次运行结果:
第二次运行结果:
第三次运行结果:
第四次运行结果:
第五次运行结果:
可以发现上述代码在CPU环境下运行每次结果均不太相同,而且离希望得到结果都不一样。
希望的结果为 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
在GPU上运行:
第一次结果:
第二次结果:
第三次结果:
第四次结果:
第五次结果:
可以发现上述代码在GPU环境下运行每次结果均相同,但都不是希望的结果。
希望的结果为 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
以上则为所引帖子中所提问题。
==================================================================
由上面的问题做了写尝试:(以下测试均在GPU上执行)
1.
import tensorflow as tf a = tf.constant([1.0,]) mean_a, mean_a_uop = tf.metrics.mean(a) sess = tf.InteractiveSession() tf.global_variables_initializer().run() tf.local_variables_initializer().run() for _ in range(10): print(sess.run([mean_a_uop, mean_a])) print('result:--------------------') print(sess.run(mean_a))
最终的均值 mean_a 为1.0, 结果正确。
过程中 mean_a_uop 为全局更新操作,结果一直为1.0,结果正确。
过程中 均值 mean_a 在浮动,不一直为1.0, 结果不正确。
2.
import tensorflow as tf import numpy as np a = tf.constant([1.]) mean_a, mean_a_uop = tf.metrics.mean(a) with tf.control_dependencies([mean_a_uop]): op=tf.no_op() sess = tf.InteractiveSession() tf.global_variables_initializer().run() tf.local_variables_initializer().run() for _ in range(10): print(sess.run([mean_a, op,mean_a_uop])) print('result: --------------------') print(sess.run(mean_a))
最终的均值 mean_a 为1.0, 结果正确。
过程中 mean_a_uop 为全局更新操作,结果一直为1.0,结果正确。
过程中 均值 mean_a 在浮动,不一直为1.0, 结果不正确。
3.
import tensorflow as tf a = tf.constant([1.,]) mean_a, mean_a_uop = tf.metrics.mean(a) with tf.control_dependencies([mean_a_uop]): mean_a2 = tf.identity(mean_a) sess = tf.InteractiveSession() tf.global_variables_initializer().run() tf.local_variables_initializer().run() for _ in range(10): print(sess.run([mean_a2, mean_a, mean_a_uop])) print('result: ---------------') print(sess.run(mean_a))
最终的均值 mean_a 为1.0, 结果正确。
过程中 mean_a_uop 为全局更新操作,结果一直为1.0,结果正确。
过程中 均值 mean_a, mean_a2相等 且在浮动,不一直为1.0, 结果不正确。
===============================================================
根据原帖子将原始代码中的tf.constant 换成 tf.Variable,效果如何呢?
import tensorflow as tf a = tf.Variable(tf.constant(1.)) mean_a, mean_a_uop = tf.metrics.mean(a) with tf.control_dependencies([mean_a_uop]): mean_a = tf.identity(mean_a) sess = tf.InteractiveSession() tf.global_variables_initializer().run() tf.local_variables_initializer().run() for _ in range(10): print(sess.run(mean_a))
CPU上运行:
第一次运行结果:
第二次运行结果:
第三次运行结果:
在GPU上运行呢???
第一次运行:
第二次运行:
第三次运行:
===========================================================================
综上发现如果不规范的使用 tf.metrics 会引发不可预知的后果,主要使用不当如下:(虽然如下的做法也没理由出错,但是事实却是常出错,有问题)
mean_a, mean_a_uop = tf.metrics.mean(a) with tf.control_dependencies([mean_a_uop]): mean_a = tf.identity(mean_a)
for _ in range(10):
print(sess.run(mean_a))
正确使用如下:
import tensorflow as tf a = tf.Variable(tf.constant(1.)) mean_a, mean_a_uop = tf.metrics.mean(a) #with tf.control_dependencies([mean_a_uop]): # mean_a = tf.identity(mean_a) sess = tf.InteractiveSession() tf.global_variables_initializer().run() tf.local_variables_initializer().run() for _ in range(10): print(sess.run(mean_a_uop)) print('result:-------------') print(sess.run(mean_a))
CPU上运行:
GPU上运行:
解决 tf.metrics 出错问题 的关键就是 不使用 依赖控制 tf.control_dependencies 。
mean_a, mean_a_uop = tf.metrics.mean 中的 均值mean_a 和 更新mean_a_uop 不在一个session执行中获得, 即
如下操作:
for _ in range(10): print(sess.run(mean_a_uop)) print('result:-------------') print(sess.run(mean_a))
而且在更新过程中, mean_a_uop 的结果会一直保证正确, mean_a只有在新的session执行中才保证正确。
至于为什么会有这么个结果也是无法解释的,不过这应该是既成事实,使用过程中注意就好,还有就是 依赖控制 慎用 tf.control_dependencies , 不是必须使用的时候就不用。