Java教程

深度学习:算法优化之动量算法(Momentum)

本文主要是介绍深度学习:算法优化之动量算法(Momentum),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1.原理

  运用物理学上的动量思想,在梯度下降的问题中引入动量项 m m m 和折扣因子 γ \gamma γ,公式为: m t = γ m t + 1 m_t=\gamma m_{t+1} mt​=γmt+1​其中 m m m 是动量项 m m m的指数加权平均后的值, γ \gamma γ表示历史梯度的影响力,也就是权重值, γ \gamma γ越大,权重越大。从直观上看,如果当前时刻的梯度与历史梯度方向趋近,这种趋势会在当前时刻加强,否则减弱。

2.指数加权平均

  在分析动量算法之前,我们先来了解指数加权平均的含义。假定给一个序列,例如北京一年每天的气温值,图中蓝色的点代表真实数据:

这时温度值波动比较大,我们使用加权平均值来进行平滑,如下图红线就是平滑后的结果:
在这里插入图片描述
计算方法如下所示:
S t = { Y 1 ,                                  t = 1 β S t − 1 + ( 1 − β ) Y t , t > 1 S_t= \begin{cases} Y_1,\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ t=1\\ \beta S_t-1+(1-\beta)Y_t, t>1 \end{cases} St​={Y1​,                                t=1βSt​−1+(1−β)Yt​,t>1​
  其中 Y t Y_t Yt​为 t t t时刻的真实值, S t S_t St​为 t t t时刻加权后的平均值, β \beta β为权重值。红线即是指数加权平均后的结果。
上图中 β \beta β设为0.9,那么指数加权平均的计算结果为:

S 1 = Y 1 S_1=Y_1 S1​=Y1​

S 2 = 0.9 S 1 + 0.1 Y 2 S_2=0.9S_1+0.1Y_2 S2​=0.9S1​+0.1Y2​

S 3 = 0.9 S 2 + 0.1 Y 3 S_3=0.9S_2+0.1Y_3 S3​=0.9S2​+0.1Y3​

⋯ \cdots ⋯

S 99 = 0.9 S 98 + 0.1 Y 99 S_{99}=0.9S_{98}+0.1Y_{99} S99​=0.9S98​+0.1Y99​

S 100 = 0.9 S 99 + 0.1 Y 100 = 0.9 ( 0.9 S 98 + 0.1 Y 99 ) + 0.1 Y 100 = 0.9 × 0.9 S 98 + 0.09 Y 99 + 0.1 Y 100 = 0.9 × 0.9 ( 0.9 S 97 + 0.1 Y 98 ) + 0.1 × 0.9 Y 99 + 0.1 Y 100 = 0.1 Y 100 + 0.1 × ( 0.9 ) 1 Y 99 + 0.1 × ( 0.9 ) 2 Y 98 + ⋯ + 0.1 × ( 0.9 ) 99 Y 1 \begin{aligned} S_{100}&=0.9S_{99}+0.1Y_{100}\\ &=0.9(0.9S_{98}+0.1Y_{99})+0.1Y_{100}\\ &=0.9\times0.9S_{98}+0.09Y_{99}+0.1Y_{100}\\ &=0.9\times0.9(0.9S_{97}+0.1Y_{98})+0.1\times 0.9Y_{99}+0.1Y_{100}\\ &=0.1Y_{100}+0.1\times(0.9)^1Y_{99}+0.1\times(0.9)^2Y_{98}+\cdots+0.1\times(0.9)^{99}Y_1 \end{aligned} S100​​=0.9S99​+0.1Y100​=0.9(0.9S98​+0.1Y99​)+0.1Y100​=0.9×0.9S98​+0.09Y99​+0.1Y100​=0.9×0.9(0.9S97​+0.1Y98​)+0.1×0.9Y99​+0.1Y100​=0.1Y100​+0.1×(0.9)1Y99​+0.1×(0.9)2Y98​+⋯+0.1×(0.9)99Y1​​
  从上边式子可知:实质上是以指数式递减加权的移动平均。各数值的加权随时间而呈指数式递减,越近期的数据加权越重,越旧的数据加权越小,但是仍有相应的加权。我们可以看到指数加权平均的求解过程实际上是一个递推的过程,那么这样就会有一个非常大的好处,每当我要求从0到某一时刻(n)的平均值的时候,并不需要像普通求解平均值那样,保留所有时刻值,求和,然后除以n。而是只需要保留0~(n-1)时刻的平均值和n时刻的温度值即可。也就是每次只需要保留常数值,然后进行运算即可,这对于深度学习中的海量数据来说,是一个很好的减少内存和空间的做法。另外, β \beta β值设置的越大,曲线越平滑,相反,曲线越震荡。

3 动量梯度下降算法

  动量梯度下降(Gradient Descent with Momentum)计算梯度的指数加权平均数,并利用该值来更新参数值。

S d W = β S d W + ( 1 − β ) d W S_{dW}=\beta S_{dW}+(1-\beta)dW SdW​=βSdW​+(1−β)dW

S d b = β S d b + ( 1 − β ) d b S_{db}=\beta S_{db}+(1-\beta)db Sdb​=βSdb​+(1−β)db

因此:

W = W − α S d W W=W-\alpha S_{dW} W=W−αSdW​

b = b − α S d b b=b-\alpha S_{db} b=b−αSdb​

与原始的梯度下降相比,动量梯度下降趋势更加平滑。
在这里插入图片描述
  在tf.keras中使用Momentum算法仍使用功能SGD方法,但要设置momentum参数,实现过程如下:

# 导入相应的工具包
import tensorflow as tf
# 实例化优化方法:SGD 指定参数beta=0.9
opt = tf.keras.optimizers.SGD(learning_rate=0.1, momentum=0.9)
# 定义要调整的参数,初始值
var = tf.Variable(1.0)
val0 = var.value()
# 定义损失函数
loss = lambda: (var ** 2)/2.0         
#第一次更新:计算梯度,并对参数进行更新,步长为 `- learning_rate * grad`
opt.minimize(loss, [var]).numpy()
val1 = var.value()
# 第二次更新:计算梯度,并对参数进行更新,因为加入了momentum,步长会增加
opt.minimize(loss, [var]).numpy()
val2 = var.value()
# 打印两次更新的步长
print("第一次更新步长={}".format((val0 - val1).numpy()))
print("第二次更新步长={}".format((val1 - val2).numpy()))

结果是:

第一次更新步长=0.10000002384185791
第二次更新步长=0.18000000715255737
这篇关于深度学习:算法优化之动量算法(Momentum)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!