一、自动差分引擎-正向与反向(预期与反馈)
有点类似于pid,误差计算、反馈与参数设置
加载模型与建立模板图像
import torch, torchvision
model = torchvision.models.resnet18(pretrained=True)
data = torch.rand(1, 3, 64, 64)//单个 3通道 高、宽
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 的微分与梯度
我们用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
。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g67P3Uzp-1628232016333)(img/tex4-1.gif)]
Q = 3*a**3 - b**2
假设a
和b
是神经网络的参数,Q
是误差。 在 NN 训练中,我们想要相对于参数的误差,即
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q07MkCoJ-1628232016335)(img/tex4-2.gif)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fD597qM5-1628232016337)(img/tex4-3.gif)]
当我们在Q
上调用.backward()
时,Autograd 将计算这些梯度并将其存储在各个张量的.grad
属性中。
我们需要在Q.backward()
中显式传递gradient
参数,因为它是向量。 gradient
是与Q
形状相同的张量,它表示Q
相对于本身的梯度,即
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oiidEGQX-1628232016339)(img/tex4-4.gif)]
同样,我们也可以将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)
出:
tensor([True, True])
tensor([True, True])