PyTorch 基础学习(16)- 优化算法

系列文章:
《PyTorch 基础学习》文章索引

介绍

在深度学习的训练过程中,选择合适的优化算法对模型的性能起着至关重要的作用。PyTorch为我们提供了多种优化器,它们在不同任务和数据集上有着独特的优势。本文将深入探讨几种常用的PyTorch优化算法,包括其原理、典型应用场景以及使用实例。

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

原理

随机梯度下降(SGD)是一种经典的优化算法,它通过对损失函数的梯度计算来更新模型参数。与标准梯度下降不同,SGD在每次迭代中使用随机选择的小批量数据(mini-batch)而不是整个训练集进行参数更新。这种方法减少了计算开销,使得它非常适合处理大规模数据集。然而,由于它只使用小部分数据,可能导致更新过程中的波动和不稳定性,但这也可能帮助SGD逃离局部最优解,找到全局最优解。

公式:
θ t + 1 = θ t − η ⋅ ∇ θ t L ( θ t ; x ( i ) , y ( i ) ) \theta_{t+1} = \theta_t - \eta \cdot \nabla_{\theta_t} L(\theta_t; x^{(i)}, y^{(i)}) θt+1=θt−η⋅∇θtL(θt;x(i),y(i))

其中, θ t \theta_t θt表示模型参数, η \eta η表示学习率, L L L是损失函数, ( x ( i ) , y ( i ) ) (x^{(i)}, y^{(i)}) (x(i),y(i))是第i个样本。

典型应用场景
  • 大型数据集训练:SGD在处理非常大的数据集时表现良好,因为它仅使用一部分数据进行每次更新,减少了计算开销。
  • 在线学习:SGD适用于在线学习场景,即数据逐步到达并立即进行处理的情况。
用法实例
python 复制代码
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

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

原理

Adam优化器结合了动量法和RMSProp的优点,为每个参数分别计算一阶动量(梯度的指数加权平均)和二阶动量(梯度平方的指数加权平均)。动量法通过积累过去的梯度,能够加速收敛,尤其是在凹谷和平坦区域。RMSProp则通过调整学习率,防止梯度更新过快或过慢。Adam在训练初期提供较大的步长,而在训练后期自动收敛,表现出优异的性能。

公式:
m t = β 1 m t − 1 + ( 1 − β 1 ) ∇ θ L ( θ t ) m_t = \beta_1 m_{t-1} + (1 - \beta_1) \nabla_{\theta}L(\theta_t) mt=β1mt−1+(1−β1)∇θL(θt)
v t = β 2 v t − 1 + ( 1 − β 2 ) ( ∇ θ L ( θ t ) ) 2 v_t = \beta_2 v_{t-1} + (1 - \beta_2) (\nabla_{\theta}L(\theta_t))^2 vt=β2vt−1+(1−β2)(∇θL(θt))2
m ^ t = m t 1 − β 1 t , v ^ t = v t 1 − β 2 t \hat{m}_t = \frac{m_t}{1-\beta_1^t}, \quad \hat{v}t = \frac{v_t}{1-\beta_2^t} m^t=1−β1tmt,v^t=1−β2tvt
θ t + 1 = θ t − η ⋅ m ^ t v ^ t + ϵ \theta
{t+1} = \theta_t - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} θt+1=θt−η⋅v^t +ϵm^t

其中, β 1 \beta_1 β1和 β 2 \beta_2 β2分别是动量项的指数衰减率, ϵ \epsilon ϵ是一个防止除零的常数。

典型应用场景
  • 深度学习:Adam是深度学习中非常流行的优化器,适用于各种神经网络结构,包括卷积神经网络(CNN)和递归神经网络(RNN)。
  • 稀疏数据:在稀疏数据或稀疏梯度的情况下(如自然语言处理中的词嵌入),Adam表现优越。
用法实例
python 复制代码
optimizer = optim.Adam(model.parameters(), lr=0.001)

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

原理

RMSprop优化器通过对每个参数的历史梯度平方值进行指数加权移动平均来调整学习率。这种方法通过缩放每个参数的学习率,确保参数更新的稳定性,防止了学习率过小导致的训练停滞以及梯度爆炸问题。RMSprop特别适用于非平稳目标或变化剧烈的损失函数。

公式:
v t = β v t − 1 + ( 1 − β ) ( ∇ θ L ( θ t ) ) 2 v_t = \beta v_{t-1} + (1-\beta) (\nabla_{\theta}L(\theta_t))^2 vt=βvt−1+(1−β)(∇θL(θt))2
θ t + 1 = θ t − η v t + ϵ ⋅ ∇ θ L ( θ t ) \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{v_t} + \epsilon} \cdot \nabla_{\theta}L(\theta_t) θt+1=θt−vt +ϵη⋅∇θL(θt)

其中, β \beta β是指数加权衰减因子。

典型应用场景
  • 循环神经网络(RNN)训练:RMSprop在RNN中表现良好,特别是在处理较长时间序列时,可以有效控制梯度爆炸和梯度消失。
  • 不稳定损失函数:适用于那些损失函数变化剧烈的情况,能够帮助平滑训练过程。
用法实例
python 复制代码
optimizer = optim.RMSprop(model.parameters(), lr=0.01)

4. 权重衰减的Adam优化器(AdamW) - Adam with Weight Decay

原理

AdamW优化器是对Adam的改进版本,它将权重衰减(Weight Decay)从学习率调整中分离出来,直接作用于参数更新。这种方法不仅能够像Adam一样快速收敛,还能够有效控制模型的正则化效果,防止模型过拟合。通过对参数引入惩罚项,AdamW在模型复杂性控制方面表现更加优越。

公式:
θ t + 1 = θ t − η ⋅ m ^ t v ^ t + ϵ − η ⋅ λ ⋅ θ t \theta_{t+1} = \theta_t - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} - \eta \cdot \lambda \cdot \theta_t θt+1=θt−η⋅v^t +ϵm^t−η⋅λ⋅θt

其中, λ \lambda λ是权重衰减因子。

典型应用场景
  • 图像分类任务:在图像分类任务中,特别是使用深层神经网络时,AdamW有助于防止过拟合。
  • Transformer模型:广泛应用于NLP中的Transformer架构中,能够有效管理模型的复杂度。
用法实例
python 复制代码
optimizer = optim.AdamW(model.parameters(), lr=0.001, weight_decay=0.01)

5. 自适应梯度算法(Adagrad) - Adaptive Gradient Algorithm

原理

Adagrad优化器为每个参数分配独立的学习率,并根据历史梯度进行调整。具体来说,它对每个参数的梯度平方和进行累积,并使用该累积值来调整每个参数的学习率。这样,更新频繁的参数会有较小的学习率,而更新较少的参数学习率会更大,从而适应不同特征的学习。这使得Adagrad特别适合处理稀疏数据或带有稀疏特征的模型。

公式:
v t = v t − 1 + ( ∇ θ L ( θ t ) ) 2 v_t = v_{t-1} + (\nabla_{\theta}L(\theta_t))^2 vt=vt−1+(∇θL(θt))2
θ t + 1 = θ t − η v t + ϵ ⋅ ∇ θ L ( θ t ) \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{v_t} + \epsilon} \cdot \nabla_{\theta}L(\theta_t) θt+1=θt−vt +ϵη⋅∇θL(θt)

典型应用场景
  • 文本和图像处理:在处理高维稀疏特征(如文本分类中的词向量)时表现良好。
  • 低频更新的参数:适合在模型中需要频繁更新某些特定参数的情况。
用法实例
python 复制代码
optimizer = optim.Adagrad(model.parameters(), lr=0.01)

6. 自适应Delta算法(Adadelta) - Adaptive Delta

原理

Adadelta优化器是Adagrad的改进版本,旨在解决Adagrad随着时间推移学习率不断减小的问题。Adadelta通过限制累积历史梯度的窗口大小,使得模型能够在整个训练过程中保持较为稳定的学习率。不同于Adagrad,Adadelta不再需要预先设定学习率,而是通过梯度的累积信息自适应调整参数更新幅度

。这种方法不仅简化了超参数的调节,还提高了模型的收敛性和稳定性。

公式:
v t = β v t − 1 + ( 1 − β ) ( ∇ θ L ( θ t ) ) 2 v_t = \beta v_{t-1} + (1-\beta) (\nabla_{\theta}L(\theta_t))^2 vt=βvt−1+(1−β)(∇θL(θt))2
Δ θ t = − s t − 1 + ϵ v t + ϵ ⋅ ∇ θ L ( θ t ) \Delta\theta_t = - \frac{\sqrt{s_{t-1} + \epsilon}}{\sqrt{v_t + \epsilon}} \cdot \nabla_{\theta}L(\theta_t) Δθt=−vt+ϵ st−1+ϵ ⋅∇θL(θt)
s t = β s t − 1 + ( 1 − β ) ( Δ θ t ) 2 s_t = \beta s_{t-1} + (1-\beta) (\Delta\theta_t)^2 st=βst−1+(1−β)(Δθt)2

典型应用场景
  • 不需要学习率调整的场景:适用于那些不希望手动调整学习率的场景,如基于超大规模数据的模型训练。
  • 时间序列数据:在处理时间序列数据的模型中,Adadelta的自适应性能够帮助稳定训练过程。
用法实例
python 复制代码
optimizer = optim.Adadelta(model.parameters(), lr=1.0)

7. Nesterov加速梯度(NAG) - Nesterov Accelerated Gradient

原理

Nesterov加速梯度(NAG)是在动量法的基础上进一步优化的一种方法。动量法通过在梯度的基础上加入历史动量来加速收敛,但容易出现过冲问题。NAG通过在计算梯度之前,先对参数进行一个提前的预测更新,从而在正式更新之前对未来的梯度有一个预估。这种"提前看一眼"的策略能够更有效地引导梯度下降方向,减少过冲,提高收敛速度。

公式:
v t = γ v t − 1 + η ∇ θ L ( θ t − γ v t − 1 ) v_t = \gamma v_{t-1} + \eta \nabla_{\theta}L(\theta_t - \gamma v_{t-1}) vt=γvt−1+η∇θL(θt−γvt−1)
θ t + 1 = θ t − v t \theta_{t+1} = \theta_t - v_t θt+1=θt−vt

其中, γ \gamma γ是动量因子。

典型应用场景
  • 图像分类任务:在卷积神经网络(CNN)的训练中,NAG可以帮助更快地收敛。
  • 深度神经网络:适用于深度网络中的复杂优化问题,能够更好地处理不稳定的梯度。
用法实例
python 复制代码
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9, nesterov=True)

8. 限制内存BFGS算法(LBFGS) - Limited-memory Broyden--Fletcher--Goldfarb--Shanno Algorithm

原理

LBFGS是一种拟牛顿法,通过近似计算二阶导数(海森矩阵)来进行优化。相比于标准牛顿法需要计算和存储完整的海森矩阵,LBFGS利用了前m次迭代的梯度信息来构造海森矩阵的近似值,从而大幅减少了计算和存储成本。这使得LBFGS能够在不需要存储大量数据的前提下,仍能在较少的迭代次数内获得较高的优化精度。因此,它特别适合于小规模数据集或要求高精度解的任务。

公式:
θ t + 1 = θ t − H t ∇ θ L ( θ t ) \theta_{t+1} = \theta_t - H_t \nabla_{\theta}L(\theta_t) θt+1=θt−Ht∇θL(θt)

其中, H t H_t Ht是海森矩阵的近似逆矩阵。

典型应用场景
  • 小型数据集:在处理较小的数据集时,LBFGS可以在较少的迭代次数内达到较好的优化效果。
  • 精确优化:适用于需要高精度解的任务,如图像分割、医学图像分析等。
用法实例
python 复制代码
optimizer = optim.LBFGS(model.parameters(), lr=1)

总结

在深度学习的实际应用中,选择合适的优化算法能够显著提高模型的性能。本文详细介绍了PyTorch中常用的几种优化器,包括其原理、典型应用场景以及使用实例。理解这些优化算法的特点,有助于在不同的任务中做出最优的选择,从而实现更好的模型训练效果。

相关推荐
一棵开花的树,枝芽无限靠近你6 分钟前
【PPTist】添加PPT模版
前端·学习·编辑器·html
VertexGeek24 分钟前
Rust学习(八):异常处理和宏编程:
学习·算法·rust
石小石Orz25 分钟前
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~
javascript·人工智能·算法
zhangfeng113344 分钟前
pytorch 的交叉熵函数,多分类,二分类
人工智能·pytorch·分类
Seeklike1 小时前
11.22 深度学习-pytorch自动微分
人工智能·pytorch·深度学习
二进制_博客1 小时前
Flink学习连载文章4-flink中的各种转换操作
大数据·学习·flink
jiao_mrswang1 小时前
leetcode-18-四数之和
算法·leetcode·职场和发展
codebolt1 小时前
ADS学习记录
学习
YRr YRr1 小时前
如何使用 PyTorch 实现图像分类数据集的加载和处理
pytorch·深度学习·分类
qystca1 小时前
洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp
c语言·开发语言·算法