前言
在机器学习模型中,我们会使用损失函数对模型的输出和标注信息计算他们之间的差异,然后使用损失进行反向传播,在反向传播中,我们的目的是不断地更新参数使得模型损失越来越小直至达到最小,这过程是优化参数的过程,基础的优化算法是使用梯度下降法(如下图),梯度下降法利用了梯度的反方向是函数下降最快的方向的特性,该过程可以理解成寻找山谷。随后为了提高效率和准确率许多的改进的优化算法被提出,下面我们将介绍几种常用的优化算法。
1 梯度下降算法
假设线性回归函数为:$\boldsymbol{h_\theta(x^{(i)}) = \theta _1x^{(i)} + \theta_0}$,代价函数为:$\boldsymbol{J(\theta_0,
\theta_1) = \frac{1}{2m}\sum_{i=1}^{m}(h_\theta(x^{(i)}) - y^{(i)})^2}$,其中 $\boldsymbol{i= 1,2, … ,𝑚}$ 表示样本数,$\boldsymbol{𝑗 = 0,1}$ 表示特征数,这里我们使用偏置项 $\boldsymbol{x_0^{(i)} = 1}$。
1.1 BGD
批量梯度下降(BGD)是最原始的形式,在每一次迭代时使用所有样本来对参数进行更新,也即使用了所有样本只更新了一次参数。更新算法如下:
优点:
- 目标函数为凸函数时,能得到全局最优解。
- 易于并行实现。
缺点:
- 当样本数目过多时,训练过程较慢,时间成本高。
1.2 SGD
随机梯度下降(SGD)在每一次迭代时使用一个样本来对参数进行更新。更新算法如下:
优点:
- 训练速度快。
缺点:
- 准确度下降,很大程度上并不是全局最优。
- 不易于并行实现。
1.3 MBGD
小批量梯度下降(MBGD)在每一次迭代时使用 $\boldsymbol{batch\_size}$ 个样本来对参数进行更新。更新算法如下:
MBGD 减少了 BGD 和 SGD 的缺点,结合了 BGD 和 SGD 的优点,我们在平时的实验过程中往往使用 MBGD。
2 基于动量的优化算法
2.1 基于动量的SGD
梯度下降法在遇到平坦或高曲率区域时,学习过程有时很慢。利用动量算法能比较好解决这个问题。动量算法与传统梯度下降优化的效果对比如下:
从上图可以看出,不使用动量算法的 SGD 学习速度较慢,振幅较大; 而使用动量算法的 SGD,振幅较小,而且会较快到达极值点。动量(Momentum)是模拟物理里动量的概念,具有物理上惯性的含义,一个物体在运动时具有惯性,把这个思想运用到梯度下降计算中,可以增加算法的收敛速度和稳定性。在动量学习算法中,我们假设是单位质量,因此速度向量 $\boldsymbol{v}$ 也可以看作是粒子的动量。超参数 $\boldsymbol{α ∈ [0, 1)}$ 决定了之前梯度的贡献衰减得有快,示意图如下:
由上图知动量算法每下降一步都是由前面下降方向的一个累积和当前点的梯度方向组合而成。含动量的随机梯度下降法的算法流程如下:
在实践中,$\boldsymbol{\alpha}$ 的一般取值为 $\mathbf{0.5}$,$\mathbf{0.9}$ 和 $\mathbf{0.99}$。和学习率一样,$\boldsymbol{\alpha}$ 也会随着时间不断调整。一般初始值是一个较小的值,随后会慢慢变大。随着时间推移调整 $\boldsymbol{\alpha}$ 没有收缩 $\boldsymbol{ϵ}$ 重要。
2.2 基于NAG的SGD
Nesterov Accelerated Gradient,简称 NAG 算法,是普通动量算法的改进版本。普通动量算法中每一步都要将两个梯度方向(历史梯度、当前梯度)做一个合并再 下降,那就可以先按照历史梯度往前走那么一小步,按照前面一小步位置的“超前梯度”来做梯度合并。这样就可以先往前走一步,在靠前一点的位 置(如下图中的C点)看到梯度,然后按照那个位置再来修正这一步的梯度方向。
仔细观察他们的示意图可以发现,普通动量的下降方向的合成是四边形合成而 NAG 是三角合成,NAG 更新规则如下:
其中参数 $\boldsymbol{α}$ 和 $\boldsymbol{ϵ}$ 发挥了和标准动量方法中类似的作用。Nesterov动量和标准动量之间的区别体现在梯度计算上。Nesterov 动量中,梯度计算在施加当前速度之后。因此,Nesterov 动量可以解释为往标准动量方法中添加了一个校正因子。含 Nesterov 动量的随机梯度下降法的算法流程如下:
NAG 算法的预更新方法能防止大幅振荡,不会错过最小值,并会对参数更新更加敏感。
3 自适应优化算法
传统梯度下降算法对学习率这个超参数非常敏感,难以驾驭,对参数空 间的某些方向也没有很好的方法。这些不足在深度学习中,因高维空间、多层神经网络等因素,常会出现平坦、鞍点、悬崖等问题,因此,传统梯度下降法在深度学习中显得力不从心。上面介绍的动量算法在一定程度上缓解了对参数空间某些方向的问题,但需要新增一个超参数,而且对学习率的控制还不是很理想。为了更好地驾驭这个超参数,自适应优化算法被提出,使用自适应优化算法, 学习率不再是一个固定不变值,它会根据不同情况自动调整来适应相应的情况。
3.1 AdaGrad
AdaGrad 算法能够独立地适应所有模型参数的学习率,缩放每个参数反比于其所有梯度历史平方值总和的平方根。具有损失最大偏导的参数相应地有一个快速下降的学习率,而具有小偏导的参数在学习率上有相对较小的下降。净效果是在参数空间中更为平缓的倾斜方向会取得更大的进步。因此,AdaGrad算法非常适合处理稀疏数据。对于训练深度神经网络模型而言,从训练开始时积累梯度平方会导致有效学习率过早和过量的减小从而使得模型的效果不好。算法流程如下:
其中 $\boldsymbol{\delta}$ 一般取一个较小值,这是为了出现分母为零的情况,$\boldsymbol{\bigodot}$ 表示逐元运算。且由上面的算法流程可知:
- 随着迭代时间越长,累积梯度 $\boldsymbol{r}$ 越大,导致学习速率 $\boldsymbol{\frac{ϵ}{\delta + \sqrt{r}}}$ 随着时间减小,在接近目标值时,不会因为学习速率过大而越过极值点。
- 不同参数之间的学习速率不同,因此,与前面固定学习速率相比, 不容易在鞍点卡住。
- 如果梯度累积参数 $\boldsymbol{r}$ 比较小,则学习速率会比较大,所以参数迭代的步长就会比较大。相反,如果梯度累积参数比较大,则学习速率会比较小, 所以迭代的步长会比较小。
3.2 RMSProp
RMSProp 算法通过修改AdaGrad得来,其目的是在非凸背景下效果更好。RMSProp 使用指数衰减平均以丢弃遥远过去的历史,使其能够在找到凸碗状结构后快速收敛,它就像一个初始化于该碗状结构的 AdaGrad 算法实例。相比于 AdaGrad,使用移动平均引入了一个新的超参数ρ,用来控制移动平均的长度范围。算法流程如下:
3.3 Adam
Adam(Adaptive Moment Estimation)本质上是带有动量项的 RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。Adam 的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。 Adam 是另一种学习速率自适应的深度神经网络方法,它利用梯度的一 阶矩估计和二阶矩估计动态调整每个参数的学习速率。算法流程如下:
Adam 通常被认为对超参数的选择相当鲁棒,尽管学习率有时需要从建议的默认修改。
4 优化器的选择
AdaGrad、RMSprop、和 Adam 被认为是自适应优化算法,因为它们会自动更新学习率。而使用 SGD 时,必须手动选择学习率和动量参数,通常会随着时间的推移而降低学习率。
有时可以考虑综合使用这些优化算法,如采用先使用 Adam,然后使用 SGD 的优化方法,这个想法,实际上是由于在训练的早期阶段 SGD 对参数调整和初始化非常敏感。因此,我们可以通过先使用 Adam 优化算法来进行训 练,这将大大地节省训练时间,且不必担心初始化和参数调整,一旦用 Adam 训练获得较好的参数后,就可以切换到 SGD + 动量优化,以达到最佳性能。