backward()用法介绍
深度学习中反向传播尤为重要,pytorch中的torch.autograd.backward()函数实现了反向传播的功能。具体相关的参数如下所示:
torch.autograd.backward(tensors, grad_tensors=None, retain_graph=None, create_graph=False, grad_variables=None)
- tensors: 指定需要被求梯度的张量
- grad_tensors:通常是对应张量的每个元素的梯度
- retain_graph:释放或者保留用于计算梯度的计算图
- create_graph:用于计算高阶导数
给定三个向量分别是y=(y1,y2,⋯ ,y3),x=(x1,x2,⋯ ,x3),a=(a1,a2,⋯ ,a3)\boldsymbol{y}=(y_1,y_2,\cdots,y_3),\quad\boldsymbol{x}=(x_1,x_2,\cdots,x_3),\quad \boldsymbol{a}=(a_1,a_2,\cdots,a_3)y=(y1,y2,⋯,y3),x=(x1,x2,⋯,x3),a=(a1,a2,⋯,a3)利用backward()\mathrm{backward}()backward()求y\boldsymbol{y}y关于x\boldsymbol{x}x的梯度的命令为
Jacobian-vecotr = y.backward(torch.FloatTensor([a]))
返回的结果是一个向量,并且每个分量值的数学计算结果为Jacobian_vector(i)=a1y1xi+a2y2xi+a3y3xi+⋯+amymxi(1)\tag{1}\mathrm{Jacobian\_vector(i)}=a_1 \frac{y_1}{x_i}+a_2\frac{y_2}{x_i}+a_3 \frac{y_3}{x_i}+\cdots+a_m \frac{y_m}{x_i}Jacobian_vector(i)=a1xiy1+a2xiy2+a3xiy3+⋯+amxiym(1)
实例讲解
假定令x=(x1,x2)=(2,3)\boldsymbol{x}=(x_1,x_2)=(2,3)x=(x1,x2)=(2,3),y=(x12,x22)\boldsymbol{y}=(x_1^2,x^2_2)y=(x12,x22),则有∂y∂x=(2x1002x2)=(4006)\frac{\partial \boldsymbol{y}}{\partial\boldsymbol{x}}=\left(\begin{array}{cc}2x_1&0\\0&2x_2\end{array}\right)=\left(\begin{array}{cc}4&0\\0&6\end{array}\right)∂x∂y=(2x1002x2)=(4006)根据公式(1)可知,如下命令的结果理论值为
y.backward(torch.FloatTensor([1,1])) => x.grad=(4+0,0+6)=(4,6)
y.backward(torch.FloatTensor([1,0])) => x.grad=(4+0,0+0)=(4,0)
y.backward(torch.FloatTensor([0,1])) => x.grad=(0+0,0+6)=(0,6)
为了验证如上结果,具体的程序代码如下所示:
import torch
from torch.autograd import Variable
FloatTensorList = [torch.FloatTensor([1,1]),torch.FloatTensor([1,0]),torch.FloatTensor([0,1])]
for item in FloatTensorList:
x = Variable(torch.tensor([2.0 , 3.0]), requires_grad = True)
y = x**2
y.backward(item, retain_graph=True)
print(x.grad)
运行的结果为:
tensor([4., 6.])
tensor([4., 0.])
tensor([0., 6.])
由此可以发现,理论值与实验结果值一致。