本文介绍常见的一阶数值优化算法,这些方法在现代神经网络框架(tensorflow, caffe, torch)中已经是标准配置。
问题
设系统参数为
ω
。对于样本
i
,其代价函数为
Qi(ω)
。在n个样本组成的训练集上,其整体代价函数为:
要求 ω 使得上式最小,由于没有闭式解,需要通过近似迭代逐步逼近。
基础一阶优化
GD
GD
(Gradient Descent)以
η
为学习率,在每次迭代中用一阶泰勒展开近似:
将求和与梯度互换。GD方法的增量来源于对所有样本同时求梯度之和:
设 ω 的维度为D,代价函数 Q 是个标量,减号后的梯度也是一个D维向量。
SGD
SGD
(Stochastic Gradient Descent)在每次迭代中,顺次使用每个样本的梯度,更新参数:
for i=1 to n
一种折衷的方法是,把m个样本组成一个mini-batch,使用mini-batch的总梯度更新参数:
for i=1 to n/m
其中 Qij(ω) 为第i个minibatch中第j个样本的代价。
为书写简便,以下说明中不再出现样本序号i。 ?Q(ω) 可以指一个样本、一个mini-batch或者全部样本的梯度只和。
更快的一阶优化
这些方法都以GD
为基础,但收敛速度更快,换句话说
?t
更小。
关于收敛速度的意义,请参看这篇博客。
ASGD
ASGD
(Average Stochastic Gradient Descent)选择一个迭代的时间点(代数)
t0
,在这个时间点之前,和SGD
一样:
在这个时间点之后,使用
t0
到当前时刻
t
的平均值:
AdaGrad
AdaGrad
1(Adaptive Gradient)方法对参数的每一维进行归一化,使用的分母是之前步骤中该维度的平方和:
相当于 为每一维参数设定了不同的学习率 :压制常常变化的参数,突出稀缺的更新。能够更有效地利用少量有意义样本。
AdaDelta
AdaDelta
2(Adaptive Delta)和AdaGrad
一样为每一维参数设定不同学习率,但是不用再设定基础学习率
η
。
首先维护一个期望D,描述之前迭代中的参数变化情况,同样是个D维向量:
另一个期望G,描述之前迭代中的梯度的平方:
使用D和G的比值作为权重,分别归一化每一维参数:
减号后的归一化参数决定了:单位梯度变化对应多少参数变化。
Adam
Adam
3(Adaptive Moment Estimation)的思路和AdaGrad
相似,都使用梯度平方根归一化学习率。
注意:为书写简便,后续的矩阵相乘相除都逐元素进行,更新也对参数每一维单独进行。
维护一个一阶momentum,等价于梯度:
另一个二阶momentum,等价于梯度平方:
由于
m,v
都初始化为0,使用t次幂让其在头几次迭代中更大一些:
使用梯度平方
v
归一化学习率,更新幅度为梯度
m
:
Rprop
RProp
4(Resilient Propagation)比较本次梯度
?Q(ω)dt+1
和上次梯度
?Q(ω)dt
符号变化来为参数d的变化加权。
如果两次梯度符号相反,则抑制参数变化(
η?<1
):
如果两次符号相同,则增强参数变化(
η+>1
):
RMSprop
RMSprop
5(Root Mean Square Propagation)类似于简化版的AdaDelta,但是是独立发展而来的。
维护期望G,描述之前迭代中的梯度的平方:
用G修正学习率:
NAG
NAG
6(Nesterov’s Accelerated Gradient),发明者是毛国数学家Yurii Nesterov。
参数变化由
γ
控制:
导数的计算点不再是当前参数 ω ,而是从当前参数根据前次变化前进一小步。
用
mt
更新参数:
总结
提速可以归纳为以下几个方面:
- 使用momentum来保持前进方向(velocity);
- 为每一维参数设定不同的学习率:在梯度连续性强的方向上加速前进;
- 用历史迭代的平均值归一化学习率:突出稀有的梯度;
辨:其他优化方法
共轭梯度法(Conjugate Gradient)也是一阶方法,针对特殊形式的代价函数:
常见的各种牛顿法, L-BFGS核心都是二阶优化方法,利用了代价函数的Hessian矩阵:
换句话说,牛顿法用线性函数拟合代价函数的导数,而不是代价函数本身。
具体的一阶优化方法:
BGD
即batch gradient descent. 在训练中,每一步迭代都使用训练集的所有内容. 也就是说,利用现有参数对训练集中的每一个输入生成一个估计输出 yi^ ,然后跟实际输出 yi 比较,统计所有误差,求平均以后得到平均误差,以此来作为更新参数的依据.
具体实现:
需要:学习速率
ϵ
, 初始参数
θ
每步迭代过程:
1. 提取训练集中的所有内容
{x1,…,xn}
,以及相关的输出
yi
2. 计算梯度和误差并更新参数:
优点:
由于每一步都利用了训练集中的所有数据,因此当损失函数达到最小值以后,能够保证此时计算出的梯度为0,换句话说,就是能够收敛.因此,使用BGD时不需要逐渐减小学习速率
ϵk
缺点:
由于每一步都要使用所有数据,因此随着数据集的增大,运行速度会越来越慢.
SGD
SGD全名 stochastic gradient descent, 即随机梯度下降。不过这里的SGD其实跟MBGD(minibatch gradient descent)是一个意思,即随机抽取一批样本,以此为根据来更新参数.
具体实现:
需要:学习速率
ϵ
, 初始参数
θ
每步迭代过程:
1. 从训练集中的随机抽取一批容量为m的样本
{x1,…,xm}
,以及相关的输出
yi
2. 计算梯度和误差并更新参数:
优点:
训练速度快,对于很大的数据集,也能够以较快的速度收敛.
缺点:
由于是抽取,因此不可避免的,得到的梯度肯定有误差.因此学习速率需要逐渐减小.否则模型无法收敛
因为误差,所以每一次迭代的梯度受抽样的影响比较大,也就是说梯度含有比较大的噪声,不能很好的反映真实梯度.
学习速率该如何调整:
那么这样一来,
ϵ
如何衰减就成了问题.如果要保证SGD收敛,应该满足如下两个要求:
而在实际操作中,一般是进行线性衰减:
其中 ϵ0 是初始学习率, ϵτ 是最后一次迭代的学习率. τ 自然代表迭代次数.一般来说, ϵτ 设为 ϵ0 的1%比较合适.而 τ 一般设为让训练集中的每个数据都输入模型上百次比较合适 .那么初始学习率 ϵ0 怎么设置呢?书上说,你 先用固定的学习速率迭代100次,找出效果最好的学习速率,然后 ϵ0 设为比它大一点就可以了.
Momentum
上面的SGD有个问题,就是每次迭代计算的梯度含有比较大的噪音. 而Momentum方法可以比较好的缓解这个问题,尤其是在面对小而连续的梯度但是含有很多噪声的时候,可以很好的加速学习.Momentum借用了物理中的动量概念,即前几次的梯度也会参与运算.为了表示动量,引入了一个新的变量v(velocity).v是之前的梯度的累加,但是每回合都有一定的衰减.
具体实现:
需要:学习速率
ϵ
, 初始参数
θ
, 初始速率v, 动量衰减参数
α
每步迭代过程:
1. 从训练集中的随机抽取一批容量为m的样本
{x1,…,xm}
,以及相关的输出
yi
2. 计算梯度和误差,并更新速度v和参数
θ
:
其中参数
α
表示每回合速率v的衰减程度.同时也可以推断得到,如果每次迭代得到的梯度都是g,那么最后得到的v的稳定值为
也就是说,Momentum最好情况下能够将学习速率加速 11−α 倍.一般 α 的取值有0.5,0.9,0.99这几种.当然,也可以让 α 的值随着时间而变化,一开始小点,后来再加大.不过这样一来,又会引进新的参数.
特点:
前后梯度方向一致时,能够加速学习
前后梯度方向不一致时,能够抑制震荡
Nesterov Momentum
这是对之前的Momentum的一种改进,大概思路就是,先对参数进行估计,然后使用估计后的参数来计算误差
具体实现:
需要:学习速率
ϵ
, 初始参数
θ
, 初始速率v, 动量衰减参数
α
每步迭代过程:
1. 从训练集中的随机抽取一批容量为m的样本
{x1,…,xm}
,以及相关的输出
yi
2. 计算梯度和误差,并更新速度v和参数
θ
:
注意在估算 g^ 的时候,参数变成了 θ+αv 而不是之前的 θ
AdaGrad
AdaGrad可以自动变更学习速率,只是需要设定一个全局的学习速率
ϵ
,但是这并非是实际学习速率,实际的速率是与以往参数的模之和的开方成反比的.也许说起来有点绕口,不过用公式来表示就直白的多:
其中 δ 是一个很小的常亮,大概在 10−7 ,防止出现除以0的情况.
具体实现:
需要:全局学习速率
ϵ
, 初始参数
θ
, 数值稳定量
δ
中间变量: 梯度累计量r(初始化为0)
每步迭代过程:
1. 从训练集中的随机抽取一批容量为m的样本
{x1,…,xm}
,以及相关的输出
yi
2. 计算梯度和误差,更新r,再根据r和梯度计算参数更新量
优点:
能够实现学习率的自动更改。如果这次梯度大,那么学习速率衰减的就快一些;如果这次梯度小,那么学习速率衰减的就满一些。
缺点:
任然要设置一个变量
ϵ
经验表明,在普通算法中也许效果不错,但在深度学习中,深度过深时会造成训练提前结束。
RMSProp
RMSProp通过引入一个衰减系数,让r每回合都衰减一定比例,类似于Momentum中的做法。
具体实现:
需要:全局学习速率
ϵ
, 初始参数
θ
, 数值稳定量
δ
,衰减速率
ρ
中间变量: 梯度累计量r(初始化为0)
每步迭代过程:
1. 从训练集中的随机抽取一批容量为m的样本
{x1,…,xm}
,以及相关的输出
yi
2. 计算梯度和误差,更新r,再根据r和梯度计算参数更新量
优点:
相比于AdaGrad,这种方法很好的解决了深度学习中过早结束的问题
适合处理非平稳目标,对于RNN效果很好
缺点:
又引入了新的超参,衰减系数
ρ
依然依赖于全局学习速率
RMSProp with Nesterov Momentum
当然,也有将RMSProp和Nesterov Momentum结合起来的
具体实现:
需要:全局学习速率
ϵ
, 初始参数
θ
, 初始速率v,动量衰减系数
α
, 梯度累计量衰减速率
ρ
中间变量: 梯度累计量r(初始化为0)
每步迭代过程:
1. 从训练集中的随机抽取一批容量为m的样本
{x1,…,xm}
,以及相关的输出
yi
2. 计算梯度和误差,更新r,再根据r和梯度计算参数更新量
Adam
Adam(Adaptive Moment Estimation)本质上是带有动量项的RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。
具体实现:
需要:步进值
ϵ
, 初始参数
θ
, 数值稳定量
δ
,一阶动量衰减系数
ρ1
, 二阶动量衰减系数
ρ2
其中几个取值一般为:
δ=10−8,ρ1=0.9,ρ2=0.999
中间变量:一阶动量s,二阶动量r,都初始化为0
每步迭代过程:
1. 从训练集中的随机抽取一批容量为m的样本
{x1,…,xm}
,以及相关的输出
yi
2. 计算梯度和误差,更新r和s,再根据r和s以及梯度计算参数更新量