2019-12-02 13:48:53 ly18846826264 阅读数 21
  • 玩转深度学习实战教程

    玩转深度学习视频培训课程,详细讲解深度学习的原理和利用深度学习框架TensorFlow进行项目实战。课程通过Kaggle竞赛平台的Titanic问题讲解TensorFlow的基本用法以及问题处理的常用技巧,讲解深度学习图像领域的卷积神经网络CNN和多个经典的网络架构、CNN的应用,讲解自然语言处理领域的RNN、LSTM以及它们的多种变种结构,构建语言模型和对话机器人,介绍损失函数和优化深度学习算法在TensorFlow中的实现。

    2840 人正在学习 去看看 王而川

Optimizer in Deep Learning

0-关于优化的基础

神经网络可以简单地看成是找一个很好的非线性函数来进行端到端的映射,开始时先给了一个初始化(权重以及偏置),通过不断最小化损失函数,对神经网络这个函数来进行更新。由于激励函数的存在(sigmoid、 tanh、relu),这个函数是一个非线性的,于是优化问题就是非线性优化问题,目前还没有通用的解法来求解。

  • 梯度下降
    目前对于无约束优化问题最简单有效的当属梯度下降法,设输入x=(x1,x2,x3,,xn)Tx = (x_1,x_2, x_3, \cdots, x_n)^T,对函数f(x)f(x),定义函数的梯度为
    xf(x)=(f(x)x1,f(x)x2,,f(x)x3,,f(x)xn,)T\nabla _x f(x) = ( \frac{\partial f(x)}{\partial x_1}, \frac{\partial f(x)}{\partial x_2},, \frac{\partial f(x)}{\partial x_3}, \cdots, \frac{\partial f(x)}{\partial x_n},)^T

f(x)f(x)沿方向uu的方向导数定义为αf(x+αu)\frac{\partial }{\partial \alpha} f(x+\alpha u),通过链式法则,可以写成uTxf(x)u^T\nabla _xf(x)

为了最优化f(x)f(x),我们的目标是找一个方向使得函数减小的最快,即
minuuTxf(x)s.t.   u2=1\min \limits _u u^T\nabla _xf(x) \\ s.t. \ \ \ ||u||_2=1最小的值是一个向量内积形式,于是假设二者夹角为θ\theta,则上述问题等价于u2xf(x)2cosθ||u||_2||\nabla _xf(x)||_2 \cos\theta,
考虑到u2=1||u||_2=1,且梯度的大小与夹角无关,于是问题就成了
minθcosθ\min \limits _\theta\cos \theta答案肯定是θ=π\theta = \pi,也即是说uu的方向是沿着与梯度相反的方向。
得出结论:梯度的方向是函数值增加最快的方向,梯度值的反方向是函数值减小最快的方向。

梯度下降法就是不断迭代,每次沿着梯度方向前进一点,直到梯度的值等于0或在某个允许的范围内。

方向有了,但前进多少呢?这就是关于学习率(或者称为步长)的选择问题。

  1. 固定长度的η\eta
  2. 线性搜索:给定多个η\eta,选择使得更新后的函数值最小的那个
  3. 最速下降法:这个学习率的选取直接影响了学习的快慢与效果,它满足η=argminηf(xηxf(x))\eta = \arg \min \limits _\eta f(x-\eta \nabla_xf(x))于是就继续求解子优化问题

在这里插入图片描述

  • 海森矩阵
    一阶导数反映斜率,二阶导数反映曲率。
    在这里插入图片描述
    上图说明,同样在梯度是1的情况下,步长选择η\eta,二阶导为负时,实际走得更多,二阶导为正时,实际走的更少。所以,好的优化是需要考虑二阶导数的。

当输入是多维时,就有了海森矩阵Hi,j=2xixjf(x)H_{i,j} = \frac{\partial^2}{\partial x_i \partial x_j}f(x)

考虑二阶导之后,就有牛顿法、拟牛顿法等有效算法,但在深度学习中用得不多,这里留待以后补充。

1-梯度下降法

主要有三种常用算法:随机梯度下降(SGD, Stochastic Gradient Descent)、Mini-批处理梯度下降(Mini-Batch Gradient Descent)和批处理梯度下降(BGD, Batch Gradient Descent),三者的区别在于神经网络前向计算时使用了多少样本,分别对应单个样本、部分样本和全部样本。

梯度下降算法:

输入:学习率η\eta,初始参数θ\theta
迭代,直到满足条件
1、从训练集随机抽取m个(m对应一个、一部分或所有),对应标签为{y1,y2,,ym}\{ y_1, y_2, \cdots,y_m\}
2、计算梯度g1mi=1mθL(f(xi;θ),yi)g \leftarrow \frac{1}{m}\sum\limits _{i=1}^m \nabla _\theta L(f(x_i;\theta), y_i)3、更新参数:θθηg\theta \leftarrow \theta - \eta g

  • 使用随机梯度下降会引入噪声,即单个样本的梯度不一定是整个训练集的梯度方向,所以它的更新曲线更加曲折,但已经证明,只要噪声不是特别大也能很好的收敛;且对于大型数据集,速度更快
  • 使用Mini-Batch是的Batch大小很重要,太大和太小都不好,需要调到比较合适;它每次更新用到了多个样本,所以能有效降低参数更新时的方差,且用到了矩阵操作,Mini-Batch用到的最多
  • 批处理抗噪能力最好,但训练速度慢,容易陷入局部最优解

2-动量(Momentum)方法

使用梯度下降算法的缺点时,虽然每次的方向找对了(梯度方向),但是不知道该迈多大的步子(学习率η\eta),比如在曲率很小的时候可以大胆向前走,而在曲率很复杂时需要慢点走,这样即使在接近最优值时,也不会学习率固定导致收敛变慢。

在这里插入图片描述

于是动量方法就通过类比物理中位移、速度、加速度关系,将算出的梯度视为加速度,然后更新速度v,最后由v来更新参数,多了一步v的缓存过程。这里简单推导(本身就是种类比,不需要太计较物理意义):

θ\theta为位移,LL是损失函数,也是势能,于是力F=ηθL(f(x;θ),y)F = -\eta \nabla _\theta L(f(x;\theta),y),根据动量定理
FΔt=Δ(m×v)F\Delta t = \Delta(m \times v)设作用时间和质量均为单位值,于是有F=ΔvF = \Delta v,即ηθL=vtv0- \eta \nabla _\theta L = v_t-v_0,对速度加一个衰减系数α\alpha,则有vαvηθLv \leftarrow \alpha v - \eta \nabla _\theta L这段时间的位移增量vΔt=vv\Delta t = v,这里考虑段时间内的速度变化不大,所以使用了初始速率,当然也可以用更新后的速率,因此有位移公式θ=θ+v\theta = \theta + v使用动量的SGD算法:

输入:学习率η\eta,初始参数θ\theta,初始速度vv,速度衰减参数α\alpha
迭代,直到算法停止
1、从训练集中随机采样m个样本(一个、一部分或全部),对应标签为{y1,y2,,ym}\{ y_1, y_2, \cdots,y_m\}
2、计算梯度g1mi=1mθL(f(xi;θ),yi)g \leftarrow \frac{1}{m}\sum\limits _{i=1}^m \nabla _\theta L(f(x_i;\theta), y_i)3、更新速度:vαv+ηgv \leftarrow \alpha v + \eta g
4、更新参数:θ=θ+v\theta = \theta + v

为什么有效:

  • 在曲率变化较小的地方,应该大胆更新使劲走,SGD会走固定的步长,而加入Momentum之后,前一时刻的梯度存在v中,因为曲率变化不大,所以v的新加的值与上个时刻的v的方向基本相同,因此不怎么抵消,所以能使劲走;
  • 而在曲率变化大的地方,上个时刻v与现在的梯度方向可能不太一样,所以对θ\theta的更新就会通过二者的垂直分量不断抵销使得走的步子小了(当然方向也会有所折中)。

在这里插入图片描述

3-牛顿动量

也称作Nesterov Accelerated Gradient(NGA)Nesterov\ Accelerated\ Gradient(NGA),是Momentum的变种,区别在于计算梯度时使用不是上一时刻的θ\theta,而是更新后的θ+αv\theta+\alpha v
vαvηθJ(θ+αv)θθ+vv \leftarrow \alpha v- \eta \nabla _\theta J(\theta+\alpha v)\\ \theta \leftarrow \theta+v关键之处就在于计算的梯度,相当于加了矫正因子,也就是作用力超前一步知道作用的方向,这样可以防止走得过快,刹不住,同时也减小了震荡。

在这里插入图片描述

4-AdaGrad

我们希望在学习过程中,梯度长大了,要学会自适应步长。该方法的思想是:参数空间每个方向的学习率反比于该方向上梯度分量所有历史平方值之和的平方根。

  • 学习率是个正的,用平方和的平均值而不是平均是怕算出来某个分量为负
  • 用历史之和是因为要看平时表现,不能看一次半次的

AdaGrad算法:

输入学习率η\eta,初始参数θ\theta,足够小的常数δ\delta(防止0做除数时无法计算)
初始化梯度累计变量rr
迭代,直到停止条件
1、从训练集中随机采样m个样,对应标签为{y1,y2,,ym}\{ y_1, y_2, \cdots,y_m\}
2、计算梯度g1mi=1mθL(f(xi;θ),yi)g \leftarrow \frac{1}{m}\sum\limits _{i=1}^m \nabla _\theta L(f(x_i;\theta), y_i)3、计算累计平方梯度:rr+ggr \leftarrow r+ g \odot g
4、更新参数:θθηδ+rg\theta \leftarrow \theta - \frac{\eta}{\delta+\sqrt{r}}\odot g

用这个算法的一个问题就是学习率早期降的太快,到了后期,可能还没到最优值,学习率已经没了。

5-RMSProp

看来用梯度历史的平方和有点问题,老了学不动了,所以将求和改成了指数加权的移动平均。

RMSProp算法:

输入学习率η\eta,初始参数θ\theta,衰减速率ρ\rho,足够小的常数δ\delta(防止0做除数时无法计算)
初始化梯度累计变量rr
迭代,直到停止条件
1、从训练集中随机采样m个样,对应标签为{y1,y2,,ym}\{ y_1, y_2, \cdots,y_m\}
2、计算梯度g1mi=1mθL(f(xi;θ),yi)g \leftarrow \frac{1}{m}\sum\limits _{i=1}^m \nabla _\theta L(f(x_i;\theta), y_i)3、计算平方梯度:rρr+(1ρ)ggr \leftarrow \rho r+ (1-\rho)g \odot g
4、更新参数:θθηδ+rg\theta \leftarrow \theta - \frac{\eta}{\delta+\sqrt{r}}\odot g

5.1 为何这样改动有效

为什么改动这么点效果就好了呢?我们假设更新过程中梯度是个固定值c=ggc=g\odot g

  • RMSProp算法:
    其经过τ\tau次计算后,平方梯度的系数为r=c(1ρτ)r=c(1-\rho^\tau),参数的更新大小为ηδ+1ρτ\frac{\eta}{\delta + \sqrt{1-\rho^\tau}}
  • AdaGrad算法:
    经过τ\tau次计算后,平方梯度的系数为r=τcr = \tau c,参数的更新大小为etaδ+τ\frac{eta}{\delta + \sqrt{\tau}}

二者都与迭代次数有关,初始时刻二者更新均较大,经过一定次数迭代后,不管此时梯度值大小,RMSProp算法的更新依然能保持较大(η\eta),而AdaGrad已经接近0。

5.2 RMSProp动量算法

RMSPRP目的是自适应学习率,而动量是为了更新参数,二者不冲突,因此可以结合。

RMSProp-Momentum算法:

输入学习率η\eta,初始参数θ\theta,衰减速率ρ\rho,动量系数α\alpha,初始速度vv
初始化梯度累计变量rr
迭代,直到停止条件
1、从训练集中随机采样m个样,对应标签为{y1,y2,,ym}\{ y_1, y_2, \cdots,y_m\}
2、向前一步走:θ=θ+αv\theta = \theta + \alpha v
3、计算梯度g1mi=1mθL(f(xi;θ),yi)g \leftarrow \frac{1}{m}\sum\limits _{i=1}^m \nabla _\theta L(f(x_i;\theta), y_i)3、计算平方梯度:rρr+(1ρ)ggr \leftarrow \rho r+ (1-\rho)g \odot g
4、更新速度:vαvηrgv \leftarrow \alpha v - \frac{\eta}{\sqrt{r}}\odot g
5、更新参数:θθ+v\theta \leftarrow \theta +v

6-Adam

adam除了引入自适应学习率,还引入了自适应动量,是目前最常用的优化算法。

Adam算法:

输入学习率η\eta,初始参数θ\theta,矩估计的指数衰减速率ρ1\rho_1ρ2\rho_2,默认值为0.9和0.999,小常数δ\delta
初始化一阶矩和二阶矩srs、r
初始化时间步t=0t=0
迭代,直到停止条件
1、从训练集中随机采样m个样,对应标签为{y1,y2,,ym}\{ y_1, y_2, \cdots,y_m\}
2、计算梯度g1mi=1mθL(f(xi;θ),yi)g \leftarrow \frac{1}{m}\sum\limits _{i=1}^m \nabla _\theta L(f(x_i;\theta), y_i)3、更新时间:tt+1t \leftarrow t+1
4、更新一阶矩估计(梯度指数加权平均,更新梯度):sρ1s+(1ρ1)gs \leftarrow \rho_1 s+ (1-\rho_1)g
5、更新二阶矩估计(梯度平方指数加权平均,更新学习率):rρ2r+(1ρ2)ggr \leftarrow \rho_2 r+ (1-\rho_2)g \odot g
6、修正一阶矩的偏差(剔除时间的影响):ss1ρ1ts \leftarrow \frac{s}{1-\rho_1^t}
7、修正二阶矩的偏差(剔除时间的影响):rr1ρ2tr \leftarrow \frac{r}{1-\rho_2^t}
8、更新参数:θθηr+δs\theta \leftarrow \theta -\frac{\eta}{\sqrt{r}+\delta}s

7-RAdam

使用Adam算法,在训练初期,学习率的方差很大,因此有必要针对自适应的学习率,显式修正其方差,使得训练初期也能够使方差稳定。(没细看,不要问,问就王富贵)

RAdam算法:

输入学习率η\eta,初始参数θ\theta,矩估计的指数衰减速率ρ1\rho_1ρ2\rho_2,近似指数ρ\rho_\infty
初始化一阶矩和二阶矩srs、r,初始化加权平均长度ρ21ρ21\rho \leftarrow \frac{2}{1-\rho_2}-1
初始化时间步t=0t=0
迭代,直到停止条件
1、从训练集中随机采样m个样,对应标签为{y1,y2,,ym}\{ y_1, y_2, \cdots,y_m\}
2、计算梯度g1mi=1mθL(f(xi;θ),yi)g \leftarrow \frac{1}{m}\sum\limits _{i=1}^m \nabla _\theta L(f(x_i;\theta), y_i)3、更新时间:tt+1t \leftarrow t+1
4、更新一阶矩估计(梯度指数加权平均,更新梯度):sρ1s+(1ρ1)gs \leftarrow \rho_1 s+ (1-\rho_1)g
5、更新二阶矩估计(梯度平方指数加权平均,更新学习率):rρ2r+(1ρ2)ggr \leftarrow \rho_2 r+ (1-\rho_2)g \odot g
6、修正一阶矩的偏差(剔除时间的影响):ss1ρ1ts \leftarrow \frac{s}{1-\rho_1^t}
7、计算t时刻近似指数加权平均长度:ρρ2tρ2t1ρ2t\rho \leftarrow \rho_\infty - \frac{2t\rho_2^t}{1-\rho_2^t}
8、if ρ<4\rho<4θθηs\theta \leftarrow \theta -\eta s
elserr1ρ2tp(ρ4)(ρ2)ρ(ρ4)(ρ2)ρθθηr+δsr\leftarrow \sqrt{\frac{r}{1-\rho_2^t}}\\ p \leftarrow \sqrt{\frac{(\rho-4)(\rho -2)\rho_\infty}{(\rho_\infty-4)(\rho_\infty-2)\rho}}\\ \theta \leftarrow \theta -\frac{\eta}{\sqrt{r}+\delta}s

8-Lookahead

lookahead不同于已有的优化算法,它使用了两组权重,与其说其是一种优化算法,我觉得更像是交叉应用。基本思想就是下象棋时候的“走一步看k步”,求出了一次梯度不也是更新一点吗?那我就先不更新,看看你再求几步是什么情况。

但是看似每次没用梯度值,那还是没少算呀?这叫“磨刀不误砍柴工”,就是说虽然这k次没少算,但最后到的点与k次计算的点是不一样的,虽然没有避免计算这k次,但避免了因为使用k次结果所在点继续往下走可能的徘徊(步履蹒跚走一些于整体无用的路);其次,使用k次计算点作为更新方向,最终到的点可能是使用梯度下降一辈子都不会探索的区域,就很有可能越过局部极值点。

官方名称里称这k步计算的权值为快权重,最终使用的是慢权重,计算快权重使用的优化器A可以是SGD、Adam任何一种。

在这里插入图片描述

lookahead算法:

输入初始化参数θ\thetaϕ\phi,同步周期数kk,学习率η\eta,优化器A(任何一个之前介绍的优化器)
迭代,直到停止条件
1、同步参数:θϕ\theta \leftarrow \phi
2、k次循环:θθ+A\theta \leftarrow \theta + A
3、用第k次结果更新:ϕϕ+η(θϕ)\phi \leftarrow \phi + \eta (\theta-\phi)

参考

[1] 数值计算
[2] 优化器
[3] 机器学习:各种优化器的总结与比较
[4] 深度学习最全优化方法总结比较
[5] 代码仿真

2018-03-15 17:24:29 u013498583 阅读数 278
  • 玩转深度学习实战教程

    玩转深度学习视频培训课程,详细讲解深度学习的原理和利用深度学习框架TensorFlow进行项目实战。课程通过Kaggle竞赛平台的Titanic问题讲解TensorFlow的基本用法以及问题处理的常用技巧,讲解深度学习图像领域的卷积神经网络CNN和多个经典的网络架构、CNN的应用,讲解自然语言处理领域的RNN、LSTM以及它们的多种变种结构,构建语言模型和对话机器人,介绍损失函数和优化深度学习算法在TensorFlow中的实现。

    2840 人正在学习 去看看 王而川

深度学习最全优化方法总结比较(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)

转载自:https://zhuanlan.zhihu.com/p/22252270

SGD
此处的SGD指mini-batch gradient descent,关于batch gradient descent, stochastic gradient descent, 以及 mini-batch gradient descent的具体区别就不细说了。现在的SGD一般都指mini-batch gradient descent。

SGD就是每一次迭代计算mini-batch的梯度,然后对参数进行更新,是最常见的优化方法了。即:

gt=θt1f(θt1)

Δθt=ηgt

其中,η是学习率,gt是梯度

SGD完全依赖于当前batch的梯度,所以\eta可理解为允许当前batch的梯度多大程度影响参数更新

缺点:(正因为有这些缺点才让这么多大神发展出了后续的各种算法)

选择合适的learning rate比较困难
- 对所有的参数更新使用同样的learning rate。对于稀疏数据或者特征,有时我们可能想更新快一些对于不经常出现的特征,对于常出现的特征更新慢一些,这时候SGD就不太能满足要求了

SGD容易收敛到局部最优,并且在某些情况下可能被困在鞍点【原来写的是“容易困于鞍点”,经查阅论文发现,其实在合适的初始化和step size的情况下,鞍点的影响并没这么大。感谢@冰橙的指正】

Momentum
momentum是模拟物理里动量的概念,积累之前的动量来替代真正的梯度。公式如下:

mt=μmt1+gt

Δθt=ηmt

其中,μ是动量因子

特点:

下降初期时,使用上一次参数更新,下降方向一致,乘上较大的μ能够进行很好的加速
下降中后期时,在局部最小值来回震荡的时候,gradient0μ使得更新幅度增大,跳出陷阱
在梯度改变方向的时候,μ能够减少更新

总而言之,momentum项能够在相关方向加速SGD,抑制振荡,从而加快收敛

Nesterov
nesterov项在梯度更新时做一个校正,避免前进太快,同时提高灵敏度。
将上一节中的公式展开可得:

Δθt=ημmt1ηgt

可以看出,mt1
并没有直接改变当前梯度gt,所以Nesterov的改进就是让之前的动量直接影响当前的动量。即:

gt=θt1f(θt1ημmt1)

mt=μmt1+gt

Δθt=ηmt

所以,加上nesterov项后,梯度在大的跳跃后,进行计算对当前梯度进行校正。如下图:

这里写图片描述

momentum首先计算一个梯度(短的蓝色向量),然后在加速更新梯度的方向进行一个大的跳跃(长的蓝色向量),nesterov项首先在之前加速的梯度方向进行一个大的跳跃(棕色向量),计算梯度然后进行校正(绿色梯向量)

其实,momentum项和nesterov项都是为了使梯度更新更加灵活,对不同情况有针对性。但是,人工设置一些学习率总还是有些生硬,接下来介绍几种自适应学习率的方法

Adagrad
Adagrad其实是对学习率进行了一个约束。即:

nt=nt1+gt2

Δθt=ηnt+ϵgt

此处,对gt从1到t进行一个递推形成一个约束项regularizer1r=1t(gr)2+ϵϵ用来保证分母非0

特点:

前期gt较小的时候, regularizer较大,能够放大梯度
后期gt较大的时候,regularizer较小,能够约束梯度
适合处理稀疏梯度

缺点:
由公式可以看出,仍依赖于人工设置一个全局学习率
η设置过大的话,会使regularizer过于敏感,对梯度的调节太大
中后期,分母上梯度平方的累加将会越来越大,使gradient\to0,使得训练提前结束

Adadelta
Adadelta是对Adagrad的扩展,最初方案依然是对学习率进行自适应约束,但是进行了计算上的简化。
Adagrad会累加之前所有的梯度平方,而Adadelta只累加固定大小的项,并且也不直接存储这些项,仅仅是近似计算对应的平均值。即:

nt=νnt1+(1ν)gt2

Δθt=ηnt+ϵgt

在此处Adadelta其实还是依赖于全局学习率的,但是作者做了一定处理,经过近似牛顿迭代法之后:

E|g2|t=ρE|g2|t1+(1ρ)gt2

Δxt=r=1t1ΔxrE|g2|t+ϵ

其中,E代表求期望。

此时,可以看出Adadelta已经不用依赖于全局学习率了。

特点:

训练初中期,加速效果不错,很快
训练后期,反复在局部最小值附近抖动

RMSprop
RMSprop可以算作Adadelta的一个特例:

ρ=0.5时,E|g2|t=ρE|g2|t1+(1ρ)gt2就变为了求梯度平方和的平均数。

如果再求根的话,就变成了RMS(均方根):

RMS|g|t=E|g2|t+ϵ
此时,这个RMS就可以作为学习率\eta的一个约束:

Δxt=ηRMS|g|tgt
特点:

其实RMSprop依然依赖于全局学习率
RMSprop算是Adagrad的一种发展,和Adadelta的变体,效果趋于二者之间
适合处理非平稳目标
- 对于RNN效果很好

Adam
Adam(Adaptive Moment Estimation)本质上是带有动量项的RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。公式如下:

mt=μmt1+(1μ)gt

nt=νnt1+(1ν)gt2

mt^=mt1μt

nt^=nt1νt

Δθt=mt^nt^+ϵη

其中,mtnt分别是对梯度的一阶矩估计和二阶矩估计,可以看作对期望E|gt|E|gt2|的估计;mt^nt^是对mtnt的校正,这样可以近似为对期望的无偏估计。
可以看出,直接对梯度的矩估计对内存没有额外的要求,而且可以根据梯度进行动态调整,而mt^nt^+ϵ对学习率形成一个动态约束,而且有明确的范围。

特点:

结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点
对内存需求较小
为不同的参数计算不同的自适应学习率
也适用于大多非凸优化
- 适用于大数据集和高维空间

Adamax
Adamax是Adam的一种变体,此方法对学习率的上限提供了一个更简单的范围。公式上的变化如下:

nt=max(νnt1,|gt|)

Δx=mt^nt+ϵη

可以看出,Adamax学习率的边界范围更简单

Nadam
Nadam类似于带有Nesterov动量项的Adam。公式如下:

gt^=gt1Πi=1tμi

mt=μtmt1+(1μt)gt

mt^=mt1Πi=1t+1μi

nt=νnt1+(1ν)gt2

nt^=nt1νtmt¯=(1μt)gt^+μt+1mt^

Δθt=ηmt¯nt^+ϵ

可以看出,Nadam对学习率有了更强的约束,同时对梯度的更新也有更直接的影响。一般而言,在想使用带动量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果。

经验之谈
对于稀疏数据,尽量使用学习率可自适应的优化方法,不用手动调节,而且最好采用默认值
SGD通常训练时间更长,但是在好的初始化和学习率调度方案的情况下,结果更可靠
如果在意更快的收敛,并且需要训练较深较复杂的网络时,推荐使用学习率自适应的优化方法。
Adadelta,RMSprop,Adam是比较相近的算法,在相似的情况下表现差不多。
在想使用带动量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果

2019-09-11 15:04:46 LEILEI18A 阅读数 29
  • 玩转深度学习实战教程

    玩转深度学习视频培训课程,详细讲解深度学习的原理和利用深度学习框架TensorFlow进行项目实战。课程通过Kaggle竞赛平台的Titanic问题讲解TensorFlow的基本用法以及问题处理的常用技巧,讲解深度学习图像领域的卷积神经网络CNN和多个经典的网络架构、CNN的应用,讲解自然语言处理领域的RNN、LSTM以及它们的多种变种结构,构建语言模型和对话机器人,介绍损失函数和优化深度学习算法在TensorFlow中的实现。

    2840 人正在学习 去看看 王而川

                                       如何改进和优化深度学习方法?

1. 学术上

 

2. 工程上

    在训练集训练,再和训练集一起划分的测试集上测试,效果很好,但是实际测试效果很差,需要从多方面进行分析,然后才能改进。

    从 数据集情况/数据预处理方式/网络结构/损失函数/后处理等方面进行分析。

首先,分析数据集应用场景是否接近;是否数据集数量太少,导致过拟合;

然后,分析训练集是否足够多,包含更多的情况(颜色、视角、图片分辨率、图片质量等),包含情况越多,泛化性一般越好些;

然后,逐一分析一些典型图片,对比原始图片,标签对应图片,预测类别对应的图片,从颜色/视角/光亮度等对三者进行分析;

         判断是否为数据集的问题,无论是与不是,都要进一步分析数据预处理方式,要怎么预处理增加一些“情况”,增加亮度等。

 

其次,分析网络结构问题(后续更新这一步骤);

其次,分析后处理问题。

 

 

2016-08-18 14:33:32 pipisorry 阅读数 6313
  • 玩转深度学习实战教程

    玩转深度学习视频培训课程,详细讲解深度学习的原理和利用深度学习框架TensorFlow进行项目实战。课程通过Kaggle竞赛平台的Titanic问题讲解TensorFlow的基本用法以及问题处理的常用技巧,讲解深度学习图像领域的卷积神经网络CNN和多个经典的网络架构、CNN的应用,讲解自然语言处理领域的RNN、LSTM以及它们的多种变种结构,构建语言模型和对话机器人,介绍损失函数和优化深度学习算法在TensorFlow中的实现。

    2840 人正在学习 去看看 王而川

http://blog.csdn.net/pipisorry/article/details/52135832

深度学习最优化算法

深度学习框架中常见的最优化方法,如tensorflow中的最优化方法及相关参数如下:

[tensorflow Optimizers]

基本算法

随机梯度下降SGD

此处的SGD指mini-batch gradient descent。SGD就是每一次迭代计算mini-batch的梯度,然后对参数进行更新,是最常见的优化方法了。即:

其中,\eta是学习率,g_t是梯度SGD完全依赖于当前batch的梯度,所以\eta可理解为允许当前batch的梯度多大程度影响参数更新

缺点:

  • 选择合适的learning rate比较困难- 对所有的参数更新使用同样的learning rate。对于稀疏数据或者特征,有时我们可能想更新快一些对于不经常出现的特征,对于常出现的特征更新慢一些,这时候SGD就不太能满足要求了
  • SGD容易收敛到局部最优,并且在某些情况下可能被困在鞍点【查阅论文发现,其实在合适的初始化和step size的情况下,鞍点的影响并没这么大】

[最优化方法:梯度下降(批梯度下降和随机梯度下降)]

动量Momentum

如果把要优化的目标函数看成山谷的话,可以把要优化的参数看成滚下山的石头,参数随机化为一个随机数可以看做在山谷的某个位置以0速度开始往下滚。目标函数的梯度可以看做给石头施加的力,由力学定律知:F=ma,所以梯度(施加的力)与石头下滚的加速度成正比。因而,梯度直接影响速度,速度的累加得到石头的位置,对这个物理过程进行建模,可以得到参数更新过程为:

启发式算法:物体的动能 = 上一个时刻的动能 + 上一时刻的势能差(相对于单位质量),当前的速度取决于上一个时刻的速度和势能的改变量。由于有阻力和转换时的损失,所以两者都乘以一个系数。

这样在更新参数时,除了考虑到梯度以外,还考虑了上一个时刻参数的历史变更幅度。如果参数上一次更新幅度较大,并且梯度还不小,那么再更新时也应该很猛烈。

# Momentum update
v = momentum * v - learning_rate * dx # integrate velocity
x += v # integrate position

代码中v指代速度,其计算过程中有一个超参数momentum,称为动量(momentum)。虽然名字为动量,其物理意义更接近于摩擦,其可以降低速度值,降低了系统的动能,防止石头在山谷的最底部不能停止情况的发生(除非momentum为0,不然还是停不下来的,可能通过NAG解决)。

动量的取值范围通常为[0.5, 0.9, 0.95, 0.99],一种常见的做法是在迭代开始时将其设为0.5,在一定的迭代次数(epoch)后,将其值更新为0.99

在实践中,一般采用SGD+momentum的配置,相比普通的SGD方法,这种配置通常能极大地加快收敛速度。faster convergence and reduced oscillation振荡。

 

Nesterov accelerated gradient(NAG)

还是以上面小球的例子来看,momentum方式下小球完全是一种盲目被动的方式滚下的。这样有个缺点就是在临近最优点附近控制不住速度(梯度为0了,但是moment不为0,还是有速度,还会运动)。我们希望小球很smart,它可以预判后面的"地形",要是后面地形还是很陡,那就继续坚定不移的大胆走下去;不然的话咱就收敛点~当然,小球自己也不知道真正要走到哪里,所以这里(θ−γv_{t−1})作为近似下一位置

vt=γvt−1+η∇θJ(θ−γvt−1).  θ=θ−vt.

Hinton的slides是这样给出的:

momentum首先计算一个梯度(短的蓝色向量),然后在加速更新梯度的方向进行一个大的跳跃(长的蓝色向量),nesterov项首先在之前加速的梯度方向进行一个大的跳跃(棕色向量),计算梯度然后进行校正(绿色梯向量)

两个blue vectors分别理解为梯度和动能,两个向量和即为momentum方式的作用结果。

而靠左边的brown vector是动能,可以看出它那条blue vector是平行的,但是它预测了下一阶段的梯度是red vector,因此向量和就是green vector,即NAG方式的作用结果。

某小皮

 

 

其实,momentum项和nesterov项都是为了使梯度更新更加灵活,对不同情况有针对性。但是,人工设置一些学习率总还是有些生硬,接下来介绍几种自适应学习率的方法。

自适应学习率算法

Adagrad

之前所讲的方法中所有参数在更新时均使用同一个learning rate,而在Adagrad的每一个参数的每一次更新中都使用不同的learning rate

Adagrad其实是对学习率进行了一个约束。即:

n_t=n_{t-1}+g_t^2

\Delta{\theta_t}=-\frac{\eta}{\sqrt{n_t+\epsilon}}*g_t    (lz当前梯度在历史梯度中大则更新快点)

此处,对g_t从1到t进行一个递推形成一个约束项regularizer,-\frac{1}{\sqrt{\sum_{r=1}^t(g_r)^2+\epsilon}}\epsilon用来保证分母非0 ;一般超参数 η 就取 0.01。

对迭代次数 t,基于每个参数之前计算的梯度值,将每个参数的学习率η按如下方式修正:

其中G是一个对角阵,对角线上的元素是从一开始到 t 时刻目标函数对于参数梯度的平方和。是一个平滑项,以避免分母为 0 的情况,它的数量级通常在。有趣的是,如果不开方的话,这个算法的表现会变得很糟。

因为在其对角线上,含有过去目标函数对于参数 梯度的平方和,我们可以利用一个元素对元素的向量乘法,将我们的表达式向量化:

[深度解读最流行的优化算法:梯度下降]

特点:

  • 前期g_t较小的时候, regularizer较大,能够放大梯度;
  • 后期g_t较大的时候,regularizer较小,能够约束梯度;
  • 适合处理稀疏梯度。("It adapts the learning rate to the parameters, performing larger updates for infrequent and smaller updates for frequent parameters." 它对不同的参数调整学习率,具体而言,对低频出现的参数???进行大的更新,对高频出现的参数进行小的更新。因此,他很适合于处理稀疏数据。因此,Adagrad对于稀疏数据上有着良好的表现。)(lz 只有gt大才有显著效果)

缺点:

  • 由公式可以看出,仍依赖于人工设置一个全局学习率
  • \eta设置过大的话,会使regularizer过于敏感,对梯度的调节太大
  • 中后期,分母上梯度平方的累加将会越来越大,使gradient\to0,使得训练提前结束。RMSprop 和 Adadelta 都是为了解决 Adagrad 学习率急剧下降问题的。

然而一般大多数自适应的learning rate都是有根据变化幅度而更改,并且具有逐渐收敛的特性。所以这种启发式方法仅是一种可行性方式,并不是唯一的,也绝不是最好的,把握其本质即可。

Adadelta

Adadelta是对Adagrad的扩展,最初方案依然是对学习率进行自适应约束,但是进行了计算上的简化。Adagrad会累加之前所有的梯度平方,而Adadelta只累加固定大小的项,并且也不直接存储这些项,仅仅是近似计算对应的平均值。即:

n_t=\nu*n_{t-1}+(1-\nu)*g_t^2
\Delta{\theta_t} = -\frac{\eta}{\sqrt{n_t+\epsilon}}*g_t  超参数设定值: 学习率 η 为 0.001。

在此处Adadelta其实还是依赖于全局学习率的,但是作者做了一定处理,经过近似牛顿迭代法之后:

E|g^2|_t=\rho*E|g^2|_{t-1}+(1-\rho)*g_t^2 超参数设定值: 一般设定为 0.9
\Delta{x_t}=-\frac{\sqrt{\sum_{r=1}^{t-1}\Delta{x_r}}}{\sqrt{E|g^2|_t+\epsilon}}

其中,E代表求期望。

此时,可以看出Adadelta已经不用依赖于全局学习率了。

特点:

  • 训练初中期,加速效果不错,很快
  • 训练后期,反复在局部最小值附近抖动

RMSprop

RMSprop 是 Geoff Hinton 提出的一种自适应学习率方法。RMSprop可以算作Adadelta的一个特例

\rho=0.5时,E|g^2|_t=\rho*E|g^2|_{t-1}+(1-\rho)*g_t^2就变为了求梯度平方和的平均数。

如果再求根的话,就变成了RMS(均方根):

RMS|g|_t=\sqrt{E|g^2|_t+\epsilon}

此时,这个RMS就可以作为学习率\eta的一个约束:

\Delta{x_t}=-\frac{\eta}{RMS|g|_t}*g_t

特点:

  • 其实RMSprop依然依赖于全局学习率
  • RMSprop算是Adagrad的一种发展,和Adadelta的变体,效果趋于二者之间
  • 适合处理非平稳目标- 对于RNN效果很好

 

Adam

Adam(Adaptive Moment Estimation)本质上是带有动量项的RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。

除了像 Adadelta 和 RMSprop 一样存储了过去梯度的平方 vt 的指数衰减平均值 ,也像 momentum 一样保持了过去梯度 mt 的指数衰减平均值:

m_t=\mu*m_{t-1}+(1-\mu)*g_t       n_t=\nu*n_{t-1}+(1-\nu)*g_t^2

如果 mt 和 vt 被初始化为 0 向量,那它们就会向 0 偏置,所以做了偏差校正, 通过计算偏差校正后的 mt 和 vt 来抵消这些偏差?:

\hat{m_t}=\frac{m_t}{1-\mu^t}       \hat{n_t}=\frac{n_t}{1-\nu^t}

\Delta{\theta_t}=-\frac{\hat{m_t}}{\sqrt{\hat{n_t}}+\epsilon}*\eta

其中,m_tn_t分别是对梯度的一阶矩估计和二阶矩估计,可以看作对期望E|g_t|E|g_t^2|的估计;\hat{m_t}\hat{n_t}是对m_tn_t的校正,这样可以近似为对期望的无偏估计。可以看出,直接对梯度的矩估计对内存没有额外的要求,而且可以根据梯度进行动态调整,而-\frac{\hat{m_t}}{\sqrt{\hat{n_t}}+\epsilon}对学习率形成一个动态约束,而且有明确的范围。

超参数设定值: 建议 u= 0.9,v = 0.999,ϵ = 10e−8

实践表明,Adam 比其他适应性学习方法效果要好。

特点:

  • 结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点
  • 对内存需求较小
  • 为不同的参数计算不同的自适应学习率
  • 也适用于大多非凸优化- 适用于大数据集和高维空间

Adamax

Adamax是Adam的一种变体,此方法对学习率的上限提供了一个更简单的范围。公式上的变化如下:

n_t=max(\nu*n_{t-1},|g_t|)

\Delta{x}=-\frac{\hat{m_t}}{n_t+\epsilon}*\eta

可以看出,Adamax学习率的边界范围更简单

Nadam

Nadam类似于带有Nesterov动量项的Adam。公式如下:

\hat{g_t}=\frac{g_t}{1-\Pi_{i=1}^t\mu_i}

m_t=\mu_t*m_{t-1}+(1-\mu_t)*g_t

\hat{m_t}=\frac{m_t}{1-\Pi_{i=1}^{t+1}\mu_i}

n_t=\nu*n_{t-1}+(1-\nu)*g_t^2

\hat{n_t}=\frac{n_t}{1-\nu^t}\bar{m_t}=(1-\mu_t)*\hat{g_t}+\mu_{t+1}*\hat{m_t}

\Delta{\theta_t}=-\eta*\frac{\bar{m_t}}{\sqrt{\hat{n_t}}+\epsilon}

可以看出,Nadam对学习率有了更强的约束,同时对梯度的更新也有更直接的影响。一般而言,在想使用带动量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果。

经验之谈

  • 对于稀疏数据,尽量使用学习率可自适应的优化方法,不用手动调节,而且最好采用默认值。
  • SGD通常训练时间更长,但是在好的初始化和学习率调度方案的情况下,结果更可靠。
  • 如果在意更快的收敛,并且需要训练较深较复杂的网络时,推荐使用学习率自适应的优化方法。
  • Adadelta,RMSprop,Adam是比较相近的算法,在相似的情况下表现差不多。
  • 在想使用带动量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果。
  • 如果需要更快的收敛,或者是训练更深更复杂的神经网络,需要用一种自适应的算法。

 

效果比较

下面看一下几种算法在鞍点和等高线上的表现:

上面两种情况都可以看出,Adagrad, Adadelta, RMSprop 几乎很快就找到了正确的方向并前进,收敛速度也相当快,而其它方法要么很慢,要么走了很多弯路才找到。由图可知自适应学习率方法即 Adagrad, Adadelta, RMSprop, Adam 在这种情景下会更合适而且收敛性更好。

[深度学习最全优化方法总结比较(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)]

[深度学习优化器算法详解:梯度更新规则+缺点+如何选择]

[深度解读最流行的优化算法:梯度下降]

from: http://blog.csdn.net/pipisorry/article/details/52135832

ref: [http://sebastianruder.com/optimizing-gradient-descent/]

 

2017-01-03 12:51:43 yas12345678 阅读数 2214
  • 玩转深度学习实战教程

    玩转深度学习视频培训课程,详细讲解深度学习的原理和利用深度学习框架TensorFlow进行项目实战。课程通过Kaggle竞赛平台的Titanic问题讲解TensorFlow的基本用法以及问题处理的常用技巧,讲解深度学习图像领域的卷积神经网络CNN和多个经典的网络架构、CNN的应用,讲解自然语言处理领域的RNN、LSTM以及它们的多种变种结构,构建语言模型和对话机器人,介绍损失函数和优化深度学习算法在TensorFlow中的实现。

    2840 人正在学习 去看看 王而川

最近在看Google的Deep Learning一书,看到优化方法那一部分,正巧之前用tensorflow也是对那些优化方法一知半解的,所以看完后就整理了下放上来,主要是一阶的梯度法,包括SGD, Momentum, Nesterov Momentum, AdaGrad, RMSProp, Adam。 其中SGD,Momentum,Nesterov Momentum是手动指定学习速率的,而后面的AdaGrad, RMSProp, Adam,就能够自动调节学习速率. 
二阶的方法目前我水平太差,看不懂….就不放上来了。


BGD

即batch gradient descent. 在训练中,每一步迭代都使用训练集的所有内容. 也就是说,利用现有参数对训练集中的每一个输入生成一个估计输出yi^,然后跟实际输出yi比较,统计所有误差,求平均以后得到平均误差,以此来作为更新参数的依据.

具体实现: 
需要:学习速率 ϵ, 初始参数 θ 
每步迭代过程: 
1. 提取训练集中的所有内容{x1,,xn},以及相关的输出yi 
2. 计算梯度和误差并更新参数: 

g^+1nθiL(f(xi;θ),yi)θθϵg^

优点: 
由于每一步都利用了训练集中的所有数据,因此当损失函数达到最小值以后,能够保证此时计算出的梯度为0,换句话说,就是能够收敛.因此,使用BGD时不需要逐渐减小学习速率ϵk

缺点: 
由于每一步都要使用所有数据,因此随着数据集的增大,运行速度会越来越慢.


SGD

SGD全名 stochastic gradient descent, 即随机梯度下降。不过这里的SGD其实跟MBGD(minibatch gradient descent)是一个意思,即随机抽取一批样本,以此为根据来更新参数.

具体实现: 
需要:学习速率 ϵ, 初始参数 θ 
每步迭代过程: 
1. 从训练集中的随机抽取一批容量为m的样本{x1,,xm},以及相关的输出yi 
2. 计算梯度和误差并更新参数: 

g^+1mθiL(f(xi;θ),yi)θθϵg^

优点: 
训练速度快,对于很大的数据集,也能够以较快的速度收敛.

缺点: 
由于是抽取,因此不可避免的,得到的梯度肯定有误差.因此学习速率需要逐渐减小.否则模型无法收敛 
因为误差,所以每一次迭代的梯度受抽样的影响比较大,也就是说梯度含有比较大的噪声,不能很好的反映真实梯度.

学习速率该如何调整: 
那么这样一来,ϵ如何衰减就成了问题.如果要保证SGD收敛,应该满足如下两个要求: 

k=1ϵk=k=1ϵ2k<

而在实际操作中,一般是进行线性衰减: 
ϵk=(1α)ϵ0+αϵτα=kτ

其中ϵ0是初始学习率, ϵτ是最后一次迭代的学习率. τ自然代表迭代次数.一般来说,ϵτ 设为ϵ0的1%比较合适.而τ一般设为让训练集中的每个数据都输入模型上百次比较合适.那么初始学习率ϵ0怎么设置呢?书上说,你先用固定的学习速率迭代100次,找出效果最好的学习速率,然后ϵ0设为比它大一点就可以了.


Momentum

上面的SGD有个问题,就是每次迭代计算的梯度含有比较大的噪音. 而Momentum方法可以比较好的缓解这个问题,尤其是在面对小而连续的梯度但是含有很多噪声的时候,可以很好的加速学习.Momentum借用了物理中的动量概念,即前几次的梯度也会参与运算.为了表示动量,引入了一个新的变量v(velocity).v是之前的梯度的累加,但是每回合都有一定的衰减.

具体实现: 
需要:学习速率 ϵ, 初始参数 θ, 初始速率v, 动量衰减参数α 
每步迭代过程: 
1. 从训练集中的随机抽取一批容量为m的样本{x1,,xm},以及相关的输出yi 
2. 计算梯度和误差,并更新速度v和参数θ

g^+1mθiL(f(xi;θ),yi)vαvϵg^θθ+v

其中参数α表示每回合速率v的衰减程度.同时也可以推断得到,如果每次迭代得到的梯度都是g,那么最后得到的v的稳定值为 

ϵg1α

也就是说,Momentum最好情况下能够将学习速率加速11α倍.一般α的取值有0.5,0.9,0.99这几种.当然,也可以让α的值随着时间而变化,一开始小点,后来再加大.不过这样一来,又会引进新的参数.

特点: 
前后梯度方向一致时,能够加速学习 
前后梯度方向不一致时,能够抑制震荡


Nesterov Momentum

这是对之前的Momentum的一种改进,大概思路就是,先对参数进行估计,然后使用估计后的参数来计算误差

具体实现: 
需要:学习速率 ϵ, 初始参数 θ, 初始速率v, 动量衰减参数α 
每步迭代过程: 
1. 从训练集中的随机抽取一批容量为m的样本{x1,,xm},以及相关的输出yi 
2. 计算梯度和误差,并更新速度v和参数θ

g^+1mθiL(f(xi;θ+αv),yi)vαvϵg^θθ+v

注意在估算g^的时候,参数变成了θ+αv而不是之前的θ


AdaGrad

AdaGrad可以自动变更学习速率,只是需要设定一个全局的学习速率ϵ,但是这并非是实际学习速率,实际的速率是与以往参数的模之和的开方成反比的.也许说起来有点绕口,不过用公式来表示就直白的多: 

ϵn=ϵδ+n1i=1gigi

其中δ是一个很小的常亮,大概在107,防止出现除以0的情况.

具体实现: 
需要:全局学习速率 ϵ, 初始参数 θ, 数值稳定量δ 
中间变量: 梯度累计量r(初始化为0) 
每步迭代过程: 
1. 从训练集中的随机抽取一批容量为m的样本{x1,,xm},以及相关的输出yi 
2. 计算梯度和误差,更新r,再根据r和梯度计算参数更新量 

g^+1mθiL(f(xi;θ),yi)rr+g^g^θ=ϵδ+rg^θθ+θ

优点: 
能够实现学习率的自动更改。如果这次梯度大,那么学习速率衰减的就快一些;如果这次梯度小,那么学习速率衰减的就满一些。

缺点: 
任然要设置一个变量ϵ 
经验表明,在普通算法中也许效果不错,但在深度学习中,深度过深时会造成训练提前结束。


RMSProp

RMSProp通过引入一个衰减系数,让r每回合都衰减一定比例,类似于Momentum中的做法。

具体实现: 
需要:全局学习速率 ϵ, 初始参数 θ, 数值稳定量δ,衰减速率ρ 
中间变量: 梯度累计量r(初始化为0) 
每步迭代过程: 
1. 从训练集中的随机抽取一批容量为m的样本{x1,,xm},以及相关的输出yi 
2. 计算梯度和误差,更新r,再根据r和梯度计算参数更新量 

g^+1mθiL(f(xi;θ),yi)rρr+(1ρ)g^g^θ=ϵδ+rg^θθ+θ

优点: 
相比于AdaGrad,这种方法很好的解决了深度学习中过早结束的问题 
适合处理非平稳目标,对于RNN效果很好

缺点: 
又引入了新的超参,衰减系数ρ 
依然依赖于全局学习速率


RMSProp with Nesterov Momentum

当然,也有将RMSProp和Nesterov Momentum结合起来的

具体实现: 
需要:全局学习速率 ϵ, 初始参数 θ, 初始速率v,动量衰减系数α, 梯度累计量衰减速率ρ 
中间变量: 梯度累计量r(初始化为0) 
每步迭代过程: 
1. 从训练集中的随机抽取一批容量为m的样本{x1,,xm},以及相关的输出yi 
2. 计算梯度和误差,更新r,再根据r和梯度计算参数更新量 

θ~θ+αvg^+1mθ~iL(f(xi;θ~),yi)rρr+(1ρ)g^g^vαvϵrg^