深度学习基础概念 -- 优化器Optimizer
关于优化器这块,网上的资料已经蛮多了,这里主要记录一些自己的思考。本文主要探讨以下问题:
- 目前主流优化器是朝着哪些研究方向发展?背后可能的一些逻辑是什么样的?
- 关于优化器的一些似是而非的问题的理解;
正式开始之前,首先给出一些基本的符号定义:
- 模型参数 ;
- 目标函数为 ;
- 学习率为 ;
- 梯度 ;
优化器的分类
个人认为,目前主流的优化器,从迭代思路来看,主要朝两个方向发展:
-
动量(Momentum)法;
基本思想是参考物理学中惯性的概念,在梯度更新时参考历史趋势。具体又可以分为以下两种,主要区别在于是否考虑梯度的提前预测/修正。
- 传统方法,如带动量的随机梯度下降(SGDM);
- Nesterov 动量法(Nesterov accelerated gradient,NAG);
-
一阶和二阶矩(Moment)估算法;
基本思想是利用指数滑动平均(Exponential Moving Average,EMA)方法分别估算梯度 的一阶和二阶原点矩(Moment),从而达到梯度降噪、自适应调整学习率的目的。
比较典型的优化器有 AdaDelta/RMSprop、Adam 等;
上述两种思路在实现上虽有所差异,但内在还是存在一定联系的,尤其是一阶矩估算法,本质思想也是动量法。不过为了方便讨论,本文还是将其分开处理。
传统梯度下降法
讨论其他优化器之前,我们先来回顾一下传统梯度下降法的相关概念。其计算方法相对比较直观:
-
梯度计算
-
梯度下降更新
传统方法下,需要注意的是 Batch/Mini-batch 梯度下降、随机梯度下降(SGD)等几类方法中参与计算的样本数量上的区别以及对应的数据处理方法。
动量(Momentum)法
传统方法
动量(Momentum)本来算是一个物理概念,与传统梯度下降法相比,在梯度更新的基础之上,又添加了一项动量项(Momentum Term),其中参数 叫做动量参数(Momentum Parameter),一般设置为 0.9,其物理意义更加接近于摩擦系数(实际对应 )的概念。动量法梯度更新公式如下
简单来说,添加动量项的目的在于模拟物理学中的惯性原理,在梯度更新时考虑当前时刻梯度 与前一时刻梯度更新值 ,这样操作,既可以增大从局部最小值(Local Minima)或者鞍点(Saddle Point)等冲出去的概率,也能在一定程度上缓和因梯度方向突变造成的剧烈震荡。
Nesterov 动量法(NAG)
相较于传统方法,NAG 实际上是通过修正动量项的影响提前预测下一步的梯度。既然已知 中肯定包含 ,那何不提前预测 ,即使不是非常精确,也至少比 前瞻性要好吧,能修正一点是一点。
实验结果显示,NAG 的这一点小小的改动,在不少场合,还是对优化过程起到了很大作用的。
一阶和二阶矩(Moment)估算法
矩(Moment)
**矩(Moment)**是统计学中的概念,根据 Wiki 上的描述,在实数域上的连续实函数 ,相对于值 的 阶矩的定义如下:
通常情况下,实数 ,根据定义可知,一阶原点矩(即 )对应随机变量的期望值(平均数),二阶原点矩(即 )对应随机变量平方值的期望,二阶中心矩(即 )对应随机变量与均值(期望)差值平方的期望,也就是方差。
在深度学习优化器这块,我们采纳的主要是一阶原点矩和二阶原点矩的概念。
指数滑动平均(Exponential Moving Average)
指数滑动平均(EMA)是以指数式递减加权的滑动平均(moving average)。各数值的加权影响力随时间而指数式递减,越近期的数据加权影响力越重,但较早的数据也会给予一定的加权值。已知时间 的数值为 ,时间 的 EMA 为 ,时间 的 EMA 为 ,计算时间 的一般公式为
其中, 叫做衰减系数,其值越大,表明历史数据影响力越小。其与动量法中的参数 作用类似。
AdaGrad 优化器
讨论一阶和二阶矩估算法之前,有必要简单介绍一下 AdaGrad 优化器,它在一定程度上启发了自适应学习率的思想。
AdaGrad 的主要改动在于,每次梯度更新时让学习率 除以一个新的变量 ,具体公式为
其中,为防止分母为零,通常取平滑项 , 为对角矩阵,其对角线上的每个元素均为历史梯度平方和,即 G*{t, nn}=\sum*{t=1}^{n} g_t^2
二阶矩(Moment)估算
在了解 AdaGrad 的原理后,其实也很容易发现它的缺点,虽然在稀疏数据场景下表现较好, 但由于 始终是单调递增的,意味着等效学习率
始终单调递减,这显然不符合预期。理想的状态是, 的增减与 的增减尽量保持一致。
那么该如何简单地构建这层关系呢?二阶原点矩恰好符合要求,其关键就在于取了一个平均。那么,仅仅对 取平均是否就可以了呢,即
上述公式中的 对应 的二阶原点矩,但此处我们还希望这种平均方法能做到以下几点:
- 各个历史梯度在平均值计算过程中,最好不是等权重的,我们希望越靠近当前时刻的梯度权重越大;
- 没有必要计算所有 的平均值,过去一段时间窗口的均值就可以反应一定趋势;
- 计算量越少越好,计算速度越快越好;
这种情况下,使用
只能说是差强人意,而利用指数滑动平均(EMA)去估算梯度 的二阶原点矩 则效果更好,这种思路下的具体公式为
简单来说, 就是对二阶原点矩的估算,可以近似看作是过去 个时间段(滑动窗口)内 的平均。
以上大概就是二阶矩估算法的基本思想,该方法差不多同时期见于 AdaDelta、RMSprop 优化器中。
一阶矩(Moment)估算
二阶矩估算法是受到 AdaGrad 的启发,在此基础上,再拓展到一阶矩估算法就很自然了。在二阶矩方法中,注意到梯度更新项\dfrac{\eta}{\sqrt{v_{t} }+ \epsilon} \cdot g_{t} 中, 算是二阶矩 的一种近似替代,那么同样地,另一个精确值,也就是当前时刻的梯度 能否也由一个平均值替代呢?
之前我们提到过,当前时刻梯度 的突变有可能会造成运动轨迹的反复震荡,如果采用历史均值,直觉上应该是能够缓和这种情况的。梯度 的一阶原点矩为
参考二阶矩估算法,可以得到一阶矩估算法相关公式
同样地,此处 可以近似看作是过去 个时间段(滑动窗口)内 的平均。
Adam 优化器
同时结合一阶矩估值 和二阶矩估值 ,即可得到新的梯度更新公式
上述公式即为 Adam 优化器的一般计算公式。
由于被初始化为 0, 、 会在初始阶段偏向于 0 值,尤其是衰减系数 很小的情况(对应于 ),可以通过以下公式校正
其中, 、 是对 、 的偏置校正(bias correction),可以近似为对期望(滑动窗口区间内均值)的无偏估计。
当然,如果初始值不为 0,是可以避免初始化的偏差的,并且这种偏差也不会影响滑动平均的最终收敛。
Nadam 优化器
从前面的分析来看,Adam 优化器已经是算是各种技巧的集大成者,实际效果也的确不错。但如果考虑到动量法那部分的内容,就可以发现,NAG 的提前预测的思路同样可以应用在 Adam 上面。其基本公式如下
上述就是 Nadam 优化器的基本思想。当然,考虑到计算便捷性,文献作者对上述结果又做了些近似处理,具体参考原文。
优化器的理解
AdaDelta 与 RMSprop 的区别
RMSprop 的思想与一阶矩估算一致,而 AdaDelta 则在此基础上又多做了一步操作,作者发现
中, 与 量纲不一致,所以作者对梯度差值
做了二阶矩估算,即
最终得到
这样处理的好处是完全不需要考虑学习率 的选值了。
关于 Adam
Adam 实际上是用指数滑动平均(EMA)的方法去估算(estimate)梯度的一阶和二阶矩(Moment)。
之所以选择指数滑动平均(EMA),主要是因为 EMA 的加权系数呈指数级衰减,收敛速度较快,而且不同的权重可以进一步突出近期数据的趋势,当然也正因此,Adam 存在初始值偏置的问题。
作为一阶原点距估算值,实际是通过滑动窗口的计算历史平均,以此用于控制梯度更新的方向;而作为二阶原点矩估算值的 ,则通过改变学习率,可以控制实际梯度下降的步长。这里需要说明的是,之所以叫估算(estimate),是因为仅当滑动窗口的区间(近似由 确定)放宽至整个历史时间段, 与 才真正意义上对应一阶二阶原点矩。
至于当初为何选择一阶二阶矩,而不是其他比如 范数之类指标,其原因可能是,在估算二阶原点矩的时候,实际上是使用了 这个量的(对应 范数平方), 也因此可以认为是 范数平方的二阶原点矩估算。至于为何不使用其他的范数,首先,用 范数来替代梯度 去做一阶矩估算显然是不行的,使用 、 等范数去做更高阶矩估算,从定义上来说可以,但研究发现, 范数随着 值的增大会让数值变得不稳定,唯一的特例就是无穷范数,AdaMax 优化器正是采用的这种做法。
一阶矩估算与动量法的关系
对比一阶矩估算与前述动量法的计算公式,可以看出,两者都包含了形式为 的动量项,展开后可以看作是梯度 的历史加权,与之相对的,二阶矩则是梯度平方和 的历史加权,所以从本质上来说,一阶矩估算法与动量法是一致的,只是具体计算公式有所不同,而一阶矩估算法与一阶矩估算法,虽然计算方法相同,但结果表示的意义并不一样。
另外,国内很多文章将一阶矩翻译成一阶动量,二阶矩翻译成二阶动量,个人认为,直接将矩(Moment)与动量(Momentum)等同是不太合理的,单看定义,他们是完全不一样的概念,并且个人查阅到的外文资料上也是将两者分开处理的,虽然在优化器算法这块,两者之间确实存在一些联系,但直接画等号还是容易产生误解。
小结
整体而言,Adagrad、Adadelta、RMSprop、Adam 均可以视为一类算法。其中 RMSprop 与 Adadelta 都是为了解决 Adagrad 的学习率单调递减的问题,Adadelta 相比 RMSprop 对学习率又做了一定处理。而 Adam 可以认为是在 RMSprop 基础上增加了动量和偏置校正,Nadam 则是同时结合了 Nesterov 与 Adam 的优势。
虽然优化器的选择并无绝对,但一般情况下还是推荐直接使用 Adam 或者 SGD + Nesterov,可以应付大多数情况,当然目前学术界一个很有趣的现象是,SGD 才是很多大佬的最爱,所以实际的选择还是仁者见仁智者见智了。
Reference
- An overview of gradient descent optimization algorithms (ruder.io)
- CS231n Convolutional Neural Networks for Visual Recognition
- Optimization Algorithms — Dive into Deep Learning 0.16.6 documentation (d2l.ai)
- http://www.princeton.edu/~yc5/ele522_optimization/lectures/stochastic_gradient.pdf
- Moment (mathematics) - Wikipedia
- Why Momentum Really Works (distill.pub)
- 一个框架看懂优化算法之异同 SGD/AdaGrad/Adam - 知乎 (zhihu.com)
- 从动量和矩的角度探讨优化理论的内涵(以动量法、AdaGrad 和 Adam 举例) - 知乎 (zhihu.com)
- 从 SGD 到 Adam —— 深度学习优化算法概览(一) - 知乎 (zhihu.com)