前言
对深度学习中常见优化器进行总结,包括BGD、SGD、Momentum、Nesterov、Adagrad、Adam
BGD
批量梯度下降法,模型参数的调整更新与全部输入样本的代价函数的和(即批量/全局误差)有关。即每次权值调整发生在批量样本输入之后,而不是每输入一个样本就更新一次模型参数。
θ : = θ − η ⋅ ∑ i = 1 n ∇ θ J ( θ ) (1) \theta := \theta - \eta \cdot \sum_{i=1}^{n} \nabla_{\theta} J(\theta) \tag{1} θ:=θ−η⋅i=1∑n∇θJ(θ)(1)
其中, n n n 为训练样本量, θ \theta θ 为模型参数, η \eta η 为学习率
SGD
BGD中每次对全量样本计算梯度,虽然可以保证梯度的准确性,但计算量非常大。于是,SGD每次随机选取一条样本数据计算梯度:
θ : = θ − η ⋅ ∇ θ J ( θ ) (2) \theta := \theta - \eta \cdot \nabla_{\theta} J(\theta) \tag{2} θ:=θ−η⋅∇θJ(θ)(2)
优点
- 每次只用一个样本更新参数,训练速度快
- 随机梯度下降所带来的波动有利于优化的方向从当前的局部极小值点跳到另一个更好的局部极小值点,这样对于非凸函数,最终收敛于一个较好的局部极值点,甚至全局极值点。
缺点
- 遇到局部最优或鞍点时,梯度为0,参数无法继续更新
- 损失曲面陡峭方向震荡严重,平缓维度进展缓慢,收敛速度慢
Momentum
Momentum是在SGD上面增加动量参数,使模型在梯度下降过程中增加惯性,这样就有利于逃脱局部最小值
v t : = γ ⋅ v t − 1 + η ⋅ ∇ θ J ( θ ) (3) v_t := \gamma \cdot v_{t-1} + \eta \cdot \nabla_{\theta} J(\theta) \tag{3} vt:=γ⋅vt−1+η⋅∇θJ(θ)(3)
θ : = θ − v t (4) \theta := \theta - v_t \tag{4} θ:=θ−vt(4)
由于当前权值的改变会受到上一次权值改变的影响,类似于小球向下滚动的时候带上了惯性。这样可以加快小球向下滚动的速度。
优点
动量法相比SGD移动的更快,并且有机会逃脱局部最小值
Nesterov
v t : = γ ⋅ v t − 1 + η ∇ θ J ( θ t − γ v t − 1 ) (5) v_t := \gamma \cdot v_{t-1} + \eta \nabla_{\theta} J(\theta_t - \gamma v_{t-1}) \tag{5} vt:=γ⋅vt−1+η∇θJ(θt−γvt−1)(5)
参数更新如下:
θ t + 1 : = θ t − v t (6) \theta_{t+1} := \theta_t - v_t \tag{6} θt+1:=θt−vt(6)
其中, v t v_t vt 表示 t t t 时刻积攒的加速度; γ \gamma γ 表示动力的大小; η \eta η 表示学习率; θ \theta θ 表示 t t t 时刻的模型参数, ∇ θ J ( θ t − γ v t − 1 ) \nabla_\theta J(\theta_t - \gamma v_{t-1}) ∇θJ(θt−γvt−1) 表示代价函数关于 θ \theta θ 的梯度。
一次更新的方向来更新当前位置的梯度
优点
- 有利于跳出当前的局部最优沟壑,寻找新的最优值
缺点
- 收敛速度慢
Adagrad
AdaGrad算法,独立地适应所有模型参数的学习率,缩放每个参数反比于其所有梯度历史平均值总和的平方根。具有代价函数最大梯度的参数相应地有个快速下降的学习率,而具有小梯度的参数在学习率上有相对较小的下降。
梯度表示如下:
g t = ∇ θ J ( θ ) (7) g_t = \nabla_\theta J(\theta) \tag{7} gt=∇θJ(θ)(7)
梯度加速变量 G G G 为 t t t 时刻前梯度的平方和:
G t = G t − 1 + g t 2 (8) G_{t} = G_{t-1} + g_{t}^{2} \tag{8} Gt=Gt−1+gt2(8)
参数更新如下:
θ : = θ − η G t + ϵ ⋅ ∇ θ J ( θ ) (9) \theta := \theta - \frac{\eta}{\sqrt{G_t + \epsilon}} \cdot \nabla_{\theta} J(\theta) \tag{9} θ:=θ−Gt+ϵη⋅∇θJ(θ)(9)
从表达式可以看出,对出现比较多的类别数据,Adagrad给予越来越小的学习率,而对于比较少的类别数据,会给予较大的学习率。因此Adagrad适用于数据稀疏或者分布不平衡的数据集。
优点
- 在稀疏数据场景下表现比较好
- 使用二阶动量关注学习率的变化
缺点
- 二阶动量的更新是单调递增的,所以会使学习率降至0,可能会使训练过程提前结束
AdaDelta
Adagrad会累加之前所有的梯度平方,而Adadelta只累加固定大小的项,并且也不直接存储这些项,仅仅是近似计算对应的平均值。
E E E 的计算公式如下, t t t 时刻的依赖于前一时刻的平均和当前的梯度:
E [ g 2 ] t : = γ ⋅ E [ g 2 ] t − 1 + ( 1 − γ ) ⋅ g t 2 (10) E[g^2]_t := \gamma \cdot E[g^2]_{t-1} + (1 - \gamma) \cdot g_t^2 \tag{10} E[g2]t:=γ⋅E[g2]t−1+(1−γ)⋅gt2(10)
与Adagrad相比,分母的 G G G 换成了过去梯度平方的衰减平均值:
∇ θ t = − η E [ g 2 ] t + ϵ (11) \nabla \theta_t = - \frac{\eta}{\sqrt{E[g^2]_t + \epsilon}} \tag{11} ∇θt=−E[g2]t+ϵη(11)
这个分母相当于梯度的均方根,可以用RMS简写:
∇ θ t = − η R M S [ g ] t ⋅ g t (12) \nabla \theta_t = -\frac{\eta}{RMS[g]_t} \cdot g_t \tag{12} ∇θt=−RMS[g]tη⋅gt(12)
此外,学习率也换成了 R M S [ ∇ θ ] t − 1 RMS[\nabla \theta]_{t-1} RMS[∇θ]t−1:
∇ θ t = − R M S [ ∇ θ ] t − 1 R M S [ g ] t ⋅ g t (13) \nabla \theta_t = -\frac{RMS[\nabla \theta]_{t-1}}{RMS[g]_t} \cdot g_t \tag{13} ∇θt=−RMS[g]tRMS[∇θ]t−1⋅gt(13)
参数更新如下:
θ t + 1 : = θ t + ∇ θ t (14) \theta_{t+1} := \theta_t + \nabla \theta_t \tag{14} θt+1:=θt+∇θt(14)
Adam
梯度表示同(7):
m t = β 1 m t − 1 + ( 1 − β 1 ) ⋅ g t , v t = β 2 v t − 1 + ( 1 − β 2 ) ⋅ g t 2 (15) m_t = \beta_1 m_{t-1} + (1 - \beta_1) \cdot g_t, \ \ \ \ \ v_t = \beta_2 v_{t-1} + (1 - \beta_2) \cdot g_t^2 \tag{15} mt=β1mt−1+(1−β1)⋅gt, vt=β2vt−1+(1−β2)⋅gt2(15)
其中, m t m_t mt 和 v t v_t vt 分别是对梯度的一阶矩估计和二阶矩估计;
分别对 m t m_t mt 和 v t v_t vt 进行校正:
m ^ t = m t 1 − β 1 t , v ^ t = v t 1 − β 2 t (16) \hat m_t = \frac{m_t}{1-\beta_1^t} , \ \ \ \ \hat v_t = \frac{v_t}{1-\beta_2^t} \tag{16} m^t=1−β1tmt, v^t=1−β2tvt(16)
参数更新为:
θ : = θ − η v ^ t + ϵ m ^ t (17) \theta := \theta - \frac{\eta}{\sqrt{\hat v_t} + \epsilon} \hat m_t \tag{17} θ:=θ−v^t+ϵηm^t(17)
优点
- 一阶动量和二阶动量,有效控制了学习率步长和梯度的方向,既能防止梯度的剧烈震荡又可以避免在鞍点处静止
缺点
- 可能不收敛
- 可能错过全局最优解:自适应学习率算法可能会对前期出现的特征过拟合,后期才出现的特征很难纠正前期的拟合效果。后期Adam的学习率太低,影响了有效的收敛。