Python 张量流中的自定义渐变-无法理解此示例

Python 张量流中的自定义渐变-无法理解此示例,python,tensorflow,gradient,differentiation,autodiff,Python,Tensorflow,Gradient,Differentiation,Autodiff,我一直在想,我即将了解自定义渐变,但我在这个示例中进行了测试,我无法弄清楚到底发生了什么。我希望有人能告诉我下面到底发生了什么。我认为这本质上是因为我没有明确理解向后函数中的“dy”是什么 v = tf.Variable(2.0) with tf.GradientTape() as t: x = v*v output = x**2 print(t.gradient(output, v)) **tf.Tensor(32.0, shape=(), dtype=float32)**

我一直在想,我即将了解自定义渐变,但我在这个示例中进行了测试,我无法弄清楚到底发生了什么。我希望有人能告诉我下面到底发生了什么。我认为这本质上是因为我没有明确理解向后函数中的“dy”是什么

v = tf.Variable(2.0)
with tf.GradientTape() as t:
    x = v*v 
    output = x**2
print(t.gradient(output, v)) 
**tf.Tensor(32.0, shape=(), dtype=float32)** 
这里一切都很好,梯度也正如人们所期望的那样。然后,我使用定制的渐变来测试这个例子,根据我的理解,这个渐变不可能影响我在clip_by_norm中输入的这个巨大的阈值

@tf.custom_gradient
def clip_gradients2(y):
    def backward(dy):
        return tf.clip_by_norm(dy, 20000000000000000000000000)
    return y**2, backward

v = tf.Variable(2.0) 
with tf.GradientTape() as t: 
    x=v*v
    
    output = clip_gradients2(x) 


print(t.gradient(output, v))
tf.Tensor(4.0,shape=(),dtype=float32)


但是它被减少到4,所以这在某种程度上是有效果的。这究竟是如何导致更小的梯度的?

在编写自定义梯度时,您必须自己定义整个导数计算。在没有自定义渐变的情况下,我们有以下导数:

((x**2)**2)dx = (x**4)dx = 4*(x**3) = 32 when x=2
当覆盖渐变计算时,只有

(x**2)dx = 2x = 4 when x=2
您需要计算函数中的导数,即:

@tf.custom_gradient
def clip_gradients2(y):
    def backward(dy):
        dy = dy * (2*y)
        return tf.clip_by_norm(dy, 20000000000000000000000000)
    return y**2, backward

以获得所需的行为。

您的代码中有一个小的输入错误,在
自定义梯度2
函数中应该是
返回y**2
。至于行为,我会尽力回答你。是的,很好发现,现在更新。非常感谢。这就是我的原因,我不知道y**2的导数在哪里消失了——这很有道理。干杯