神经网络优化方法

本文主要结合 B站 Up 主 @王木头学科学 关于神经网络优化方法的视频 来总结各个优化算法。

科学家们很早就提出了神经网络的优化算法–梯度下降法,但是很长时间以来,其只是停留在理论层面,在实际应用中效果并不好。总结起来,梯度下降法主要有这两个特点(缺点),

  1. 每次迭代需要遍历数据集中的每个样本,计算量很大。
  2. 需要经过很多次迭代才能达到极值点。

因此,想要改进梯度下降法,就要从这两个方面着手,进行改进。

改进思路为:

  1. 不再遍历整个数据集才进行一次参数更新,而是每个样本更新一次,也就是随机梯度下降。
  2. 优化迭代路径,缩小其到达极值点所需要的迭代次数。

针对随机梯度下降是否真的能达到极值点,数学家进行了证明(见视频 04:43)。因此,使用随机梯度下降的可行性得到了保证。在实际使用中,经常使用小批量随机梯度下降,也就是 mini-batch SGD. 平时使用时也将其称作随机梯度下降。

到这里,梯度下降的第一个缺点可以说得到了改进。接下来,考虑第二个优化思路–对迭代路径进行优化。这也是本文的重点。

迭代路径优化的必要性

Q: 既然梯度(其反方向)已经是下降最快的方向了,为什么还要对其路径进行优化?

  1. 对随机梯度下降来说,每次选择一个样本计算梯度。这个样本的随机性较大(甚至可能是离群点),利用其求得的梯度方向和整个数据集求得的梯度方向可能有偏差。
  2. 即使是针对标准梯度下降,依然是有必要的。因为,梯度是针对参数空间某个点的,其是一个极小范围内的最快下降方向(微积分思想)。若要得到最快下降路径,每次迭代的步长必须是无限小的,这对计算机来说显然是不现实的。而针对一个不是无限小的步长,必然会发生其前进的方向不是最优优化方向的情况。而这也为优化迭代路径提供了空间。
    图1. A迭代到A'的过程中经过B,A->A'的方向与B点处梯度方向有偏差

因此,目标转化成了如果在保证一定步长的情况下,更好地贴合最优下降路径。

二阶优化 - 牛顿法

考虑一个一维的损失函数 J\textit{J}, 橙色的线是点 a0\textit{a}_0 处的切线。我们发现,绿色的二次曲线比橙色的切线在一定范围内更能拟合函数 J\textit{J} 在点 a0\textit{a}_0 附近的状况。也就是说,在一定范围内(绿色曲线最小值点以左),我们可以用二次曲线来拟合损失函数 J\textit{J}. 这也是泰勒级数的思想。我们将泰勒展开保留到二阶导,由于二次函数在极小值时距 J\textit{J} 差距最小,因此参数下一步就将前进到极小值处。如下图所示,
图2. 牛顿法

上文讨论的是一维函数,针对高维损失函数,考虑也是类似的。只不过二阶导的形式发生了变化,如下图
图3. 高维情形的牛顿法

个人理解:可以看出,针对 N\textit{N} 维的损失函数,需要计算 Hessian 矩阵。对一个有非常多维的神经网络来说,其有成千上万维的参数,因此计算 Hessian 矩阵并求逆的计算量是非常大的。因此,虽然相对梯度下降法,牛顿法只需较少的迭代次数就能逼近极值点,但是牛顿法每次迭代的巨大计算量完全将它的这个优势抵消了。因而在实际情况下,牛顿法没有被广泛使用。
参考

一阶优化

以牛顿法为代表的二阶优化算法虽然需要的迭代次数较少,但是每次迭代需要的计算量较大,不适合实际应用。

在实际的应用场景中,我们主要采用的还是基于梯度下降的一阶优化。

深度学习优化算法经历了 SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam 这样的发展历程。接下来主要记录每种方法的细节。

标准梯度下降 Batch gradient descent

θ=θηθJ(θ)\theta = \theta - \eta \cdot \nabla_\theta J( \theta)

随机梯度下降 Stochastic gradient descent

θ=θηθJ(θ;x(i);y(i))\theta = \theta - \eta \cdot \nabla_\theta J( \theta; x^{(i)}; y^{(i)})

其中,x(i)x^{(i)}, y(i)y^{(i)} 分别代表每一个样本和标签。

小批次梯度下降 Mini-batch gradient descent

θ=θηθJ(θ;x(i:i+n);y(i:i+n))\theta = \theta - \eta \cdot \nabla_\theta J( \theta; x^{(i:i+n)}; y^{(i:i+n)})

动量法 Momentum

由定义可知, SGD 方法在每一步处的前进方向是完全取决于当前点处的梯度向量的。上一个时刻及之前的时刻的前进方向对其是完全没有影响的。因此,在图像上来看,SGD 的迭代路径会震荡得比较厉害。
图4. SGD 方法震荡

如上图所示,第二次迭代位置的梯度在纵轴上与第一次迭代位置在纵轴上的方向是刚好相反的,在横轴方向上是相同的。由于极值点是在横向上的右方,因此一个自然的想法就是,是否可以抑制纵轴不同梯度方向的震荡以及加强横轴上同方向的变化力度。

而这可以通过引入历史梯度信息来实现。
图5. 引入历史梯度信息

但是上面的图的方法是有问题的,因为其将历史上的所有梯度信息都收集了起来。很久之前的梯度对当前的影响和前一刻的梯度对当前的影响相同。但是很久之前的梯度信息可能已经和当前完全不一样了,因此这是不合适的。这可以通过指数加权移动平均法解决。如下图所示,
图6. 指数加权移动平均

可以看出,离当前时刻越远的时间点的梯度对当前前进方向的影响越小。

因此,动量法的公式可以写作

V(t)=βV(t1)+(1β)W(t)iV_(t) = \beta \cdot V_{(t-1)} + (1-\beta)\cdot \bigtriangleup W_{(t)i}

W(t)i=W(t1)iηV(t)W_{(t)i} = W_{(t-1)i} - \eta \cdot V_{(t)}

总结:动量法的思想就是:

以前的改变是具有惯性的,想要发生改变,必须先将其抵消,然后才能发生变化。

Nestrov

我们不仅可以参考历史的数据,还可以超前参考未来的数据。假设当前时刻为 tt,如果我们知道使用动量法后,t+2t+2 时刻的大致位置,则可以为 t+1t+1 时刻的前进方向提供参考。

由下图可以看出,如果使用动量法,t+2t+2 时刻的位置将偏离灰色的最佳下降路线较远,就像是绕了远路。而如果可以通过 t+2t+2 时刻的位置指导 ttt+1t+1 时刻的前进方向,则可以更加直接,更加靠近最优下降路线。
图7. 动量法偏离最佳下降路线

Nestrov法和动量法的区别在于,动量法使用的是当前位置的梯度,而 Nestrov 法则是计算的是当前位置沿着动量方向前进一段距离后所到达的位置的梯度。见下图,
图8. 动量法和Nestrov法的区别

个人感觉王木头这里画的有点问题,在前进了一步,也就是到达了上图中的第二个灰色圆圈处后,其动量方向不应是绿色的虚线,而应是沿着第一个灰色圆圈指向第二个灰色圆圈的方向。不过,这不影响这里的结论以及 Nestrov 算法的有效性。只是作出说明。

将新的位置处的梯度向量平移到当前位置,并与旧的动量向量一同计算新的动量,最后更新参数。见下图,
图9. Nestrov法的更新

有人将 Nestrov 法称为牛顿冲量法,这里和前面讲到的牛顿法没有什么关联。

可以看出,冲量法和 Nestrov 法都是相当于在学习的时候,对参数的变化量进行了一个 0次项的修正。如下图,
图10. 0次项修正

AdaGrad

我们回顾一下标准的梯度下降公式,

θ=θηθJ(θ)\theta = \theta - \eta \cdot \nabla_\theta J( \theta)

可以看出,参数的更新部分由学习率 η\eta 和 梯度 θJ(θ)\nabla_\theta J( \theta) 两部分共同决定。
而动量法和 Nestrov 法主要是在梯度部分进行改进。

随着学习的过程,学习率肯定是不能固定的。因此,我们想要学习率随着学习的过程自动地变化。这就是 AdaGrad 的思路。

之前,参数 θ\theta 中的所有参数 θi\theta_{i} 的学习率都是一样的,都是 η\eta. 在 AdaGrad 中,每个参数 θi\theta_{i} 的学习率是不一样的。简单来说,AdaGrad 算法将学习率适应参数的变化,对变化剧烈的维度的参数(也就是梯度值较大),进行大的修正,对变化较小的维度的参数(梯度值较小),进行小的修正。这也可以从 AdaGrad 的公式看出。

gt,ig_{t, i} 为 参数 θi\theta_{i} 在时刻 tt 的偏微分

gt,i=θJ(θt,i)g_{t, i} = \nabla_\theta J( \theta_{t, i} )

那么每个参数 θi\theta_{i} 在时刻 tt 的更新公式如下

θt+1,i=θt,iηGt,ii+ϵgt,i\theta_{t+1, i} = \theta_{t, i} - \dfrac{\eta}{\sqrt{G_{t, ii} + \epsilon}} \cdot g_{t, i}

GtRd×dG_{t} \in \mathbb{R}^{d \times d} 是一个对角线矩阵,对角线上的每一个值 (i,i)(i,i) 是到时刻 tt 时所有时间点上对 \theta_{i}} 梯度的平方和。

可以看出,当某个维度的参数 θi\theta_{i} 梯度值较大,也就是说更新较大时(梯度值大代表着更新大,这很好理解),它就要进行大的修正,这个修正就是通过历史上梯度的平方和再开根号实现的。

比较动量法和 AdaGrad 方法,可以看出,动量法修正的是图 10 中的 0 次项,AdaGrad 方法修正的是 1 次项。

个人理解:这里所谓修正的是 0 次项是指再标准 SGD 的基础上,增加了图 10 中的 0 次项。而 AdaGrad 则确实是对 1 次项进行修正。他们是不可替代的。

AdaGrad 方法适合稀疏数据。所谓稀疏数据是指,使用某数据集训练出来的结果,更大程度上取决于其中是否由某类特征,而不是某类特征的程度,则认为是稀疏数据。如果是稀疏数据,则说明在某个特征或者某个维度上,提供的数据不是很充分,这时使用梯度下降法则很容易出现震荡。此时选择 AdaGrad 方法的优势明显。

AdaGrad 的缺点:由于其考虑的是历史上所有的梯度,因此其学习率是递减的,这也会导致其在该快速变化的时刻遇到小的学习率,导致变化较慢。如下图红色所示,其跨越平台期后,应再次快速变化,但是却越来越慢。
图11. AdaGrad缺点

Adadelta

前面讲到了 AdaGrad 的缺点,就是它的学习率总是递减的,这也使其在需要大学习率的地方只能得到小的学习率。为了解决这一问题,我们想到是否只考虑其最近一段时间的影响,而不是从一开始到现在的影响,也就是说,不要背负所有的“历史包袱”。这感觉起来就像滑动平均。

Adadelta 就是这样的思想。(这也是 Adadelta 中 delta 的由来)

Adadelta 只累计过去的时间窗口 ww 内的梯度的平方。而且它不是简单地记录前 ww 个梯度的平方(比如计算前 ww 个梯度的平方和)。它采用了跟动量的定义类似的方式,递归地将梯度和定义为过去所有时刻的梯度平方的衰减平均(decay average)。公式如下,

E[g2]t=γE[g2]t1+(1γ)gt2E[g^2]_t = \gamma E[g^2]_{t-1} + (1 - \gamma) g^2_t

在 AdaGrad 的公式中,学习率是要除以一个 Gt,ii+ϵ\sqrt{G_{t, ii} + \epsilon} 的。在这里,我们将 GtG_t 替换成前面的滑动平均 E[g2]tE[g^2]_t
这样,每个维度的变化量从 Δθt=ηGt+ϵgt\Delta \theta_t = - \dfrac{\eta}{\sqrt{G_{t} + \epsilon}} \odot g_{t} 变成了 Δθt=ηE[g2]t+ϵgt\Delta \theta_t = - \dfrac{\eta}{\sqrt{E[g^2]_t + \epsilon}} g_{t}. 容易发现,分母部分 E[g2]t+ϵ\sqrt{E[g^2]_t + \epsilon}是梯度的均方根误差(Root Mean Squared error, RMS error),因此可以缩写为 Δθt=ηRMS[g]tgt\Delta \theta_t = - \dfrac{\eta}{RMS[g]_{t}} g_t.

但是这里,仍然有 η\eta 的存在,也就是说,依然跟设定的全局学习率有关。或者说,

The authors note that the units in this update (as well as in SGD, Momentum, or Adagrad) do not match, i.e. the update should have the same hypothetical units as the parameter. To realize this, they first define another exponentially decaying average, this time not of squared gradients but of squared parameter updates. source这段其实我不大理解,不明白什么叫 units do not match

尝试解释:这一段所说的 update, 应该就是指 Δθt\Delta \theta_t 这个值。这里所说的 units do not match, 我猜是指量纲不匹配。按理说, Δθt\Delta \theta_t 的量纲应该是和 θt\theta_t 的量纲是一致的,就好像长度的变化量应该依旧是长度,而不可能是面积一样。但是现在的公式量纲和参数量纲不一致。可以看出,其量纲和 η\eta 以及梯度有关(严格来说只和 η\eta 有关,因为分子分母上梯度相关的部分,量纲刚好抵消了)。因此,作者想要将这个 update 的量纲和参数的量纲一致(哪怕这个量纲是个假设值)。

不管怎样,他们又定义了一个指数衰减平均。这次不是梯度平方的指数衰减平均,而是参数更新量(update)的平方的指数衰减平均。公式如下,

E[Δθ2]t=γE[Δθ2]t1+(1γ)Δθt2E[\Delta \theta^2]_t = \gamma E[\Delta \theta^2]_{t-1} + (1 - \gamma) \Delta \theta^2_t

其均方误差写作

RMS[Δθ]t=E[Δθ2]t+ϵRMS[\Delta \theta]_{t} = \sqrt{E[\Delta \theta^2]_t + \epsilon}

很显然,我们在时间 tt 处还没有进行更新,因此是不知道 Δθ\Delta \theta 的值的,也就不知道 RMS[Δθ]tRMS[\Delta \theta]_{t} 的值。我们用直到前一时刻的参数更新量的 RMS 来近似它。将学习率 η\eta 替换为 RMS[Δθ]t1RMS[\Delta \theta]_{t-1}, 则得到最终的 Adadelta 的更新公式

Δθt=RMS[Δθ]t1RMS[g]tgt\Delta \theta_t = - \dfrac{RMS[\Delta \theta]_{t-1}}{RMS[g]_{t}} g_{t}

θt+1=θt+Δθt\theta_{t+1} = \theta_t + \Delta \theta_t

可以看出,使用 Adadelta,我们就不需要手动设置默认学习率了。

RMSprop

RMSprop 其实就是我们上面推论 Adadelta 第一阶段的结果。

E[g2]t=0.9E[g2]t1+0.1gt2E[g^2]_t = 0.9 E[g^2]_{t-1} + 0.1 g^2_t

θt+1=θtηE[g2]t+ϵgt\theta_{t+1} = \theta_{t} - \dfrac{\eta}{\sqrt{E[g^2]_t + \epsilon}} g_{t}

可以看出,

  • 其实 RMSprop 依然依赖于全局学习率
  • RMSprop 算是 Adagrad 的一种发展,和 Adadelta 的变体,效果趋于二者之间

Adam (Adaptive Moment Estimation)

从名字就可以推测出,Adam 本质上是带动量的 RMSprop 或 Adadelta. Adam 不仅计算梯度平方的指数衰减平均,也计算梯度的指数衰减平均。

mt=β1mt1+(1β1)gtm_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t

vt=β2vt1+(1β2)gt2v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2

其中,mtm_tvtv_t 分别是梯度的一阶估计(均值)和二阶估计(未中心化方差)。mtm_tvtv_t 都是初始化成零向量的,Adam 作者观察到,在开始的几次迭代内,它们偏向于 0,尤其是当衰减系数很小时(也就是 β1\beta_1β2\beta_2 接近 1).

它们通过对 mtm_tvtv_t 进行校正来获取无偏估计

m^t=mt1β1t\hat{m}_t = \dfrac{m_t}{1 - \beta^t_1}

v^t=vt1β2t\hat{v}_t = \dfrac{v_t}{1 - \beta^t_2}

因此,最后的更新公式为

θt+1=θtηv^t+ϵm^t\theta_{t+1} = \theta_{t} - \dfrac{\eta}{\sqrt{\hat{v}_t} + \epsilon} \hat{m}_t

作者建议的默认值分别为 β1=0.9\beta_1=0.9, β=0.999\beta=0.999, ϵ=108\epsilon=10^{-8}

Nadam (Nesterov-accelerated Adaptive Moment Estimation)

前面说过,Adam 可以看作 RMSprop 和 momentum 的结合体。NAG (Nesterov accelerated gradient) 是朴素 momentum 方法的改进。因此,我们考虑是否可以把 Adam 和 NAG 结合起来,也就是 Nadam.

回忆一下 NAG 的更新公式:

gt=θtJ(θtγmt1)g_t = \nabla_{\theta_t}J(\theta_t - \gamma m_{t-1})

mt=γmt1+ηgtm_t = \gamma m_{t-1} + \eta g_t

θt+1=θtmt\theta_{t+1} = \theta_t - m_t

Dozat 对 NAG 进行了修改:与其使用两次 mt1m_{t-1} – 一次更新梯度(第一个公式),一次更新参数,现在直接应用 look-ahead momentum vector 来更新当前参数:

gt=θtJ(θt)g_t = \nabla_{\theta_t}J(\theta_t)

mt=γmt1+ηgtm_t = \gamma m_{t-1} + \eta g_t

θt+1=θt(γmt+ηgt)\theta_{t+1} = \theta_t - (\gamma m_t + \eta g_t)

可以看出,现在是直接使用的当前时刻的动量 mtm_t 来 look-ahead,而不是之前的 mt1m_{t-1}.
(将 NAG 公式中的 mtm_t 代入 θ\theta 更新公式,可以得到 θt+1=θt(γmt1+ηgt)\theta_{t+1} = \theta_t - (\gamma m_{t-1} + \eta g_t), 而现在的更新公式是 θt+1=θt(γmt+ηgt)\theta_{t+1} = \theta_t - (\gamma m_t + \eta g_t), 也就是说,我们现在使用当前的动量向量 mtm_t 来 look ahead. 而之前的 look ahead 是在 gt=θtJ(θtγmt1)g_t = \nabla_{\theta_t}J(\theta_t - \gamma m_{t-1}) 中体现的)

同样地,回忆一下 Adam 的更新公式:

mt=β1mt1+(1β1)gtm_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t

m^t=mt1β1t\hat{m}_t = \frac{m_t}{1 - \beta^t_1}

θt+1=θtηv^t+ϵm^t\theta_{t+1} = \theta_{t} - \frac{\eta}{\sqrt{\hat{v}_t} + \epsilon} \hat{m}_t

将第二条代入第三条,得到

θt+1=θtηv^t+ϵ(β1mt11β1t+(1β1)gt1β1t)\theta_{t+1} = \theta_{t} - \dfrac{\eta}{\sqrt{\hat{v}_t} + \epsilon} (\dfrac{\beta_1 m_{t-1}}{1 - \beta^t_1} + \dfrac{(1 - \beta_1) g_t}{1 - \beta^t_1})

其中,β1mt11β1t\dfrac{\beta_1 m_{t-1}}{1 - \beta^t_1} 就是 m^t1\hat{m}_{t-1}.
因此,更新公式变成

θt+1=θtηv^t+ϵ(β1m^t1+(1β1)gt1β1t)\theta_{t+1} = \theta_{t} - \dfrac{\eta}{\sqrt{\hat{v}_t} + \epsilon} (\beta_1 \hat{m}_{t-1} + \dfrac{(1 - \beta_1) g_t}{1 - \beta^t_1})

可以看出,这个公式很像上面一节 NAG 的更新公式。这时,想要加上 Nestrov 的部分,我们只要像上面一样,将更新公式里的 m^t1\hat{m}_{t-1} 替换为 mt1m_{t-1}

这样下来,Nadam 的公式就变成了

θt+1=θtηv^t+ϵ(β1m^t+(1β1)gt1β1t)\theta_{t+1} = \theta_{t} - \dfrac{\eta}{\sqrt{\hat{v}_t} + \epsilon} (\beta_1 \hat{m}_t + \dfrac{(1 - \beta_1) g_t}{1 - \beta^t_1})

番外:用一个框架统一起来

前面讲了很多在标准 SGD 上的优化操作,看似花里胡哨,不成体系,但是仔细分析,却发现可以用一个框架把这些优化算法统一起来。这样更有条理性,更适合记忆。

这个部分的内容参考这篇文章

在参考文章中,一个统一的参数更新框架是:

  1. gt=f(wt)g_t=\triangledown f(w_t)
  2. mt=ϕ(g1,g2,,gt),Vt=ψ(g1,g2,,gt)m_t=\phi (g_1,g_2,\dots,g_t), V_t=\psi (g_1,g_2,\dots,g_t). 参考文章将其分别称为 一阶动量,二阶动量。
  3. ηt=αmt/Vt\eta_t=\alpha\cdot m_t/\sqrt[]{V_t}
  4. wt+1=wtηtw_{t+1}=w_t-\eta_t

这里的 VtV_t 应该就是 Adadelta 部分引入的 过去所有时刻的梯度平方的衰减平均,即 E[g2]t=γE[g2]t1+(1γ)gt2E[g^2]_t = \gamma E[g^2]_{t-1} + (1 - \gamma) g^2_t

接下来尝试将各个优化方法代入这个框架,看是否符合框架。

SGD

SGD 没有动量概念,因此很自然地得到,mt=gt;Vt=I2m_t=g_t; V_t=I^2, 最后更新公式

wt+1=wtαgtw_{t+1}=w_t-\alpha\cdot g_t

动量法

momentum 法只有一阶动量,没有二阶动量。因此 mt=β1mt1+(1β1)gt;Vt=I2m_t=\beta_1\cdot m_{t-1}+(1-\beta_1)\cdot g_t; V_t=I^2

Nestrov 方法

Nestrov 方法的创新之处在于:它不只使用当前位置的动量和梯度,而是观察一下,如果跟着当前的动量走一步后,它的梯度会去哪里,然后再跟当前的动量一起决定前进的方向。因此,在这个框架里,发生改变的是梯度的计算过程,也就是第一步。

gt=f(wtαmt1/Vt1)g_t=\triangledown f(w_t-\alpha \cdot m_{t-1}/\sqrt[]{V_{t-1}})

这里相比图 9 多了个 Vt1\sqrt[]{V_{t-1}} 的部分,但是可以通过令 Vt=I2V_t=I^2 来达到一致。

AdaGrad 方法

此前我们都没有用到二阶动量。二阶动量的出现,才意味着 “自适应学习率” 优化算法时代的到来。SGD 及其变种以同样的学习率更新每个参数,但深度神经网络往往包含大量的参数,这些参数并不是总会用得到(想想大规模的 embedding)。对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;对于偶尔更新的参数,我们了解的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些。

AdaGrad 方法在框架里的体现是:

Vt=τ=1tgτ2V_t=\sum_{\tau =1}^{t}g_\tau^2

其计算的是过去所有时刻的梯度的平方和。

Adadelta & RMSprop

为了解决 AdaGrad 方法学习率单调递减,最后逐渐消失的问题。考虑改变二阶动量 VtV_t 的计算方式:不是计算历史梯度的平方和,而是计算历史梯度平方的指数移动平均(decay average)。这在之前已经提过了。

因此,这里在框架里的体现就是:

Vt=β2Vt1+(1β2)gt2V_t=\beta_2*V_{t-1}+(1-\beta _2)g_t^2

这样,就能避免二阶动量的持续累积,从而导致训练提前结束了。

Adam

到这里,Adam 就很好理解了。很显然,Adam 是同时有一阶动量和二阶动量的定义的。
体现在框架中就是:

mt=β1mt1+(1β1)gtm_t=\beta_1\cdot m_{t-1}+(1-\beta_1)\cdot g_t

Vt=β2Vt1+(1β2)gt2V_t=\beta_2*V_{t-1}+(1-\beta _2)g_t^2

它们分别来自 momentum 方法和 Adadelta 方法。

Nadam

很自然的,我们可以看出,Nadam=Adam+Nestrov,
体现在框架中就是

gt=f(wtαmt1/Vt1)g_t=\triangledown f(w_t-\alpha \cdot m_{t-1}/\sqrt[]{V_{t-1}})

mt=β1mt1+(1β1)gtm_t=\beta_1\cdot m_{t-1}+(1-\beta_1)\cdot g_t

Vt=β2Vt1+(1β2)gt2V_t=\beta_2*V_{t-1}+(1-\beta _2)g_t^2

也就是说,对框架第 1,2 步中共 3 个值都进行了重新定义,而这也是梯度+一阶动量+二阶动量排列组合的最完整的组合了。

参考

除了王木头的视频,本博客还参考了许多其他文章,尤其是 Adam 和 Nadam 的部分,王木头的视频里并未详细分析。
参考的文章列表如下:


文章作者: taosean
文章链接: https://taosean.github.io/2021/12/26/Neural-Network-Optimization/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 taosean's 学习之旅