Earyant的技术博客

欢迎来到Earyant的技术博客,在这里我将与你分享新技术。

调参-优化算法

简介

优化算法在深度学习中也是十分重要的,虽然一般情况下无脑 Adam 即可,但有时采用其余的优化算法反而能够获得更好的结果,这点很有意思。同时,理解优化算法的原理对于选择和面试还是很有帮助的。

超参数设置 — 遵循原论文

优化算法 超参数
SGD
Momentum $\gamma: 0.9$
Adagrad $\gamma: 0.9$
RMSprop/ Adadelta
Adam $\beta_1: 0.9, \quad \beta_2: 0.999, \quad \epsilon: 1e-8$
Adamax
Nadam

1. 三大基本算法

1. 随机梯度下降

2. 标准梯度下降

3. mini-batch 梯度下降

三者比较

  • 随机梯度下降: 每次更新的方向并不向全局最优解的方向前进,最终的收敛结果也往往在全局最优解附近,但并不能达到最优解。迭代过程不可测。不容易陷入局部最小值。
  • 标准梯度下降: 更新速度很慢,每次都要计算全部样本的梯度。且由于梯度方向过于稳定一致(没有随机因素)且更新次数过少,很容易陷入鞍点或局部最小值。
  • mini-batch 梯度下降: 二者折中,batch size 的设置是一个艺术。

2. 梯度下降算法的一点改进

1. 动量梯度下降法

在使用梯度下降算法中,很容易产生一种“震荡现象”(相邻前后梯度正负相反),这种震荡现象减慢了梯度下降法的速度,这也导致你无法使用更大的学习率, 如果你使用较大的学习率, 可能导致震荡更大, 收敛更慢。

Momentum的核心思想: 通过计算梯度的指数加权平均值,并利用该平均值来更新你的权重,这样梯度的变化就没有那么快了。其本质是通过增加动量来减少随机,增加梯度的稳定性。

举个例子, 假如这里有个碗状的峡谷, 峡谷中坑坑洼洼,有许多小坡, 如果我们从峡谷上推下一个球, 根据物理现象,由于加速度,小球的速度在下降的过程中越来越快, 即使路上遇到小坡,也能够轻松跨越(跨不过去,就是局部最小点了), 直至到达谷底。

引申到动量法的参数变化中: 对于在梯度点处具有相同的方向的维度,表明加速度为正,那么速度自然加快;对于在梯度点处改变方向的维度, 加速度为负, 速度减缓。 这样,我们可以得到更快的收敛速度, 同时可以减少摇摆。

2. Nesterov Accelerated Gradient

momentum

  • 思想: 在动量法中, 小球总是以一种盲目的方式滚动, 这会造成一个问题, 在临近最优点的附近时控制不住速度,于是会造成我们在最优点附近摇啊摇,最终收敛。

    我们希望小球足够聪明,它能够预判后面的地形, 如果后面是下坡路就加速下降, 如果后面是上坡路,说明我们已经到了最优点附近, 该减速了。

  • 实现方式:Nesterov就利用这一思想,它将 $J(\theta - \gamma v_{t-1})$ 假定为下一位置, 通过计算它的梯度,就可以得到我们接下来是加速还是刹车了,的确很聪明。

  • 优点:Nesterov Accelerated Gradient 相比Momentum, 能显著的提升了优化效果,收敛速度要快很多。

我们来从数学角度分析一下, 相对 momentum, 到底发生了什么变化:

具体推论需要再次参考 比Momentum更快:揭开Nesterov Accelerated Gradient的真面目

3. 自适应学习率优化算法

0. 为何要自适应学习率?

在梯度下降的过程中,每个参数更新的频率与幅度是不同的,到了训练中后期,对于某些变量,也许已经到达了极小值附近,而有些变量仍然在初始位置不远处。 此时,如果我们采用不同的学习率会导致一个问题: 如果学习率偏小,则那些更新不多的参数会收敛的很慢,如果学习率偏大,那么对于处于极小值附近的参数,很容易产生不稳定现象。

为了解决这个问题,我们需要针对不同的参数设置不同的学习率, 但参数是无穷尽的, 不可能去人为的设置每一个参数的学习率,因此,自适应学习率就显得很有必要了。

1. Adagrad

  • $G_{i,t}$ 是一个对角矩阵, $G[i][i]$ 上的元素表示在第 t 步更新时, 历史上 $\theta$ 梯度的积累。

  • 思想:对每个参数用不同的学习率,这个学习率在一开始比较大,用于快速梯度下降。随着优化过程的进行,对于已经下降很多的参数,则减缓学习率,对于还没怎么下降的参数,则保持一个较大的学习率。

  • 方法: 通过维护一个对角矩阵来累积历史梯度来实现学习率的变化, 其中对角线上的每个元素表示某个参数历史梯度的累积。

    如果某参数历史梯度较大,那么说明该参数优化的快,更有可能到达最优点附近, 而此时它在对角矩阵上对应的累积梯度也大, 从而使得对应的学习率较小,最终实现不同参数有着不同的学习率。

  • 优点: 十分适合处理稀疏数据。消除了需要手动调整学习率的问题。

  • 缺陷: 分母项的积累: 由于每个附加项都是正数,因此累积总和在训练期间不断增长。这反过来导致学习速率缩小并最终变得无限小,此时算法不再进行优化。

2. Adadelta

  • $E[g^2]_t$ 表示 t 时刻的平方梯度对数平均值, 本质的思想用了对数平均的思路。
  • 改进: 改进 Adagrad 中学习率最终无限小的问题。
  • 思想: 通过设定一个窗口大小 w , 来求最近 w 个平方梯度的对数平均值(对数平均的思想),采用求平均值而非求和的方式可以有效的避免学习率无限低问题。

3. RMSprop

比较 RMSprop 与 Adadelta 二者公式可以发现,在 Adadelta 取 $\gamma = 0.9$ 就是RMSprop了。

4. Adam

  • $m_t$ 是历史梯度对数平均估计, $v_t$ 是历史梯度平方对数平均估计,其实就是求取的$E[g_t], E[g_t^2]$ 的近似。
  • $\hat{m_t}, \hat{v_t}$ 是对 $m_t, v_t$ 的校正,可以近似为对 $E[g_t], E[g_t^2]$ 的无偏估计。

我们结合 Momentum 与 RMSProp 算法来看, Adam算法本质上就是将二者结合,同时考虑到梯度与梯度平方, 通过历史梯度来加速收敛, 通过历史梯度平方来修正学习率。

  • 优点: 高效的计算,收敛非常快。适合解决大规模数据和参数优化问题。

  • 为何要进行偏差修正:

    因为初始化的 $m_t$ 与 $v_t$ 为 0 向量,在通过指数平均计算均值时会偏差向 0, 尤其是在初始时间步中和 $\beta_1, \beta_2$ 非常小的情况下(接近于1),尤其如此。

更复杂的分析,推荐: 深度学习最常用的算法:Adam优化算法

5. AdaMax

6. Nadam

如何选择优化算法?

我个人一般选择 Adam, 优点是,收敛快,这样模型迭代起来也快, 如果是轻量级模型的话, 需要好好选择优化算法调参, 而如果是重量级的模型, 无脑 Adam 是一个相当不错的选择。

QA


1. 在mini-batch 中, batch size 会带来怎样的影响?

batch size 的大小往往是由多个因素决定的:

  • 较大的批能得到更精确的梯度估计
  • 较小的批能带来更好的泛化误差,泛化误差通常在批大小为 1 时最好。但是,因为梯度估计的高方差,小批量训练时需要较小的学习率以保持稳定性,这意味着更长的训练时间
  • batch size 与所需显存息息相关,可参见:GPU 显存不足怎么办?
  • 在 GPU 上, 请采用 2 的幂数作为 batch size, 一般取值在 32 - 256。
  • 小批量更容易利用多核架构,但是太小的批并不会减少计算时间,这促使我们使用一些绝对最小批量

2. 深度学习为什么不用二阶优化?

目前深度学习中,反向传播主要是依靠一阶梯度。二阶梯度在理论和实际上都是可以应用都网络中的,但相比于一阶梯度,二阶优化会存在以下一些主要问题:

  • 计算量大,训练非常慢。
  • 二阶方法能够更快地求得更高精度的解,这在浅层模型是有益的。而在神经网络这类深层模型中对参数的精度要求不高,甚至不高的精度对模型还有益处,能够提高模型的泛化能力。
  • 稳定性:二阶方法能更快求高精度的解,同样对数据本身要的精度也会相应的变高,这就会导致稳定性上的问题。

Reference

[1] An overview of gradient descent optimization algorithms

路遥知马力——Momentum

比Momentum更快:揭开Nesterov Accelerated Gradient的真面目

欢迎关注我的其它发布渠道