Pytorch中的backward

  • Post author:
  • Post category:其他


首先声明Pytorch的backward机制:



y.backward()



时,如果



y



是标量(scalar),则不需要为



backward()



传入任何参数;


如果



y



是张量(tensor),需要传入一个与

y



同形的



Tensor(张量)


①y是scalar标量

image.png

②y是Tensor张量

①如果直接像标量那样计算
image.png

就会报错显示:

RuntimeError: grad can be implicitly created only for scalar outputs。

翻译过来就是,grad只能隐式地为标量输出创建。



y


调用



backward



时需要传入一个和



y



同形的权重向量进行加权求和得到一个标量


image.png

所以要谨记:

在Pytorch中,


调用



backward



时,一定是标量对张量求导


③续

1.为什么不能

Tensor 对 Tensor 求导

举个例子,假设形状为

m x n

的矩阵 X 经过运算得到了

p x q

的矩阵 Y,Y 又经过运算得到了

s x t

的矩阵 Z。那么按照前面讲的规则,dZ/dY 应该是一个

s x t x p x q

四维张量,dY/dX 是一个

p x q x m x n

的四维张量。问题来了,怎样反向传播?怎样将两个四维张量相乘???这要怎么乘???就算能解决两个四维张量怎么乘的问题,四维和三维的张量又怎么乘?导数的导数又怎么求,这一连串的问题,感觉要疯掉…… 为了避免这个问题,我们

不允许张量对张量求导,只允许标量对张量求导,求导结果是和自变量同形的张量


2.

y.backward(w)

前面提高的都是直接

y.backward()

,那么如果是

y.backward(w)

呢?


y.backward(w) 求的就不是 y 对 x 的导数,而是 l = torch.sum(y*w) 对 x 的导数,即dl/dx = d(y*w)/dx。


举个例子:



image.png



image.png


t.backward(z)

,即

l = torch.sum(t*z)

所以x.grad = dl/dx = d(t * z)/dx = d((x +y) * z)/dx = z;

y.grad = dl/dy = d(t * z)/dy = d((x +y) * z)/dy = z;

【参考资料:①Dive-into-DL-PyTorch-master   ②

https://zhuanlan.zhihu.com/p/29923090




版权声明:本文为qq_38880969原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。