系列文章
李沐《动手学深度学习》预备知识 张量操作及数据处理
李沐《动手学深度学习》预备知识 线性代数及微积分
李沐《动手学深度学习》线性神经网络 线性回归
李沐《动手学深度学习》线性神经网络 softmax回归
李沐《动手学深度学习》多层感知机 模型概念和代码实现
李沐《动手学深度学习》多层感知机 深度学习相关概念
李沐《动手学深度学习》深度学习计算
李沐《动手学深度学习》卷积神经网络 相关基础概念
李沐《动手学深度学习》卷积神经网络 经典网络模型
李沐《动手学深度学习》循环神经网络 相关基础概念
李沐《动手学深度学习》循环神经网络 经典网络模型
李沐《动手学深度学习》注意力机制
李沐《动手学深度学习》优化算法(相关概念、梯度下降法、牛顿法)
目录
教材:李沐《动手学深度学习》
一、动量法
(一)用泄漏平均值取代梯度计算
- 原理: 在优化算法中使用梯度的移动平均值来代替原始的梯度值
- 核心思想: 对历史梯度信息进行指数加权平均,从而平滑梯度的变化,减少梯度更新的震荡和方向变化,提高算法的稳定性和收敛速度。
(二)条件不佳的问题
- "条件不佳"通常用于描述优化问题中的某些情况,特别是在梯度下降等优化算法中;
- 指代函数的曲率或梯度的特性不利于算法的收敛或性能表现良好。这种情况可能会导致优化算法的收敛速度变慢,甚至陷入局部最优解。
(三)动量法
主要思想: 在参数更新时考虑上一步的动量,使得参数更新方向更加平滑和连续,从而减少参数更新的震荡和方向变化,加速收敛并提高算法的性能。
动量法和泄露平均值:
- 动量法的主要原理是在参数更新时考虑上一步的动量,泄露平均值是对历史信息进行指数加权平均的一种方法;
- 动量法主要应用于梯度下降等优化算法中,通过引入动量项来改进算法的收敛速度和稳定性;泄露平均值通常应用于时间序列数据或信号处理中,用于平滑数据并提取出数据的长期趋势;
- 动量法主要用于改进参数更新的方向性和稳定性,而用泄漏平均值取代梯度计算则主要用于减少梯度更新的随机性和波动。
二、AdaGrad算法
AdaGrad算法的基本概念:
- 主要思想:根据每个参数在训练过程中的历史梯度信息来调整学习率,从而使得每个参数的学习率可以自适应地调整,更好地适应不同参数的特性。
- 特点:对每个参数的学习率进行适应性调整,使得在训练过程中梯度较大的参数的学习率变小,而梯度较小的参数的学习率变大。
- AdaGrad算法的更新公式:(
w
t
w_t
wt是第t步迭代的参数,
∇
f
(
w
t
)
\nabla f(w_t)
∇f(wt)是第t步迭代的梯度,
G
t
+
1
G_{t+1}
Gt+1是第t+1步迭代的历史梯度的平方累计,
η
\eta
η是学习率)
G t + 1 = G t + ( ∇ f ( w t ) ) 2 w t + 1 = w t − η G t + 1 + ϵ ⊙ ∇ f ( w t ) G_{t+1}=G_t+(\nabla f(w_t))^2 \\ w_{t+1}=w_t-\frac{\eta}{\sqrt{}G_{t+1}+\epsilon}\odot \nabla f(w_t) Gt+1=Gt+(∇f(wt))2wt+1=wt−Gt+1+ϵη⊙∇f(wt)
关于稀疏特征(即只在偶尔出现的特征)的模型训练面临的问题:
- 只有在这些不常见的特征出现时,与其相关的参数才会得到有意义的更新。
- 鉴于学习率下降,我们可能最终会面临这样的情况:常见特征的参数相当迅速地收敛到最佳值,而对于不常见的特征,我们仍缺乏足够的观测以确定其最佳值。
- 换句话说,学习率要么对于常见特征而言降低太慢,要么对于不常见特征而言降低太快。
解决该问题的方法:
- 记录看到特定特征的次数( s ( i , t ) s(i,t) s(i,t)),然后将其用作调整学习率;
- AdaGrad算法通过将粗略的计数器
s
(
i
,
t
)
s(i,t)
s(i,t)替换为先前观察所得梯度的平方之和来解决这个问题:
使用 s ( i , t + 1 ) = s ( i , t ) + ( ∂ i f ( x ) ) 2 s(i,t+1)=s(i,t)+(\partial_i f(x))^2 s(i,t+1)=s(i,t)+(∂if(x))2来调整学习率
AdaGrad方法的两个优点:
- 不需要决定梯度何时算足够大。
- 它会随梯度的大小自动变化。通常对应于较大梯度的坐标会显著缩小,而其他梯度较小的坐标则会得到更平滑的处理。 在实际应用中,它促成了计算广告学及其相关问题中非常有效的优化程序。 但是,它遮盖了AdaGrad固有的一些额外优势,这些优势在预处理环境中很容易被理解。
三、RMSProd算法
(一)基本概念
RMSProp算法的更新公式:(
w
t
w_t
wt是第t步迭代的参数,
∇
f
(
w
t
)
\nabla f(w_t)
∇f(wt)是第t步迭代的梯度,
v
t
+
1
v_{t+1}
vt+1是第t+1步迭代的历史梯度的平方累计,
η
\eta
η是学习率,
β
\beta
β是一个衰减系数)
v
t
+
1
=
β
v
t
+
(
1
−
β
)
(
∇
f
(
w
t
)
)
2
w
t
+
1
=
w
t
−
η
v
t
+
1
+
ϵ
⊙
∇
f
(
w
t
)
v_{t+1}=\beta v_t+(1-\beta)(\nabla f(w_t))^2 \\ w_{t+1}=w_t-\frac{\eta}{\sqrt{}v_{t+1}+\epsilon}\odot \nabla f(w_t)
vt+1=βvt+(1−β)(∇f(wt))2wt+1=wt−vt+1+ϵη⊙∇f(wt)
RMSProp算法通过引入衰减系数 β \beta β,在计算梯度平方的累积时降低了历史梯度的影响,从而避免了学习率过早减小的问题。这样做能够更好地适应不同参数的梯度变化情况,提高了算法的稳定性和收敛速度。
(二)RMSProp算法与Adagrad算法
相同点:
- 两者都使用梯度的平方来缩放系数。
- RMSProp算法与动量法都使用泄漏平均值。
不同点:
RMSProp算法是对AdaGrad算法的改进:AdaGrad算法中,由于历史梯度的累积可能会导致学习率不断减小,从而影响算法的收敛速度。RMSProp通过引入一个衰减系数来解决这个问题,从而使得学习率的衰减更加平缓,提高了算法的稳定性和收敛速度。
四、Adadelta
Adadelta算法是优化神经网络训练中常用的一种自适应学习率算法,它是AdaGrad的扩展版本,旨在解决AdaGrad算法学习率急剧下降的问题。Adadelta算法的核心思想是使用指数加权移动平均来估计梯度的二阶矩和参数更新的平方梯度的指数加权移动平均,并且使用这些估计来调整学习率。广义上Adadelta被称为没有学习率,因为它使用变化量本身作为未来变化的校准。
- Adadelta使用两个状态变量: s t s_t st用于存储梯度二阶导数的泄露平均值, Δ x t \Delta x_t Δxt用于存储模型本身中参数变化二阶导数的泄露平均值。
s t = ρ s t − 1 + ( 1 − ρ ) g t 2 s_t=\rho s_{t-1}+(1-\rho)g_t^2 st=ρst−1+(1−ρ)gt2
- 使用重新缩放的梯度
g
t
′
g_t'
gt′执行更新:
x t = x t − 1 − g t ′ x_t=x_{t-1}-g'_t xt=xt−1−gt′ - 调整后的梯度:(
Δ
x
t
\Delta x_t
Δxt用于存储模型本身中参数变化二阶导数的泄露平均值)
g t ′ = Δ x t − 1 + ϵ s t + ϵ ⊙ g t g'_t=\frac{\sqrt{\Delta x_{t-1}+\epsilon}}{s_t+\epsilon} \odot g_t gt′=st+ϵΔxt−1+ϵ⊙gt - 在每个步骤中使用
g
t
′
g'_t
gt′更新
Δ
x
t
\Delta x_t
Δxt:
Δ x t = ρ Δ x t − 1 + ( 1 − ρ ) g t ′ 2 \Delta x_t=\rho \Delta x_{t-1}+(1-\rho){g'_t}^2 Δxt=ρΔxt−1+(1−ρ)gt′2
五、Adam算法
(一)概述
Adam算法是一种用于优化神经网络训练的自适应学习率优化算法。它结合了动量梯度下降和自适应学习率方法的优点,具有广泛的应用和高效的性能。
(二)算法
- Adam算法使用指数加权移动平均值来估算梯度的动量和二次矩,即它使用状态变量:
v t ← β 1 v t − 1 + ( 1 − β 1 ) g t s t ← β 2 s t − 1 + ( 1 − β 2 ) g t 2 v_t\leftarrow \beta_1 v_{t-1}+(1-\beta_1)g_t\\ s_t\leftarrow \beta_2 s_{t-1}+(1-\beta_2)g_t^2 vt←β1vt−1+(1−β1)gtst←β2st−1+(1−β2)gt2 - 标准化状态变量:
v t ^ = v t 1 − β 1 t a n d s t ^ = s t 1 − β 2 t \hat{v_t}=\frac{v_t}{1-\beta_1^t} and \hat{s_t}=\frac{s_t}{1-\beta_2^t} vt^=1−β1tvtandst^=1−β2tst - 用类似RMSProp算法的方式重新缩放梯度:
g t ′ = η v t ^ s t ^ + ϵ g_t'=\frac{\eta \hat{v_t}}{\sqrt{\hat {s_t}}+\epsilon} gt′=st^+ϵηvt^ - 进行更新:
x t ← x t − 1 − g t ′ x_t\leftarrow x_{t-1}-g_t' xt←xt−1−gt′
(三)Yogi算法
Yogi算法在Adam算法的基础上引入了一个动态的学习率调整机制,旨在更好地处理学习率的动态变化和收敛速度。
六、学习率调度器
(一)调整学习率需要考虑的几个方面
- 学习率的大小。 如果它太大,优化就会发散;如果它太小,训练就会需要过长时间,或者我们最终只能得到次优的结果。
- 衰减速率。 如果学习率持续过高,我们可能最终会在最小值附近弹跳,从而无法达到最优解。
- 初始化。 这既涉及参数最初的设置方式,又关系到它们最初的演变方式。这被戏称为预热(warmup),即我们最初开始向着解决方案迈进的速度有多快。一开始的大步可能没有好处,特别是因为最初的参数集是随机的。最初的更新方向可能也是毫无意义的。
- 许多优化变体可以执行周期性学习率调整。例如,如何通过对整个路径参数求平均值来获得更好的解。
(二)单因子调度器
单因子调度器的原理:基于模型训练的某个因子(例如训练轮数、迭代次数等)来动态地调整学习率。通常情况下,随着训练的进行,学习率会逐渐减小,以便模型能够更好地收敛到最优解。
(三)多因子调度器
多因子调度器与单因子调度器相比,考虑了多个因素来决定学习率的变化,使得模型的训练过程更加灵活和自适应。
(四)余弦调度器
- 余弦调度器(Cosine Annealing Scheduler)是一种多因子调度器,在训练过程中动态调整学习率的策略之一。它通过余弦函数的形式来调整学习率,使得学习率在训练过程中以余弦形式逐渐降低,从而提高模型的稳定性和收敛性。
- 余弦调度器的主要思想是在每个训练步骤中,使用余弦函数的值来计算当前学习率。学习率在初始时较大,随着训练的进行逐渐减小,直至最小值,然后再逐渐增加,形成一个周期性的学习率变化曲线。这种周期性的调整可以帮助模型跳出局部最优解,更好地探索全局最优解。
(五)预热
-
在某些情况下,初始化参数不足以得到良好的解。 这对某些高级网络设计来说尤其棘手,可能导致不稳定的优化结果。 对此,一方面,我们可以选择一个足够小的学习率, 从而防止一开始发散,然而这样进展太缓慢。 另一方面,较高的学习率最初就会导致发散。
-
解决这种困境的一个相当简单的解决方法是使用预热期,在此期间学习率将增加至初始最大值,然后冷却直到优化过程结束。