梯度下降:SGD vs Momentum vs NAG vs Adagrad vs Adadelta vs RMSprop vs Adam

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了梯度下降:SGD vs Momentum vs NAG vs Adagrad vs Adadelta vs RMSprop vs Adam相关的知识,希望对你有一定的参考价值。

参考技术A

梯度下降优化基本公式:

这三种梯度下降优化框架的区别在于每次更新模型参数时使用不同的样本数。

批/全量梯度下降每次更新模型参数时使用全部的训练样本。
, 为训练样本数

随机梯度下降每次更新参数时从训练样本中随机选择一个样本。

关于优化波动,带来的好处是在有很多local minima的区域,优化波动可能会使得优化的方向从当前的local minima跳到另一个更好的local minima,甚至是global minima,最终收敛于一个较好的minima。由于波动,迭代次数增多,收敛速度下降,不过最终会和批梯度下降一样具有收敛性。

小批量梯度下降每次更新模型参数时从训练样本中随机选择 个样本, , 常取32~256。

一般,SGD指小批量梯度下降。SGD存在的问题:

以下,将 记作 。

, 为动量项

其中,动量项超参数 越大,之前梯度方向对当前方向的影响也越大。

NAG计算“超前梯度”更新动量项。

既然参数要沿着 方向更新(蓝线),不妨计算下未来位置 处的梯度(红线),再将动量项与其合并作为最终的更新项(绿线)。

可以在梯度下降的过程中自动调节 。大原则是 随更新次数的增大而减小,同时也要针对不同的参数设置不同的 。有很多这样的自动调节 的梯度下降方法,名称常以"Ada"开头。

, 为过去到当前时刻的参数梯度平方和
, 为平滑参数,常为1e-8
作为regularizer项,其分母部分使用1阶导数的函数计算近似了2阶导数的计算,没有增加额外的花费来估计2阶导数。训练前期,梯度较小,regularizer项较大,放大梯度;训练后期,梯度较大,regularizer项较小,约束梯度。

, 为过去到当前时刻的参数梯度值平方的加权平均


, 为过去到前一时刻的参数更新值平方的加权平均
Adadelta作者用2个反复近似的式子来说明一阶方法比起二阶方法到底差在哪里。
一阶方法如SGD中: 。
二阶方法如牛顿法中: 。
注:用矩阵对角线近似逆矩阵: ;对 的一阶导数取log正比于 。
一阶方法与参数成逆相关,二阶方法与参数成正相关。
基于一阶梯度近似代替二阶梯度的思想,有 ,RMS指Root Mean Square。

是Adadelta的特例,无 有 。

, 为梯度的加权平均,一阶矩变量,有偏
, 为梯度平方的加权平均,二阶矩变量,有偏,梯度的加权有偏方差
和 均初始化为 ,Adam作者发现它们会倾向于为 ,特别是在 和 趋于1时。
为了改进这个问题,对 和 进行偏差修正,近似于期望的无偏估计。



经过偏置校正后,每一次迭代的学习率都有个确定的范围,使得参数比较平稳。

Adagrad、Adadelta、RMSprop在loss surface上能够立刻转移到正确的移动方向上达到快速的收敛,而Momentum、NAG会导致偏离,相较于Momentum,NAG能够在偏移之后更加迅速地修正其路线。

在saddle point处,SGD、Momentum、NAG一直在鞍点梯度为0的方向上振荡,Adagrad、Adadelta、RMSprop能够很快地向梯度不为0的方向上转移。
如果数据特征是稀疏的,最好使用自适应的梯度优化策略。
实验中,SGD常能够收敛到更好的minima,但是相对于其他的GD,可能花费的时间更长,并且依赖于初始值以及学习速率退火策略,并且容易陷入local minima以及鞍点。

恰好,可以走到局部最小值点; 太小,走得太慢,也可以走到局部最小值点; 太大,很可能走不到局部最小值点,卡在某处上; 太太大,很可能走出去。

变化, 变化小, 对loss影响小; 变化, 变化大, 对loss影响大。

一般来说,椭圆形中不同方向的 需求不一样,需要使用如"Ada"的自适应梯度下降方法;圆形中更新次数较少。因为无论椭圆形还是圆形,更新时都是沿着等高线的法线方向,而圆形直接向着圆心走。

通过将特征归一化,使得特征各个维度上的均值为0、方差为1来实现特征缩放.

梯度下降法VS随机梯度下降法 (Python的实现)

技术分享

 

 1 # -*- coding: cp936 -*-
 2 import numpy as np
 3 import matplotlib.pyplot as plt
 4 
 5 
 6 # 构造训练数据
 7 x = np.arange(0., 10., 0.2)
 8 m = len(x)                                      # 训练数据点数目
 9 x0 = np.full(m, 1.0)                 
10 input_data = np.vstack([x0, x]).T               # 将偏置b作为权向量的第一个分量
11 target_data = 2 * x + 5 + np.random.randn(m)
12 
13 
14 # 两种终止条件
15 loop_max = 10000   # 最大迭代次数(防止死循环)
16 epsilon = 1e-3     
17 
18 # 初始化权值
19 np.random.seed(0)
20 w = np.random.randn(2)
21 #w = np.zeros(2)
22 
23 alpha = 0.001      # 步长(注意取值过大会导致振荡,过小收敛速度变慢)
24 diff = 0.           
25 error = np.zeros(2) 
26 count = 0          # 循环次数
27 finish = 0         # 终止标志
28 # -------------------------------------------随机梯度下降算法----------------------------------------------------------
29 ‘‘‘
30 while count < loop_max:
31     count += 1
32 
33     # 遍历训练数据集,不断更新权值
34     for i in range(m):  
35         diff = np.dot(w, input_data[i]) - target_data[i]  # 训练集代入,计算误差值
36 
37         # 采用随机梯度下降算法,更新一次权值只使用一组训练数据
38         w = w - alpha * diff * input_data[i]
39 
40         # ------------------------------终止条件判断-----------------------------------------
41         # 若没终止,则继续读取样本进行处理,如果所有样本都读取完毕了,则循环重新从头开始读取样本进行处理。
42 
43     # ----------------------------------终止条件判断-----------------------------------------
44     # 注意:有多种迭代终止条件,和判断语句的位置。终止判断可以放在权值向量更新一次后,也可以放在更新m次后。
45     if np.linalg.norm(w - error) < epsilon:     # 终止条件:前后两次计算出的权向量的绝对误差充分小  
46         finish = 1
47         break
48     else:
49         error = w
50 print ‘loop count = %d‘ % count,  ‘\tw:[%f, %f]‘ % (w[0], w[1])
51 ‘‘‘
52 
53 
54 # -----------------------------------------------梯度下降法-----------------------------------------------------------
55 while count < loop_max:
56     count += 1
57 
58     # 标准梯度下降是在权值更新前对所有样例汇总误差,而随机梯度下降的权值是通过考查某个训练样例来更新的
59     # 在标准梯度下降中,权值更新的每一步对多个样例求和,需要更多的计算
60     sum_m = np.zeros(2)
61     for i in range(m):
62         dif = (np.dot(w, input_data[i]) - target_data[i]) * input_data[i]
63         sum_m = sum_m + dif
64 
65     w = w - alpha * sum_m  # 注意步长alpha的取值,过大会导致振荡
66     #w = w - 0.005 * sum_m # alpha取0.005时产生振荡,需要将alpha调小
67     
68     # 判断是否已收敛
69     if np.linalg.norm(w - error) < epsilon:
70         finish = 1
71         break
72     else:
73         error = w
74 print loop count = %d % count,  \tw:[%f, %f] % (w[0], w[1])
75 
76 
77 plt.plot(x, target_data, k+)
78 plt.plot(x, w[1] * x + w[0], r)
79 plt.show()

技术分享

参考:http://www.tuicool.com/articles/MRbee2i

以上是关于梯度下降:SGD vs Momentum vs NAG vs Adagrad vs Adadelta vs RMSprop vs Adam的主要内容,如果未能解决你的问题,请参考以下文章