优化算法框架
神经网络模型中有多种优化算法,优化算法的作用用来优化更新参数。
对于优化算法而言,主要的框架如下。
参数: 目标函数: 学习率。
对于每个epoch t:
step1:计算当前梯度
step2:计算动量。
一阶动量:
二阶动量:
step3:计算当前时刻下降梯度
step4:更新参数
对于不同的优化算法而言,区别主要在于第一步和第二步。对于梯度的计算,一阶动量的计算,和二阶动量的计算存在差别。
三、四步的计算更新,各个算法之间都是相同的。
优化算法介绍
SGD
最常见的SGD
直接没有step2,没有引入动量。
在实际的实现中,可能会对学习率进行改变,会使用衰减学习率。
SGD的缺点是 1 收敛速度慢,2 有可能会困在局部最优解。
SGDM
也就是SGD+ Momentum。这里引入了一阶动量。
从直观理解就是加入了一个惯性,在坡度比较陡的地方,会有较大的惯性,这是下降的多。坡度平缓的地方,惯性较小,下降的会比较慢。
修改SGD中的一阶动量为
等式右边有两部分,加号左边的部分为之前积累的下降方向,加号右边为当前的梯度。两者的权重用参数来控制。
越大,说明下降的方向越依赖于以往的惯性。可以减少方向的突变。
SGD+NAG
NAG是:Nesterov Accelerated Gradient
这里是针对SGD会陷在局部最优附近的缺点进行改进。
在前面针对收敛慢改,引进一阶动量后,这里着眼于step1里的梯度计算。通常会设的比较大,这就说明下降方向主要由历史方向积累决定,那么在step1里,不看当前的梯度,而是看下一步时刻的梯度。直观理解为多看一步,计算下一步的梯度。
用下一个点的梯度下降方向,与历史累积动量结合,计算step2里的一阶动量。
计算公式如下
AdaGrad
前面的优化算法主要着眼于一阶动量的设计,从AdaGrad开始,将引入二阶动量。参数的二阶动量在这里表示为当前维度上,历史积累的全部的梯度的平方和。
将step3里的公式修改一下顺序,那前面的部分可以看成学习率。这里的分母是二阶动量。这里的学习率(包含二阶动量)会随着二阶动量的积累而逐渐变化,这就是‘自适应学习’。
宏观来分析,这里参数更新时,希望从少更新的维度多学习,经常更新的参数那里少学习一点。对于频繁更新的的参数,二阶动量迅速积累,会使的学习率降低,那么在同一次更新中,模型会学到比较少的内容。而不频繁更新的参数,学习率会比较大,每次更新时学到的东西比较多。
Ada算法的缺点也很明显,二阶动量是历史梯度的积累,是个单调递增的值,当分母越来越大时,整个的学习率会趋于0,会提前停止学习。
AdaDelta / RMSProp
为了改进AdaGrad中的二阶动量会不断增加的缺点,这里提出了一个时间窗口。计算二阶动量的时候只计算这个时间窗口内的动量。避免了二阶动量的持续积累。
二阶动量的计算公式如下
Adam
SGD-M 引入了一阶动量,AdaG 引入了二阶动量。
二者结合就是Adam,同时考虑一阶动量和二阶动量。
二者的计算公式如下:
Nadam
回头看最初的优化框架,已经分别在一阶动量和二阶动量做了研究。还剩下当前的梯度可以进行尝试。参考前面的NAG,Nadam就是Adam+Nesterov。
在Adam的基础上保持其他计算公式不变,更改当前梯度的计算公式为
自适应优化算法缺点分析
从前面的介绍可以看出,Adam系列的算法表面上更优秀,针对原本的SGD的缺点做了各种改变。但是对于Adam算法,目前也存在着缺点。
其中一个很严重的问题是Adam算法有可能不收敛。因为二阶动量取决于一段时间内的梯度的积累。这段时间内的数据如果有异常,会导致这个二阶动量极不稳定。在学习的后期,学习率有可能不断震荡,导致整个模型无法收敛。
同时因为动量的引入,在学习的后期,存在可能使一步过大,错过最优解。
综上所述,虽然Adam看着很完美,但在实际应用中还是存在着缺点。所以到底是各种优化器要如何选择,还是要取决于具体的情况和个人的调参经验。
调参经验
后续会逐渐更新个人的调参经验。
参考文献
[1]一个框架看懂优化算法之异同 SGD/AdaGrad/Adam
[2]Adam的两宗罪
[3]如何理解随机梯度下降(Stochastic gradient descent,SGD)?