转载地址

https://www.jianshu.com/p/aebcaf8af76e

基于随机梯度下降(SGD)的优化算法在科研和工程的很多领域里都是极其核心的。很多理论或工程问题都可以转化为对目标函数进行最小化的数学问题。

按吴恩达老师所说的,梯度下降(Gradient Descent)就好比一个人想从高山上奔跑到山谷最低点,用最快的方式(steepest)奔向最低的位置(minimum)。

SGD基本公式


动量(Momentum)

参考链接:https://distill.pub/2017/momentum/

基本的mini-batch SGD优化算法在深度学习取得很多不错的成绩。然而也存在一些问题需解决:

1. 选择恰当的初始学习率很困难。

2. 学习率调整策略受限于预先指定的调整规则。

3. 相同的学习率被应用于各个参数。

4. 高度非凸的误差函数的优化过程,如何避免陷入大量的局部次优解或鞍点。

自适应优化

AdaGrad

针对简单的SGD及Momentum存在的问题,2011年John Duchi等发布了AdaGrad优化算法(Adaptive Gradient,自适应梯度),它能够对每个不同的参数调整不同的学习率,对频繁变化的参数以更小的步长进行更新,而稀疏的参数以更大的步长进行更新。

公式:

gt表示第t时间步的梯度(向量,包含各个参数对应的偏导数,gt,i表示第i个参数t时刻偏导数)

gt2表示第t时间步的梯度平方(向量,由gt各元素自己进行平方运算所得,即Element-wise)

与SGD的核心区别在于计算更新步长时,增加了分母:梯度平方累积和的平方根。此项能够累积各个参数gt,i的历史梯度平方,频繁更新的梯度,则累积的分母项逐渐偏大,那么更新的步长(stepsize)相对就会变小,而稀疏的梯度,则导致累积的分母项中对应值比较小,那么更新的步长则相对比较大。

AdaGrad能够自动为不同参数适应不同的学习率(平方根的分母项相当于对学习率α进进行了自动调整,然后再乘以本次梯度),大多数的框架实现采用默认学习率α=0.01即可完成比较好的收敛。

优势:在数据分布稀疏的场景,能更好利用稀疏梯度的信息,比标准的SGD算法更有效地收敛。

缺点:主要缺陷来自分母项的对梯度平方不断累积,随之时间步地增加,分母项越来越大,最终导致学习率收缩到太小无法进行有效更新。

RMSProp

RMSProp是Geoffrey Hinton教授在教案中提到的算法,结合梯度平方的指数移动平均数来调节学习率的变化。能够在不稳定(Non-Stationary)的目标函数情况下进行很好地收敛。

Hinton教授讲述RMSProp算法的材料:

http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf

计算t时间步的梯度:

计算梯度平方的指数移动平均数(Exponential Moving Average),γ是遗忘因子(或称为指数衰减率),依据经验,默认设置为0.9。

梯度更新时候,与AdaGrad类似,只是更新的梯度平方的期望(指数移动均值),其中ε=10^-8,避免除数为0。默认学习率α=0.001。

优势:能够克服AdaGrad梯度急剧减小的问题,在很多应用中都展示出优秀的学习率自适应能力。尤其在不稳定(Non-Stationary)的目标函数下,比基本的SGD、Momentum、AdaGrad表现更良好。

Adam优化器

2014年12月,Kingma和Lei Ba两位学者提出了Adam优化器,结合AdaGrad和RMSProp两种优化算法的优点。对梯度的一阶矩估计(First Moment Estimation,即梯度的均值)和二阶矩估计(Second

Moment Estimation,即梯度的未中心化的方差)进行综合考虑,计算出更新步长。

主要包含以下几个显著的优点:

1. 实现简单,计算高效,对内存需求少

2. 参数的更新不受梯度的伸缩变换影响

3. 超参数具有很好的解释性,且通常无需调整或仅需很少的微调

4. 更新的步长能够被限制在大致的范围内(初始学习率)

5. 能自然地实现步长退火过程(自动调整学习率)

6. 很适合应用于大规模的数据及参数的场景

7. 适用于不稳定目标函数

8. 适用于梯度稀疏或梯度存在很大噪声的问题

综合Adam在很多情况下算作默认工作性能比较优秀的优化器。

Adam实现原理

算法伪代码:

Adam更新规则

计算t时间步的梯度:

首先,计算梯度的指数移动平均数,m0 初始化为0。

类似于Momentum算法,综合考虑之前时间步的梯度动量。

β1 系数为指数衰减率,控制权重分配(动量与当前梯度),通常取接近于1的值。

默认为0.9

下图简单展示出时间步1~20时,各个时间步的梯度随着时间的累积占比情况。

其次,计算梯度平方的指数移动平均数,v0初始化为0。

β2 系数为指数衰减率,控制之前的梯度平方的影响情况。

类似于RMSProp算法,对梯度平方进行加权均值。

默认为0.999

第三,由于m0初始化为0,会导致mt偏向于0,尤其在训练初期阶段。

所以,此处需要对梯度均值mt进行偏差纠正,降低偏差对训练初期的影响。

第四,与m0 类似,因为v0初始化为0导致训练初始阶段vt偏向0,对其进行纠正。

第五,更新参数,初始的学习率α乘以梯度均值与梯度方差的平方根之比。

其中默认学习率α=0.001

ε=10^-8,避免除数变为0。

由表达式可以看出,对更新的步长计算,能够从梯度均值及梯度平方两个角度进行自适应地调节,而不是直接由当前梯度决定。

Adam代码实现

算法思路很清晰,实现比较直观:

代码地址:https://github.com/dream-catcher/learning_blogs/blob/master/Adam_Optimizer/adam_optimizer.py

Adam可视化

notebook试验地址:https://github.com/dream-catcher/learning_blogs/tree/master/Adam_Optimizer

Adam缺陷及改进

虽然Adam算法目前成为主流的优化算法,不过在很多领域里(如计算机视觉的对象识别、NLP中的机器翻译)的最佳成果仍然是使用带动量(Momentum)的SGD来获取到的。Wilson 等人的论文结果显示,在对象识别、字符级别建模、语法成分分析等方面,自适应学习率方法(包括AdaGrad、AdaDelta、RMSProp、Adam等)通常比Momentum算法效果更差。

针对Adam等自适应学习率方法的问题,主要两个方面的改进:

1、解耦权重衰减

在每次更新梯度时,同时对其进行衰减(衰减系数w略小于1),避免产生过大的参数。

在Adam优化过程中,增加参数权重衰减项。解耦学习率和权重衰减两个超参数,能单独调试优化两个参数。

参考链接:http://ruder.io/deep-learning-optimization-2017/index.html

2、修正指数移动均值

最近的几篇论文显示较低的[if !msEquation][endif](如0.99或0.9)能够获得比默认值0.999更佳的结果,暗示出指数移动均值本身可能也包含了缺陷。例如在训练过程中,某个mini-batch出现比较大信息量的梯度信息,但由于这类mini-batch出现频次很少,而指数移动均值会减弱他们的作用(因为当前梯度权重及当前梯度的平方的权重,权重都比较小),导致在这种场景下收敛比较差。

https://openreview.net/pdf?id=ryQu7f-RZ

论文作者提出Adam的变形算法AMSGrad。

AMSGrad 使用最大的来更新梯度,而不像Adam算法中采用历史的指数移动均值来实现。作者在小批量数据集及CIFAR-10上观察到比Adam更佳的效果。

参考资料

http://ruder.io/optimizing-gradient-descent/

http://ruder.io/deep-learning-optimization-2017/index.html

简单认识Adam优化器的更多相关文章

  1. (五) Keras Adam优化器以及CNN应用于手写识别

    视频学习来源 https://www.bilibili.com/video/av40787141?from=search&seid=17003307842787199553 笔记 Adam,常 ...

  2. 优化器Optimizer

    目前最流行的5种优化器:Momentum(动量优化).NAG(Nesterov梯度加速).AdaGrad.RMSProp.Adam,所有的优化算法都是在原始梯度下降算法的基础上增加惯性和环境感知因素进 ...

  3. TensorFlow从0到1之TensorFlow优化器(13)

    高中数学学过,函数在一阶导数为零的地方达到其最大值和最小值.梯度下降算法基于相同的原理,即调整系数(权重和偏置)使损失函数的梯度下降. 在回归中,使用梯度下降来优化损失函数并获得系数.本节将介绍如何使 ...

  4. Tensorflow-各种优化器总结与比较

    优化器总结 机器学习中,有很多优化方法来试图寻找模型的最优解.比如神经网络中可以采取最基本的梯度下降法. 梯度下降法(Gradient Descent) 梯度下降法是最基本的一类优化器,目前主要分为三 ...

  5. TensorFlow优化器及用法

    TensorFlow优化器及用法 函数在一阶导数为零的地方达到其最大值和最小值.梯度下降算法基于相同的原理,即调整系数(权重和偏置)使损失函数的梯度下降. 在回归中,使用梯度下降来优化损失函数并获得系 ...

  6. 深度学习——优化器算法Optimizer详解(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)

    在机器学习.深度学习中使用的优化算法除了常见的梯度下降,还有 Adadelta,Adagrad,RMSProp 等几种优化器,都是什么呢,又该怎么选择呢? 在 Sebastian Ruder 的这篇论 ...

  7. 【深度学习】深入理解优化器Optimizer算法(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)

    在机器学习.深度学习中使用的优化算法除了常见的梯度下降,还有 Adadelta,Adagrad,RMSProp 等几种优化器,都是什么呢,又该怎么选择呢? 在 Sebastian Ruder 的这篇论 ...

  8. Pytorch实现MNIST(附SGD、Adam、AdaBound不同优化器下的训练比较) adabound实现

     学习工具最快的方法就是在使用的过程中学习,也就是在工作中(解决实际问题中)学习.文章结尾处附完整代码. 一.数据准备  在Pytorch中提供了MNIST的数据,因此我们只需要使用Pytorch提供 ...

  9. 优化器,SGD+Momentum;Adagrad;RMSProp;Adam

    Optimization 随机梯度下降(SGD): 当损失函数在一个方向很敏感在另一个方向不敏感时,会产生上面的问题,红色的点以“Z”字形梯度下降,而不是以最短距离下降:这种情况在高维空间更加普遍. ...

随机推荐

  1. web测试中不容忽视的细节

    最近在自动化测试的圈子里,我总是碰到很多人在群里和其他地方问为什么这个会出现错误? 为什么这个运行不了?为什么我百度了还是没用? 其实真正的原因可能是你忽略了下面这些需要注意的小地方: 1.页面分辨率 ...

  2. Maven如何利用父工程对版本进行统一管理

    项目开发中我们该怎么对项目依赖的版本进行统一管理呢 答:创建一个父级工程,让所有的业务模块都继承该父级工程,即所有的业务都为Module 在父级工程pom文件添加<dependencyManag ...

  3. 【Python学习笔记四】获取html内容之后,如何提取信息:使用正则表达式筛选

    在能够获取到网页内容之后,发现内容很多,那么下一步要做信息的筛选,就和之前的筛选图片那样 而在python中可以通过正则表达式去筛选自己想要的数据 1.首先分析页面内容信息,确定正则表达式.例如想获取 ...

  4. element-ui设置级联选择器表单验证

    data(){<el-form :model="ruleForm" :rules="rules" ref="ruleForm" lab ...

  5. 分布式ID生成服务,真的有必要搞一个

    目录 阐述背景 Leaf snowflake 模式介绍 Leaf segment 模式介绍 Leaf 改造支持RPC 阐述背景 不吹嘘,不夸张,项目中用到ID生成的场景确实挺多.比如业务要做幂等的时候 ...

  6. java大数据最全课程学习笔记(6)--MapReduce精通(二)--MapReduce框架原理

    目前CSDN,博客园,简书同步发表中,更多精彩欢迎访问我的gitee pages 目录 MapReduce精通(二) MapReduce框架原理 MapReduce工作流程 InputFormat数据 ...

  7. 水题-------判断Digit Generator

    题目链接:https://vjudge.net/problem/UVA-1583 题意:给出一个数N,判断最小的数x使x+(x各位数字的和)=N 题解:这是一个暴力求解题,不过有技巧,x各位数字的和最 ...

  8. 一个文本框的andriod教程

    https://blog.csdn.net/androidmsky/article/details/49870823

  9. 理解k8s资源限制系列(二):cpu time

    本文介绍几种在K8S中限制资源使用的几种方法. 资源类型 在K8S中可以对两类资源进行限制:cpu和内存. CPU的单位有: 正实数,代表分配几颗CPU,可以是小数点,比如0.5代表0.5颗CPU,意 ...

  10. paramiko上传文件到Linux

    一.传输单个文件到Linux服务器 import paramiko transport = paramiko.Transport(('host',22)) transport.connect(user ...