PyTorch学习02-torch.autograd的简要介绍

提示1:原文链接
提示2:反向传播原理讲解


前言

  提示:本篇博客主要是记录torch.autograd的学习过程,当作是一个笔记来使用。
  背景知识:

  • 神经网络(NN)是在某些输入数据上执行的嵌套函数的集合。 这些函数由参数(由权重和偏差组成)定义,这些参数在 PyTorch 中存储在张量中。
  • 训练 NN 分为两个步骤:
  • 正向传播:在正向传播中,NN 对正确的输出进行最佳猜测。 它通过其每个函数运行输入数据以进行猜测。
  • 反向传播:在反向传播中,NN 根据其猜测中的误差调整其参数。 它通过从输出向后遍历,收集有关函数参数(梯度)的误差导数并使用梯度下降来优化参数来实现。

一、正向传播

  通过模型的每一层运行输入数据以进行预测, 这是正向传播,下面的代码帮助理解。

import torch, torchvision
model = torchvision.models.resnet18(pretrained=True)
data = torch.rand(1, 3, 64, 64)
labels = torch.rand(1, 1000)
prediction = model(data) # 正向传播

二、反向传播

2.1 反向传播过程

  核心过程如下图,详细内容指路 此处
反向传播核心

2.2 案例代码

2.2.1 反向传播

  使用模型的预测和相应的标签来计算误差(loss)。 下一步是通过网络反向传播此误差。 当我们在误差张量上调用【.backward()】时,开始反向传播。 然后,Autograd 会为每个模型参数计算梯度并将其存储在参数的【.grad】属性中。代码如下:

loss = (prediction - labels).sum()
loss.backward() # 反向传播

2.2.2 优化参数

  接下来,加载一个优化器,在本例中为 SGD,学习率为 0.01,动量为 0.9。 我们在优化器中注册模型的所有参数。最后,我们调用【.step()】启动梯度下降。 优化器通过.grad中存储的梯度来调整每个参数。

optim = torch.optim.SGD(model.parameters(), lr=1e-2, momentum=0.9)
optim.step() # 梯度下降

三、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 = 3 a 3 − b 2 Q=3a^3 - b^2 Q=3a3b2,则
∂ Q ∂ a = 9 a 2 \frac{\partial Q}{\partial a}=9a^2 aQ=9a2 ∂ Q ∂ b = − 2 b \frac{\partial Q}{\partial b}=-2b bQ=2b
  当我们在Q上调用【.backward()】时,Autograd 将计算这些梯度并将其存储在各个张量的【.grad】属性中。我们需要在Q.backward()中显式传递gradient参数,因为它是向量。 gradient是与Q形状相同的张量,它表示Q相对于本身的梯度,即
d Q d Q = 1 \frac{dQ}{dQ} = 1 dQdQ=1
  同样,我们也可以将Q聚合为一个标量,然后隐式地向后调用,例如Q.sum().backward()。

external_grad = torch.tensor([1., 1.])
Q.backward(gradient=external_grad)

  梯度现在沉积在a.grad和b.grad中,使用下列代码可以查看。

print(9*a**2 == a.grad)
print(-2*b == b.grad)

四、计算图

  从概念上讲,Autograd 在由 函数 对象组成的有向无环图(DAG)中记录数据(张量)和所有已执行的操作(以及由此产生的新张量)。 在此 DAG 中,叶子是输入张量,根是输出张量。 通过从根到叶跟踪此图,可以使用链式规则自动计算梯度。

常用函数:

  • torch.Tensor.grad:默认情况下,此属性为 None 并在第一次调用 backward() 为 self 计算梯度时变为张量。
  • torch.Tensor.requires_grad:为True时计算梯度

在正向传播中,Autograd 同时执行两项操作:

  • 运行请求的操作以计算结果张量;
  • 并且在 DAG 中维护操作的梯度函数。

当在 DAG 根目录上调用.backward()时,后退通道开始,autograd然后:

  • 从每个.grad_fn计算梯度,
  • 将它们累积在各自的张量的.grad属性中,
  • 然后使用链式规则,一直传播到叶子张量。

注意:
   1、DAG 在 PyTorch 中是动态的。要注意的重要一点是,图是从头开始重新创建的; 在每个【.backward()】调用之后,Autograd 开始填充新图。 这正是允许您在模型中使用控制流语句的原因。 您可以根据需要在每次迭代中更改形状,大小和操作。
   2、【torch.autograd】跟踪所有将其requires_grad标志设置为True的张量的操作。 对于不需要梯度的张量,将此属性设置为False会将其从梯度计算 DAG 中排除,在 NN 中,不计算梯度的参数通常称为冻结参数。 如果事先知道您不需要这些参数的梯度,则“冻结”模型的一部分很有用(通过减少自动梯度计算,这会带来一些表现优势)。


总结

  反向误差传播是一个比较难理解的点,PyTorch框架将此内容整合到了框架里面,因此后续的学习中只要会使用就可以了,想弄清具体原理的还需要自行查阅资料,希望本篇博客可以帮到你。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦想拯救世界_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值