【AI】求解器SGD、BGD、MBGD等详解

参考博客:

***** 深度学习必备:随机梯度下降(SGD)优化算法及可视化:
**** 深度学习——优化器算法Optimizer详解(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam):
***** 为什么说随机最速下降法 (SGD) 是一个很好的方法?:
}

一、概述

求解器(solver),也称为优化器。
对于优化算法,优化的目标是网络模型中的参数θ(是一个集合,θ1、θ2、θ3 …)。目标函数为损失函数L = 1/N ∑ Li (每个样本损失函数的叠加求均值)。
这个损失函数L变量就是θ,其中L中的参数是整个训练集,换句话说,目标函数(损失函数)是通过整个训练集来确定的,训练集全集不同,则损失函数的图像也不同。
那么为何在mini-batch中如果遇到鞍点/局部最小值点就无法进行优化了呢?因为在这些点上,L对于θ的梯度为零,换句话说,对θ每个分量求偏导数,带入训练集全集,导数为零。
对于SGD/MBGD而言,每次使用的损失函数只是通过这一个小批量的数据确定的,其函数图像与真实全集损失函数有所不同,所以其求解的梯度也含有一定的随机性,
在鞍点或者局部最小值点的时候,震荡跳动,因为在此点处,如果是训练集全集带入即BGD,则优化会停止不动,如果是mini-batch或者SGD,每次找到的梯度都是不同的,就会发生震荡,来回跳动。

二、各个求解器详解
1、BGD:Batch Gradient Descent 批量梯度下降

1)梯度更新规则:
BGD 采用整个训练集的数据来计算损失函数loss_function(或称为cost function)对参数的梯度;
每次使用全量的训练集样本来更新模型参数,即: θ=θ−η⋅∇θJ(θ)

2)缺点:
由于这种方法是在一次更新中,就对整个数据集计算梯度,所以计算起来非常慢,如果训练集很大以至于需要消耗大量的内存,
而且不能投入新数据实时更新模型(即,全量梯度下降不能进行在线模型参数更新)。

3)优点:
在于每次更新都会朝着正确的方向进行,最后能够保证收敛于极值点(凸函数收敛于全局极值点,非凸函数可能会收敛于局部极值点)

2、SGD:Stochastic Gradient Descent 随机梯度下降

1)梯度更新规则:
随机梯度下降算法每次从训练集中随机选择一个样本来进行学习,即: θ=θ−η⋅∇θJ(θ;xi;yi)

随机梯度下降是通过每个样本来迭代更新一次,如果样本量很大的情况,那么可能只用其中部分的样本,就已经将theta迭代到最优解了,
对比上面的批量梯度下降,迭代一次需要用到十几万训练样本,一次迭代不可能最优,如果迭代10次的话就需要遍历训练样本10次。

2)缺点:
SGD的噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。所以虽然训练速度快,但是准确度下降,并不是全局最优。
虽然包含一定的随机性,但是从期望上来看,它是等于正确的导数的。
SGD 因为更新比较频繁,会造成 cost function 有严重的震荡。
BGD 可以收敛到局部极小值,当然 SGD 的震荡可能会跳到更好的局部极小值处。

3)优点:
批量梯度下降算法(BGD)每次都会使用全部训练样本,因此这些计算是冗余的,因为每次都使用完全相同的样本集。
而随机梯度下降算法每次只随机选择一个样本来更新模型参数,因此每次的学习是非常快速的,并且可以进行在线更新。

随机梯度下降是通过每个样本来迭代更新一次,如果样本量很大的情况,那么可能只用其中部分的样本,就已经将theta迭代到最优解了,
对比批量梯度下降(BGD),迭代一次需要用到十几万训练样本,一次迭代不可能最优,如果迭代10次的话就需要遍历训练样本10次。

随机梯度下降所带来的波动有个好处就是,对于类似盆地区域(即很多局部极小值点)那么这个波动的特点可能会使得优化的方向从当前的局部极小值点跳到另一个更好的局部极小值点,
这样便可能对于非凸函数,最终收敛于一个较好的局部极值点,甚至全局极值点。

由于波动,因此会使得迭代次数(学习次数)增多,即收敛速度变慢。不过最终其会和全量梯度下降算法一样,具有相同的收敛性,即凸函数收敛于全局极值点,非凸损失函数收敛于局部极值点。

4)当我们稍微减小 learning rate,SGD 和 BGD 的收敛性是一样的。

3、MBGD:Mini-Batch Gradient Descent 小批量梯度下降

1)梯度更新规则:
MBGD 每一次利用一小批样本,即 n 个样本进行计算,这样它可以降低参数更新时的方差,收敛更稳定,另一方面可以充分地利用深度学习库中高度优化的矩阵操作来进行更有效的梯度计算。
和 SGD 的区别是每一次循环不是作用于一个样本,而是具有 n 个样本的批次。

Mini-batch 梯度下降综合了BDG与SGD,在每次更新速度与更新次数中间取得一个平衡,其每次更新从训练集中随机选择 m,m θ=θ−η⋅∇θJ(θ;xi:i+m;yi:i+m)

2)超参数设定值: n 一般取值在 50~256

3)缺点:(两大缺点)
Mini-batch gradient descent 不能保证很好的收敛性,learning rate 如果选择的太小,收敛速度会很慢,如果太大,loss function 就会在极小值处不停地震荡甚至偏离。
(有一种措施是先设定大一点的学习率,当两次迭代之间的变化低于某个阈值后,就减小 learning rate,不过这个阈值的设定需要提前写好,这样的话就不能够适应数据集的特点。)
对于非凸函数,还要避免陷于局部极小值处,或者鞍点处,因为鞍点周围的error是一样的,所有维度的梯度都接近于0,SGD 很容易被困在这里。
(会在鞍点或者局部最小点震荡跳动,因为在此点处,如果是训练集全集带入即BGD,则优化会停止不动,如果是mini-batch或者SGD,每次找到的梯度都是不同的,就会发生震荡,来回跳动。)

SGD对所有参数更新时应用同样的 learning rate,如果我们的数据是稀疏的,我们更希望对出现频率低的特征进行大一点的更新。LR会随着更新的次数逐渐变小。
4)优点;
相对于随机梯度下降,Mini-batch梯度下降降低了收敛波动性,即降低了参数更新的方差,使得更新更加稳定。
相对于全量梯度下降,其提高了每次学习的速度。并且其不用担心内存瓶颈从而可以利用矩阵运算进行高效计算。
一般而言每次更新随机选择[50,256]个样本进行学习,但是也要根据具体问题而选择,实践中可以进行多次试验,选择一个更新速度与更次次数都较适合的样本数。
mini-batch梯度下降可以保证收敛性,常用于神经网络中。

4、Momentum

如果在峡谷地区(某些方向较另一些方向上陡峭得多,常见于局部极值点),SGD会在这些地方附近振荡,从而导致收敛速度慢。这种情况下,动量(Momentum)便可以解决。

1)梯度更新规则:
动量在参数更新项中加上一次更新量(即动量项),即: νt=γνt−1+η ∇θJ(θ),θ=θ−νt
Momentum 通过加入 γv_t−1 ,可以加速 SGD, 并且抑制震荡.
加上动量项就像从山顶滚下一个球,球往下滚的时候累积了前面的动量(动量不断增加),因此速度变得越来越快,直到到达终点。
同理,在更新模型参数时,对于那些当前的梯度方向与上一次梯度方向相同的参数,那么进行加强,即这些方向上更快了;
对于那些当前的梯度方向与上一次梯度方向不同的参数,那么进行削减,即这些方向上减慢了。因此可以获得更快的收敛速度与减少振荡。

2)超参数设定值: 一般 γ 取值 0.9 左右。

3)缺点:
这种情况相当于小球从山上滚下来时是在盲目地沿着坡滚,如果它能具备一些先知,例如快要上坡时,就知道需要减速了的话,适应性会更好。

5、NAG:Nesterov Accelerated Gradient, Nesterov加速梯度

1)梯度更新规则:
从山顶往下滚的球会盲目地选择斜坡。更好的方式应该是在遇到倾斜向上之前应该减慢速度。
Nesterov accelerated gradient(NAG,涅斯捷罗夫梯度加速)不仅增加了动量项,并且在计算参数的梯度时,在损失函数中减去了动量项,
即计算∇θJ(θ−γνt−1),这种方式预估了下一次参数所在的位置。即:νt=γνt−1+η⋅∇θJ(θ−γνt−1),θ=θ−νt
用 θ−γv_t−1 来近似当做参数下一步会变成的值,则在计算梯度时,不是在当前位置,而是未来的位置上.

2)超参数设定值: 一般 γ 仍取值 0.9 左右。

3)NAG 可以使 RNN 在很多任务上有更好的表现。
目前为止,我们可以做到,在更新梯度时顺应 loss function 的梯度来调整速度,并且对 SGD 进行加速。
我们还希望可以根据参数的重要性而对不同的参数进行不同程度的更新。

6、Adagrad (Adaptive gradient algorithm)

1)优点:
这个算法就可以对低频的参数做较大的更新,对高频的做较小的更新,也因此,对于稀疏的数据它的表现很好,很好地提高了 SGD 的鲁棒性
减少了学习率的手动调节
它能够对每个参数自适应不同的学习速率,对稀疏特征,得到大的学习更新,对非稀疏特征,得到较小的学习更新,因此该优化算法适合处理稀疏特征数据。
Adagrad主要优势在于它能够为每个参数自适应不同的学习速率,而一般的人工都是设定为0.01。

2)缺点:
它的缺点是分母会不断积累,这样学习率就会收缩并最终会变得非常小。
其缺点在于需要计算参数梯度序列平方和,并且学习速率趋势是不断衰减最终达到一个非常小的值。

3)超参数设定值:一般η选取0.01

7、Adadelta

这个算法是对 Adagrad 的改进,和 Adagrad 相比,就是分母的 G 换成了过去的梯度平方的衰减平均值,指数衰减平均值.
这个分母相当于梯度的均方根 root mean squared (RMS),在数据统计分析中,将所有值平方求和,求其均值,再开平方,就得到均方根值
超参数设定值: γ 一般设定为 0.9

8、RMSprop

RMSprop 是 Geoff Hinton 提出的一种自适应学习率方法。
RMSprop 和 Adadelta 都是为了解决 Adagrad 学习率急剧下降问题的,

梯度更新规则:
RMSprop 与 Adadelta 的第一种形式相同:
(使用的是指数加权平均,旨在消除梯度下降中的摆动,与Momentum的效果一样,某一维度的导数比较大,则指数加权平均就大,
某一维度的导数比较小,则其指数加权平均就小,这样就保证了各维度导数都在一个量级,进而减少了摆动。允许使用一个更大的学习率η)

超参数设定值:
Hinton 建议设定 γ 为 0.9, 学习率 η 为 0.001。

9、Adam:Adaptive Moment Estimation

这个算法是另一种计算每个参数的自适应学习率的方法。相当于 RMSprop + Momentum
超参数设定值:
建议 β1 = 0.9,β2 = 0.999,ϵ = 10e−8
实践表明,Adam 比其他适应性学习方法效果要好。

10、SGD优化方法

1)并行优化
Hogwild:
并行SGD方法。该方法在多个CPU时间进行并行。处理器通过共享内存来访问参数,并且这些参数不进行加锁。
它为每一个cpu分配不重叠的一部分参数(分配互斥),每个cpu只更新其负责的参数。
该方法只适合处理数据特征是稀疏的。该方法几乎可以达到一个最优的收敛速度,因为cpu之间不会进行相同信息重写。

Downpour SGD:
在DistBelief(Google TensorFlow的前身)使用的SGD的一个异步变种。
它在训练子集上训练同时多个模型副本。这些副本将各自的更新发送到参数服务器(PS,parameter server),
每个参数服务器只更新互斥的一部分参数,副本之间不会进行通信。因此可能会导致参数发散而不利于收敛。

Delay-tolerant Algorithms for SGD:
扩展AdaGrad,通过开发延迟容忍算法(delay-tolerant algorithms),该算法不仅自适应过去梯度,并且会更新延迟。该方法已经在实践中表明是有效的。

TensorFlow
TensorFlow是Google开源的一个大规模机器学习库,它的前身是DistBelief。
它已经在大量移动设备上或者大规模分布式集群中使用了,已经经过了实践检验。
其分布式实现是基于图计算,它将图分割成多个子图,每个计算实体作为图中的一个计算节点,他们通过Rend/Receive来进行通信。

Elastic Averaging SGD(EASGD)
它通过一个elastic force(存储参数的参数服务器中心)来连接每个work来进行参数异步更新。

2)更多的SGD优化策略
Shuffling and Curriculum Learning:
为了使得学习过程更加无偏,应该在每次迭代中随机打乱训练集中的样本。
另一方面,在很多情况下,我们是逐步解决问题的,而将训练集按照某个有意义的顺序排列会提高模型的性能和SGD的收敛性,如何将训练集建立一个有意义的排列被称为Curriculum Learning[16]。
Zaremba与Sutskever在使用Curriculum Learning来训练LSTMs以解决一些简单的问题中,表明一个相结合的策略或者混合策略比对训练集按照按照训练难度进行递增排序要好。

Batch normalization
为了方便训练,我们通常会对参数按照0均值1方差进行初始化,随着不断训练,参数得到不同程度的更新,这样这些参数会失去0均值1方差的分布属性,
这样会降低训练速度和放大参数变化随着网络结构的加深。
Batch normalization在每次mini-batch反向传播之后重新对参数进行0均值1方差标准化。
这样可以使用更大的学习速率,以及花费更少的精力在参数初始化点上。Batch normalization充当着正则化、减少甚至消除掉Dropout的必要性。

Early stopping
在验证集上如果连续的多次迭代过程中损失函数不再显著地降低,那么应该提前结束训练,详细参见NIPS 2015 Tutorial slides,或者参见防止过拟合的一些方法。

Gradient noise
Gradient noise[21]即在每次迭代计算梯度中加上一个高斯分布N(0,σ2t)的随机误差,即gt,i=gt,i+N(0,σ2t)
高斯误差的方差需要进行退火:σ2t=η(1+t)γ
对梯度增加随机误差会增加模型的鲁棒性,即使初始参数值选择地不好,并适合对特别深层次的负责的网络进行训练。
其原因在于增加随机噪声会有更多的可能性跳过局部极值点并去寻找一个更好的局部极值点,这种可能性在深层次的网络中更常见。
10}

三算法对比、选择算法
1、SGD、Adagrad、Adadelta、RMSprop、Adam、momentum选择

如果数据是稀疏的,就用自适用方法,即 Adagrad, Adadelta, RMSprop, Adam。
RMSprop, Adadelta, Adam 在很多情况下的效果是相似的。
Adam 就是在 RMSprop 的基础上加了 bias-correction 和 momentum,
随着梯度变的稀疏,Adam 比 RMSprop 效果会好。
整体来讲,Adam 是最好的选择。
很多论文里都会用 SGD,没有 momentum 等。SGD 虽然能达到极小值,但是比其它算法用的时间长,而且可能会被困在鞍点。
如果需要更快的收敛,或者是训练更深更复杂的神经网络,需要用一种自适应的算法。

2、SGD、BGD、Mini-BGD

这三种梯度下降算法,它们不同之处在于每次学习(更新模型参数)使用的样本个数,每次更新使用不同的样本会导致每次学习的准确性和学习时间不同。mini-batch梯度下降是使用最广泛的。

你可能感兴趣的:(AI)