一、设置Tensor的自动求导属性
#属性设置成自动求导 x = torch.ones(2,4,requires_grad=True) print(x) #由x经过运算得到的其他tensor,也都有equires_grad=True属性了。 y = x + 2 print(y) print(y.requires_grad) #改变x的求导属性,注意requires_grad是属性,requires_grad_是方法 x.requires_grad_(False) print(y.requires_grad,x.requires_grad)
二、求导
x = torch.tensor([[1.,2.,3.],[4.,5.,6.]],requires_grad=True) y = x+1 z = 2*y*y J = torch.mean(z)
求导只能是【标量】对标量,不能【标量】对向量/矩阵求导!所以,上图中,只能J对x、y、z求导,而z则不能对x求导。
- PyTorch里面,求导是调用
.backward()
方法。直接调用backward()方法,会计算对计算图叶节点的导数。 - 获取求得的导数,用
.grad
方法。
J.backward()
x.grad
输出的结果是:
tensor([[1.3333, 2.0000, 2.6667],
[3.3333, 4.0000, 4.6667]])
原公式写成这个模式就能理解为何结果是上面图中的公式了
$\frac{2(x_{1}+1)^{2} + 2(x_{2}+1)^{2} + 2(x_{3}+1)^{2}+2(x_{4}+1)^{2}+2(x_{5}+1)^{2}+2(x_{6}+1)^{2}}{6}$
三、backward的其他性质
一个计算图只能backward一次
原来的程序中J.backward()执行一次后就会把计算题销毁不能重复执行这个反向传播求导。加了一个参数后就可以重复执行求导(不过一般没有意义去重复)
J.backward(retain_graph=True)