局部最优和鞍点
造成神经网络难以优化的一个重要(乃至主要)原因不是高维优化问题中有很多局部极值,而是存在大量鞍点。
吴恩达视频中讲的,虽然没有理论的证明,局部最小值就是全局最小值,但是很多实际的经验告诉我们,最后,只能收敛到一个最小值,也就是说,很多现实实际问题是只有一个最小值的。但这个最小值通常是鞍点。
认识鞍点的历史
BP算法自八十年代发明以来,一直是神经网络优化的最基本的方法。神经网络普遍都是很难优化的,尤其是当中间隐含层神经元的个数较多或者隐含层层数较多的时候。长期以来,人们普遍认为,这是因为较大的神经网络中包含很多局部极小值(local minima),使得算法容易陷入到其中某些点。这种看法持续二三十年,至少数万篇论文中持有这种说法。举个例子,如著名的Ackley函数 。对于基于梯度的算法,一旦陷入到其中某一个局部极值,就很难跳出来了。
到2014年,一篇论文《Identifying and attacking the saddle point problem in high-dimensional non-convex optimization》(https://arxiv.org/pdf/1406.2572v1.pdf)。
指出高维优化问题中根本没有那么多局部极值。作者依据统计物理,随机矩阵理论和神经网络理论的分析,以及一些经验分析提出高维非凸优化问题之所以困难,是因为存在大量的鞍点(梯度为零并且Hessian矩阵特征值有正有负)而不是局部极值。
这个问题目前仍有讨论,不过大体上人们接受了这种观点,即造成神经网络难以优化的一个重要(乃至主要)原因是存在大量鞍点。造成局部极值这种误解的原因在于,人们把低维的直观认识直接推到高维的情况。在一维情况下,局部极值是仅有的造成优化困难的情形(Hessian矩阵只有一个特征值)。该如何处理这种情况,目前似乎没有特别有效的方法。
理解鞍点,以及如何有效地避开它们
大家都知道局部最小值是我们的克星,所以一个重要的问题就是如何避免局部最小值。但问题并不明显,有很多机器学习的问题没有局部最小值。即使你有局部最小值,梯度下降似乎可以轻松回避它们。神经网络如果足够大的话就会有足够的冗余,要做到这一点并不难。达到零就是全局最优解。
如果一个回路的局部最大值不是问题,它的鞍点是剩下需要解决的。
鞍点在这些体系结构中大量存在,不论是在简单的模型还是在神经网络中。它们会导致学习曲线变平。你会经常看到一个学习曲线下降很快,之后很久都是平的。这就是靠近鞍点的表现。最终你会逃离鞍点。
继续下去,你可能会碰到另一个鞍点。你会看到一个学习曲线,它这样上升和下降。某种意义上,这不是问题,如果你最终得到正确答案。但是你可能会碰到一个鞍点并在那里停滞很长一段时间,时间过久,以至于你都不知道在某个地方能找到更好的答案。特别是如果你没有那么多时间来运行你的算法。所以你可以在多维度中理解这个。
让我给你们看一张鞍点的图片。在左边我们有一个“严格”的鞍点。有一个负曲率的方向,这个负曲率是严格小于零的。在右边,它是个非严格鞍点,但第二个特征值严格为零。
如何逃离鞍点?
如果你沿着中间部分往下走,你最终会摆脱它,但这可能需要很长时间。这只是两个维度上,但如果你有上十万甚至上百万维度呢?就像现在一般的研究中一样。在这种情况下,可能只有一条出路,其他的方向都不行,所以要找到逃逸的方向可能要花很长时间。当维度越来越大的时候,就有问题了。基于梯度下降的算法可能会有麻烦。
只用一阶导数是难以区分最优点和鞍点的。但如果你有一个海森矩阵,这个问题将会消失,因为你会知道所有的方向,但你必须计算一个海森矩阵的特征向量。这两种情况都不好,因为它太复杂了也太慢。所以,梯度方法是个问题。
我们想一下,最优点和鞍点的区别不就在于其在各个维度是否都是最低点嘛~只要某个一阶导数为0的点在某个维度上是最高点而不是最低点,那它就是鞍点。而区分最高点和最低点当然就是用二阶导数(斜率从负变正的过程当然就是“下凸”,即斜率的导数大于0,即二阶导数大于0。反之则为“上凹”,二阶导数小于0)。也就是说,若某个一阶导数为0的点在至少一个方向上的二阶导数小于0,那它就是鞍点啦。
那么二阶导数大于0和小于0的概率各是多少呢?由于我们并没有先验知识,因此按照最大熵原理,我们认为二阶导数大于和小于0的概率均为0.5!
那么对于一个有n个参数的机器学习/深度学习模型,“loss曲面”即位于n+1维空间(loss值为纵轴,n个参数为n个横轴)。在这个空间里,如果我们通过梯度下降法一路下滑终于滑到了一个各方向导数均为0的点,那么它为局部最优点的概率即0.5^ n,为鞍点的概率为1-0.5^n,显然,当模型参数稍微一多,即n稍微一大,就会发现这个点为鞍点的概率会远大于局部最优点!
实际操作中避开鞍点
使用的mini-batch梯度下降法本身就是有噪声的梯度估计,哪怕我们位于梯度为0的点,也经常在某个mini-batch下的估计把它估计偏了,导致往前或者往后挪了一步摔下马鞍,也就是mini-batch的梯度下降法使得模型很容易逃离特征空间中的鞍点。
更多的,我们可以从以下方面考虑:
1)如何去设计一个尽量没有“平坦区”等危险地形的loss空间,即着手于loss函数的设计以及深度学习模型的设计;
2)尽量让模型的初始化点远离空间中的危险地带,让最优化游戏开始于简单模式,即着手于模型参数的初始化策略;
3)让最优化过程更智能一点,该加速冲时加速冲,该大胆跳跃时就大胆跳,该慢慢踱步时慢慢走,对危险地形有一定的判断力,如梯度截断策略;
4)开外挂,本来下一步要走向死亡的,结果被外挂给拽回了安全区,如batch normalization策略等。
我们知道在,优化问题中,深度学习的优化问题中,经常存在鞍点,就是这一点的导数为0,从某些维度看是极小值,从另一些维度看是极大值,比如下图所示:
深度学习的寻优过程中,鞍点所造成的困难,远比局部最小值大的多,因为:
1)在高维参数空间,鞍点存在较多。
2)大量工作表面局部最优解,对于模型而言已经足够好。
此外,正是因为深度学习中鞍点的大量存在,传统的牛顿法不适合来寻优。
因为牛顿法是通过直接寻找梯度为0的点,来寻优的,那么极有可能陷入鞍点。
(ps: 也正因为如此,牛顿法在Hessian为正定的时候,比梯度下降速度快,因为牛顿法直接找梯度为0的点,而梯度下降则是一次一次的寻找当前点的最优梯度)
那么如何逃离,跳出鞍点呢?
1)利用Hessian矩阵,判断是否为鞍点。因为Hessian在鞍点具有正负特征值,而在局部最小值点正定。
2)随机梯度,相当于给正确的梯度加了一点noise,一定程度上避免了鞍点(但是只是一定程度),达到类似于如下公式的效果 :
3)随机初始化起点,也有助于逃离鞍点,原因见here
4)增加偶尔的随机扰动,详见here
上一张各算法逃离鞍点的效果图,有一个直观的感觉:
最后,推荐大家看这两篇博客,帮助大家理解:
参考: