首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【PyTorch入门】 PyTorch不同优化器的比较

【PyTorch入门】 PyTorch不同优化器的比较

作者头像
机器学习司猫白
修改2025-01-28 16:14:29
修改2025-01-28 16:14:29
55700
代码可运行
举报
文章被收录于专栏:机器学习实战机器学习实战
运行总次数:0
代码可运行

本次分享pytorch中几种常用的优化器,并进行互相比较。

PyTorch 优化器原理及优缺点分析

在 PyTorch 中,torch.optim 提供了多种优化器用于神经网络训练。每种优化器背后有不同的更新规则和机制,旨在适应不同的训练需求。以下是五种常见优化器(SGD、Momentum、AdaGrad、RMSprop、Adam)的原理、作用、优缺点及应用场景。

1. SGD (Stochastic Gradient Descent) 随机梯度下降

原理:

SGD 是最经典的优化算法,基于梯度下降的思想。每次参数更新时,SGD 使用当前参数的梯度对参数进行调整。其更新规则如下:

\theta_{t+1} = \theta_t - \eta \cdot \nabla_{\theta} J(\theta_t)

其中,

\eta

是学习率,

\nabla_{\theta} J(\theta_t)

是当前参数点的梯度。

作用:

用于优化损失函数,更新神经网络中的权重参数。

优缺点:
  • 优点
    • 实现简单,计算资源消耗小。
    • 对于某些问题,收敛较快。
  • 缺点
    • 收敛缓慢:每次更新仅依赖单一样本或小批量数据,可能导致目标函数震荡,尤其在复杂的优化空间中。
    • 灵敏度高:学习率的选择非常关键,过大会导致发散,过小则收敛缓慢。

2. Momentum (带动量的梯度下降)

原理:

Momentum 是对 SGD 的改进,通过引入动量项来加速梯度下降,尤其在面对陡峭的梯度或局部最小值时表现更好。动量项有助于保持一定的“惯性”,从而增加当前更新的速度。更新规则如下:

v_{t+1} = \beta v_t + (1 - \beta) \nabla_{\theta} J(\theta_t)
\theta_{t+1} = \theta_t - \eta v_{t+1}

其中,

\beta

是动量参数,

\eta

是学习率。

作用:

加速收敛过程,尤其在梯度变化较小的方向上。

优缺点:
  • 优点
    • 有助于突破局部最小值,优化过程中更加稳定,避免梯度震荡。
    • 相较于普通 SGD,收敛速度更快。
  • 缺点
    • 动量参数
    \beta

    需要调节,最佳值依赖于具体问题。

    • 动量可能导致跳过局部最优解,特别是在复杂的目标函数中。

3. AdaGrad (Adaptive Gradient Algorithm 自适应梯度算法)

原理:

AdaGrad 通过对每个参数使用不同的学习率,使得参数的更新速度自适应地调整。对于频繁出现的特征,AdaGrad 会减少学习率;对于稀疏特征,则增加学习率。具体来说,AdaGrad 会对梯度的历史平方和进行累加,动态调整每个参数的学习率:

G_{t+1} = G_t + \nabla_{\theta} J(\theta_t)^2
\theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{G_{t+1} + \epsilon}} \nabla_{\theta} J(\theta_t)

其中,

\epsilon

是防止除零错误的小常数。

作用:

适用于具有稀疏特征的数据(如文本处理、推荐系统等),能够让模型快速适应不同特征的梯度变化。

优缺点:
  • 优点
    • 自动调整学习率,避免手动调整学习率的繁琐。
    • 对稀疏数据的收敛速度有显著提升。
  • 缺点
    • 随着训练进行,AdaGrad 的学习率会持续减小,导致训练后期更新过于缓慢。
    • 对于某些问题,可能导致过早收敛,特别是当参数梯度变化不大时。

4. RMSprop (Root Mean Square Propagation 均方根传播)

原理:

RMSprop 是对 AdaGrad 的改进,通过引入衰减因子来防止学习率过快减小。它通过对梯度平方的指数加权平均来调整每个参数的学习率:

v_{t+1} = \beta v_t + (1 - \beta) \nabla_{\theta} J(\theta_t)^2
\theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{v_{t+1} + \epsilon}} \nabla_{\theta} J(\theta_t)

其中,

\beta

是衰减因子,

\eta

是学习率,

\epsilon

是防止除零错误的小常数。

作用:

适用于非平稳目标函数(例如递增或递减的动态任务)。特别适用于处理RNN(递归神经网络)和时间序列数据。

优缺点:
  • 优点
    • 对梯度波动较大的问题表现更好,尤其适用于动态目标。
    • 相较于 AdaGrad,能够有效防止学习率过早减小。
  • 缺点
    • 需要调节
    \beta

    和学习率等超参数。

    • 可能需要针对具体问题进一步调整超参数,以获得最优性能。

5. Adam (Adaptive Moment Estimation 自适应矩估计)

原理:

Adam 结合了 Momentum 和 RMSprop 的思想,通过计算梯度的一阶矩(动量)和二阶矩(梯度平方的均值)来进行自适应更新。更新规则如下:

m_{t+1} = \beta_1 m_t + (1 - \beta_1) \nabla_{\theta} J(\theta_t)
v_{t+1} = \beta_2 v_t + (1 - \beta_2) \nabla_{\theta} J(\theta_t)^2
\hat{m}_{t+1} = \frac{m_{t+1}}{1 - \beta_1^{t+1}}, \quad \hat{v}_{t+1} = \frac{v_{t+1}}{1 - \beta_2^{t+1}}
\theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{\hat{v}_{t+1}} + \epsilon} \hat{m}_{t+1}

其中,

\beta_1

\beta_2

是一阶和二阶矩的衰减率,

\eta

是学习率,

\epsilon

是防止除零的常数。

作用:

适用于各种类型的神经网络,尤其在大规模数据集上表现优异。

优缺点:
  • 优点
    • 结合了动量和自适应学习率,通常可以快速收敛。
    • 适用于非平稳目标函数和大规模数据集。
    • 超参数调整较为简单,少量调整即可获得较好的性能。
  • 缺点
    • 对小数据集或过于简单的任务,可能导致过拟合。
    • 对学习率较为敏感,可能需要根据具体问题进行微调。

总结

优化器

原理

优点

缺点

适用场景

SGD

随机梯度下降

实现简单,计算开销小

收敛慢,容易震荡

基础任务,特别是小规模训练任务

Momentum

加入动量

加速收敛,避免局部最小值

动量参数选择困难

适合梯度波动较大的任务

AdaGrad

自适应调整每个参数的学习率

自动调整学习率,适合稀疏数据

学习率逐步减小,可能导致训练后期收敛缓慢

处理稀疏数据(如 NLP)

RMSprop

使用梯度平方的指数加权平均

防止学习率过早减小,适合动态任务

需要调节超参数

适用于非平稳目标函数,尤其是 RNN 和时间序列任务

Adam

结合动量和自适应学习率

快速收敛,超参数调节简单

对学习率敏感,可能过拟合

适用于各种神经网络,尤其是大规模数据集训练

示例可视化代码

代码语言:javascript
代码运行次数:0
运行
复制
import torch
import torch.nn
import torch.utils.data as Data
import matplotlib
import matplotlib.pyplot as plt
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"

matplotlib.rcParams['font.sans-serif'] = ['SimHei']

#准备建模数据
x = torch.unsqueeze(torch.linspace(-1, 1, 500), dim=1)
y = x.pow(3)

#设置超参数
LR = 0.01
batch_size = 15
epoches = 5
torch.manual_seed(10)

#设置数据加载器
dataset = Data.TensorDataset(x, y)
loader = Data.DataLoader(
    dataset=dataset,
    batch_size=batch_size,
    shuffle=True,
    num_workers=2)

#搭建神经网络
class Net(torch.nn.Module):
    def __init__(self, n_input, n_hidden, n_output):
        super(Net, self).__init__()
        self.hidden_layer = torch.nn.Linear(n_input, n_hidden)
        self.output_layer = torch.nn.Linear(n_hidden, n_output)

    def forward(self, input):
        x = torch.relu(self.hidden_layer(input))
        output = self.output_layer(x)
        return output

#训练模型并输出折线图
def train():
    net_SGD = Net(1, 10, 1)
    net_Momentum = Net(1, 10, 1)
    net_AdaGrad = Net(1, 10, 1)
    net_RMSprop = Net(1, 10, 1)
    net_Adam = Net(1, 10, 1)
    nets = [net_SGD, net_Momentum, net_AdaGrad, net_RMSprop, net_Adam]

    #定义优化器
    optimizer_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR)
    optimizer_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.6)
    optimizer_AdaGrad = torch.optim.Adagrad(net_AdaGrad.parameters(), lr=LR, lr_decay=0)
    optimizer_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
    optimizer_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
    optimizers = [optimizer_SGD, optimizer_Momentum, optimizer_AdaGrad, optimizer_RMSprop, optimizer_Adam]

    #定义损失函数
    loss_function = torch.nn.MSELoss()
    losses = [[], [], [], [], []]

    for epoch in range(epoches):
        for step, (batch_x, batch_y) in enumerate(loader):
            for net, optimizer, loss_list in zip(nets, optimizers, losses):
                pred_y = net(batch_x)
                loss = loss_function(pred_y, batch_y)
                optimizer.zero_grad()
                loss.backward()
                optimizer.step()
                loss_list.append(loss.data.numpy())

    plt.figure(figsize=(12,7))
    labels = ['SGD', 'Momentum', 'AdaGrad', 'RMSprop', 'Adam']
    for i, loss in enumerate(losses):
        plt.plot(loss, label=labels[i])
    plt.legend(loc='upper right',fontsize=15)
    plt.tick_params(labelsize=13)
    plt.xlabel('训练步骤',size=15)
    plt.ylabel('模型损失',size=15)
    plt.ylim((0, 0.3))
    plt.show()

if __name__ == "__main__":
    train()
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • PyTorch 优化器原理及优缺点分析
    • 1. SGD (Stochastic Gradient Descent) 随机梯度下降
      • 原理:
      • 作用:
      • 优缺点:
    • 2. Momentum (带动量的梯度下降)
      • 原理:
      • 作用:
      • 优缺点:
    • 3. AdaGrad (Adaptive Gradient Algorithm 自适应梯度算法)
      • 原理:
      • 作用:
      • 优缺点:
    • 4. RMSprop (Root Mean Square Propagation 均方根传播)
      • 原理:
      • 作用:
      • 优缺点:
    • 5. Adam (Adaptive Moment Estimation 自适应矩估计)
      • 原理:
      • 作用:
      • 优缺点:
    • 总结
    • 示例可视化代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档