学习率
临界点其实不一定是在训练一个网络的时候会遇到的最大的障碍。图 3.18 中的横坐标代表参数更新的次数,竖坐标表示损失。一般在训练一个网络的时候,损失原来很大,随着参数不断的更新,损失会越来越小,最后就卡住了,损失不再下降。当我们走到临界点的时候,意味着梯度非常小,但损失不再下降的时候,梯度并没有真的变得很小,图 3.19 给出了示例。图 3.19 中横轴是迭代次数,竖轴是梯度的范数(norm),即梯度这个向量的长度。随着迭代次数增多,虽然损失不再下降,但是梯度的范数并没有真的变得很小。


图 3.20 是误差表面,梯度在山谷的两个谷壁间,不断地来回“震荡”,这个时候损失不会再下降,它不是真的卡到了临界点,卡到了鞍点或局部最小值。但它的梯度仍然很大,只是损失不一定再减小了。所以训练一个网络,训练到后来发现损失不再下降的时候,有时候不是卡在局部最小值或鞍点,只是单纯的损失无法再下降。

我们现在训练一个网络,训练到现在参数在临界点附近,再根据特征值的正负号判断该临界点是鞍点还是局部最小值。实际上在训练的时候,要走到鞍点或局部最小值,是一件困难的事情。一般的梯度下降,其实是做不到的。用一般的梯度下降训练,往往会在梯度还很大的时候,损失就已经降了下去,这个是需要特别方法训练的。要走到一个临界点其实是比较困难的,多数时候训练在还没有走到临界点的时候就已经停止了。
调整学习速率
举例:
上图左边黑色为损失函数的曲线,假设从左边最高点开始,如果学习率调整的刚刚好,比如红色的线,就能顺利找到最低点。如果学习率调整的太小,比如蓝色的线,就会走的太慢,虽然这种情况给足够多的时间也可以找到最低点,实际情况可能会等不及出结果。如果 学习率调整的有点大,比如绿色的线,就会在上面震荡,走不下去,永远无法到达最低点。还有可能非常大,比如黄色的线,直接就飞出去了,更新参数的时候只会发现损失函数越更新越大。
虽然这样的可视化可以很直观观察,但可视化也只是能在参数是一维或者二维的时候进行,更高维的情况已经无法可视化了。
解决方法就是上图右边的方案,将参数改变对损失函数的影响进行可视化。比如学习率太小(蓝色的线),损失函数下降的非常慢;学习率太大(绿色的线),损失函数下降很快,但马上就卡住不下降了;学习率特别大(黄色的线),损失函数就飞出去了;红色的就是差不多刚好,可以得到一个好的结果。
AdaGrad
AdaGrad(Adaptive Gradient)是典型的自适应学习率方法,其能够根据梯度大小自动调整学习率。AdaGrad可以做到梯度比较大的时候,学习率就减小,梯度比较小的时候,学习率就放大。
梯度下降更新某个参数 $\theta_t^i$ 的过程为
$$
\theta_{t+1}^i \leftarrow \theta_t^i - \eta g_t^i \qquad(3.14)
$$
$\theta_t^i$ 在第 $t$ 个迭代的值减掉在第 $t$ 迭代参数 $i$ 出来的梯度
$$
g_t^i = \left. \frac{\partial L}{\partial\theta^i} \right|_{\theta = \theta_t} \quad(3.15)
$$
$g_t^i$ 代表在第 $t$ 迭代,即 $\theta = \theta_t$ 时,损失 $L$ 关于参数 $\theta^i$ 的偏导,学习率是固定的。
现在要有一个随着参数定制化的学习率,即把原来学习率 $\eta$ 变成 $\frac{\eta}{\sigma_t^i}$:
$$
\theta_{t+1}^i \leftarrow \theta_t^i - \frac{\eta}{\sigma_t^i} g_t^i \qquad(3.16)
$$
$\sigma_t^i$ 的上标为 $i$,这代表参数 $\sigma$ 与 $i$ 相关,不同的参数的 $\sigma$ 不同。$\sigma_t^i$ 的下标为 $t$,这代表参数 $\sigma$ 与迭代相关,不同的迭代也会有不同的 $\sigma$。学习率从 $\eta$ 改成 $\frac{\eta}{\sigma_t^i}$ 的时候,学习率就变得参数相关(parameter dependent)。
参数相关的一个常见的类型是算梯度的均方根(root mean square)。参数的更新过程为
$$
\theta_1^i \leftarrow \theta_0^i - \frac{\eta}{\sigma_0^i} g_0^i \qquad(3.17)
$$
其中 $\theta_0^i$ 是初始化参数。而 $\sigma_0^i$ 的计算过程为
$$
\sigma_0^i = \sqrt{\left(g_0^i\right)^2} = \left|g_0^i\right| \qquad(3.18)
$$
其中 $g_0^i$ 是梯度。将 $\sigma_0^i$ 的值代入更新的公式可知 $\frac{g_0^i}{\sigma_0^i}$ 的值是 +1 或 -1。第一次在更新参数,从 $\theta_0^i$ 更新到 $\theta_1^i$ 的时候,要么是加上 $\eta$,要么是减掉 $\eta$,跟梯度的大小无关,这个是第一步的情况。
第二次更新参数过程为
$$
\theta_2^i \leftarrow \theta_1^i - \frac{\eta}{\sigma_1^i} g_1^i \qquad(3.19)
$$
其中 $\sigma_1^i$ 是过去所有计算出来的梯度的平方的平均再开根号,即均方根,如式(3.20)所示。
$$
\sigma_1^i = \sqrt{\frac{1}{2}\left[\left(g_0^i\right)^2 + \left(g_1^i\right)^2\right]} \qquad(3.20)
$$
同样的操作反复继续下去,如式(3.21)所示。
$$
\theta_3^i \leftarrow \theta_2^i - \frac{\eta}{\sigma_2^i} g_2^i \quad \sigma_2^i = \sqrt{\frac{1}{3}\left[\left(g_0^i\right)^2 + \left(g_1^i\right)^2 + \left(g_2^i\right)^2\right]} \qquad(3.21)
$$
第 $t+1$ 次更新参数的时候,即
$$
\theta_{t+1}^i \leftarrow \theta_t^i - \frac{\eta}{\sigma_t^i} g_t^i \quad \sigma_t^i = \sqrt{\frac{1}{t+1}\sum_{j=0}^t \left(g_j^i\right)^2} \qquad(3.22)
$$
$\frac{\eta}{\sigma_t^i}$ 当作是新的学习率来更新参数。
图 3.24中有两个参数:$\theta^1$ 和 $\theta^2$。$\theta^1$ 坡度小,$\theta^2$ 坡度大。因为 $\theta^1$ 坡度小,根据式(3.22), $\theta^1$ 这个参数上面算出来的梯度值都比较小,因为梯度算出来的值比较小,所以算出来的 $\sigma_t^i$ 就小,$\sigma_t^i$ 小学习率就大。反过来,$\theta^2$ 坡度大,所以计算出的梯度都比较大,$\sigma_t^i$ 就比较大,在更新的时候,步伐(参数更新的量)就比较小。因此有了 $\sigma_t^i$ 这一项以后,就可以随着梯度的不同,每一个参数的梯度的不同,来自动调整学习率的大小。

Adagrad举例
下图是一个参数的更新过程
将 Adagrad 的式子进行化简:
Adagrad 存在的矛盾?
在 Adagrad 中,当梯度越大的时候,步伐应该越大,但下面分母又导致当梯度越大的时候,步伐会越小。
下图是一个直观的解释:
下面给一个正式的解释:
比如初始点在 $x_0$,最低点为 $−\frac{b}{2a}$,最佳的步伐就是 $x0$ 到最低点之间的距离 $\left | x_0+\frac{b}{2a} \right |$,也可以写成 $\left | \frac{2ax_0+b}{2a} \right |$。而刚好 $|2ax_0+b|$ 就是方程绝对值在 $x_0$ 这一点的微分。
这样可以认为如果算出来的微分越大,则距离最低点越远。而且最好的步伐和微分的大小成正比。所以如果踏出去的步伐和微分成正比,它可能是比较好的。
结论1-1:梯度越大,就跟最低点的距离越远。
这个结论在多个参数的时候就不一定成立了。
多参数下结论不一定成立
对比不同的参数
上图左边是两个参数的损失函数,颜色代表损失函数的值。如果只考虑参数 $w_1$,就像图中蓝色的线,得到右边上图结果;如果只考虑参数 $w_2$,就像图中绿色的线,得到右边下图的结果。确实对于 $a$ 和 $b$,结论1-1是成立的,同理 $c$ 和 $b$ 也成立。但是如果对比$a$ 和 $c$,就不成立了,$c$ 比 $a$ 大,但 $c$ 距离最低点是比较近的。
所以结论1-1是在没有考虑跨参数对比的情况下,才能成立的。所以还不完善。
之前说到的最佳距离 $\left | \frac{2ax_0+b}{2a} \right |$,还有个分母 $2a$ 。对function进行二次微分刚好可以得到:
$$\frac{\partial ^2y}{\partial x^2} = 2a \tag7$$
所以最好的步伐应该是:
$$
\frac{一次微分}{二次微分}
$$
即不止和一次微分成正比,还和二次微分成反比。最好的step应该考虑到二次微分:
Adagrad 进一步的解释
再回到之前的 Adagrad
对于 $\sqrt{\sum_{i=0}^t(g^i)^2}$ 就是希望再尽可能不增加过多运算的情况下模拟二次微分。(如果计算二次微分,在实际情况中可能会增加很多的时间消耗)
RMSProp
同一个参数需要的学习率,也会随着时间而改变。在图 3.25中的误差表面中,如果考虑横轴方向,绿色箭头处坡度比较陡峭,需要较小的学习率,但是走到红色箭头处,坡度变得平坦了起来,需要较大的学习率。因此同一个参数的同个方向,学习率也是需要动态调整的,于是就有了一个新的方法 - RMSprop(Root Mean Squared propagation)。
RMSprop没有论文,Geoffrey Hinton在 Coursera上开过深度学习的课程,他在他的课程里面讲了 RMSprop,如果要引用,需要引用对应视频的链接。
RMSprop第一步跟 Adagrad的方法是相同的,即
$$
\sigma_0^i = \sqrt{\left(g_0^i\right)^2} = \left|g_0^i\right| \qquad(3.23)
$$
第二步更新过程为
$$
\theta_2^i \leftarrow \theta_1^i - \frac{\eta}{\sigma_1^i} g_1^i \quad \sigma_1^i = \sqrt{\alpha\left(\sigma_0^i\right)^2 + (1-\alpha)\left(g_1^i\right)^2} \quad\text{(3.24)}
$$
其中 $0 < \alpha < 1$,其是一个可以调整的超参数。计算 $\theta_1^i$ 的方法跟 AdaGrad算均方根不一样,在算均方根的时候,每一个梯度都有同等的重要性,但在 RMSprop里面,可以自己调整现在的这个梯度的重要性。如果$\alpha$ 很小趋近于0,代表g’相较于之前算出来的梯度而言,比较重要;如果$\alpha$ 设很大趋近于1,代表g比较不重要,之前算出来的梯度比较重要。同样的过程就反复继续下去,如式(3.25)所示。

$$
\theta_{t+1}^i \leftarrow \theta_t^i - \frac{\eta}{\sqrt{\alpha (\sigma_t^i)^2 + (1 - \alpha) (g_t^i)^2}} g_t^i \ \sigma_{t+1}^i = \sqrt{\alpha (\sigma_t^i)^2 + (1 - \alpha) (g_t^i)^2} \quad (3.25)
$$
RMSProp 通过 $\alpha$ 可以决定,$g_t^i$ 相较于之前存在 $\sigma_t^i$ 里面的 $g_0^i, g_1^i, \ldots, g_{t-1}^i$ 的重要性有多大。如果使用 RMSprop,就可以动态调整 $\sigma_t^i$ 这一项。图3.26 中黑线是误差表面,球就从A走到B,AB段的路很平坦,$g_t^i$ 很小,更新参数的时候,我们会走比较大的步伐。走到 BC 段后梯度变大了,AdaGrad 反应比较慢,而 RMSprop 会把 $\alpha$ 设小一点,让新的、刚看到的梯度的影响比较大,很快地让 $\sigma_t^i$ 的值变大,很快地让步伐变小,RMSprop 可以很快地“踩刹车”。如果走到 CD 段,CD 段是平坦的地方,可以调整$\alpha$,让其比较看重最近算出来的梯度,梯度一变小,$\sigma_t^i$ 的值就变小了,走的步伐就变大了。

学习率调整
如图3.22所示的简单的误差表面,我们都训练不起来,加上自适应学习率以后,使用AdaGrad方法优化的结果如图3.27所示。一开始优化的时候很顺利,在左转的时候,有AdaGrad以后,可以再继续走下去,走到非常接近终点的位置。走到BC段时,因为横轴方向的梯度很小,所以学习率会自动变大,步伐就可以变大,从而不断前进。接下来的问题走到图3.27中红圈的地方,快走到终点的时候突然“爆炸”了。$\sigma_{t}^{i}$ 把过去所有的梯度拿来作平均。在AB段梯度很大,但在BC段,纵轴的方向梯度很小,因此纵轴方向累积了很小的$\sigma_{t}^{i}$,累积到一定程度以后,步伐就变很大,但有办法修正回来。因为步伐很大,其会走到梯度比较大的地方。走到梯度比较大的地方后,$\sigma_{t}^{i}$ 慢慢变大,更新的步伐大小会慢慢变小,从而回到原来的路线。

通过学习率调度 (learning rate scheduling) 可以解决这个问题。之前的学习率调整方法中 $\eta$ 是一个固定的值,而在学习率调度中 $\eta$ 跟时间有关,如式(3.26)所示。学习率调度中最常见的策略是学习率衰减 (learning rate decay),也称为学习率退火 (learning rate annealing)。随着参数的不断更新,让 $\eta$ 越来越小,如图 3.28所示。图 3.27的情况,如果加上学习率下降,可以很平顺地走到终点,如图 3.29所示。在图 3.27红圈的地方,虽然步伐很大,但 $\eta$ 变得非常小,步伐乘上 $\eta$ 就变小了,就可以慢慢地走到终点。
$$
\theta_{t+1}^i \leftarrow \theta_t^i - \frac{\eta_t}{\sigma_t^i} g_t^i \qquad(3.26)
$$
除了学习率下降以外,还有另外一个经典的学习率调度的方式——预热。预热的方法是让学习率先变大后变小,至于变到多大、变大的速度、变小的速度是超参数。残差网络 ${}^{[8]}$ 里面是有预热的,在残差网络里面,学习率先设置成 0.01,再设置成 0.1,并且其论文还特别说明,一开始用 0.1 反而训练不好。除了残差网络,BERT和 Transformer的训练也都使用了预热。

Q: 为什么需要预热?
A: 当我们使用Adam、RMSprop或AdaGrad时,需要计算 $\sigma$。而 $\sigma$ 是一个统计的结果。从 $\sigma$ 可知某一个方向的陡峭程度。统计的结果需要足够多的数据才精准,一开始统计结果 $\sigma$ 是不精准的。一开始学习率比较小是用来探索收集一些有关误差表面的情报,先收集有关 $\sigma$ 的统计数据,等 $\sigma$ 统计得比较精准以后,再让学习率慢慢爬升。如果读者想要学更多有关预热的东西可参考Adam的进阶版 - RAdam[9]。
所以我们从最原始的梯度下降,进化到这一个版本,如式(3.27)所示。
$$
\theta_{t+1}^i \leftarrow \theta_t^i - \frac{\eta_t}{\sigma_t^i} m_t^i \qquad(3.27)
$$
其中 $m_t^i$ 是动量。
这个版本里面有动量,其不是顺着某个时刻算出的梯度方向来更新参数,而是把过去所有算出梯度的方向做一个加权总和当作更新的方向。接下来的步伐大小为 $\frac{m_t^i}{\sigma_t^i}$。最后通过 $\eta_t$ 来实现学习率调度。这个是目前优化的完整的版本,这种优化器除了 Adam以外,还有各种变形。但其实各种变形是使用不同的方式来计算 $m_t^i$ 或 $\sigma_t^i$,或者是使用不同的学习率调度的方式。
Q: 动量 $m_{t}^{i}$ 考虑了过去所有的梯度,均方根 $\sigma_{t}^{i}$ 考虑了过去所有的梯度,一个放在分子,一个放在分母,并且它们都考虑过去所有的梯度,不就是正好抵消了吗?
A: $m_{t}^{i}$ 和 $\sigma_{t}^{i}$ 在使用过去所有梯度的方式是不一样的,动量是直接把所有的梯度都加












