新智元编译
来源:CSDN 授权转载
作者:Sebastian Ruder
译者:一只鸟的天空
【新智元导读】梯度下降算法是机器学习中使用非常广泛的优化算法,也是众多机器学习算法中最常用的优化方法。几乎当前每一个先进的(state-of-the-art)机器学习库或者深度学习库都会包括梯度下降算法的不同变种实现。但是,它们就像一个黑盒优化器,很难得到它们优缺点的实际解释。这篇文章旨在提供梯度下降算法中的不同变种的介绍,帮助使用者根据具体需要进行使用。
三种梯度下降优化框架
批量梯度下降
随机梯度下降
小批量梯度下降
问题与挑战
梯度下降优化算法
Momentum
Nesterov accelerated gradient
Adagrad
Adadelta
RMSprop
Adam
算法的可视化
选择哪种优化算法?
并行与分布式SDG
Hogwild!
Downpour SGD
Delay-tolerant Algorithms for SGD
TensorFlow
Elastic Averaging SGD
更多的SDG优化策略
训练集随机洗牌与课程学习
批规范化
Early Stopping
Gradient noise
总结
引用
批量梯度下降(Batch gradient descent)
每次使用全量的训练集样本来更新模型参数,即: θ=θ−η⋅∇θJ(θ)
epochs 是用户输入的最大迭代次数。通过上诉代码可以看出,每次使用全部训练集样本计算损失函数 loss_function 的梯度 params_grad,然后使用学习速率 learning_rate 朝着梯度相反方向去更新模型的每个参数params。一般各现有的一些机器学习库都提供了梯度计算api。如果想自己亲手写代码计算,那么需要在程序调试过程中验证梯度计算是否正确。
随机梯度下降(Stochastic gradient descent)
图1 SGD扰动
小批量梯度下降(Mini-batch gradient descent)
θ=θ−η⋅∇θJ(θ;xi:i+m;yi:i+m)
虽然梯度下降算法效果很好,并且广泛使用,但同时其也存在一些挑战与问题需要解决:
选择一个合理的学习速率很难。如果学习速率过小,则会导致收敛速度很慢。如果学习速率过大,那么其会阻碍收敛,即在极值点附近会振荡。
学习速率调整(又称学习速率调度,Learning rate schedules)[11]试图在每次更新过程中,改变学习速率,如退火。一般使用某种事先设定的策略或者在每次迭代中衰减一个较小的阈值。无论哪种调整方法,都需要事先进行固定设置,这边便无法自适应每次学习的数据集特点[10]。
模型所有的参数每次更新都是使用相同的学习速率。如果数据特征是稀疏的或者每个特征有着不同的取值统计特征与空间,那么便不能在每次更新中每个参数使用相同的学习速率,那些很少出现的特征应该使用一个相对较大的学习速率。
对于非凸目标函数,容易陷入那些次优的局部极值点中,如在神经网路中。那么如何避免呢。Dauphin[19]指出更严重的问题不是局部极值点,而是鞍点。
Nesterov accelerated gradient(NAG)
νt=γνt−1+η⋅∇θJ(θ−γνt−1),θ=θ−νt
从上图可以看出,在鞍点(saddle points)处(即某些维度上梯度为零,某些维度上梯度不为零),SGD、Momentum与NAG一直在鞍点梯度为零的方向上振荡,很难打破鞍点位置的对称性;Adagrad、RMSprop与Adadelta能够很快地向梯度不为零的方向上转移。
Hogwild
Niu[23]提出了被称为Hogwild的并行SGD方法。该方法在多个CPU时间进行并行。处理器通过共享内存来访问参数,并且这些参数不进行加锁。它为每一个cpu分配不重叠的一部分参数(分配互斥),每个cpu只更新其负责的参数。该方法只适合处理数据特征是稀疏的。该方法几乎可以达到一个最优的收敛速度,因为cpu之间不会进行相同信息重写。
Downpour SGD
Downpour SGD是Dean[4]提出的在DistBelief(Google TensorFlow的前身)使用的SGD的一个异步变种。它在训练子集上训练同时多个模型副本。这些副本将各自的更新发送到参数服务器(PS,parameter server),每个参数服务器只更新互斥的一部分参数,副本之间不会进行通信。因此可能会导致参数发散而不利于收敛。
Delay-tolerant Algorithms for SGD
McMahan与Streeter[12]扩展AdaGrad,通过开发延迟容忍算法(delay-tolerant algorithms),该算法不仅自适应过去梯度,并且会更新延迟。该方法已经在实践中表明是有效的。
TensorFlow
TensorFlow[13]是Google开源的一个大规模机器学习库,它的前身是DistBelief。它已经在大量移动设备上或者大规模分布式集群中使用了,已经经过了实践检验。其分布式实现是基于图计算,它将图分割成多个子图,每个计算实体作为图中的一个计算节点,他们通过Rend/Receive来进行通信。
Elastic Averaging SGD
Zhang等[14]提出Elastic Averaging SGD(EASGD),它通过一个elastic force(存储参数的参数服务器中心)来连接每个work来进行参数异步更新。
Shuffling and Curriculum Learning
为了使得学习过程更加无偏,应该在每次迭代中随机打乱训练集中的样本。
另一方面,在很多情况下,我们是逐步解决问题的,而将训练集按照某个有意义的顺序排列会提高模型的性能和SGD的收敛性,如何将训练集建立一个有意义的排列被称为Curriculum Learning[16]。
Zaremba与Sutskever[17]在使用Curriculum Learning来训练LSTMs以解决一些简单的问题中,表明一个相结合的策略或者混合策略比对训练集按照按照训练难度进行递增排序要好。
Batch normalization
为了方便训练,我们通常会对参数按照0均值1方差进行初始化,随着不断训练,参数得到不同程度的更新,这样这些参数会失去0均值1方差的分布属性,这样会降低训练速度和放大参数变化随着网络结构的加深。
Batch normalization[18]在每次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)γ
对梯度增加随机误差会增加模型的鲁棒性,即使初始参数值选择地不好,并适合对特别深层次的负责的网络进行训练。其原因在于增加随机噪声会有更多的可能性跳过局部极值点并去寻找一个更好的局部极值点,这种可能性在深层次的网络中更常见。
本文译文授权转载自CSDN
由于微信文章字数限制,本文未列出全部参考文献,请戳原文查看。
原文链接:http://sebastianruder.com/optimizing-gradient-descent/index.html
3月27日,新智元开源·生态AI技术峰会暨新智元2017创业大赛颁奖盛典隆重召开,包括“BAT”在内的中国主流 AI 公司、600多名行业精英齐聚,共同为2017中国人工智能的发展画上了浓墨重彩的一笔。
文字实录:新智元“春节”引爆AI原力,群星纵论中国AI大棋局
访问以下链接,回顾大会盛况: