问题
我想要去替换或修改 TensorFlow 中一个 op 或 部分计算图的梯度,该怎么整?
在某些情况下,这和 tf.stop_gradient()
是相对的:我们想要的不是“添加一个 op,然后在计算梯度的过程中忽略该 op”,我们想要的是“只在梯度计算时起作用(I want a calculation which is only used when calculating gradients)”
一个简单的例子如下:
在不改变前向传播的情况下,通过给梯度乘以一个常量来缩放梯度。
另一个例子如下:
在不改变前向传播的过程下,将梯度裁剪到给定的范围。
回答1
回答人:BlueSun
回答质量:很高
版本1
首先定义你自己的梯度计算函数,并注册到 tensorflow
@tf.RegisterGradient("CustomGrad") # 注册到tensorflow
def _const_mul_grad(unused_op, grad):
return 5.0 * grad
因为我们不想改变前向传播过程,因此下面使用上面注册的函数替换原始的梯度计算函数(即用 “CustomGrad” 覆盖 “Identity”)
g = tf.get_default_graph()
with g.gradient_override_map({
"Identity": "CustomGrad"}): # 覆盖该 op 的梯度计算函数
output = tf.identity(input, name="Identity")
下面是一个梯度裁剪的实例:
import tensorflow as tf
@tf.RegisterGradient("CustomClipGrad")
def _clip_grad(unused_op, grad):
return tf.clip_by_value(grad, -0.1, 0.1)
input = tf.Variable([3.0], dtype=tf.float32)
g = tf.get_default_graph()
with g.gradient_override_map({
"Identity": "CustomClipGrad"}):
output_clip = tf.identity(input, name="Identity")
grad_clip = tf.gradients(output_clip, input)
# output without gradient clipping in the backwards pass for comparison:
output = tf.identity(input)
grad = tf.gradients(output,<