参数的更新有许多方法;
1.Vanilla update
最简单的更新形式。假定
x
是参数矢量,
# Vanilla update
x+=-leaning_rate*dx
其中learning_rate是学习率。
2Mumentum update
在深度网络中,通常能够得到更好的收敛速率。这种更新方法来源于优化问题的物理学上的观点。特别的,损失函数可以解释为山丘的高(也可以说成是势能,因为U=mgh,其中U表示重力势能,m是质量, g是重力加速度, h是高度,
U∝h
,即势能 正比于高度)。将参数初始化为随机的数等同于将某个粒子放在某个位置,并且速度设置为0。因此,优化的过程可以看作等价于参数矢量(例如一个粒子)在地形上滚动。
因为粒子上的力与势能的梯度相关(例如
F=−▽U
,
E=−∫Fds
,其中s表示距离),粒子所拥有的力等于损失函数的负梯度。此外,
F=ma
,因此负梯度正比于粒子的加速度。
Vanilla update 中的更新过程,将梯度直接整合位置(位置的更新直接使用了当前位置的梯度),Mumentum update中:梯度仅直接影响到速度,速度反过来才影响到位置。
#Momentum update
v=mu*v-learning_rate*dx #integrate velocity
x+=v #intergrate position
上面的两个公式中,我们可以看到,第一个公式描述了梯度
dx
和速度
v
的关系,第二个公式描述了速度
Nesterov Momentum
Nesterov Momentum与Momentum update轻微的不同。对于凸函数,其具有更强的理论上的收敛保障,并且在实际应用中,一般略优于标准的Momentum 。
Nesterov Momentum的核心思想是,当前参数矢量在某个位置
x
<script type="math/tex" id="MathJax-Element-300">x</script>处,那么我们看一下上面Momentum update更新,可以看到动量项(mu*v)将单独地(也就是说,忽略带有梯度的第二项)通过mu*v
推进参数矢量。那么我们可以试想一下,如果我们将要计算梯度,那么我们可将其未来的近似位置x+mu*v
看作是“预先”,这个点是我们将要达到的点的附近。因此,我们可以计算x+mu*v
处的梯度来替代“旧”位置x处的梯度。
上图(左):红色的原点表示当前位置x,绿色的箭头表示向量:mu*v
,红色的箭头表示向量:-learning_rate * dx
,蓝色的箭头表示向量: v
,最终的位置为:红色的点+向量v,移动到蓝色箭头处。
上图(右):红色的原点表示当前位置x,绿色的箭头表示向量:mu*v
,红色的箭头表示向量:-learning_rate * d(x+mu*v)
,蓝色的箭头表示向量: v
,最终的位置为:红色的点+向量v,移动到蓝色箭头处。
即更新过程描述如下:
x_ahead = x + mu * v
# evaluate dx_ahead (the gradient at x_ahead instead of at x)
v = mu * v - learning_rate * dx_ahead
x += v
但是,在实际应用中,人们希望其更新表达形式类似于vanilla SGD 或者momenum update,即修改为下面的形式。
v_prev = v # back this up
v = mu * v - learning_rate * dx # velocity update stays the same
x += -mu * v_prev + (1 + mu) * v # position update changes form