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


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

我们现在训练一个网络,训练到现在参数在临界点附近,再根据特征值的正负号判断该临界点是鞍点还是局部最小值。实际上在训练的时候,要走到鞍点或局部最小值,是一件困难的事情。一般的梯度下降,其实是做不到的。用一般的梯度下降训练,往往会在梯度还很大的时候,损失就已经降了下去,这个是需要特别方法训练的。要走到一个临界点其实是比较困难的,多数时候训练在还没有走到临界点的时候就已经停止了。
调整学习速率
举例:
上图左边黑色为损失函数的曲线,假设从左边最高点开始,如果学习率调整的刚刚好,比如红色的线,就能顺利找到最低点。如果学习率调整的太小,比如蓝色的线,就会走的太慢,虽然这种情况给足够多的时间也可以找到最低点,实际情况可能会等不及出结果。如果 学习率调整的有点大,比如绿色的线,就会在上面震荡,走不下去,永远无法到达最低点。还有可能非常大,比如黄色的线,直接就飞出去了,更新参数的时候只会发现损失函数越更新越大。
虽然这样的可视化可以很直观观察,但可视化也只是能在参数是一维或者二维的时候进行,更高维的情况已经无法可视化了。
解决方法就是上图右边的方案,将参数改变对损失函数的影响进行可视化。比如学习率太小(蓝色的线),损失函数下降的非常慢;学习率太大(绿色的线),损失函数下降很快,但马上就卡住不下降了;学习率特别大(黄色的线),损失函数就飞出去了;红色的就是差不多刚好,可以得到一个好的结果。
AdaGrad
AdaGrad(Adaptive Gradient)是典型的自适应学习率方法,其能够根据梯度大小自动调整学习率。AdaGrad可以做到梯度比较大的时候,学习率就减小,梯度比较小的时候,学习率就放大。
梯度下降更新某个参数
现在要有一个随着参数定制化的学习率,即把原来学习率
参数相关的一个常见的类型是算梯度的均方根(root mean square)。参数的更新过程为
其中
其中
第二次更新参数过程为
其中
同样的操作反复继续下去,如式(3.21)所示。
第
图 3.24中有两个参数:

Adagrad举例
下图是一个参数的更新过程
将 Adagrad 的式子进行化简:
Adagrad 存在的矛盾?
在 Adagrad 中,当梯度越大的时候,步伐应该越大,但下面分母又导致当梯度越大的时候,步伐会越小。
下图是一个直观的解释:
下面给一个正式的解释:
比如初始点在
这样可以认为如果算出来的微分越大,则距离最低点越远。而且最好的步伐和微分的大小成正比。所以如果踏出去的步伐和微分成正比,它可能是比较好的。
结论1-1:梯度越大,就跟最低点的距离越远。
这个结论在多个参数的时候就不一定成立了。
多参数下结论不一定成立
对比不同的参数
上图左边是两个参数的损失函数,颜色代表损失函数的值。如果只考虑参数
所以结论1-1是在没有考虑跨参数对比的情况下,才能成立的。所以还不完善。
之前说到的最佳距离
所以最好的步伐应该是:
即不止和一次微分成正比,还和二次微分成反比。最好的step应该考虑到二次微分:
Adagrad 进一步的解释
再回到之前的 Adagrad
对于
随机梯度下降法
之前的梯度下降:
而随机梯度下降法更快:
损失函数不需要处理训练集所有的数据,选取一个例子
此时不需要像之前那样对所有的数据进行处理,只需要计算某一个例子的损失函数 ,就可以赶紧 update 梯度。
对比:
常规梯度下降法走一步要处理到所有二十个例子,但随机算法此时已经走了二十步(每处理一个例子就更新)
RMSProp
同一个参数需要的学习率,也会随着时间而改变。在图 3.25中的误差表面中,如果考虑横轴方向,绿色箭头处坡度比较陡峭,需要较小的学习率,但是走到红色箭头处,坡度变得平坦了起来,需要较大的学习率。因此同一个参数的同个方向,学习率也是需要动态调整的,于是就有了一个新的方法 - RMSprop(Root Mean Squared propagation)。
RMSprop没有论文,Geoffrey Hinton在 Coursera上开过深度学习的课程,他在他的课程里面讲了 RMSprop,如果要引用,需要引用对应视频的链接。
RMSprop第一步跟 Adagrad的方法是相同的,即
第二步更新过程为
其中

RMSProp 通过

Adam
最常用的优化的策略或者优化器(optimizer)是Adam(Adaptive moment estimation)。Adam 可以看作 RMSprop 加上动量,其使用动量作为参数更新方向,并且能够自适应调整学习率。PyTorch 里面已经写好了 Adam 优化器,这个优化器里面有一些超参数需要人为决定,但是往往用 PyTorch 预设的参数就足够好了。
学习率调整
如图3.22所示的简单的误差表面,我们都训练不起来,加上自适应学习率以后,使用AdaGrad方法优化的结果如图3.27所示。一开始优化的时候很顺利,在左转的时候,有AdaGrad以后,可以再继续走下去,走到非常接近终点的位置。走到BC段时,因为横轴方向的梯度很小,所以学习率会自动变大,步伐就可以变大,从而不断前进。接下来的问题走到图3.27中红圈的地方,快走到终点的时候突然“爆炸”了。

通过学习率调度 (learning rate scheduling) 可以解决这个问题。之前的学习率调整方法中
除了学习率下降以外,还有另外一个经典的学习率调度的方式——预热。预热的方法是让学习率先变大后变小,至于变到多大、变大的速度、变小的速度是超参数。残差网络

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