虽然有很多参考文献显示了如何注册渐变,但我仍然不太清楚需要定义什么样的渐变 .
一些类似的主题:How to register a custom gradient for a operation composed of tf operations
How Can I Define Only the Gradient for a Tensorflow Subgraph?
好的,这是我的问题:
我有一个前向函数 y = f(A,B)
,其中每个函数的大小为:
y: (batch_size, m, n)
A: (batch_size, a, a)
B: (batch_size, b, b)
假设我可以写下关于A和B的每个元素的y的每个元素的数学偏导数 . dy/dA, dy/dB
. 我的问题是我应该在渐变函数中返回什么?
@ops.RegisterGradient("f")
def f_grad(op, grad):
...
return ???, ???
Here表示渐变函数的结果必须是Tensor对象列表,表示相对于每个输入的渐变 .
当 y
是标量且 A
, B
是矩阵时,很容易理解要定义的梯度 . 但是当 y
是矩阵并且 A
, B
也是矩阵时,该梯度应该是什么?
1 Answer
tf.gradients计算每个输出张量之和相对于输入张量中每个值的梯度 . 渐变操作接收用于计算渐变的op,
op
以及此时累积的渐变grad
. 在您的示例中,grad
将是与y
具有相同形状的张量,并且每个值将是y
中相应值的渐变 - 也就是说,如果grad[0, 0] == 2
,则意味着将y[0, 0]
增加1将增加输出的总和张紧2(我知道,你可能已经清楚了) . 现在你必须为A
和B
计算相同的东西 . 假设您认为将A[2, 3]
增加1将使y[0, 0]
增加3并且对y
中的任何其他值都没有影响 . 这意味着将输出值的总和增加3×2 = 6,因此A[2, 3]
的梯度将为6 .举个例子,让我们采用矩阵乘法的梯度(op
MatMul
),你可以在_1844913中找到它:我们将重点关注
transpose_a
和transpose_b
都是False
的情况,因此我们在第一个分支if not t_a and not t_b:
(也忽略conj
,这意味着复数值) . 'a'和'b'是这里的操作数,如前所述,grad
具有相对于乘法结果中每个值的输出之和的梯度 . 那么,如果我将_1844923增加一个,情况将如何变化?基本上,产品矩阵的第一行中的每个元素将增加b
的第一行中的值 . 所以a[0, 0]
的梯度是b
的第一行和grad
的第一行的点积 - 也就是说,我将增加每个输出值乘以每个输出值的累计梯度 . 如果你考虑一下,那么grad_a = gen_math_ops.mat_mul(grad, b, transpose_b=True)
就是这么做的 .grad_a[0, 0]
将是grad
的第一行和b
的第一行的点积(因为我们在这里转置b
),并且,通常,grad_a[i, j]
将是grad
的i
行和j
的点积 - 第b
行 . 您也可以遵循grad_b
的类似推理 .编辑:
作为示例,请查看tf.gradients和注册的渐变如何相互关联:
输出: