优化器的选择

不同优化器的核心差异其实在于 梯度下降的方向,无论是 Momentum 的一阶动量、AdaGrad 的二阶动量自适应学习率、NAG 的「提前走一步」还是 Adam 的集大成,他们的核心基础都是 基于反向传播计算的梯度,并根据自己的理解对真正更新的方向进行一定的调整。

由于下降方向的不同,不同的算法往往到达完全不同的局部最优点。以下是一些选择的考量:

  • 推荐两种优化器选择Adam 是比较保险的优化器选择,不需要太费心,但是最终收敛的性能可能不如精调的 SGD;另一个选择可以用 SGD + Momentum + NAG,其实就是 Adam 去掉自适应学习率之后剩下的部分(这两个选择的建议来自 CS231n)。
  • 考虑不同优化器的组合:一开始用 Adam 加速收敛,后面切换成 SGD 精调。
  • 自适应学习率适合稀疏数据/模型:如果数据特征稀疏或者模型参数稀疏,优先使用自适应学习率的算法,如 Adam

优化器的发展

SGD

SGD(Stochastic Gradient Descent)是最基本的优化算法,核心是朝着负梯度方向更新参数,公式如下: $$ W_t = W_{t-1} - \alpha\cdot\nabla_t $$

其中 $W_t$ 为 $t$ 时刻的参数,$\nabla_t$ 为 $t$ 时刻的梯度,$\alpha$ 为学习率。

优缺点如下:

  • (-) 收敛速度比较慢。
  • (-) 可能会在鞍点处震荡。
  • (-) 学习率难以选择,需要反复调试。

SGD with Momentum

梯度一阶动量,保持惯性

为了抑制 SGD 的震荡,并且当梯度方向一致时加速更新,SGD with Momentum 提出存储梯度的一阶动量(Momentum),即各个时刻的梯度方向的指数移动平均值,每一步的更新方向不仅考虑当前的梯度,还要考虑之前梯度的累积。

Coursera 版本的公式比较清晰: $$ \begin{cases} V_t &= &\beta\cdot V_{t-1} + (1-\beta)\cdot\nabla_t \\ W_t &= &W_{t-1} - \alpha\cdot V_t \\ \end{cases} $$

CS231n 版本的公式略有不同: $$ \begin{cases} V_t &= &\beta\cdot V_{t-1} + \alpha\cdot\nabla_t \\ W_t &= &W_{t-1} - V_t \\ \end{cases} $$

一般取 $\beta$ = $0.9$ (CS231n)。

优缺点如下:

  • (+) 加速 SGD 在正确方向的下降(当梯度方向变化不大,更新幅度更大)。
  • (+) 抑制 SGD 震荡(当梯度方向变化较大时,更新要考虑之前的动量)。

NAG

我先走一步

NAG(Nesterov Accelerated Gradient)的出发点是,既然在 SGD with Momentum 中,累积的动量始终会影响当前更新的方向,我们下一步肯定要走当前这部分「累积动量」,那么其实这一步就可以提前把下一步的先走了(即 $\hat{W}_t$),然后再计算此时的梯度方向(即 $\hat{\nabla}_t$),如此计算得到的梯度方向会更加准确。

Coursera 版本公式:

$$ \begin{cases} \hat{W}_t &= &W_{t-1} - \beta\cdot V_{t-1} \\ V_t &= &\beta\cdot V_{t-1} + (1-\beta)\cdot\hat{\nabla}_t \\ W_t &= &W_{t-1} - \alpha\cdot V_t \\ \end{cases} $$

类似的也有 CS231n 版本公式:

$$ \begin{cases} \hat{W}_t &= &W_{t-1} - \beta\cdot V_{t-1} \\ V_t &= &\beta\cdot V_{t-1} + \alpha\cdot\hat{\nabla}_t \\ W_t &= &W_{t-1} - V_t \\ \end{cases} $$

优缺点如下:

  • (+) 提前更新一定会更新的那一步,「预测未来」,得到更加准确的梯度。

AdaGrad

梯度二阶累积,自适应调整每个方向的学习率

如果说 SGD with Momentum 是在把控梯度下降的方向,那么 AdaGrad(Adaptive Gradient)则是试图把控前进方向的「步伐」。对于经常更新的参数(二阶梯度累积较大),由于我们已经积累了大量关于它的知识,因此不希望被单个样本影响太大;对于较少更新的参数(二阶梯度累积较小),我们了解的信息太少,因此希望能从偶然出现的样本中多学习一些,即学习率更大一些。

为了度量「经常更新」,我们引入了二阶动量,即梯度的每个维度的值的平方和,记为 $S_t$。每一步更新中,每个参数的学习率各有不同,我们用预定义的学习率 $\alpha$ 除以二阶动量的算术平方根,作为当前时刻该参数的学习率。如果某个维度的二阶动量(梯度平方和)越大,则学习率越小;反之则学习率越大。

优化器公式如下: $$ \begin{cases} S_t &= &S_{t-1} + \nabla_t^2 \\ \hat{\alpha}_t &= &\frac{\alpha}{\sqrt{S_t}+\epsilon} \\ W_t &= &W_{t-1} - \hat{\alpha}_t\cdot \nabla_t \\ \end{cases} $$

优缺点如下:

  • (+) 自适应学习率,不需要太人工调整学习率。
  • (+) 适合应对特征稀疏的数据(即数据的高维特征中仅有少数非零特征)。
  • (+) 适合应对参数稀疏的模型(即模型的高维参数中仅有少数非零参数)。
  • (-) 二阶动量 $S_t$ 单调递增,导致学习率单调递减,使得训练过程提前结束。

参考:

RMSProp

AdaGrad 的指数平均版

为了解决 AdaGrad 中的二阶动量 $S_t$ 单调递增的问题,RMSProp 提出用指数移动平均的二阶动量。

Coursera 版本的公式如下: $$ \begin{cases} S_t &= &\beta\cdot S_{t-1} + (1-\beta)\cdot\nabla_t^2 \\ \hat{\alpha}_t &= &\frac{\alpha}{\sqrt{S_t}+\epsilon} \\ W_t &= &W_{t-1} - \hat{\alpha}_t\cdot \nabla_t \\ \end{cases} $$

一般取 $\beta=0.9$。

优缺点如下:

  • (+) 具有 AdaGrad的优点,而且避免了二阶动量 $S_t$ 单调递增的问题。

Adam

Momentum + RMSProp

Adam 基本上就是 SGD with MomentumRMSProp 的集成。

不过因为指数平均的存在,一阶动量 $V_t$ 和二阶动量 $S_t$ 都会在在初始阶段会过多地偏向 0,因此 Adam 对 $V_t$ 和 $S_t$ 做了 偏置校正(Bias Correction),即除以系数 $1 - \beta^t$,刚开始 $t$ 很小,使用的动量会被放大,随着 $t$ 的增大,该系数趋近于 1,当训练到若干步之后,可以去掉该偏置校正。

公式如下: $$ \begin{cases} V_t &= &\beta_1\cdot V_{t-1} + (1-\beta_1)\cdot\nabla_t \\ \hat{V}_t &= &\frac{V_t}{1-\beta_1^t} \\ S_t &= &\beta_2\cdot S_{t-1} + (1-\beta_2)\cdot\nabla_t^2 \\ \hat{S}_t &= &\frac{S_t}{1-\beta_2^t} \\ W_t &= &W_{t-1} - \frac{\alpha}{\sqrt{\hat{S}_t}+\epsilon} \cdot \hat{V}_t \end{cases} $$

一般 $\beta_1 = 0.9$, $\beta_2 = 0.99$, $\epsilon = 1e-8$(CS231n

优缺点如下:

  • (+) 集大成者,有 MomentumRMSProp 等的优点。
  • (-) 集大成者,有 MomentumRMSProp 等的缺点。
  • (-) 自适应算法可能不收敛On the Convergence of Adam and Beyond ICLR 2018)
    • 随着数据的变化,其二阶动量 $S_t$ 时大时小,在训练的后期时梯度较小的时候 $S_t$ 很容易震荡,从而使得学习率不断震荡,导致模型无法收敛。
    • 可能的解决方法是控制二阶动量 $S_t$ 的变化,防止其震荡,作者提出可以令 $S_t = \max(\hat{S_t}, S_{t-1})$,其中 $\hat{S}_t$ 是以 RMSProp 的方式算出来的二阶动量。通过这样的限制,使得 $||S_t|| \ge |S_{t-1}|$,进而使学习率单调递减,保证收敛。
  • (-) 自适应算法后期学习率太低,无法收敛到最优解
  • Improving Generalization Performance by Switching from Adam to SGD(arXiv 2017):后期 Adam 学习率太低,影响有效收敛,提出前期用 Adam,后期切成 SGD

参考:

Nadam

Adam (Momentum + RMSProp) + NAG

Adam 的基础上结合了 NAG,即提前走下一步要走的梯度,然后计算此时的梯度来更新。

补充:Adam 切换 SGD

为了既享受 Adam 的快速收敛,又能利用 SGD 精调达到更优点,我们考虑前期使用 Adam,并在训练过程中切换成 SGD。那么问题来了:

  1. 我们在什么时候切换优化算法?
  2. 如何选择切换之后的 SGD 学习率?

以下按照论文 Improving Generalization Performance by Switching from Adam to SGD(arXiv 2017)的思路来讲解。

问题一:切换后的学习率

我们先来考虑切换后使用的学习率。我们究竟需要一个什么样的学习率?很容易想到,学习率控制了参数更新的幅度,我们选择的学习率应该尽量保证梯度下降的稳定进行,即 参数的更新量要保持稳定

我们回顾一下 SGDAdam 对参数的更新量 $\eta_{\text{sgd}}$、$\eta_{\text{adam}}$ 分别是: $$ \begin{aligned} \eta_{\text{sgd}} &= \alpha_{\text{sgd}}\cdot\nabla_t \\ \eta_{\text{adam}} &= \frac{\alpha_{\text{adam}}}{\sqrt{\hat{S}_t}+\epsilon} \cdot \hat{V}_t \\ \end{aligned} $$

(具体符号含义见上文。为了方便,以下内容我们省略表示 $t$ 时刻的标记。)

其中 Adam 的更新量 $\eta_{\text{adam}}$、模型梯度 $\nabla$ 是已知的,现在要求 SGD 的学习率 $\alpha_\text{sgd}$。

事实上,$\eta_{\text{adam}}$ 相当于一个长度已知的向量,表示 Adam 的更新量;$\nabla$ 相当于长度未知的另一个向量,表示 SGD 的更新方向。那么我们的做法很简单,我们将 SGD 的更新方向投影在 Adam 的更新方向上,并利用 $\alpha_\text{sgd}$ 对该投影进行缩放,当 投影的长度等于 Adam 的更新量 时,此时的缩放因子即为我们要求的学习率 $\alpha_\text{sgd}$。

这里复习一下向量投影公式:

对于向量 $\vec{a}$、$\vec{b}$,他们的内积为:

$$ \vec{a}\cdot\vec{b}=||\vec{a}||\cdot||\vec{b}||\cdot\cos\theta $$

$\vec{a}$ 在 $\vec{b}$ 上的投影长度为:

$$ a_b = ||\vec{a}||\cdot\cos\theta = \frac{\vec{a}\cdot\vec{b}}{||\vec{b}||} $$

那么下一步只需要求解以下方程即可:

$$ \begin{aligned} \alpha_\text{sgd} \cdot \frac {\nabla^\textrm{T} \cdot \eta_{\text{adam}}} {||\eta_{\text{adam}}||} &= ||\eta_{\text{adam}}|| \\ \end{aligned} $$

解方程得 SGD 学习率 $\alpha_\text{sgd}$ 为:

$$ \begin{aligned} \alpha_\text{sgd} &= \frac {\eta_{\text{adam}}^\textrm{T}\cdot\eta_{\text{adam}}} {\eta_{\text{adam}}^\textrm{T}\cdot\nabla} \end{aligned} $$

为了得到更稳定的学习率估计,还可以加入指数移动平均,那么 $t$ 时刻的学习率 $\alpha_{\text{sgd}, t} $ 如下:

$$ \alpha_{\text{sgd}, t} = \beta_2\cdot\alpha_{\text{sgd}, t-1} + (1 - \beta_2)\cdot\hat{\alpha}_{\text{sgd}, t} $$

作者直接复用了 Adam 的 $\beta_2$ 参数,即二阶动量指数平均的系数。

问题二:何时切换

SGD 对应的学习率 $\alpha_{\text{sgd}, t}$ 基本不变的时候,我们就可以进行算法的切换,即: $$ |\alpha_{\text{sgd}, t} - \alpha_{\text{sgd}, t-1}| < \epsilon $$

参考