这篇文章将要解释pytorch autograd
文档中的vector-Jacobian product
。
文章由pytorch
官方文档中的这段话引出。
首先,雅各比矩阵J
计算的是向量Y
对于向量X
的导数。这里假设向量X[x1,x2,...,xn]
是某个model中的weight。而Y[y1,y2,...,yn]
进而由X
经过某个函数f
产生。那么在backpropagation
时,我们要求得就是这个雅各比矩阵J
那么为什么又要求vector-Jacobian product
呢?
首先复习一下backpropagation
在进行backpropagation
的过程,其实就是本层节点的导数与上流节点的导数的乘积。(local gradient * upstream gradient)
那么我们可以假设,在上面Y = f(X)
的基础上,在引入一层:l = g(Y)
,其中g
是一个新的函数,l
是标量。
那么由链式法则,我们可以知道,l
对于X
的导数即为l
对于Y
的导数与Y
对于X
的导数的乘积。
这里再假设,向量v
就是l
对于Y
的导数。
那么,l
对于X
的导数就是:
上面的公式从右往左看,说明的问题就是:当我新增加一层l = g(Y
)时,l
关于X
的导数直接用l
关于Y
的导数和之前代表导数的雅各比矩阵J
进行乘法即可。这个乘法,就是vector-Jacobian product
至于为什么,l
关于Y
的导数只有一列,因为l
是标量。
所以,pytorch
函数backward()
进行的就是vector-Jacobian product
操作。backward
的参数即为v
,调用者即为Y
。由于v
就是l
关于Y
的导数,所以v
和Y
的形状要相同。若Y
为标量,则不需要加参数。
x = torch.randn(3, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:
y = y * 2
print(y)
Out:
tensor([-1864.6609, -473.0628, 259.2955], grad_fn=<MulBackward0>)
v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)
print(x.grad)
Out:
tensor([1.0240e+02, 1.0240e+03, 1.0240e-01])
y.backward()
Out:
RuntimeError: grad can be implicitly created only for scalar outputs
csdn链接:
CSDN-专业IT技术社区-登录blog.csdn.netReference:
pytorch autogradpytorch.org cs231nwww.youtube.com Medium towards datasciencetowardsdatascience.com