Momentum

欲掌握本节知识,需先学习:指数加权平均

背景

Momentum是为解决SGD中出现的曲折摆动问题,如图所示,“之”字形的上下摆动,降低了损失函数到达最低点的速度。此情况下,若想减少摆动浮动,只能采用比较小的learning rate,这同样将导致寻优的速度较低。而Momentum就是为解决此问题而来。参考:SGD原理及其缺点
在这里插入图片描述

什么是动量?

动量是衡量让运动物体停下难度的物理量。当动量momentum越大时,其转换为势能的能量也就越大,越易摆动,难以停下来。

动量法几乎总是比标准的梯度下降法速度更快,算法的主要思想是计算梯度的指数加权平均,然后使用这个梯度来更新权重(上图中,你希望纵轴可以学习慢一点,不希望出现这些震荡,横轴上,你希望加快学习速度)

可以理解为,在到达新的一点时,SGD会直接按照该点的负梯度方向去更新,而Momentum会考虑之前的梯度及方向,即动量。更新的时候考虑梯度均值(指数加权平均),指数衰减理解为摩擦力造成的损失。
在这里插入图片描述

黑色虚线是负梯度方向,红色表示的是梯度,绿色表示更新方向,蓝色虚线就是动量

Momentum 是“动量”的意思,和物理有关。用数学式表示 Momentum 方法,如下所示。
在这里插入图片描述
在这里插入图片描述

和前面的 SGD 一样, 表示要更新的权重参数(位置),∂L/∂W 表示损失函数关于 权重 W W W 的梯度(加速度), η η η 表示学习率。这里新出现了一个变量 v v v ,对应物理上的动量。式(6.3)表示了物体在梯度方向上受力,在这个力的作用下,物体的速度增加这一物理法则。如图 6-4 所示,Momentum 方法给人的感觉就像是小球在地面上滚动。
在这里插入图片描述

图 6-4 Momentum:小球在斜面上滚动

式(6.3)中有 这一项。在物体不受任何力时,该项承担使物体逐渐减速的任务( α α α 设定为 0.9 之类的值),对应物理上的地面摩擦或空气阻力。下面是 Momentum 的代码实现。

class Momentum:
    def __init__(self, lr=0.01, momentum=0.9):
        self.lr = lr #学习率
        self.momentum = momentum
        self.v = None
    def update(self, params, grads):
        if self.v is None:
            self.v = {}
            for key, val in params.items():
                self.v[key] = np.zeros_like(val)
        for key in params.keys():
            self.v[key] = self.momentum*self.v[key] - self.lr*grads[key]
            params[key] += self.v[key]

实例变量 v v v 会保存物体的速度。初始化时, v v v 中什么都不保存,但当第一次调用 update() 时, v v v 会以字典型变量的形式保存与参数结构相同的数据。剩余的代码部分就是将式(6.3)、式(6.4)写出来,很简单。

在这里插入图片描述

现在尝试使用 Momentum 解决式(6.2)的最优化问题,如图 6-5 所示。
在这里插入图片描述

图 6-5 基于 Momentum 的最优化的更新路径

图 6-5 中,更新路径就像小球在碗中滚动一样。和 SGD(随机梯度下降) 相比,我们发现“之”字形的“程度”减轻了。

这是因为虽然 x x x 轴方向上受到的力非常小,但是一直在同一方向上受力,所以朝同一个方向会有一定的加速。

反过来,虽然 y y y 轴方向上受到的力很大,但是因为交互地受到正方向和反方向的力,它们会互相抵消,所以 y y y 轴方向上的速度不稳定。因此,和 SGD 时的情形相比,可以更快地朝 x x x 轴方向靠近,减弱“之”字形的变动程度。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐