一、最简单的例子
基本路线:
创建x——使x可被计算图跟踪——构建y与x的关系——y反向传播——最终梯度
import torch
x = torch.arange(4.0)
x.requires_grad_(True)
y = 2*torch.dot(x,x)
y.backward()
x.grad
二、分离计算——既暂时分离无关的变量,研究 相关自变量 与 因变量 的关系
此代码延续上一段代码,因为pytorch中的梯度默认会累加,所以先对梯度进行清空
z = y*x y = x^2,不考虑y,计算z对x的偏导数。因此需要想办法将y从计算图中分离
x.grad.zero_() # x梯度清零
y = x*x
u = y.detach() # 将y替换为从计算图中分离的、等大小的u
z = u*x
z.sum().backward()
x.grad
Q:为什么z在反向传播的时候必须加上.sum()
A:
pytorch规定不让张量对张量求导,只能标量对张量求导。
此时分为两种情况,当y为标量时,对y进行反向传播则不需要任何输入变量,个人理解是即默认此时y为网络输出的最后一层,其再没有上一层变量关于其的梯度了(因为为标量)。
当y为非标量Variable类型时,根据pytorch中文官网的介绍,“backward的输入参数是 此operation的输出的值的梯度,backward的返回值是此operation输入值的梯度。”,对于这句话,我个人的理解是因为输出仍未非标量,所以其还在传播过程中,pytorch需要知道该变量上一级关于其的梯度。需要在backward()的参数中传入该梯度。
参考:blog.csdn.net/qq_26826331/article/details/104333862
不过,对于非标量的反向传播,在神经网络损失函数的计算中一般用不到。回头再补充吧。