写在前面

梯度下降(Gradient descent)算法可以说是迄今最流行的机器学习领域的优化算法。并且,基本上每一个深度学习库都包括了梯度下降算法的实现,比如Lasagne、cafe、keras等。关于梯度优化的三种分类在机器学习中常用的优化方法这篇博客中已经介绍过,按照每次更新参数使用的数据量可以分为Batch gradient descent、Stochastic gradient descent和Mini-batch gradient descent。

src:An overview of gradient descent optimization algorithms

Challenges

然而,朴素Mini-batch gradient descent并没有完全确保完美的收敛性,这也为我们提供了一些需要被强调的挑战之处:

  • 选择一个合适的学习率是非常困难的。一个小的学习率会导致我们的训练过程进行地非常慢,painfully;一个大的学习率则会导致跳过最优解,同时使得损失函数表现地波动起伏。
  • 设置学习率时间表以在训练过程中调整学习率,比如,annealiing算法。通过提前设置训练期间的学习率变化特定规则来优化算法。但是,这种做法需要我们提前设定一些参数并且难以在不同的数据集中通用;
  • 此外,相同的学习率会被应用到所有参数更新。 如果我们的数据稀疏并且我们的功能具有非常不同的频率,我们可能不希望将所有数据更新到相同的范围,而是对于很少发生的功能执行更大的更新。
  • 最小化神经网络常见的高度非凸误差函数的另一个关键挑战是避免陷入其众多次优的局部最小值。 Dauphin等人认为困难实际上不是来自局部最小值,而是来自鞍点,即一维向上倾斜而另一维向下倾斜的点。 这些鞍点通常被相同误差的平台所包围,这使得SGD难以逃脱,因为梯度在所有维度上都接近于零。

梯度下降优化算法

接下来我们讨论几种在深度学习领域常用的算法,这些算法可以用于解决前面提及的challenges。


Momentum

SGD算法在遇到沟谷(ravines)会比较难以计算,即在一个维度上比另一个维度更陡峭的曲面,这些通常出现在局部最优点的附近。在这些情况下,SGD震荡且缓慢的沿着沟壑的下坡方向朝着局部最优点前进如下图所示。

SGD without momentum

Momentum是一种在相关方向加速SGD的方法,并且能够减少震荡和摇摆。如下图所示:

SGD with momentum

Momentum在更新向量中加入了先前一步的状态:

其中为动量系数,通常设置为0.9或者相似的值

本质上来说,当我们使用动量时,类似于我们把球推下山的过程。在球下山的过程中,球累计动量使得其速度越来越快(直到达到其最终速度)。相同的事情也发生在我们的参数更新过程中:对于梯度指向方向相同的维度动量项增大,对于梯度改变的方向的维度动量项减小,最终,我们获得了更快的收敛并减少了震荡。


Nesterov accelerated gradient

然而,一个球盲目地沿着斜坡下山,这不是我们希望看到的。我们希望有一个聪明的球,它知道将要去哪里并且可以在斜坡变成上坡之前减速。

Nesterov accelerated gradient(NAG)就是这样一种给与我们的动量项预知能力的神奇方法。我们知道我们将使用动量项来更新参数。因此计算可以得出我们下一个位置参数的估计,这是一个简单粗暴的方法。

我们仍然将项设置为0.9左右。Momentum算法首先计算当前梯度(下图总的小蓝色向量),然后再更新累计梯度方向上大幅度的跳跃(下图中的大蓝色向量)。与此不同的是,NAG首先在先前的累计梯度方向上进行大幅度的跳跃(下图中的棕色向量),评估这个荼毒并做一下修正(红色向量),这就构成了一次完整的NAG更新(绿色向量)。这种预期更新防止我们进行地太快,也带来了更高的响应速度,

现在我们已经能够依据误差函数的斜率来调整更新,并加快SGD的速度,此外我们也想个根据每个参数的重要性来决定进行更大还是更小

的更新。


Adagrad

Adagrad [Adaptive Subgradient Methods for Online Learning and Stochastic Optimization]的思想是这样的:根据参数来调整学习率,对于不常见的参数给予更大的更新,而对于常见的给予更小的更新。因此,Adagrad 非常适用于稀疏数据。

前面几种算法在对所有参数更新时每个参数使用相同的学习率。Adagrad在每个时间点t对每个参数使用不同的学习率,我们首先展现每个参数的更新,然后再向量化。简单起见,我们使用来表示目标函数关于在时间点t的梯度:

SGD在每个时间点t对每个参数的更新变为:

在这个更新规则里面,Adagrad在每个时间点t对每个参数都会基于过去的梯度修改学习率:

其中,是一个对角矩阵,对角元素是参数从开始到时间点t为止的梯度平方和,是一个平滑项,用于防止分母为0。有趣的是,去掉开方操作,算法性能将会大幅下降。

由于Gt的对角元素是关于所有参数的过去的梯度平方和,我们可以将上面的公式实现向量化,即使用点乘

Adagrad 最大的一个优点是我们可以不用手动的调整学习率。大多数实现使用一个默认值 0.01 。

Adagrad 主要的缺点是分母中累积的平方和梯度:由于每一个新添加的项都是正的,导致累积和在训练期间不断增大。这反过来导致学习率不断减小,最终变成无限小,这时算法已经不能再继续学习新东西了。下面的这个算法就解决了这个问题。


Adadelta

Adadelta是 Adagrad的扩展,旨在帮助缓解后者学习率单调下降的问题。 AdaGrad 中对 learning rate 进行 normalize 的参数是使用之前所有时间得到的梯度的累积, AdaDelta 的思想是通过设置窗口 w, 只使用部分时间的梯度累积.

在实际使用中, 其算法并没有存储前 w 个梯度然后计算, 而是类似与 moving average 的方法. 在任意一个时间 t, 当前的 normalize 的参数是 t-1 时刻的参数和当前的梯度做加权求和.  关于指数加权平均的具体细节可以参考:通俗理解指数加权平均

现在我们就可以使用去代替Adagrad中的正则化项:

最终的更新方法为

其中

可以看到,在Adadelta中,我们甚至不需要设置learning rate,因为其自身可以计算学习率


RMSProp

RMSProp是一种还未发布的自适应学习率的方法,有HInton老爷子在Neural Networks for Machine Learning中提出。

RMSprop 和 Adadelta 在同一时间被独立地发明出来,都是为了解决 Adagrad 的学习率递减问题。事实上 RMSprop 与我们上面讨论过的 Adadelta 的第一个更新向量一模一样:

RMSProp也是将学习率除以平方梯度的指数衰减平均值。Hinton建议将设为0.9,默认学习率为0.001。

RMSProp算法和Adagrad算法的区别在于Gt 的计算由 累积方式变成了指数衰减移动平均。在迭代过程中,每个参数的学习率并不是 呈衰减趋势,既可以变小也可以变大。其在Adagrad的基础上增加了一个衰减系数来控制历史信息的获取多少。


Adam

Adam(Adaptive momentum estimation)是另一种为每个参数计算自适应学习率的方法。除了像Adadelta和RMSProp一样存储历史平方梯度的指数衰减平均值外,Adam也存储类似Momentum的历史梯度指数衰减平均值

由于是用零向量初始化,Adam的作者发现他们趋向于0,特别是最开始的时候和衰减率很小的时候(接近于1)。

他们通过计算偏差纠正(bias-corrected)的一阶和二阶矩估计值来抵消这些偏差:

然后他们使用这些公式来更新参数,就像Adadelta和RMSProp一样:

作者建议将的默认值设为0.9,设为0.999,设为


AdaMax

在Adam参数更新规则中的项缩放了梯度,正比于历史梯度和当前梯度的l2范数:

现在我们可以将此推广到Lp范数。

注意,大的p值通常会导致数值上的不稳定,这也是L1和L2范数常用的原因。然而,一般会表现出稳定的特性。正因如此,作者们提出了AdaMax并获得了良好的表现。为了与Adam进行区分,这里使用了来代表

我们现在可以将此加进Adam的更新规则里,用代替,得到AdaMax的更新规则:

注意依赖于上面的max操作,这不像Adam中的那样容易趋向于0。建议


Nadam

正如前面说的那样,Adam可以看做是RMSProp和Momentum的组合:RMSProp贡献了历史平方梯度的指数衰减的平均值,而Momentum则负责历史梯度的指数衰减平均值。我们也发现了Nesterov accelerated gradient (NAG)要比朴素动量算法更优化。

而Nadam(Nesterov-accelerated Adaptive Moment Estimation)则是结合了Adam和NAG。为了将NAG融进Adam中,我们需要修改其中动量项

首先,让我们回顾一下Momentum更新规则:

其中,J是目标函数,是动量衰减项,是步长。将带入上述第三个式子展开得到:

这再次证明了动量更新涉及两个方向:先前动量向量的方向和当前梯度的方向。

NAG给我们提供了一种在梯度方向更精确的思路:在计算梯度之前通过动量更新参数。因此我们只需更改来将NAG融进去:

带入:

注意到是先前动量向量的偏差修正,因此我们可以用来代替:

这个式子与我们上面展开得到的动量更新规则非常相似。我们可以加进Nesterov动量,就像我们之前一样简单地用当前动量向量的偏差修正估计来代替先前动量向量的偏差修正估计。得到Nadam的更新规则:


可视化


不同算法的对比

  优点 缺点
SGD  
  • 选择合适的learning rate比较难
  • 对于所有的参数使用同样的learning rate
  • 容易收敛到局部最优
  • 可能困在saddle point

Momentum

  • 积累动量,加速训练
  • 局部极值附近震荡时,由于动量,跳出陷阱
  • 梯度方向发生变化时,动量缓解动荡。
 

Nesterov accelerated gradient

  • 避免前进太快
  • 提高灵敏度
 
Adagrad
  • 控制学习率,每一个分量有各自不同的学习率
  • 适合稀疏数据
  • 依赖一个全局学习率
  • 学习率设置太大,其影响过于敏感
  • 后期调整学习率的分母积累的太大,导致学习率很低,提前结束训练。
RMSProp
  • 解决了后期提前结束的问题
  • 依然依赖全局学习率
Adam
  • 结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点
  • 为不同的参数计算不同的自适应学习率
  • 也适用于大多非凸优化 - 适用于大数据集和高维空间
 
     
     
     
     

梯度下降优化算法总结相关推荐

  1. 基于机器学习梯度下降优化算法来寻找最佳的线性回归模型

    https://www.toutiao.com/a6638782437587419652/ 幻风的AI之路 2018-12-25 18:12:27 线性回归模型 线性回归模型是一个非常简单的算法模型, ...

  2. 梯度下降优化算法综述(转载)

    原文地址:http://www.cnblogs.com/ranjiewen/p/5938944.html 对梯度下降进行详细解释,以及总结不同的梯度下降优化算法的优劣,可以作为参考. 上两张图,简直不 ...

  3. 深度学习-各类梯度下降优化算法回顾

    本文是根据 链接 进行的翻译,回顾了深度学习的各种梯度下降优化算法.*已获得原作者的翻译许可. 文章目录 一.概述 二.引言 三.Gradient Descent Variants(梯度下降法变体) ...

  4. 深度学习中的梯度下降优化算法综述

    1 简介 梯度下降算法是最常用的神经网络优化算法.常见的深度学习库也都包含了多种算法进行梯度下降的优化.但是,一般情况下,大家都是把梯度下降系列算法当作是一个用于进行优化的黑盒子,不了解它们的优势和劣 ...

  5. 梯度下降优化算法概述

    本文原文是 An overview of gradient descent optimization algorithms,同时作者也在 arXiv 上发了一篇同样内容的 论文. 本文结合了两者来翻译 ...

  6. 【深度学习】——梯度下降优化算法(批量梯度下降、随机梯度下降、小批量梯度下降、Momentum、Adam)

    目录 梯度 梯度下降 常用的梯度下降算法(BGD,SGD,MBGD) 梯度下降的详细算法 算法过程 批量梯度下降法(Batch Gradient Descent) 随机梯度下降法(Stochastic ...

  7. 梯度下降优化算法综述与PyTorch实现源码剖析

    现代的机器学习系统均利用大量的数据,利用梯度下降算法或者相关的变体进行训练.传统上,最早出现的优化算法是SGD,之后又陆续出现了AdaGrad.RMSprop.ADAM等变体,那么这些算法之间又有哪些 ...

  8. 各种 Optimizer 梯度下降优化算法回顾和总结

    1. 写在前面 当前使用的许多优化算法,是对梯度下降法的衍生和优化.在微积分中,对多元函数的参数求  偏导数,把求得的各个参数的导数以向量的形式写出来就是梯度.梯度就是函数变化最快的地方.梯度下降是迭 ...

  9. 各种 Optimizer 梯度下降优化算法总结

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:DengBoCong,编辑:极市平台 来源:https://zhu ...

最新文章

  1. 开源软硬一体OpenCV AI Kit(OAK)
  2. mysql 1455_关于Oracle 11g导出数据时 报 ORA-1455错误的处理
  3. 安卓gridview 网格,多行多列实现
  4. Oracle 安装报错 [INS-06101] IP address of localhost could not be determined 解决方法
  5. 数字图像处理之Canny编程实现
  6. java调试 Linux_Linux上调试java项目
  7. 类似抖音的短视频app开发难度大吗?短视频源码让你事半功倍
  8. PCIE设备与HOST之间的地址转换
  9. Weld(CDI)教程
  10. android判断是华为手机,华为手机怎么辨别真假?华为手机真伪验证多种方法
  11. 机房运维服务器,机房服务器维护指导
  12. Xcode 5设置Deployment Target
  13. 计算机电路基础 - 1,计算机电路基础1.1(4页)-原创力文档
  14. SQL2008R2数据库安装教程
  15. 已有虚拟磁盘多个vmdk文件导入虚拟机
  16. Unity3D 中动态更改材质球纹理
  17. 删除主键索引 oracle,删除主键无法删除对应索引问题 drop constraint
  18. Codeforces 并查集题集(Disjoint Sets Union Step1)
  19. c语言教改课题开题报告,教改项目结题及新项目开题报告会简讯
  20. 从零开始学前端 - 1. HTML基础知识

热门文章

  1. SAP License:物料账差异
  2. *N#1234567CG,解析征信报告里的暗语
  3. CRM管理系统、教育后台、赠品管理、优惠管理、预约管理、试听课、教师、学生、客户、学员、商品管理、科目、优惠券、完课回访、客户管理系统、收费、退费、回访、账号权限、订单流水、审批、转账、rp原型
  4. Python基础知识:字符串
  5. saltstack returners
  6. 环信Demo 导入错误
  7. Mysql的简单使用(二)
  8. [hdu1242]优先队列
  9. 收藏的一个关于C# ToString的方法集合
  10. 解题报告 幸福的道路