什么是 PyTorch 中的自动微分?

什么是 PyTorch 中的自动微分?

自动微分(Automatic Differentiation,AD)是机器学习中重要的数学工具之一,也是 PyTorch 中的核心特性之一。通过自动微分,我们可以在不手动计算导数的情况下,快速准确地计算出损失函数对于模型参数的导数。这极大地简化了模型训练过程中的数学计算,并且使得深度学习算法的实现更加方便。

自动微分在 PyTorch 中的算法原理

PyTorch 中的自动微分实现了反向自动微分(Reverse Mode Automatic Differentiation,RMAD),也被称为反向模式自动微分。在该算法中,模型的前向传播和反向传播分别对应着两个阶段:

  1. 前向传播阶段:在前向传播过程中,我们将输入数据通过神经网络模型,得到预测输出的结果。在这个阶段,我们需要保留模型中每一步计算的中间结果(张量),以便在后续的反向传播中使用。

  2. 反向传播阶段:在反向传播过程中,我们首先计算损失函数对于预测输出的梯度,然后通过链式规则逐层计算模型参数的梯度。这个过程中,PyTorch 会自动根据前向传播阶段保留的中间结果来计算每一步的梯度值,并用梯度下降等优化算法来更新模型参数。

PyTorch 自动微分的公式推导

接下来,我们来推导一下 PyTorch 自动微分的公式。假设我们的模型为一个多层感知机(Multi-Layer Perceptron,MLP),其中包含了两个隐藏层和一个输出层。我们使用交叉熵损失函数作为模型的训练目标。

首先,我们定义模型的输出为 y = f ( x ) y = f(x) y=f(x),其中 x x x 是输入数据, y y y 是模型的预测输出。损失函数可以表示为 L ( y , y true ) L(y, y_{\text{true}}) L(y,ytrue),其中 y true y_{\text{true}} ytrue 是真实标签。

模型的目标是最小化损失函数 L L L,即 minimize θ   L ( y , y true ) \underset{\theta}{\text{minimize}}\,L(y, y_{\text{true}}) θminimizeL(y,ytrue),其中 θ \theta θ 是模型的参数。

根据链式法则,我们可以推导出损失函数对于模型参数的导数为:

∂ L ∂ θ = ∂ L ∂ y ⋅ ∂ y ∂ θ \frac{{\partial L}}{{\partial \theta}} = \frac{{\partial L}}{{\partial y}} \cdot \frac{{\partial y}}{{\partial \theta}} θL=yLθy

对于每个参数 θ i \theta_i θi,我们可以使用梯度下降等优化算法来更新该参数的值:

θ i ← θ i − α ⋅ ∂ L ∂ θ i \theta_i \leftarrow \theta_i - \alpha \cdot \frac{{\partial L}}{{\partial \theta_i}} θiθiαθiL

其中 α \alpha α 是学习率。

PyTorch 自动微分的计算步骤

  1. 定义模型结构:我们需要定义一个包含两个隐藏层和一个输出层的多层感知机模型。

  2. 设置损失函数:我们选择交叉熵损失函数作为模型的训练目标。

  3. 前向传播:将输入数据 x x x 通过模型,得到预测输出 y y y。在这个过程中,PyTorch 会自动记录并保留每一步的计算结果(张量)。

  4. 计算损失函数:将预测输出 y y y 和真实标签 y true y_{\text{true}} ytrue 传入损失函数,得到损失值 L L L

  5. 反向传播:调用 L.backward() 函数,PyTorch 会自动根据链式法则计算出损失函数对于模型参数的梯度。

  6. 参数更新:根据梯度下降等优化算法,使用以下公式来更新模型参数: θ i ← θ i − α ⋅ ∂ L ∂ θ i \theta_i \leftarrow \theta_i - \alpha \cdot \frac{{\partial L}}{{\partial \theta_i}} θiθiαθiL,其中 α \alpha α 是学习率。

  7. 重复步骤 3-6,直到达到设定的训练迭代次数或者收敛条件。

PyTorch 自动微分的 Python 代码示例

import torch
import torch.nn as nn
import torch.optim as optim

# 定义多层感知机模型
class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.fc1 = nn.Linear(10, 100)
        self.fc2 = nn.Linear(100, 100)
        self.fc3 = nn.Linear(100, 1)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        x = self.fc1(x)
        x = self.sigmoid(x)
        x = self.fc2(x)
        x = self.sigmoid(x)
        x = self.fc3(x)
        output = self.sigmoid(x)
        return output

# 创建模型实例
model = MLP()

# 定义损失函数和优化器
criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=0.1)

# 输入数据
x = torch.randn(100, 10)
y_true = torch.tensor([0, 1] * 50, dtype=torch.float).unsqueeze(1)

# 前向传播
y_pred = model(x)

# 计算损失函数
loss = criterion(y_pred, y_true)

# 反向传播
loss.backward()

# 参数更新
optimizer.step()

上述代码实现了一个具有三个全连接层的多层感知机模型,使用sigmoid激活函数,并以交叉熵损失函数和随机梯度下降(SGD)作为优化算法。输入数据 x 的形状为 (100, 10),真实标签 y_true 的形状为 (100, 1)

在训练过程中,我们先进行前向传播来得到预测输出 y_pred,然后计算损失函数 loss。接下来调用 loss.backward() 完成反向传播,并调用优化器的 step() 函数来更新模型参数。

PyTorch 自动微分的代码细节解释

  1. torch.autograd: PyTorch 通过 torch.autograd 模块实现了自动微分。在计算图中,张量对象通过 .requires_grad=True 属性来追踪其计算历史,并构建计算图。

  2. backward(): 调用张量对象的 .backward() 方法会进行反向传播计算导数。此过程中,PyTorch 使用计算图中的链式法则来自动计算梯度。

  3. nn.Module: PyTorch 中的神经网络模型都是通过继承 nn.Module 类来实现的。在定义模型的 forward() 方法时,我们需要写明每一步的计算过程,而 PyTorch 会自动记录中间结果用于后向传播。

  4. nn.Module.parameters(): parameters() 方法可以返回模型中可学习的参数。

  5. optim.SGD: PyTorch 中的优化器用于更新模型参数。我们可以使用 optim.SGD 来使用随机梯度下降算法。

通过 PyTorch 中的自动微分功能,我们可以方便地构建和训练复杂的神经网络模型。这种便捷性对于机器学习的发展来说非常重要。

  • 16
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值