深度学习的优化器是基于梯度这个概念来实现的,其作用是找到目标函数最小值对应的各变量值(此处的目标函数的变量即模型的参数),在介绍优化器之前,我们得先了解什么是梯度。


1.什么是梯度

在了解梯度之前,首先得介绍一元函数的导数和二元函数的方向导数。

(1)一元函数的导数:

深度学习之优化器optimizer_自适应


   从实际作用上来讲,一元函数中,某个点的导数可以表示某点处的变化率,可以理解为函数图像上该点处的陡峭程度,以y=x2y=x2为例,其导数为:dydx=2xdydx=2x,可知x越靠近0,则导数越小,即陡峭程度越小(越平缓),反之导数越大,陡峭程度越大(越陡峭)。

  从图像上直观来讲,由导数的极限公式定义可知

深度学习之优化器optimizer_自适应_02



  导数在图像上可以直观理解为切线斜率。


(2)二元函数的方向导数:

  在二元函数中,由于过某点处的切线不止一条,切线可以绕该点进行360°的旋转,实际上是一个切平面,即方向导数不唯一,可以理解为有无限多个。

深度学习之优化器optimizer_自适应_03


   那方向导数不唯一,怎么用数学公式表示出所有方向导数呢?我们可以考虑采用降维的方法,在低维空间上来实现所有方向导数的表示。

   由图可知,在某点处的切线,可以投影到XOY平面(消除函数值维度,在二元函数中也就是Z的维度)

深度学习之优化器optimizer_自适应_04


   由于切线是可以360°旋转的,所有会出现相差180°的两条“长得一样”的切线投影到XOY平面(如下图),所以我们得规定一个方向来区分这样的两条切线:

深度学习之优化器optimizer_梯度下降法_05

深度学习之优化器optimizer_深度学习_06

   我们可以给每个切线规定一个方向,投影到XOY后也会带有一个方向,就是图中紫色箭头的方向(一般规定该切点在XOY的投影点作为起始点)

   但是在投影之后虽然保留了方向,却没有保留方向导数的数值大小,所以我们要单独记下这个数值大小,我们记为∂f∂l∂f∂l

  现在切线的投影既有方向又有大小,我们可以将其视为一个向量,我们记为l⃗ l→,一个向量可以由另外两个正交的向量所表示,那么怎么找到这样两个正交向量呢?这里我们引入偏导数的概念。

  以ffxx的偏导数为例,可以设置y=y0y=y0,即把yy当作一个固定的值,那么y=y0y=y0平面和原函数曲线相交后就会形成一条交线(即下图的黑色曲线)

深度学习之优化器optimizer_深度学习_07

深度学习之优化器optimizer_自适应_08



   ffxx的偏导数投影到XOY后总是与x轴平行,也可以看作一个向量,我们记为x⃗ x→,而且我们规定其投影向量的方向是x轴正方向(图中红色轴),其大小记为∂f∂x∂f∂x。点在y=y0y=y0平面上无论怎样移动,其投影方向总是一样的,但是大小会随之改变,但是点固定后,大小也不会改变了,也就是说某个固定的点,其ffxx的偏导数大小和方向都是固定的。ffyy的偏导数也是同理,投影方向与y轴方向平行,且规定向量y⃗ y→方向是yy轴正方向,其大小记为∂f∂y∂f∂y,某个固定的点,其ffyy的偏导数大小和方向都是固定的。

  综上所述,某个固定的点,可以用方向和大小都固定的x⃗ x→y⃗ y→向量作为一对正交向量,去表示方向和大小不固定所有l⃗ l→向量。

  规定l⃗ l→向量与xx轴正方向夹角为φφ,那么可以记为:


∂f∂l=∂f∂xcosφ+∂f∂ycosφ∂f∂l=∂f∂xcos⁡φ+∂f∂ycos⁡φ


  现在所有l⃗ l→都表示出来了之后,就需要找出其中值(∂f∂l∂f∂l)最大的一个向量,说明该点延这个方向的陡峭程度是最大的。


∂f∂l=∂f∂xcosφ+∂f∂ysinφ=(∂f∂x,∂f∂y)⋅(cosφ,sinφ)=(∂f∂x,∂f∂y)⋅e⃗ =|(∂f∂x,∂f∂y)|⋅1⋅cosθ(1)(2)(3)(4)(1)∂f∂l=∂f∂xcos⁡φ+∂f∂ysin⁡φ(2)=(∂f∂x,∂f∂y)⋅(cos⁡φ,sin⁡φ)(3)=(∂f∂x,∂f∂y)⋅e→(4)=|(∂f∂x,∂f∂y)|⋅1⋅cos⁡θ

  (∂f∂x,∂f∂y)(∂f∂x,∂f∂y)可以看成x⃗ x→y⃗ y→合成的向量, (cosφcos⁡φ,sinφsin⁡φ)可以看成l⃗ l→的方向向量,记为e⃗ e→,向量的乘积公式为a⃗ ⋅b⃗ =|a⃗ |⋅|b⃗ |⋅cosθa→⋅b→=|a→|⋅|b→|⋅cos⁡θθθe⃗ e→(∂f∂x,∂f∂y)(∂f∂x,∂f∂y)向量的夹角,cosθ=1cos⁡θ=1时(即θ=0θ=0时),有最大值|(∂f∂x,∂f∂y)||(∂f∂x,∂f∂y)|

   我们用二维的平面直角坐标系来看看x⃗ x→y⃗ y→l⃗ l→e⃗ e→以及最大值向量(∂f∂x,∂f∂y)(∂f∂x,∂f∂y)之间的关系:

深度学习之优化器optimizer_自适应_09

  由于点固定时,x⃗ x→y⃗ y→固定,所以其合成的最大值向量(∂f∂x,∂f∂y)(∂f∂x,∂f∂y)也是固定且唯一的,l⃗ l→会随着φφ的改变而改变(大小和方向),当其方向和最大值向量重合时,则该向量即最大值向量,此时可以取到最大值。而这个最大值向量我们称之为梯度,记为∇f∇f


2.梯度有什么用

  深度学习时,当我们求得了目标函数的loss后,要进行反向传播对目标函数进行优化,优化的目的是找到最优的模型参数,使得目标函数的loss最小。但是由于深度学习的目标函数的参数数量极多且函数结构较为复杂,几乎不可能直接计算出最佳的参数,所以需要借助梯度的概念,使每次参数的优化往最快降低loss的方向进行(可以看作是贪心策略)。

  以一元函数y=x2y=x2为例,其导数为:dydx=2xdydx=2x,当x=−2x=−2时,dydx=−4dydx=−4,使x=−2−(−4)=2x=−2−(−4)=2,可以使xx朝着yy值减少的方向(x轴正方向)移动,当x=2x=2时,dydx=4dydx=4,使x=2−(4)=−2x=2−(4)=−2,可以使xx朝着yy值减少的方向(x轴负方向)移动。但是这样移动的跨度太大了,越过了最低点,所以我们通常在要减去的导数值前面乘以一个ηη,例如设置η=0.1η=0.1,那么当x=2x=2时,dydx=4dydx=4,使x=2−0.1×(4)=−1.6x=2−0.1×(4)=−1.6,向着最低点移动了一小步。

  当到了多元函数时,以二元函数为例,在上一小节找到了最大值向量(梯度)后,怎么朝着该方向移动相应的大小呢?二元函数是z=f(x,y)z=f(x,y),只有通过xxyy两个值来控制点的移动,所以分别应用两次一元函数的移动方法即可(x=x−η∂f∂xx=x−η∂f∂xy=y−η∂f∂yy=y−η∂f∂y),整体上的效果便是朝着梯度方向移动了相应的梯度值。


3.梯度下降法

  我们通常将需要优化的目标函数为J(θ)J(θ),其中θθ表示目标函数中所有参数的集合,即θ=θ12,...,θnθ=θ1,θ2,...,θn。在深度学习中,xxyy作为输入输出,一般是不作为参数的。

  我们将∇J(θ)∇J(θ)做为JJ对所有θθ的梯度,对某一个参数,可以表示为∇J(θj)、∇J(θj)、\frac{\partial J(\theta)}{\theta_j}\mathrm{d} \theta_j$。


4.常用的优化器

随机梯度下降法SGD

批量梯度下降法BGD

mini-batch梯度下降法MBGD


SGD、BGD、MBGD 三个算法都是使用梯度下降算法对网络权重进行更新,只是每次更新使用的样本数量不同。



momentum动量法

指数加权平均

深度学习之优化器optimizer_深度学习_10




Nesterov accelerated gradient NAG

Momentum和NAG算法是根据局部历史梯度对当前梯度进行平滑。


adagrad

RMSprop

Adagrad,RMSprop算法都是自适应学习率的优化算法,对于不同参数使用不同的自适应学习率;Adagrad使用梯度平方和、Adadelta,RMSprop使用梯度一阶指数平滑(一阶指数平均,局部加权历史梯度)解决了Adagrad后期梯度非常小的问题;RMSprop是Adadelta的一种特殊形式。


Adam

Adam算法吸收了Momentum和RMSprop算法的优点,同时改进了梯度计算方式和学习率,本质上是带有动量项的RMSprop。