局部最小值
https://blog.****.net/malefactor/article/details/78768210?utm_source=blogxgwz5
对于神经网络目标函数优化来说,在参数寻优过程中最常用的算法是梯度下降,目前也出现了很多基于SGD基础上的改进算法,比如带动量的SGD,Adadelta,Adagrad,Adam,RMSProp等梯度下降改进方法,这些算法大多都是针对基础更新公式进行改进:
一般深度神经网络由于很深的深度以及非线性函数这两个主要因素,导致目标的损失函数是非凸函数,该损失函数曲面中包含许多的驻点,驻点可能是以下三类关键点中的一种:鞍点,局部极小值,全局极小值,其中全局极小值是我们期望训练算法能够找到的,而其它两类是期望能够避免的。一个示意性的损失函数曲面如下图所示:
不少学习算法在训练过程中,随着误差的减少,迭代次数的增加,步长变化越来越小,训练误差越来越小直到变为零,局部探索到一个驻点,如果这个点是误差曲面的鞍点,即不是最大值也不是最小值的平滑曲面,那么一般结果表现为性能比较差;
如果这个驻点是局部极小值,那么表现为性能较好,但不是全局最优值。目前大多数训练算法在碰到无论是鞍点还是局部极值点的时候,因为此刻学习率已经变得非常小,所以会陷入非全局最优值不能自拔。这其实就是目前采用SGD类似的一阶导数方法训练机器学习系统面临的一个很重要的问题。
目前来看,没有方法能够保证找到非凸函数优化过程中的全局最小值,也就是说,不论你怎么调参将性能调到你能做到的最好,仍然大概率获得了优化过程中的一个鞍点或者局部极小值,那么一个很自然的想法就是:能否在优化过程的末尾,就是已经大概率陷入某个局部极小值或者鞍点的时候,放大学习率,强行让训练算法跳出当前的局部最小值或者鞍点,所谓“世界这么大,我想去看看”,继续寻找可能效果会更好的极值点,这样多次跳出优化过程中的局部最小值,然后比较其中性能最好的极小值,并以那个时刻的参数作为模型参数。当然,这仍然没有办法保证找到全局最小值,只是说多比较一些极值点,矮子里面拔将军的意思。
一.两种跳出驻点的方法
上面说了基本思路,其实思路很朴实也很简单:常见的训练方法在刚开始的时候学习率设置的比较大,这样可以大幅度快步向极值点迈进,加快收敛速度,随着越来越接近极值点,逐步将学习率调小,这样避免步子太大跳过极值点或者造成优化过程震荡结果不稳定。当优化到性能无法再提升的时候,此时大概率陷入了鞍点或者局部极小值,表现为梯度接近于0而且一般此时学习率已经调整到非常小的程度了。跳出驻点的思路就是说:此时可以重新把已经调整的很小的学习率数值放大,强行逼迫优化算法跳出此刻找到的鞍点或者极值点,在上述示意的损失函数曲面上等于当前在某个山谷的谷底(或者某个平台上,即鞍点),此时迈出一大步跳到比较远的地方,然后继续常规的优化过程,就是不断调小学习率,期望找到附近的另外一个山谷谷底,如此往复若干次,然后找出这些谷底哪个谷底更深,然后采取这个最深的谷底对应的参数作为模型参数。
方法1:随机漫步起跳法
这个方法比较简单,就是说当前优化走到哪个山谷谷底,就从当前位置起跳,直接调大学习率即可,因为这样类似于走到哪里走不下去就从哪里开始跳到附近的远处,走到哪算哪,所以称之为“随机漫步起跳法”。
方法2:历史最优起跳法
上面说过,在这种优化方法过程中,会不断进入某个谷底,那么假设在训练集上优化历史上已经经过K个谷底,在验证集上其对应参数的模型性能是可以知道的,分别为P1,P2……Pk。随机漫步起跳法就是从Pk作为起跳点进行起跳。而历史最优起跳法则从P1,P2……Pk中性能最优的那个山谷谷底开始起跳,假设Pi=Max(P1,P2……Pk),那么从第i个山谷开始起跳,如果跳出后发现第j个山谷的性能Pj要优于Pi,则后面从Pj的位置开始起跳,当从Pi跳过K次都没有发现比Pi性能更好的山谷,此时可以终止优化算法。这个有点像是Pi性能的“一山望着一山高”,然后不断从历史最高峰跳到更高的高山上,可以保证性能应该越来越好。从道理上讲感觉这种历史最优起跳法要好于随机漫步起跳法,但是实验结果表明两种不同的起跳方法性能是差不多的,有时候这个稍好点,有时候那个稍好点,没有哪个方法确定性的比另外一个好。
学习算法设置的参数为: 选择使用Nesterov的带动量的随机梯度下降法,初始学习率为0.01,衰减因子为1e-6,momentum因子为0.9。
2.2 Nesterov+动量SGD(固定学习率)实验效果
在上节所述的模型设置下,从结果看,最好的测试精度是0.9060,模型的误差和精度都变化地比较平滑
2.3学习率自适应减少进行训练的实验结果
其它配置类似于2.1.2所述,唯一的不同在于:使用常规策略对学习率进行缩小的改变。改变学习率的策略是如果误差10次不变化,那么学习率缩小为原来的0.1倍。 总迭代次数设置为100次。 训练误差、训练准确率、测试误差、测试准确率的变化曲线为:
从训练结果看,第47次学习率变化,性能上有一次大幅度的提高:
从训练和测试的结果看,测试精度最高的是在第80轮,达到了0.9144。此时的训练误差0.3921,训练准确率0.9926,测试误差0.3957,测试准确率0.9144。
由此可见,增加学习率的动态改变,在学习速度和质量上要比原始的学习率恒定的训练方法要好,这里性能上增加近一个百分点。
2.4随机漫步起跳法实验结果
从上面的两组实验结果过程的最后阶段可以看出,误差和准确率变化较小,很可能优化过程陷入一个局部最优值,可能是一个极值,也可能是一个鞍点,不管怎样称呼它,它就是一个驻点。(从结果看,应该是一个局部最优值)。在其它实验条件与2.1.3节所述相同情况下,采取上文所述的随机漫步起跳法强迫优化算法跳出当前局部最优,即在学习率比较低的时候,进行扩大学习率的方式(直接设置为0.1,后面再常规的逐步减少),让其在误差曲面的区域中去寻找更多的驻点。 具体做法是:如果当前发现经过三次学习率变小没有带来准确率的提升,那么在当前训练的点,将学习率恢复到初始的学习率即0.01。 迭代的效果如下训练误差、训练准确率、测试误差、测试准确率的变化曲线如下图为:
从训练过程看,从当前迭代的当前位置出发,采用学习率缩小和扩大相结合的方式,目前最高能在第153轮的准确率提高到0.9236,比之前最好的0.9144有一点提升,说明这样的学习率变大策略也是一种可行的思路。
另外,从图中看,由于我们变大学习率许多次,每次学习率变大都会呈现一个波动形式,故结果表现出锯齿状的波动趋势。
2.5历史最优起跳法实验结果
我们做了类似的实验,发现历史最优起跳法与随机漫步起跳法性能相当,有时这个好点有时那个好点,没有发现性能明显差异。
我们随机抽了其它几个最优网络结构自动探索出的深度神经网络结构,表现与上述网络结构类似,而如果基础网络结构本身性能越差,这个差别越大。
所以可以得出的结论是:优化过程中采用常规动态学习率调整效果要优于固定学习率的方法,而随机漫步起跳法效果略优于常规的动态学习率调整方法,但是历史最优起跳法相对常规动态学习率方法没有发现改善。