SGD方法的好处和失效的场景,以及解决办法
SGD方法的好处和失效的场景,以及解决办法
SGD方法的好处是,不必计算所有样本的梯度,
这样做的效果是快,快在两方面,一方面计算快,一方面是收敛快,
计算快好理解,只计算了一个样本的梯度,
收敛快是指,如果不是特别差的损失函数,(这里差是指难优化的意思),
假设数据量100w,那么全局梯度下降更新一次梯度的计算时间,sgd已经更新了100w次,所以到达收敛状态所需的时间更短了。
失效的场景:
因为SGD在每一步放弃了对梯度准确性的追求,每步仅仅随机采样少量样本来计算梯度,计算速度快,内存开销小,但是由于每步接受的信息量有限,对梯度的估计出现偏差也在所难免,造成目标函数曲线收敛轨迹显得很不稳定,伴有剧烈波动,甚至有时出现不收敛的情况。图1展示了GD与SGD在优化过程中的参数轨迹,可以看到GD稳定地逼近最低点,而SGD曲曲折折简直是“黄河十八弯”。
对SGD来说,可怕的不是局部最优点,而是两类地形——山谷和鞍点。
山谷指的是狭长的山间小道,左右两边是峭壁;
鞍点的形状像是一个马鞍,一个方向上两头翘,另一个方向上两头垂,而中心区域是一片近乎水平的平地。
在山谷的地形下,一般的SGD由于上面所说的缘故,会在小道两边的山壁上来回撞击,
(这时我们需要有惯性保持的能力,想有一股直接垂直下山的动力,从而减小左右来回撞这个方向上的动力)
在鞍点的地形下,SGD走入一片平坦之地(此时离最低点还很远),想象一下蒙着双眼只凭借脚底感觉坡度,如果坡度不明显那么很可能走错方向。SGD本来就对微小变化的梯度不敏感,所以在几近零的梯度区域,容易停滞下来,不再更新。
(这时我们需要有环境感知的能力 ,即使蒙上双眼,依靠前几次迈步的感觉,我们也应该能判断出一些信息,比如这个方向总是坑坑洼洼的,那个方向可能很平坦。这里如何获取前几步的感觉,数学上的形式就是考虑对最近的梯度综合利用,累加或者求平均,累加到一定程度,sgd就自然对周边边境有了更多的认识,容易找个一个正确的方向。SGD中,对环境的感知是指在参数空间中,对不同参数方向上的经验性判断,确定这个参数的自适应学习速率,即更新不同参数的步子大小应是不同的。)
所以,对sgd失效场景的分析,引出了梯度更新优化算法,都是基于惯性保持和环境感知这两个idea来的,
基本的sgd:
Momentum:
看成Momentum:中每次前进的步子是,前进步子由两部分组成:(1) 学习速率和当前估计梯度,(2) 衰减下的前一次步子,系数控制衰减前一次的步子。
可类比物理学中,速度与加速度,当前步子就是当前时刻速度,上一步的步子就是上一时刻的速度,而当前梯度就好比当前时刻受力产生的加速度,所以当前速度不仅与加速度()有关而且与上一时刻的速度()有关,系数扮演来阻力的作用。
因此,与SGD相比,Momentum的收敛速度快,收敛曲线稳定。
AdaGrad:
名字中的Ada 注意体现在各维度的学习率不同,
历史上(累加的)梯度大的维度,学习率应该低一点,学慢一点(以免错误最佳点)
历史上(累加的)梯度小的维度,学习率应该大一点,学快一点(加快该维度上的收敛)
从而得到学习率应该与历史上(累加的)梯度成反比的想法,
数学形式是:
之所以用过往梯度平方和累加,而不是过往梯度平方和累加,主要考虑到,
退火的思想,即学习率只能是越来越小的单调减小的,而不可能变大,如果不加平方项,而采用这个式子,就会因为梯度有正有负,而不排除这个式子出现先小后大,后者先大后小的错误趋势。
Adam:
从名字一看就知道,Adam是个二合一的算法,结合AdaGrad的Ada和Momentum的m
机器学习中很多算法都是二合一或者三合一
Adam将惯性保持和环境感知两个有点都集于一身,一方面,Adam记录梯度的first moment一阶矩,即历史梯度和当前梯度的平均,这体现 来惯性保持,另一方面,Adam记录梯度的second moment二阶矩,即历史梯度平方和当前梯度平方的平均,这类似AdaGrad,体现了环境感知,提供二阶矩主要是为了为不同维度提供不同的学习率。
First moment和second moment求平均并不是直接累加,而是采用了类似滑动窗口内求平均的思想,把梯度分为,当前梯度和近一段时间内的梯度两类,并对两类梯度赋予不同权重,
其实是区别各维度的
其中β1, β2为衰减系数。
如何理解Adam记录梯度的first moment一阶矩和second moment二阶矩,
其实也挺好理解的,
First moment相当于估计,由于当下梯度是随机采样估计的结果(我们只拿了一个当前样本),比起是我们更关心它在统计意义上的期望,也就是First moment一阶矩;
second moment相当于估计,这点与AdaGrad不同,这里不是从开始到现在的累计和而是它的期望。
它们的物理意义是:
当一阶矩的绝对值大且二阶矩大时,梯度大且稳定,表明遇到一个明显的大坡,前进方向明确;
当一阶矩的绝对值趋向0且二阶矩大时,梯度不稳定,可能遇到一个峡谷,容易引起反弹震荡;
当一阶矩的绝对值大且二阶矩趋向0时,这种情况不存在;
当一阶矩的趋向0且二阶矩趋向0时,梯度趋零,可能到达局部最低点,也可能走到一片坡度极缓的平地,此时要避免陷入plateau高原上。
Adam还考虑在零初始值情况下的偏置矫正,所以加上了hat。Adam的更新公式为:
.
实际使用过程中,参数的经验值是
β1=0.9, β2=0.999
初始化:
、
这个时候我们看到,在初期,,都会接近于0,这个估计是有问题的。因此我们常常根据下式进行误差修正:
这样很容易记住sgd, momentum, adagrad, adam各自算法的初衷和公式。
https://zhuanlan.zhihu.com/p/32262540
Adam那么棒,为什么还对SGD念念不忘 (2)—— Adam的两宗罪
提到,1,AdaGrad: 学习率一定是下降的,而Adam 的学习率不一定是下降的,
2,错过最优解,后期Adam的学习率太低,影响了有效的收敛,所以后期改sgd
另外一篇是 Improving Generalization Performance by Switching from Adam to SGD,进行了实验验证。他们CIFAR-10数据集上进行测试,Adam的收敛速度比SGD要快,但最终收敛的结果并没有SGD好。他们进一步实验发现,主要是后期Adam的学习率太低,影响了有效的收敛。他们试着对Adam的学习率的下界进行控制,发现效果好了很多。
于是他们提出了一个用来改进Adam的方法:前期用Adam,享受Adam快速收敛的优势;后期切换到SGD,慢慢寻找最优解。这一方法以前也被研究者们用到,不过主要是根据经验来选择切换的时机和切换后的学习率。这篇文章把这一切换过程傻瓜化,给出了切换SGD的时机选择方法,以及学习率的计算方法,效果看起来也不错。