【PyTorch】torch.optim.SGD 类:随机梯度下降(SGD)优化器

torch.optim.SGD

torch.optim.SGD 是 PyTorch 中实现的 随机梯度下降(SGD)优化器,用于更新模型参数。它是最基础也是最常见的优化算法之一。SGD 在训练神经网络时通过最小化损失函数来调整网络权重。


1. SGD 基本原理

随机梯度下降(SGD)是优化算法中的一种,它通过计算损失函数的梯度(即损失函数相对于模型参数的导数),然后沿着负梯度方向更新模型参数。它的更新公式如下:

θ = θ − η ⋅ ∇ θ J ( θ ) \theta = \theta - \eta \cdot \nabla_{\theta} J(\theta) θ=θηθJ(θ)

  • θ \theta θ:模型的参数。
  • η \eta η:学习率(step size)。
  • ∇ θ J ( θ ) \nabla_{\theta} J(\theta) θJ(θ):损失函数相对于参数的梯度。

SGD 是一个基于批量的优化方法,每次更新只基于一个样本(或者一个小批量)。相比于 批量梯度下降(使用所有样本计算梯度),SGD 每次只计算一个样本的梯度,因而可以节省计算资源,尤其是在数据集较大的时候。


2. 语法

torch.optim.SGD(
    params,              # 需要优化的参数,通常是模型的参数
    lr=0.01,             # 学习率(默认为 0.01)
    momentum=0,          # 动量(默认为 0),用于加速SGD收敛
    dampening=0,         # 动量衰减(默认为 0)
    weight_decay=0,      # 权重衰减(L2正则化)系数
    nesterov=False,      # 是否使用 Nesterov 加速梯度(默认为 False)
    foreach=None,        # 是否使用每次迭代的 batch 更新,通常用在分布式训练中
    maximize=False,      # 是否最大化目标函数(默认为最小化损失函数)
    differentiated=False # 是否与分布式环境兼容
)

3. 参数说明

  • params

    • 需要优化的参数,通常是模型的参数。可以传递一个包含模型参数的迭代器,通常使用 model.parameters()
  • lr (学习率):

    • 控制每次参数更新的步长。较大的学习率可能导致梯度更新过大,而较小的学习率可能导致收敛速度过慢。
  • momentum (动量):

    • 控制优化过程中的惯性,帮助加速 SGD 的收敛。动量项的引入可以有效减少更新过程中震荡的波动,使得更新趋于平稳。
  • dampening

    • 动量衰减,控制每次迭代中动量的衰减,默认为 0,通常不常用。
  • weight_decay (权重衰减):

    • 是 L2 正则化的系数,控制权重的大小。较大的 weight_decay 会对较大的权重进行惩罚,防止过拟合。
  • nesterov

    • 是否启用 Nesterov 动量。Nesterov 动量在更新参数前会先预测一次梯度更新,从而比标准动量更快收敛。
  • foreach

    • 如果设置为 True,则采用 foreach 方法加速某些操作,通常在分布式训练中使用。
  • maximize

    • 是否最大化目标函数。默认是最小化目标函数(损失函数),如果要最大化目标函数(例如强化学习中的回报),可以将其设置为 True
  • differentiated

    • 是否与分布式环境兼容,通常用于分布式训练。

4. 基本使用示例

4.1 使用 SGD 优化器训练模型
import torch
import torch.nn as nn
import torch.optim as optim

# 定义一个简单的模型
class SimpleModel(nn.Module):
    def __init__(self):
        super(SimpleModel, self).__init__()
        self.fc = nn.Linear(10, 2)  # 输入大小10,输出大小2

    def forward(self, x):
        return self.fc(x)

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

# 定义损失函数
criterion = nn.CrossEntropyLoss()

# 创建 SGD 优化器
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

# 模拟训练过程
for epoch in range(5):
    optimizer.zero_grad()  # 清空梯度

    # 随机生成一个输入样本和目标标签
    inputs = torch.randn(32, 10)  # 假设一个批次32个样本,每个样本10个特征
    labels = torch.randint(0, 2, (32,))  # 32个样本的二分类标签

    # 前向传播
    outputs = model(inputs)

    # 计算损失
    loss = criterion(outputs, labels)

    # 反向传播
    loss.backward()

    # 更新参数
    optimizer.step()

    print(f'Epoch {epoch+1}, Loss: {loss.item():.4f}')

4.2 使用带动量的 SGD
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

# 与上述类似,进行训练时的参数更新

在这个例子中,momentum=0.9 使得每次更新不仅依赖于当前的梯度,还考虑了之前更新的历史信息,这可以加速收敛并减少震荡。


4.3 使用 Nesterov 动量
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9, nesterov=True)

Nesterov 动量比标准动量更加智能,它通过先进行预测更新来提高收敛速度。在优化过程中,Nesterov 动量比标准动量在收敛上更为高效。


5. 适用场景

  • 常见深度学习优化算法:SGD 是最基础的优化算法之一,适用于大多数任务,尤其是参数较多且数据量较大的情况。
  • 动量和 Nesterov 动量:当模型在训练过程中存在震荡时,可以启用动量或 Nesterov 动量来帮助加速收敛。
  • L2 正则化:通过设置 weight_decay 参数,SGD 可以集成 L2 正则化,有助于控制模型的复杂度,防止过拟合。

6. 优缺点

优点
  • 简单且高效:SGD 是最基础的优化方法,理论简单,计算量小。
  • 易于实现:与其他复杂优化算法相比,SGD 的实现非常简单。
  • 适用于大规模数据:由于每次只计算一个样本的梯度,因此适合处理大规模数据。
缺点
  • 收敛速度慢:SGD 可能收敛较慢,特别是当数据复杂且梯度变化大时。
  • 震荡问题:在某些情况下,SGD 更新会震荡,尤其在陡峭的梯度下降区域。
  • 需要调参:需要调节学习率、动量等超参数来找到最佳的训练效果。

7. 总结

  • torch.optim.SGD 是 PyTorch 中最常用的优化器之一,适用于多种神经网络训练任务。
  • 通过设置不同的超参数(如 momentumweight_decaynesterov 等),SGD 可以更好地适应不同的训练场景和问题。
  • 对于更复杂的任务,可以结合其他高级优化器(如 Adam)来进一步提高模型的训练效率和准确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

彬彬侠

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

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

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

打赏作者

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

抵扣说明:

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

余额充值