深度学习库能够充分发挥GPU并行计算的能力,但是有时我们却不得不需要串行。这时就需要用到依赖控制。
import tensorflow as tf
a = tf.Variable(1)
b = tf.Variable(2)
s = tf.add(a, b)
asiggn = tf.assign(a, 4)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run([a, b, s, asiggn]))
理论上,这段程序有时输出6,有时输出3。也就是说,求和操作和复制操作无法确定谁先执行。
如果想要先求和再赋值,那么需要使用依赖控制指明依赖。
import tensorflow as tf
a = tf.Variable(1)
b = tf.Variable(2)
s = tf.add(a, b)
with tf.control_dependencies([s]):
asiggn = tf.assign(a, 4)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run([a, b, s, asiggn]))
每一次sess.run,每个结点只求解一次。
然而需要理解的一个关键点是:
将多个结点打包之后,对这个包加上依赖控制,并不会影响被打包的各个结点的依赖。
# 将结点打包,同时执行多个结点
import tensorflow as tf
tf.reset_default_graph()
a = tf.Variable(1, name="a")
b = tf.Variable(2, name="b")
c = tf.Variable(3, name="c")
with tf.control_dependencies([a, b, c]):
before_sum = tf.add_n([a, b, c])
a_add1 = tf.assign(a, tf.add(a, 1, name='a_add1'))
b_add2 = tf.assign(b, tf.add(b, 2, name='b_add2'))
c_add3 = tf.assign(c, tf.add(c, 3, name='c_add3'))
with tf.control_dependencies([before_sum]):
# group操作run之后返回值为None,它只负责同时执行,它并不负责控制依赖
op = tf.group(a_add1, b_add2, c_add3)
with tf.control_dependencies([op]): # 如果没有这句话,则sum操作和op操作是并行的,导致出现奇怪的现象
after_sum = tf.add_n([a, b, c])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run([before_sum, op, a, b, c, after_sum]))
输出为:[12, None, 2, 4, 6, 12]
表示beforesum并没有在op之前执行。
要想在op之前求before_sum,那就需要为op中的每个结点添加依赖
# 将结点打包,同时执行多个结点
import tensorflow as tf
tf.reset_default_graph()
a = tf.Variable(1, name="a")
b = tf.Variable(2, name="b")
c = tf.Variable(3, name="c")
with tf.control_dependencies([a, b, c]):
before_sum = tf.add_n([a, b, c])
with tf.control_dependencies([before_sum]):
a_add1 = tf.assign(a, tf.add(a, 1, name='a_add1'))
with tf.control_dependencies([before_sum]):
b_add2 = tf.assign(b, tf.add(b, 2, name='b_add2'))
with tf.control_dependencies([before_sum]):
c_add3 = tf.assign(c, tf.add(c, 3, name='c_add3'))
with tf.control_dependencies([before_sum]):
# group操作run之后返回值为None,它只负责同时执行,它并不负责控制依赖
op = tf.group(a_add1, b_add2, c_add3)
with tf.control_dependencies([op]): # 如果没有这句话,则sum操作和op操作是并行的,导致出现奇怪的现象
after_sum = tf.add_n([a, b, c])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run([before_sum, op, a, b, c, after_sum]))
"""
执行顺序不同会出现什么情况
"""