在进行神经网络训练时,很多同学都不太注重损失函数图和损失函数的优化算法的理解,造成的结果就是:看起来效果不错,但是不知道训练的参数是否合理,也不知道有没有进一步优化的空间,也不知道初始点的选择是否恰当。本篇文章着重介绍神经网络损失函数最小化过程中使用的优化算法,前面先对梯度下降法进行介绍,后面介绍梯度下降法中使用的几种优化算法,中间穿插着自变量的更新轨迹和损失函数图像的讲解,以期同学们对损失函数相关的知识有清晰明确的认识,这是学好神经网络的基础。

梯度下降法

梯度下降法是最原始的对模型的参数向量进行更新的方法,它的目标函数是训练数据集中有关各个样本的损失函数的平均。设

是有关索引为
的训练数据样本的损失函数,
是训练数据样本数,
是模型的参数向量,那么目标函数定义为

目标函数在

处的梯度为:

模型的参数向量更新:

例如,对于目标函数

,使用上述迭代方法更新自变量的轨迹如下(学习率为0.1,迭代了20次):

可以看到自变量的迭代轨迹与等高线是垂直的,说明迭代一直朝着梯度的反方向进行(直达目的地)。但是梯度下降法每次更新模型参数需要对所有样本计算梯度,所以每次自变量迭代的计算开销为

.因此,当训练数据样本数很大时,梯度下降每次迭代的计算开销很高。

随机梯度下降法

为了减少计算的开销,采用了随机梯度下降(SGD)方法。在随机梯度下降的每次迭代中,我们随机均匀采样的一个样本索引

,并计算梯度
来迭代

我们的目标是把所有样本的损失降到一个极小值,但是这种方式只能把一个样本的损失给降低,那么这样能达到我们的目标吗?可以证明:经过很多次的迭代之后随机梯度下降能达到梯度下降相同的效果,也就是说随机梯度

是对梯度
的无偏估计。同样是对于目标函数
,采用随机梯度下降更新自变量的轨迹如下(学习率为0.1,迭代了20次):

可以看到自变量的迭代轨迹与等高线不是垂直的,说明迭代没有完全按照梯度下降的方向走,但是最后也到达了跟梯度下降方法同样的终点,再次证明了我们上述说的“经过很多次的迭代之后随机梯度下降能达到梯度下降相同的效果”。但是此时可能存在损失函数图像是以下形状:

出现这种损失函数在某个值附近波动,说明学习率太大了,以至于在这个值附近跳来跳去,无法继续朝着梯度的反方向达到极小值点,通常需要降低学习率。

小批量随机梯度下降法

除了梯度下降和随机梯度下降,我们还能每次处理一批样本,当这一批样本的数量等于整个训练集时,就成了梯度下降;当这一批样本的数量为一个样本时,就成了随机梯度下降。

小批量随机梯度下降对自变量的迭代如下:

对于目标函数

,采用随机梯度下降更新自变量的轨迹如下(学习率为0.1,迭代了20次):(注意这里把
的系数变为了0.1,刚才
的系数都是1,也就是说这里在两个方向上,方向导数差了一个数量级):

可以看到小批量随机梯度下降也大体是朝着等高线垂直的方向前进。但是注意:在前几次的迭代过程中垂直方向上每一步的跨度都超过了水平方向上的跨度,这是因为两个方向的方向导数差别太大导致的,这种情况如果我们更新参数的时候在各个方向还是使用相同的学习率就会带来不好的结果:具体来说就是当学习率设置的大的时候方向导数比较大的那个维度容易发散,这样就找不到极小值了。当学习率设置的比较小的时候方向导数比较小的那个维度移动较慢,可能训练已经结束了,还没达到极小值点(在实际的训练中经常发生这样的事情,因为高维空间的函数及其复杂,可能存在大片平坦区域,很久也走不出去)。针对这种情况,出现了两种优化方法:动量法和AdaGrad算法。下面分别介绍。

动量法

动量法的思想很简单,就是要把之前时间步的梯度考虑进来,比如在某一个维度上,前面好几个时间步的梯度都是同一个符号,说明在这个方向上一直在下坡,还没有跳过极小值点,那么就需要加速,一次跳的更远一些,这样接近极小值更快一些。再比如在另一个维度上,前面好几个时间步的梯度的正负符号不一致,那么说明在这个区域内,这个维度在极小值附近跳来跳去,也就是说当前的(学习率*梯度)太大了,以至于不能更靠近极小值。这两种情况都可以通过一个办法解决,那就是把最近几个时间步的学习率*梯度考虑进来,如果最近几个时间步的都为同一个符号,那么它们相加就会变大,更新的就快;如果最近几个时间步的为不同的符号,那么它们相加就会相互抵消,就会变小,就更容易靠近极小值点。动量法的更新方法如下:

相比以前,多了一步

的计算,并且
的更新不再是减
了,而是减
,但是看这个式子其实体现不出上面描述的思想,我们把这个式子变形一下可得:

例如:

=0.9,那么上式就是

其实就是,本来应该减

的,现在把最近的10个
分别乘以它们的权值之后相加,通过这样就把最近10个时间步的
考虑了进来,实现了上述描述的思想。

同样是上述目标函数,这里我们把学习率设置的和刚才一样,但是使用动量法并设置动量超参数为

=0.5,自变量更新的轨迹如下:

可以看到动量法在竖直方向上的移动更加平滑。

AdaGrad算法

还是要解决刚才的问题,动量法是把最近的(学习率*梯度)考虑了进来,另一种想法就是针对每一维我们设置不同的学习率不就行了吗,如果某个维度的导数比较大,我们就设置比较小的学习率,如果某个维度的方向导数比较小,我们就设置稍微大一点的学习率,这正是AdaGrad算法算法的思路。

AdaGrad算法的更新方法如下(时间步0时,

的每个元素初始化为0):

其中

是学习率,
是为了维持数值稳定性而添加的常数,如
.这个式子看起来不太容易,我们把这个式子变形一下可得:

上式为了好看把

去掉了,从上述可以清楚的看出AdaGrad是如何针对每一个维度设置学习率的,它仅仅是把当前时间步之前的所有梯度按元素平方然后累加开方求倒数。所以如果某一维梯度比较大,那么相加开方之后这一维仍然比较大,求倒数之后就变得很小,也就是学习率很小。而且需要注意到,在每一个时间步,上式的分母都在累加,所以每个时间步学习率都在降低,所以,

当学习率在迭代早期降得较快且当前解依然不佳时,AdaGrad算法在迭代后期由于学习率过小,可能较难找到一个有用的解

还是使用目标函数

及学习率0.4,使用AdaGrad法自变量更新的轨迹如下:

损失函数的变化图形大致如下所示:

可以看到由于前期学习率下降太快,导致后期的迭代变得特别慢,20轮迭代之后,自变量仍未达到极小值点。由于在实际的机器学习过程中,损失函数都是高维函数,函数将变得非常复杂,学习率下降太快会导致不管训练了多久可能都出不了某个区域的情况。

RMSProp算法

针对上面这个问题,提出了RMSProp算法。RMSProp算法综合了动量法和AdaGrad算法的思想,它既想用过去的时间步的梯度来更新当前

向量,又不想学习率下降的太快导致后期找不到有效解。因此RMSProp算法采用的方法是:

像刚才一样,我们还是做一个变形:

相当于给每个

加了个权重。然后计算方法照AdaGrad算法这样进行。

还是使用目标函数

及学习率0.4,使用RMSProp算法对自变量更新的轨迹如下(
=0.9):

损失函数的变化图形大致如下所示:

可以看到,RMSProp算法可以更快逼近最优解,并且像动量法一样在竖直方向上的移动更加平滑,也克服了AdaGrad法迭代较慢的现象。

Adam算法

Adam算法在RMSProp算法基础上对小批量随机梯度也做了指数加权移动平均,可以看做是RMSProp算法与动量法的结合,也就是RMSProp算法的增强和优化版本。

Adam算法使用了动量变量

和RMSProp算法中的
,并在时间步0将它们中每个元素初始化为0,Adam算法更新自变量的过程如下:

另外还有一点,就是上面的

还可以写成
这个公式其实就是t个向量相加,每一个向量是一个系数
乘以梯度向量
,举个例子,比如t=2时,
,大家会发现系数相加0.3+0.6不等于1,实际上上面的t个系数相加:
,但是让各权值相加为1才能更好的把历史梯度考虑进来,所以我们让上述系数除以一个
,从而使过去各时间步小批量随机梯度权值之和为1,对应刚才的那个例子,就相当于

所以Adam算法真正的公式如下:

Adam算法是应用最广泛、效果最好的优化算法之一,近年来又提出了很多优化算法,但核心思想都是为了解决梯度下降过程中存在的上述几个问题。把这几个算法理解清楚,就理解了整个梯度下降的过程,对于后续研究其它优化算法也打下了坚实的基础。

算法函数_关于损失函数和优化算法,看这一篇就够了相关推荐

  1. adam算法_关于损失函数和优化算法,看这一篇就够了

    在进行神经网络训练时,很多同学都不太注重损失函数图和损失函数的优化算法的理解,造成的结果就是:看起来效果不错,但是不知道训练的参数是否合理,也不知道有没有进一步优化的空间,也不知道初始点的选择是否恰当 ...

  2. 机器学习算法优缺点_用于机器学习的优化算法的优缺点

    机器学习算法优缺点 A deep-dive into Gradient Descent and other optimization algorithms 深入研究梯度下降和其他优化算法 Optimi ...

  3. tarjan算法总结 (强连通分量+缩点+割点),看这一篇就够了~

    文章目录 一.tarjan求强连通分量 1:算法流程 2:模板 二.tarjan缩点 1:相关定义 2:算法流程 三.tarjan求割点.桥 1.什么是割点 2.割点怎么求? 3.割点tarjan模板 ...

  4. 后端数据成功返回 页面不渲染_如何统计页面访问量,看这一篇就够了

    大家好我是CloudCoder,译为云时代的码农,专注分享linux/go/java等相关技术. 如何使用前后端统计页面的访问量? 这是我的一个github项目 链接为:https://github. ...

  5. 百万并发下的Nginx优化,看这一篇就够了!

    本文作者主要分享在 Nginx 性能方面的实践经验,希望能给大家带来一些系统化思考,帮助大家更有效地去做 Nginx. 优化方法论 我重点分享如下两个问题: 保持并发连接数,怎么样做到内存有效使用. ...

  6. 合并文件夹中子目录_如何整理文件夹,看这一篇就够了,简单易学

    说出来可能你们不信,松鼠君在办公室看到了人类第八大奇迹-- 一个全是新建文件夹的电脑! 我的乖乖,他到底是怎么干活的 层级分类 在我们日常的工作生活中,对电脑的文件进行整理成了不可避免的工作:而如何高 ...

  7. 单点登录 cas 设置回调地址_单点登录(SSO)看这一篇就够了

    背景 在企业发展初期,企业使用的系统很少,通常一个或者两个,每个系统都有自己的登录模块,运营人员每天用自己的账号登录,很方便. 但随着企业的发展,用到的系统随之增多,运营人员在操作不同的系统时,需要多 ...

  8. Dropout、梯度消失/爆炸、Adam优化算法,神经网络优化算法看这一篇就够了

    作者 | mantch 来源 | 知乎 1. 训练误差和泛化误差 对于机器学习模型在训练数据集和测试数据集上的表现.如果你改变过实验中的模型结构或者超参数,你也许发现了:当模型在训练数据集上更准确时, ...

  9. 智能优化算法1-冠状病毒群免疫优化算法(CHIO)

    智能优化算法1-冠状病毒群免疫优化算法(CHIO) 1.算法简介 2020年Mohammed Azmi Al-Betar等人提出的一种新的基于自然的优化算法--冠状病毒群体免疫优化算法(CHIO).其 ...

最新文章

  1. Java学习总结:7
  2. [Angular Tutorial] 11 -Custom Filters
  3. 阿里云 物联网产品架构
  4. java实现转账功能_如何利用Java代码模拟银行转账这一功能?
  5. Windows使用筛选器来处理异常
  6. linux下xargs命令用法详解
  7. 小米MIX4不会采用四曲面屏:结果未必是坏事
  8. 11g大对象数据新技术
  9. 【ASP.NET Web API教程】2.3.4 创建Admin视图
  10. 汕尾php培训,系统发生错误
  11. HDU 4664 Triangulation(SG函数)
  12. 微信小程序怎样生成体验版二维码?微信小程序怎么转化为二维码?
  13. C语言入门-绝对值(abs)
  14. 程序员们的薪酬待遇大起底,如何提高自己的收入?
  15. iRedmail配置手册
  16. 跳一跳,python脚本原理
  17. 2016版excel_EXCEL表格如何换行
  18. csvn-httpd启动报AH00094错解决办法
  19. Docker容器化技术
  20. ig信息增益 java_【Python 编程】实现文本分类中的信息增益算法

热门文章

  1. Linux的Nginx九:负载均衡
  2. 收银机多少钱一台推荐科脉系统_防火门监控系统安装预算多少钱?防火门监控系统安装预算表[今日推荐]...
  3. linux中怎样建立批量用户,Linux 大批量建立用户
  4. 某个软件调用目标异常_线上RPC远程调用频繁超时问题排查,大功臣Arthas
  5. android 全屏动画,Android开发之全屏与非全屏的切换设置方法小结
  6. 高德软件测试工资,【高德工资】软件测试工程师待遇-看准网
  7. 【微信小程序】 setData 的用法
  8. 【SpringBoot】项目实现热部署的两种方式
  9. 华为服务器提示错误信息,服务器错误日志
  10. webpack打包jquery多页_Webpack打包与程序调试