torch.autograd
torch.autograd是自动差分引擎,可为神经网络训练提供支持。
神经网络是在某些输入数据上执行的嵌套函数集合。这些函数由权重和偏差(这两个参数)定义,这些参数存储在Pytorch张量中。
神经网络的两个内步骤:
正向传播:在正向传播中,神经网络对正确的输出进行最佳的预测。他通过其每个函数运行输入数据进行猜测。
反向传播:在反向传播中,神经网络根据猜测中的误差来调整其参数。他通过从输出向后遍历,收集有关函数参数(梯度)的误差导数,使用梯度下降来优化参数来实现。
例子
从torchvision中加载了经过预训练的resnet18模型。创建一个随机数据张量来表示具有3个通道的单个图像,其赌赢的label初始化为一些随机值。
import torch, torchvision
model = torchvision.models.resnet18(pretrained=True)
data = torch.rand(1, 3, 64, 64)
labels = torch.rand(1, 1000)
接下来,通过模型的每一层运行输入数据进行预测,这是正向传播。
prediction = model(data) # forward pass
使用模型的预测和相应的标签来计算误差(loss)。下一步是通过网络反向传播此误差,当在误差张量上调用.backward()时,开始反向传播。然后,Autograd会为每个模型参数计算梯度并将其存储在参数.grad属性中。
loss = (prediction - labels).sum()
loss.backward() # backward pass
接下来,在加载一个优化器,在这个例子中为SGD,学习率为0.01,动量为0.9.
optim = torch.optim.SGD(model.parameters(), lr=1e-2, momentum=0.9)
最后,调用.step()启动梯度下降。优化器通过.grad中存储的梯度来调整每个参数。
optim.step() #gradient descent
以上即是训练一个神经网络所需要的一切。
Autograd的微分
接下来看一下autograd是如何收集梯度。
用requires_grad = True创建两个张量a,b。这向autograd发出信号,应跟踪他们的操作。
import torch
a = torch.tensor([2., 3.], requires_grad=True)
b = torch.tensor([6., 4.], requires_grad=True)
从a和b创建另一个张量Q。
Q = 3a² - b²
Q = 3*a**3 - b**2
假设a和b是神经网络的参数,Q是误差。 在 神经网络 训练中,想要相对于参数的误差,即
在Q上调用.backward()时,Autograd将计算这些梯度并将其存储在各个张量的.grad属性中。需要在Q.backward()中
显式传递gradient参数,因为它是向量。gradient是与Q形状相同的张量,他表示Q相对于本身的梯度,即:
同样,也可以将Q聚合为一个标量,然后隐式地向后调用,例如Q.sum().backward().
external_grad = torch.tensor([1., 1.])
Q.backward(gradient=external_grad)
梯度现在沉积在a.grad 和 b.grad中
# check if collected gradients are correct
print(9*a**2 == a.grad)
print(-2*b == b.grad)