![](/img/trans.png)
[英]Is there any option at Pytorch autograd function for these problem?
[英]PyTorch autograd: dimensionality of custom function gradients?
问题总结:自定义函数的backward pass中如何处理输入和输出的维度?
根据手册,自定义函数的基本结构如下:
class MyFunc(torch.autograd.Function):
@staticmethod
def forward(ctx, input): # f(x) = e^x
result = input.exp()
ctx.save_for_backward(result)
return result
@staticmethod
def backward(ctx, grad_output): # df(x) = e^x
result, = ctx.saved_tensors
return grad_output * result
对于单个输入和输出维度,这完全没问题,而且效果很好。 但是对于更高的维度,向后传递变得混乱。 显然,PyTorch只接受的结果backward
具有相同维数的结果forward
(对于相同的输入)。 返回错误的形状会产生RuntimeError: Function MyFunc returned an invalid gradient at index 0 - got [*] but expected shape compatible with [*]
。 所以我想知道:向后实际计算什么?
它不是雅可比行列式吗? 例如,当我有一个函数f(x) = ( f_1(x_1, ... , x_n), ... , f_k(x_1, ... , x_n) )
具有n
输入和k
输出时,我希望梯度计算将产生维度为k*n
的雅可比矩阵。 然而,PyTorch 实现只需要一个维度为n
的向量。 那么向后结果实际上意味着什么,它不可能是雅可比行列式呢?
它不处理批次? 此外,如果我想通过这个函数推送一批输入向量怎么办,例如一个维度为b*n
且批量大小为b
。 然后,而不是像b*k*n
之类的东西,梯度也应该具有形状b*n
。 它甚至打算考虑使用自定义函数处理批处理吗?
手册中似乎没有解决这些问题,并且提供的示例非常简单,根本没有帮助。 也许隐藏在某处的公式更详细地解释了提供的Function
接口的背景,但我还没有找到它们。
它不存储/返回雅可比行列式(我想这与内存考虑有关)。
从训练的角度来看,我们不需要雅可比矩阵来进一步更新参数/反向传播。
对于更新参数,我们只需要dL/dy_j
, j<n
:
y_j -= alpha * dL/dy_j
对于z
反向传播,假设z=f(y)=f(g(x))
:
dL/dz_k = dL/dy_j * dy_j/dz_k
有人可能会说“但我们这里需要dy_j/dz_k
!” -- 确实如此,但我们不需要存储它(就像我们在这一步中根本不使用dx_i/dy_j
的雅可比行列式dx_i/dy_j
)。
换句话说,雅可比行列式只是隐式使用,大部分不需要,因此为了记忆而取消。
对于批处理部分,请注意小批量学习大多只是平均梯度。 PyTorch 期望您在向后函数中处理它(同样,该函数尽可能少地返回并节省尽可能多的内存)。
注意:可以“收集”雅可比矩阵并获得您提到的n
大小的向量。 具体来说,在k
维上求和,在批处理维上求平均值。
编辑:不是 100% 确定,但我认为向后调用(f(x)=y)预计会返回这个向量:
其中\\nabla x
是backward
的输入参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.