数值优化算法【4】-- Adam 方法

RMSProp 和 AdaDelta 均采用加权移动平均的方法,对二阶动量做了窗口限制,使得学习效率得到明显提升; AdaDelta 方法进一步对学习率的分子项做了自动累积计算,无需人工指定全局学习率超参数(实际情况表明, AdaDelta 容易陷入局部最优解的陷阱)。 Adam 算法则采用了另外一种思路,其没有将思路放在自动计算学习率上,而是考虑将一阶动量引入学习率的更新,使学习过程更优。

1、 算法介绍

Adam 算法使用了一阶动量变量 vt\boldsymbol{v}_t 和 RMSProp 算法中的二阶动量变量 Gt\boldsymbol{G}_t ,并在时间步0将其初值置为0。

给定超参数 0β1<10 \leq \beta_1 < 1 (算法作者建议设为 0.90.9 ),时间步 tt 的一阶动量变量 vt\boldsymbol{v}_t 为梯度 gt\boldsymbol{g}_tvt1v_{t-1} 加权移动平均:

vtβ1vt1+(1β1)gt\boldsymbol{v}_t \leftarrow \beta_1 \boldsymbol{v}_{t-1} + (1 - \beta_1) \boldsymbol{g}_t

和 RMSProp 算法中一样,给定超参数 0β2<10 \leq \beta_2 < 1 (算法作者建议设为 0.999 ),
时间步 tt 的二阶动量 GtG_tGt1G_{t-1}gtgt\boldsymbol{g}_t \odot \boldsymbol{g}_t (梯度按元素平方)的加权移动平均 :

Gtβ2Gt1+(1β2)gtgt\boldsymbol{G}_t \leftarrow \beta_2 \boldsymbol{G}_{t-1} + (1 - \beta_2) \boldsymbol{g}_t \odot \boldsymbol{g}_t

由于我们将 v0\boldsymbol{v}_0G0\boldsymbol{G}_0 中的元素都初始化为 00 ,在时间步 tt 我们得到 vt=(1β1)i=1tβ1tigi\boldsymbol{v}_t = (1-\beta_1) \sum_{i=1}^t \beta_1^{t-i} \boldsymbol{g}_i 。将过去各时间步 gtg_t 的权值相加,得到 (1β1)i=1tβ1ti=1β1t(1-\beta_1) \sum_{i=1}^t \beta_1^{t-i} = 1 - \beta_1^t 。需要注意的是,当 tt 较小时,过去各时间步梯度权值之和会较小。例如,当 β1=0.9\beta_1 = 0.9 时, v1=0.1g1\boldsymbol{v}_1 = 0.1\boldsymbol{g}_1 。为了消除这样的影响,对于任意时间步 tt ,我们可以将 vt\boldsymbol{v}_t 再除以 1β1t1 - \beta_1^t ,从而使过去各时间步小批量随机梯度权值之和为1。这也叫作偏差修正。

在 Adam 算法中,对变量 vt\boldsymbol{v}_tGt\boldsymbol{G}_t 均作偏差修正:

v^tvt1β1tG^tGt1β2t\begin{equation} \begin{aligned} \hat{\boldsymbol{v}}_t &\leftarrow \frac{\boldsymbol{v}_t}{1 - \beta_1^t}\\\\ \hat{\boldsymbol{G}}_t &\leftarrow \frac{\boldsymbol{G}_t}{1 - \beta_2^t} \end{aligned} \end{equation}

接下来, Adam 算法使用以上偏差修正后的变量 v^t\hat{\boldsymbol{v}}_tG^t\hat{\boldsymbol{G}}_t ,将模型参数的梯度调整为:

gtηG^t+ϵv^t\boldsymbol{g}_t' \leftarrow \frac{\eta }{\sqrt{\hat{\boldsymbol{G}}_t + \epsilon}}\hat{\boldsymbol{v}}_t

其中 η\eta 是学习率, ϵ\epsilon 是为了维持数值稳定性而添加的常数,如 10810^{-8} 。和 AdaGrad 算法、 RMSProp 算法以及 AdaDelta 算法一样,目标函数自变量中每个元素都分别拥有自己的学习率。最后,使用 gt\boldsymbol{g}_t' 迭代自变量:

θtθt1gt.\boldsymbol{\theta}_t \leftarrow \boldsymbol{\theta}_{t-1} - \boldsymbol{g}_t'.

Adam 中引入了一阶动量估计,同时相比于缺少修正因子导致二阶矩估计可能在训练初期具有很高偏置的 RMSProp , Adam 包括了对一阶和二阶动量的偏置修正。

Adam 算法策略可以表示为:

vt=β1vt1+(1β1)gtGt=β2Gt1+(1β2)gtgtv^t=vt1β1tG^t=Gt1β2tgt=ηG^t+ϵv^tθt=θt1gt.\begin{equation} \begin{aligned} \boldsymbol{v}_t &= \beta_1 \boldsymbol{v}_{t-1} + (1 - \beta_1) \boldsymbol{g}_t\\\\ \boldsymbol{G}_t &= \beta_2 \boldsymbol{G}_{t-1} + (1 - \beta_2) \boldsymbol{g}_t \odot \boldsymbol{g}_t\\\\ \hat{\boldsymbol{v}}_t &= \frac{\boldsymbol{v}_t}{1 - \beta_1^t}\\\\ \hat{\boldsymbol{G}}_t &= \frac{\boldsymbol{G}_t}{1 - \beta_2^t}\\\\ \boldsymbol{g}_t' &= \frac{\eta }{\sqrt{\hat{\boldsymbol{G}}_t + \epsilon}}\hat{\boldsymbol{v}}_t\\\\ \boldsymbol{\theta}_t &= \boldsymbol{\theta}_{t-1} - \boldsymbol{g}_t'. \end{aligned} \end{equation}

其中, GGvv 分别为二阶动量项和一阶动量项。β1,β2\beta_1, \beta_2 为动力值大小,通常分别取0.9和0.999; G^t,v^t\hat{G}_t, \hat{v}_t 分别为各自的修正值。 θt\theta_t 表示 tt 时刻即第 tt 次迭代模型的参数, gtg_t%3D%CE%94J%28W_t%29) 表示 tt 次迭代中,代价函数 JJ 关于 θ\theta 的梯度;ϵ\epsilon 是一个取值很小的数(一般为 10810^{-8})为了避免分母为0。

Adam 方法和 RMSProp、AdaDelta 很像,但是引入了平滑版的一阶动量 vv ,而不是原始梯度 gg 。鉴于上述有点,在实际操作中,可以考虑用 Adam 作为默认算法,一般比 RMSProp 要好一点。