control_dependencies(control_inputs)
返回一个上下文管理器,它指定了控制依赖项
使用with关键字来指定所有在上下文中构建的操作,都对于control_inputs有控制依赖。比如:
with g.control_dependencies([a, b, c]):
#’d’和’e’只会在’a’,’b’和’c’运行之后运行
d = ...
e = ...
多次调用control_dependencies()能够被嵌套,并且在这种情况下,新的操作将对所有活动的上下文中的control_inputs组合有控制依赖。
with g.control_dependencies([a, b]):
#在这里创建的操作会在a和b后运行
with g.control_dependencies([c, d]):
#在这里创建的操作会在a,b,c和d后运行
你可以传参None来清除控制依赖:
with g.control_dependencies([a, b]):
# 在这里创建的操作在a和b后运行
with g.control_dependencies(None):
# 在这里创建的操作正常运行,不需要等待a或者b
with g.control_dependencies([c, d]):
# 在这里创建的操作在c和d之后运行,也不需要等待a或者b
注意:控制依赖上下文仅仅应用于那些在上下文里创建的操作上。只是在上下文中使用一个操作或者张量不会添加一个控制依赖。接下来的例子解释了这点:
# WRONG
def my_func(pred, tensor):
t = tf.matmul(tensor, tensor)
with tf.control_dependencies([pred]):
# 乘法操作在上下文之外创建,因此没有控制依赖被添加
return t
# RIGHT
def my_func(pred, tensor):
with tf.control_dependencies([pred]):
# 乘法操作在上下文内创建,因此添加了一个控制依赖
return tf.matmul(tensor, tensor)
同时要注意的是尽管在这个范围之内创建的操作运行会出发依赖的运行,但是在这个范围内创建的操作依然可能被从tensorflow的图中删减。例如,在下列代码片段中,依赖绝不会运行:
loss = model.loss()
with tf.control_dependencies(dependencies):
loss = loss + tf.constant(1) # 注意:依赖在反向传播中被忽略
return tf.gradients(loss, model.variables)
这是因为计算梯度图不会要求计算在向前传播中创建的constant(1)操作。(这里的理解是tf.gradients(loss, model.variables)这个操作,不会触发上述指定的控制依赖中dependencies操作,原因是算梯度的时候,可以忽略常量,就是loss=loss+1不会影响梯度的计算)
参数:
control_inputs:在运行在上下文中定义的操作之前,需要被运行或计算的操作或张量的列表。也可以是None来清除控制依赖。
返回:
上下文管理器,指定了在上下文中创建的所有操作的控制依赖
抛出:
TypeError:如果control_inputs不是操作或者张量对象的列表