文章目录
- 一、学习率调整
- 1 余弦退火
- (1)Warm up
- (2)Cosine Anneal
- 2 AdaGrad
- 3 RMSprop算法
- 4 AdaDelta算法
- 二、梯度估计修正
- 1 动量法
- 2 Nesterov加速梯度
- 3 Adam
- 修正的原因
- 4 AdamW
- 三、总结
- 参考资料
在当今快速发展的人工智能领域,优化算法在深度学习模型(比如语言大模型)的训练过程中尤为重要。本文主要介绍与随机梯度下降法相关的两个技巧——学习率调整和梯度修正方法。
本文主要基于1,将介绍各种学习率策略,如余弦退火和自适应学习率算法(如 AdaGrad、RMSprop、AdaDelta),这些策略旨在加速收敛和提高训练稳定性。此外,还介绍了梯度估计修正技术,如动量法和 Nesterov 加速梯度,它们通过减少梯度的随机性来提高训练效率。特别地,我们分析了 Adam 和 AdamW 算法,展示了如何通过解耦权重衰减来增强模型的正则化能力。
一、学习率调整
学习率是神经网络优化时的重要超参数.在梯度下降法中,参数的更新规则为:
θ
t
=
θ
t
−
1
−
α
⋅
g
t
\theta_t = \theta_{t-1}-\alpha\cdot g_t
θt=θt−1−α⋅gt
其中
θ
t
\theta_t
θt为第
t
t
t次迭代的参数,
g
t
g_t
gt是第
t
t
t次迭代的梯度,
α
\alpha
α为学习率。学习率𝛼的取值非常关键,如果过大就不会收敛,如果过小则收敛速度太慢.
常用的学习率调整方法包括学习率衰减、学习率预热、周期性学习率调整以及一些自适应调整学习率的方法,比如 AdaGrad、RMSprop、AdaDelta 等1.
1 余弦退火
从经验上看,学习率在一开始要保持大些来保证收敛速度,在收敛到最优点附近时要小些以避免来回振荡.下面介绍一个常用的学习率调整方法:warm up + Cosine Anneal.
(1)Warm up
由于一开始参数不稳定, 梯度较大, 如果此时学习率设置过大可能导致数值不稳定。为了提高训练稳定性,我们可以在最初几轮迭代时,采用比较小的学习率,等梯度下降到一定程度后再恢复到初始的学习率,这种方法称为学习率预热(Learning Rate Warmup).使用warm up有助于减缓模型在初始阶段对mini-batch 的提前过拟合现象, 保持分布的平稳, 其次也有助于保持模型深层的稳定性。
(2)Cosine Anneal
梯度下降算法使得loss值接近全局最小值, 学习率应当变得更小, 才能够使其更加容易实现。余弦退火首先使得学习率先缓慢下降, 然后再快速下降, 可以满足上面的需求。公式如下:
α t = α min + 1 2 ( α max − α min ) ( 1 + cos ( T cur T max π ) ) \alpha_t=\alpha_{\min }+\frac{1}{2}\left(\alpha_{\max }-\alpha_{\min }\right)\left(1+\cos \left(\frac{T_{\text {cur }}}{T_{\max }} \pi\right)\right) αt=αmin+21(αmax−αmin)(1+cos(TmaxTcur π))
其中, α max \alpha_{\max} αmax 为学习率最大值, α min \alpha_{\min} αmin 为最小值, T c u r T_{c u r} Tcur 为当前轮次, T m a x T_{ m a x} Tmax 为训练最大迭代步。
Warm up + Cosine Anneal两阶段结合起来的学习率变化如下图所示:
2 AdaGrad
在标准的梯度下降法中,每个参数在每次迭代时都使用相同的学习率.由于每个参数的维度上收敛速度都不相同,因此有必要根据不同参数的收敛情况分别设置学习率.
AdaGrad 算法( Adaptive Gradient Algorithm )[Duchi et al., 2011]是借鉴 ℓ 2 \ell_2 ℓ2正则化的思想,每次迭代时自适应地调整每个参数的学习率. 在第 t t t 次迭代时, 先计算每个参数梯度平方的累计值
G
t
=
∑
τ
=
1
t
g
τ
⊙
g
τ
,
G_t=\sum_{\tau=1}^tg_\tau\odot g_\tau,
Gt=τ=1∑tgτ⊙gτ,
其中
⊙
\odot
⊙为按元素乘积,
g
τ
∈
R
∣
θ
∣
\mathbf{g}_\tau\in\mathbb{R}^{|\theta|}
gτ∈R∣θ∣是第
τ
\tau
τ次迭代时的梯度,
G
t
∈
R
∣
θ
∣
G_t\in\mathbb{R}^{|\theta|}
Gt∈R∣θ∣。AdaGrad 算法的参数更新差值为
Δ
θ
t
=
−
α
G
t
+
ε
⊙
g
t
,
\Delta\theta_t=-\frac\alpha{\sqrt{G_t+\varepsilon}}\odot\mathbf{g}_t,
Δθt=−Gt+εα⊙gt,
其中
- α \alpha α 是初始的学习率, ε \varepsilon ε是为了保持数值稳定性而设置的非常小的常数,一般取值 e − 7 \mathrm{e}^{-7} e−7到 e − 10 \mathrm{e}^{-10} e−10.
- 此外,这里的开平方、除、加运算都是按元素进行的操作
- 在 AdaGrad 算法中,如果某个参数的偏导数累积比较大,其学习率相对较小; 相反,如果其偏导数累积较小,其学习率相对较大,但整体是随着迭代次数的增加,学习率逐渐缩小.
AdaGrad 算法的缺点是在经过一定次数的迭代依然没有找到最优点时,由于这时的学习率已经非常小,很难再继续找到最优点.
3 RMSprop算法
RMSprop 算法是 Geoff Hinton 提出的一种自适应学习率的方法, 可以在有些情况下避免 AdaGrad 算法中学习率不断单调下降以至于过早衰减的缺点.
RMSprop 算法首先计算每次迭代梯度
g
t
\mathbf{g}_t
gt平方的指数加权移动平均,
G
t
=
β
G
t
−
1
+
(
1
−
β
)
g
t
⊙
g
t
=
(
1
−
β
)
∑
τ
=
1
t
β
t
−
τ
g
τ
⊙
g
τ
,
\begin{aligned}G_{t}&=\beta G_{t-1}+(1-\beta)\mathbf{g}_t\odot\mathbf{g}_t\\&=(1-\beta)\sum_{\tau=1}^t\beta^{t-\tau}\mathbf{g}_\tau\odot\mathbf{g}_\tau,\end{aligned}
Gt=βGt−1+(1−β)gt⊙gt=(1−β)τ=1∑tβt−τgτ⊙gτ,
其中
β
\beta
β 为衰减率,一般取值为0.9.RMSprop 算法的参数更新差值为
Δ
θ
t
=
−
α
G
t
+
ε
⊙
g
t
,
\Delta\theta_t=-\frac\alpha{\sqrt{G_t+\varepsilon}}\odot\mathbf{g}_t,
Δθt=−Gt+εα⊙gt,
其中
α
\alpha
α是初始的学习率,比如0.001.从上式可以看出,RMSProp 算法和 AdaGrad 算法的区别在于
G
t
G_t
Gt 的计算由累积方式变成了指数加权移动平均.在迭代过程中,每个参数的学习率并不是呈衰减趋势,既可以变小也可以变大。
4 AdaDelta算法
AdaDelta 算法 也是 AdaGrad 算法的一个改进. 和 RMSprop算法类似,AdaDelta 算法通过梯度平方的指数衰减移动平均来调整学习率. 此外, AdaDelta算法还引入了每次参数更新差值 Δ θ \Delta \theta Δθ 的平方的指数衰減权移动平均.
第 t t t 次迭代时, 参数更新差值 Δ θ \Delta \theta Δθ 的平方的指数衰减权移动平均为
Δ X t − 1 2 = β 1 Δ X t − 2 2 + ( 1 − β 1 ) Δ θ t − 1 ⊙ Δ θ t − 1 \Delta X_{t-1}^2=\beta_1 \Delta X_{t-2}^2+\left(1-\beta_1\right) \Delta \theta_{t-1} \odot \Delta \theta_{t-1} ΔXt−12=β1ΔXt−22+(1−β1)Δθt−1⊙Δθt−1
其中 β 1 \beta_1 β1 为衰减率. 此时 Δ θ t \Delta \theta_t Δθt 还未知, 因此只能计算到 Δ X t − 1 \Delta X_{t-1} ΔXt−1.AdaDelta算法的参数更新差值为
Δ θ t = − Δ X t − 1 2 + ε G t + ε g t \Delta \theta_t=-\frac{\sqrt{\Delta X_{t-1}^2+\varepsilon}}{\sqrt{G_t+\varepsilon}} g_t Δθt=−Gt+εΔXt−12+εgt
其中 G t G_t Gt 的计算方式和 RMSprop 算法一样 , Δ X t − 1 2 \Delta X_{t-1}^2 ΔXt−12 为参数更新差值 Δ θ \Delta \theta Δθ 的指数衰减权移动平均.
从上式可以看出,AdaDelta 算法将 RMSprop 算法中的初始学习率 α \alpha α 改为动态计算的 Δ X t − 1 2 \sqrt{\Delta X_{t-1}^2} ΔXt−12, 在一定程度上平抑了学习率的波动.
二、梯度估计修正
在随机(小批量)梯度下降法中,如果每次选取样本数量比较小,损失会呈现振荡的方式下降.也就是说,随机梯度下降方法中每次迭代的梯度估计和整个训练集上的最优梯度并不一致,具有一定的随机性.
如何缓解梯度的随机性?
- 增加批量大小.
- 使用最近一段时间内的平均梯度来代替当前时刻的随机梯度来作为参数更新的方向,从而提高优化速度.
1 动量法
动量( Momentum ) 是模拟物理中的概念. 一个物体的动量指的是该物体在它运动方向上保持运动的趋势,是该物体的质量和速度的乘积.动量法( Momentum Method)是用之前积累动量来替代真正的梯度.每次迭代的梯度可以看作加速度.在第 t t t 次迭代时,计算负梯度的“加权移动平均”作为参数的更新方向,
Δ
θ
t
=
ρ
Δ
θ
t
−
1
−
α
g
t
=
−
α
∑
τ
=
1
t
ρ
t
−
τ
g
τ
,
\Delta\theta_t=\rho\Delta\theta_{t-1}-\alpha\mathbf{g}_t=-\alpha\sum_{\tau=1}^t\rho^{t-\tau}\mathbf{g}_\tau,
Δθt=ρΔθt−1−αgt=−ατ=1∑tρt−τgτ,
其中
ρ
\rho
ρ 为动量因子,通常设为0.9
,
α
,\alpha
,α为学习率(注意这里学习率并没有调整)。这样,每个参数的实际更新差值取决于最近一段时间内梯度的加权平均值. 当某个参数在最近一段时间内的梯度方向不一致时,其真实的参数更新幅度变小;相反,当在最近一段时间内的梯度方向都一致时,其真实的参数更新幅度变大,起到加速作用。
如下图所示,引进 momentum 不仅可以加速梯度下降法的收敛速度,还可以一定程度避免在局部最小值处“收敛”(借助前一次的 Momentum,或许可以“冲”过局部最小值处)。
注意到:
- 一般而言,在迭代初期,梯度方向都比较一致,动量法会起到加速作用,可以更快地到达最优点.(如上图前三个点所示)
- 在迭代后期,梯度方向会不一致,在收敛值附近振荡,动量法会起到减速作用,增加稳定性,从某种角度来说,当前梯度叠加上部分的上次梯度,一定程度上可以近似看作二阶梯度。
2 Nesterov加速梯度
Nesterov 加速梯度 (Nesterov Accelerated Gradient, NAG) 是一种对动量法的改进 , 也称为Nesterov 动量法 (Nesterov Momentum ).
在动量法中,实际的参数更新方向 Δ θ t \Delta \theta_t Δθt 为上一步的参数更新方向 Δ θ t − 1 \Delta \theta_{t-1} Δθt−1 和当前梯度的反方向 − g t -g_t −gt 的叠加. 这样, Δ θ t \Delta \theta_t Δθt 可以被拆分为两步进行, 先根据 Δ θ t − 1 \Delta \theta_{t-1} Δθt−1 更新一次得到参数 θ ^ \hat{\theta} θ^, 再用 − g t -g_t −gt 进行更新.
θ ^ = θ t − 1 + ρ Δ θ t − 1 θ t = θ ^ − α g t \begin{aligned} \hat{\theta} & =\theta_{t-1}+\rho \Delta \theta_{t-1} \\ \theta_t & =\hat{\theta}-\alpha g_t \end{aligned} θ^θt=θt−1+ρΔθt−1=θ^−αgt
其中梯度
g
t
g_t
gt 为点
θ
t
−
1
\theta_{t-1}
θt−1 上的梯度, 因此在第二步更新中有些不太合理. 更合理的更新方向应该为
θ
^
\hat{\theta}
θ^ 上的梯度.这样,所以Nesterov Momentum修改后的更新方向为
θ
^
=
θ
t
−
1
+
ρ
Δ
θ
t
−
1
θ
t
=
θ
^
−
α
g
(
θ
^
)
\begin{aligned} \hat{\theta} & =\theta_{t-1}+\rho \Delta \theta_{t-1} \\ \theta_t & =\hat{\theta}-\alpha {g(\hat{\theta})} \end{aligned}
θ^θt=θt−1+ρΔθt−1=θ^−αg(θ^)
合并后更新方向为:
Δ
θ
t
=
ρ
Δ
θ
t
−
1
−
α
g
t
(
θ
t
−
1
+
ρ
Δ
θ
t
−
1
)
\Delta \theta_t=\rho \Delta \theta_{t-1}-\alpha g_t\left(\theta_{t-1}+\rho \Delta \theta_{t-1}\right)
Δθt=ρΔθt−1−αgt(θt−1+ρΔθt−1)
其中 g t ( θ t − 1 + ρ Δ θ t − 1 ) g_t\left(\theta_{t-1}+\rho \Delta \theta_{t-1}\right) gt(θt−1+ρΔθt−1) 表示损失函数在 θ ^ = θ t − 1 + ρ Δ θ t − 1 \hat{\theta}=\theta_{t-1}+\rho \Delta \theta_{t-1} θ^=θt−1+ρΔθt−1 上的偏导数.
下图给出了动量法和Nesterov加速梯度在参数更新时的比较,红色虚线是主要区别。
1
3 Adam
Adam 算法 (Adaptive Moment Estimation Algorithm ) 2可以看作动量法和 RMSprop 算法的结合. 不但使用动量作为参数更新方向, 而且可以自适应调整学习率。
Adam 算法一方面计算梯度平方 g t 2 \mathbf{g}_t^2 gt2 的指数加权平均(和 RMSprop 算法类似), 另一方面计算梯度 g t \mathrm{g}_t gt 的指数加权平均 (和动量法类似).
M t = β 1 M t − 1 + ( 1 − β 1 ) g t , ( 一阶矩估计 ) G t = β 2 G t − 1 + ( 1 − β 2 ) g t ⊙ g t , ( 二阶矩估计 ) \begin{aligned} M_t&=\beta_1 M_{t-1}+\left(1-\beta_1\right) g_t, &(\text{一阶矩估计})\\ G_t&=\beta_2 G_{t-1}+\left(1-\beta_2\right) g_t \odot g_t,&(\text{二阶矩估计})\\ \end{aligned} MtGt=β1Mt−1+(1−β1)gt,=β2Gt−1+(1−β2)gt⊙gt,(一阶矩估计)(二阶矩估计)
其中 β 1 \beta_1 β1 和 β 2 \beta_2 β2 分别为两个移动平均的衰減率, 通常取值为 β 1 = 0.9 , β 2 = 0.99 \beta_1=0.9, \beta_2=0.99 β1=0.9,β2=0.99. 我们可以把 M t M_t Mt 和 G t G_t Gt 分别看作梯度的均值(一阶矩)和未减去均值的方差(二阶矩).
假设 M 0 = 0 , G 0 = 0 M_0=0, G_0=0 M0=0,G0=0 ,那么在迭代初期 M t M_t Mt 和 G t G_t Gt 的值会比真实的均值和方差要小, 特别是当 β 1 \beta_1 β1 和 β 2 \beta_2 β2 都接近于 1 时, 偏差会很大. 因此, 需要对偏差进行修正.
M ^ t = M t 1 − β 1 t ( 偏差修正 ) G ^ t = G t 1 − β 2 t ( 偏差修正 ) \begin{aligned} \hat{M}_t & =\frac{M_t}{1-\beta_1^t} &(\text{偏差修正})\\ \hat{G}_t & =\frac{G_t}{1-\beta_2^t} &(\text{偏差修正})\\ \end{aligned} M^tG^t=1−β1tMt=1−β2tGt(偏差修正)(偏差修正)
Adam算法的参数更新差值为
θ t = θ t − 1 − α G ^ t + ϵ M ^ t ( 参数更新 ) \theta_t=\theta_{t-1}-\frac{\alpha}{\sqrt{\hat{G}_t+\epsilon}} \hat{M}_t \quad(\text{参数更新})\\ θt=θt−1−G^t+ϵαM^t(参数更新)
其中学习率 α \alpha α 通常设为 0.001 , 并且也可以进行衰減, 比如采用余弦退火.
修正的原因
在 Adam 算法中,初期的估计值偏小是因为 指数加权平均 的计算方式依赖于前面的梯度信息,而在初始阶段,梯度的历史数据很少,因此计算出的平均值往往低于实际值。我们可以用一个具体的例子来说明这个偏差为什么会发生。
假设我们有一个优化过程,在第一个时间步 t = 1 t = 1 t=1,我们记录到的梯度值为 g 1 g_1 g1。我们使用 Adam 的一阶矩的指数加权平均来计算梯度的平均值。
Adam 中一阶矩的指数加权平均的公式为:
M t = β 1 M t − 1 + ( 1 − β 1 ) g t M_t = \beta_1 M_{t-1} + (1 - \beta_1) g_t Mt=β1Mt−1+(1−β1)gt
- 假设 β 1 = 0.9 \beta_1 = 0.9 β1=0.9。
- 初始时刻 M 0 = 0 M_0 = 0 M0=0,即指数加权平均的初值为 0。
在第一个时间步 t = 1 t = 1 t=1:
M
1
=
β
1
M
0
+
(
1
−
β
1
)
g
1
M
1
=
0.9
×
0
+
(
1
−
0.9
)
×
g
1
M
1
=
0.1
×
g
1
\begin{aligned} M_1 &= \beta_1 M_0 + (1 - \beta_1) g_1\\ M_1 &= 0.9 \times 0 + (1 - 0.9) \times g_1\\ M_1 &= 0.1 \times g_1 \end{aligned}
M1M1M1=β1M0+(1−β1)g1=0.9×0+(1−0.9)×g1=0.1×g1
由于
M
0
=
0
M_0 = 0
M0=0,所以
M
1
M_1
M1 的值只包含了当前梯度值的 10%。这明显比实际的
g
1
g_1
g1 要小很多,若
β
1
\beta_1
β1约接近于0,那么偏差就越大。
同理可知 G t G_t Gt也是如此,所以两者都需要引入一个修正项。
4 AdamW
AdamW是一个在深度学习中广泛应用的优化器,它是经典Adam优化器的一个变体,专门为了解决Adam在权重衰减(Weight Decay)方面的问题而提出。AdamW最早在论文《Decoupled Weight Decay Regularization》中提出3,它结合了Adam的自适应学习率和L2正则化的优势, 解决了Adam中错误使用权重衰减的问题。
在深度学习中,权重衰减(weight decay) 是一种常用的正则化技术,它通过在每次更新参数时引入一个额外的项来控制权重的增长,从而防止过拟合。在经典的梯度下降方法中,权重衰减的实现非常简单:
θ = θ − η ( ∇ L ( θ ) + λ θ ) \theta=\theta-\eta(\nabla L(\theta)+\lambda \theta) θ=θ−η(∇L(θ)+λθ)
其中,
λ
θ
\lambda \theta
λθ 是权重衰减项(L2正则化项)。这种方法能够有效防止模型参数过拟合。在原始的 Adam 算法中,如果使用了权重衰减(也就是 L2 正则化),它是将正则化项添加到梯度上,即损失函数对参数的梯度
g
t
g_t
gt被修改为:
g
t
=
∇
L
(
θ
t
)
+
λ
θ
t
g_t = \nabla L(\theta_t)+\lambda \theta_t
gt=∇L(θt)+λθt
L2正则化和Adam的动量更新机制耦合在了一起,导致了不理想的正则化效果。AdamW通过将权重衰减与梯度更新解耦, 解决了Adam在权重衰减方面的缺陷。 它将权重衰减独立处理, 而不再作为Adam优化器更新的一部分。这使得模型在参数更新时可以保持更高的稳定性,并且防止过拟合。
AdamW的参数更新公式如下:
- 动量和二阶矩的计算(与Adam相同):
M
t
=
β
1
M
t
−
1
+
(
1
−
β
1
)
g
t
,
(
一阶矩估计
)
G
t
=
β
2
G
t
−
1
+
(
1
−
β
2
)
g
t
⊙
g
t
,
(
二阶矩估计
)
\begin{aligned} M_t&=\beta_1 M_{t-1}+\left(1-\beta_1\right) g_t, &(\text{一阶矩估计})\\ G_t&=\beta_2 G_{t-1}+\left(1-\beta_2\right) g_t \odot g_t,&(\text{二阶矩估计})\\ \end{aligned}
MtGt=β1Mt−1+(1−β1)gt,=β2Gt−1+(1−β2)gt⊙gt,(一阶矩估计)(二阶矩估计)
2. 偏差修正:
M
^
t
=
M
t
1
−
β
1
t
(
偏差修正
)
G
^
t
=
G
t
1
−
β
2
t
(
偏差修正
)
\begin{aligned} \hat{M}_t & =\frac{M_t}{1-\beta_1^t} &(\text{偏差修正})\\ \hat{G}_t & =\frac{G_t}{1-\beta_2^t} &(\text{偏差修正})\\ \end{aligned}
M^tG^t=1−β1tMt=1−β2tGt(偏差修正)(偏差修正)
3. 参数更新:
θ t = θ t − 1 − α ( M ^ t G ^ t + ϵ + λ θ t − 1 ) \theta_t=\theta_{t-1}-\alpha\left(\frac{\hat{M}_t}{\sqrt{\hat{G}_t}+\epsilon}+\lambda \theta_{t-1}\right) θt=θt−1−α(G^t+ϵM^t+λθt−1)
其中:
- M ^ t G t + ϵ \frac{\hat{M}_t}{\sqrt{G_t}+\epsilon} Gt+ϵM^t 是Adam的梯度更新部分。
- λ θ t − 1 \lambda \theta_{t-1} λθt−1 是独立的权重衰减项,与梯度更新无关。
通过这种方式, AdamW能够更好地控制权重衰减, 防止模型过拟合,而不影响优化器的动量和自适应学习率更新。相比于传统的Adam,AdamW 具有以下优势4:
- 更准确的权重衰减: AdamW将权重衰减与梯度更新解耦,避免了Adam优化器中的错误正则化处理。这样可以有效防止模型的参数过度增长,并提高泛化能力。
- 更好的正则化效果: 由于权重衰减项是独立处理的,AdamW能够更有效地施加L2正则化,尤其在大模型(如LLaMA等)训练中表现更为稳定。
- 提高模型的泛化能力: 通过更好的权重控制,AdamW能够在不影响优化过程的前提下提升模型在测试集上的表现,减少过拟合问题。
三、总结
本节介绍的几种优化方法大体上可以分为两类:
- 调整学习率,使得优化更稳定;
- 梯度估计修正,优化训练速度.
这些优化算法可以使用下面公式来统一描述概括:
Δ
θ
t
=
−
α
t
G
t
+
ϵ
M
t
\Delta\theta_t = -\frac{\alpha_t}{\sqrt{G_t+\epsilon}}M_t
Δθt=−Gt+ϵαtMt
其中
G
t
,
M
t
G_t,M_t
Gt,Mt都是梯度
g
1
,
g
2
,
⋯
,
g
t
g_1,g_2,\cdots,g_t
g1,g2,⋯,gt的函数,不同算法的
G
t
,
M
t
G_t,M_t
Gt,Mt取法总结如下表所示:
参考资料
邱锡鹏,神经网络与深度学习,机械工业出版社,https://nndl.github.io/, 2020. ↩︎ ↩︎ ↩︎
Kingma, Diederik P., and Jimmy Ba. "Adam: A method for stochastic optimization."arXiv preprint arXiv:1412.6980(2014). ↩︎
Loshchilov, Ilya, and Frank Hutter. "Decoupled weight decay regularization."arXiv preprint arXiv:1711.05101(2017). ↩︎
AdamW和Adam优化器对比分析 ↩︎