神经网络中的各种优化方法

神经网络中的各种优化方法

大家耳熟能详的优化方法有梯度下降法(Gradient Descent)、随机梯度下降法(Stochastic Gradient Descent)、Adam方法等等。虽然很多听过甚至用过这些方法,但是却未必能够说出他们的区别,已经什么时候改用什么样的优化算法。这篇文章将会从原理、区别和使用场景等角度详细介绍神经网络中的各种优化算法。

什么是优化算法

优化算法就是一种能够帮我们最小化或者最大化目标函数(有时候也叫损失函数)的一类算法。而目标函数往往是模型参数和数据的数学组合。例如给定数据XX和其对应的标签YY,我们构建的模型是一个线性模型f(x)=Wx+bf(x)=Wx+b,有了模型后,根据输入xx就可以得到预测输出f(x)f(x),并且可以计算出预测值和真实值之间的差距(f(x)Y)2\left (f(x)-Y\right)^2,这个就是损失函数。我们的目的是找到合适的W,bW, b时上述的损失函数的值达到最小,损失值越小,则说明我们的模型越接近于真实情况。

通过上面的描述可以知道,模型的内参(W,bW, b) 在模型中扮演着非常重要的角色,而这些内参的更新和优化就用到我们所说的优化算法,所以优化算法也层出不穷,而一个好的优化算法往往能够更加高效、更加准确的训练模型的内参。

优化算法的种类

一般的,根据优化算法在优化过程中使用的导数阶数。可以将优化算法可以分为两大类,一阶优化算法和二阶优化算法。

1、 一阶优化算法

一阶优化算法是指使用参数梯度值来最小化或者最大化损失函数的优化算法。最为广泛应用的就是梯度下降法,参数的一阶导能够清晰的告诉我们损失函数在某个特定点上是增加的还是减少的。那什么是梯度呢?简而言之,梯度就是函数输出关于输的偏导数,只不过这里的输入和输出并不是简单的数值,而是向量。梯度与导数的区别就是导数是单个变量的,而梯度是多个变量的。梯度往往采用雅克比矩阵(Jacobian Matrix)进行表达。

2、二阶优化算法

顾名思义,二阶优化算法就是采用二阶导数进行优化算法。二阶导数,有时候也被成为海森矩阵(Hessian)。因为二阶导数要求两次导数,尤其是在矩阵中进行求导,运算量会非常的大,所以二阶优化算法被用的比较少。

各种梯度下降法

1、Gradient Descent

梯度下降法是最重要的一种方法,也是很多其他优化算法的基础。

θ=θηΔJ(θ)\theta = \theta-\eta\Delta J(\theta)

上面的公式就是梯度下降法的基本形式,其中 η\eta 是学习率 ΔJ(θ)\Delta J(\theta) 是损失函数 J(θ)J(\theta) 关于模型参数 θ\theta 的梯度。

这里的损失函数 J(θ)J(\theta) 是在整个数据集上进行计算得到的。

因为这里的损失函数是在整个数据集上进行计算得到的均值,所以每更新一次模型参数,就要对整个数据集进行一个计算,可想而知这样非常的慢,并且当数据集变得非常大的时候,如此多的数据没法都load到内存中。

特点:

对于凸目标函数,肯定可以找到全局最优,对于非凸目标函数,可以找到局部最优

每次更新都对整个数据集进行计算,计算量大

2、随机梯度下降法(Stochastic Gradient Descent)

θ=θηΔJ(θ;xi,yi)\theta = \theta - \eta \Delta J(\theta; x_i, y_i)

随机梯度下降法和梯度下降法其实是走的两个极端,梯度下降法是每次更新都计算整个数据集的loss,而随机梯度下降法每次更新都只用了一对样本,即上面公式中的一对样本(xi,yi)(x_i, y_i)。由于每个样本都会对模型进行更新,所以模型更新的特别频繁,参数就会变成高方差,损失函数的波动也会有很大强度的变化。有时候,这是好事,因为这样的可以帮助我们探索新的更新方向,找到更加好的局部极值点。但是,由于频繁的更新和波动,会导致模型的损失收敛的非常不稳定。

上图就是随机梯度下降法更新过程中loss值的变化,可以发现loss值的变化非常大,这就是模型超调了,整个模型比较不稳定。

特点:

每次只用一个样本进行更新,计算量小,更新频率高

容易导致模型超调不稳定,收敛也不稳定

3、Mini Batch Gradient Descent

mini batch 梯度下降法是梯度下降法和随机梯度下降法的折衷,即在计算loss的时候,既不是直接计算整个数据集的loss,也不是只计算一个样本的loss,而是计算一个batch的loss,batch的大小自己设定。

θ=θη1Bi=1BJ(θ;xi,yi)\theta = \theta - \eta * \frac{1}{B}\sum_{i=1}^B J(\theta; x_i, y_i)

其中B就是自己设定的batch size的大小。

特点:
每次更新模型时,采用一部分数据进行计算
现在几乎在所有的深度学习应用中,都使用的是mini batch梯度下降法
正是因为使用广泛,所以很多深度学习的库和框架都对这方面的矩阵操作进行了特别优化

梯度下降法面临的挑战:

Challenges:

1、很难选择一个合适学习率,需要我们大量的尝试。太小的学习率会导致模型收敛变得缓慢,导致训练时间变长;太大的学习率会阻碍模型的收敛,使损失函数在最优值附近来回波动甚至是发散。

2、对于所有的参数,均使用相同的学习率。如果有的参数的梯度很大,有的很小,使用相同的学习率显然就不是很合适。

3、在非凸函数的优化过程中,我们往往希望模型能够跳过那些局部极值点,去找一个更好的极值。在实际训练过程中,鞍点也是非常难以解决的问题。

鞍点:一个数在所在行中是最大值,在所在列中是最小值

例如,在某个点处,一个维度的梯度方向是往上的,一个维度的梯度是往下的,那梯度下降法在就很难跳出这个点,因为这个点所有维度的梯度是接近0的。

4、Momentum

带momentum(动量)的梯度下降法也是一种很常用的的优化算法。这种方法因为引入了momentum量,所以能够对梯度下降法起到加速的作用。

打个比方,一个球顺着斜坡往下滚动,会因为地心引力的原因而一直加速,速度越来越快的往坡低滚去。梯度下降法中的Momentum量就和地心引力的作用很类似,能够让梯度下降法沿着下降的方向逐渐扩大幅度。起到对梯度下降法进行加速的作用。

V(t)=γV(t1)+ηΔJ(θ)1θ=θV(t)2 V(t) = \gamma V(t-1) + \eta \Delta J(\theta) -----(1)\\ \theta = \theta - V(t) -----(2)

从上述公式(1)可以看出,当当前的梯度方向(ΔJ(θ)\Delta J(\theta)的正负号)和 V(t1)V(t-1) 的方向相同时,V(t)>ηΔJ(θ)V(t) > \eta\Delta J(\theta) 所以参数 θ\theta 的变化幅度会增大,从而加快梯度下降法的幅度;而当方向不同时,会逐步减小当前更新的幅度。这样可以有效的对梯度下降法进行加速,同时提高模型的稳定性。

特点:

能够更快更稳定的收敛

能够减少模型的波动震荡

5、Nesterov

Nesterov是一位学者,他发现Momentum方法中存在一个问题。当我们把球放在斜坡上,小球会一直往下滚动,并且越滚越快,当球到达坡底时,速度最快。我们的目的是让小球能够停在坡底,可是当小球到达坡底时,由于仍旧有较大的速度,小球会往另一个方向爬坡,并不会稳稳的停在谷底。

具体到梯度下降法,就是Momentum方法在极值附近不能进行提前减速,且在极值附近仍旧以较大的幅度进行改变,有时候可能就直接跳出了这个极值。

为了解决这一问题,Nesterov就提出了 Nestrov Accelerated Gradient(NAG)。

NAG算法简而言之,就是在进行Momentum梯度下降法之前,先做一个预演,看看沿着以前的方向进行更新是否合适,不合适就立马调整方向。也就是说参数更新的方向不再是当前的梯度方向,而是参数未来所要去的真正方向。

V(t)=γV(t1)+ηΔJ(θγV(t1))(3)θ=θV(t)(4) V(t)=\gamma V(t-1) + \eta\Delta J(\theta - \gamma V(t-1)) ---- (3) \\ \theta = \theta - V(t) ---- (4)

特点:

能够在对梯度下降法进行加速的同时,提高稳定性,避免越过极值

6、Adagrad

前面讲了在mini batch梯度下降法中,因为对所有的参数均使用相同的学习率,而当有的参数的梯度很大,有的很小时,显然不合适。另外,对于不同的样本,如果有的样本出现的较为频繁,导致其对应的一些参数更新较为频繁,而有的样本出现的频率很低,导致一些参数更新频率很低时,再采用相同的学习率有时候也不太合适。我们更加希望那些出现更新频率比较低的参数能够有更大的更新幅度。

根据每个参数以前的梯度情况,对不同参数使用不同的学习率,同时动态调整参数学习率

gi,t=gi,t1+ΔJ(θi,t)25θi,t=θi,t1ηgi,t+ϵΔJ(θi,t)(6) g_{i,t} = g_{i,t-1} + \Delta J(\theta_{i,t})^2 ---(5)\\ \theta_{i,t} = \theta_{i, t-1} - \frac{\eta}{\sqrt{g_{i,t} + \epsilon}}\cdot \Delta J(\theta_{i,t}) --- (6)\\
其中ΔJ(θi,t)\Delta J(\theta_{i,t})代表第i个参数在第t个迭代中的梯度ϵ\epsilon是一个微小量,为了防止分母为0,一般取1e-8

特点:
在训练过程中,每个不参数都有自己的学习率,并且这个学习率会根据自己以前的梯度平方和而进行衰减。
优点:在训练的过程中不用认为的调整学习率,一般设置好默认的初始学习率就行了

缺点:随着迭代的进行,公式(6)中的学习率部分会因为分母逐渐变大而变得越来越小,在训练后期模型几乎不再更新参数。

7、AdaDelta

AdaDelta是Adagrad的改进版,目的就是解决Adagrad在训练的后期,学习率变得非常小,降低模型收敛速度。AdaGrad方法是完全累计先前所有梯度的平方和,AdaDelta则是添加一个衰减系数 ww 用来减小很久以前的梯度对当前训练的影响,从而避免学习率无限减小的问题。

gi,t=wgi,t1+(1w)ΔJ(θi,t)2θi,t=θi,t1ηgi,t+ϵΔJ(θi,t) g_{i,t} = wg_{i,t-1} + (1-w)\Delta J(\theta_{i,t})^2\\ \theta_{i,t} = \theta_{i,t-1} - \frac{\eta}{\sqrt{g_{i,t}+\epsilon}}\cdot\Delta J(\theta_{i,t}) \\

AdaDelta也可以和Nesterov方法进行结合:
gi,t=wgi,t1+(1w)ΔJ(θi,tγVi(t1))2Vi(t)=γVi(t1)+ηgi,t+ϵΔJ(θi,tγVi(t1))θi,t=θi,t1V(t) g_{i,t} = wg_{i,t-1} + (1-w)\Delta J(\theta_{i,t} - \gamma V_i(t-1))^2\\ V_i(t)=\gamma V_i(t-1) + \frac{\eta}{\sqrt{g_{i,t}+\epsilon}}\cdot\Delta J(\theta_{i,t} - \gamma V_i(t-1)) \\ \theta_{i,t} = \theta_{i,t-1} - V(t)

8、Adam

前面我们从最经典的梯度下降法开始,介绍了几个改进版的梯度下降法。
Momentum方法通过添加动量,提高收敛速度;
Nesterov方法在进行当前更新前,先进行一次预演,从而找到一个更加适合当前情况的梯度方向和幅度;
Adagrad让不同的参数拥有不同的学习率,并且通过引入梯度的平方和作为衰减项,而在训练过程中自动降低学习率;
AdaDelta则对Adagrad进行改进,让模型在训练后期也能够有较为适合的学习率。

既然不同的参数可以有不同的学习率,那么不同的参数是不是也可以有不同的Momentum呢?

Adam方法就是根据上述思想而提出的,对于每个参数,其不仅仅有自己的学习率,还有自己的Momentum量,这样在训练的过程中,每个参数的更新都更加具有独立性,提升了模型训练速度和训练的稳定性。

Adam(Adaptive Moment Estimation):
V(t)=ρ1V(t1)+(1ρ)ΔJ(θ)Momentgt=ρ2gt1+(1ρ2)ΔJ(θ)2AdaDeltaV(t)^=V(t)1ρ1gt^=gt1ρ2θt=θt1ηgt^+ϵV(t)^ V(t) = \rho_1V(t-1) + (1-\rho)\Delta J(\theta) ---Moment项\\ g_t = \rho_2g_{t-1} + (1-\rho_2)\Delta J(\theta)^2 --- AdaDelta项\\ \hat{V(t)} = \frac{V(t)}{1-\rho_1}\\ \hat{g_t} = \frac{g_t}{1-\rho_2}\\ \theta_t = \theta_{t-1} - \frac{\eta}{\sqrt{\hat{g_t}+\epsilon}}\cdot \hat{V(t)}
一般的,ρ1\rho_1 设置为0.9, ρ2\rho_2 设置为0.999

总结

套用别人说过的一句话:

Adam works well in practice and outperforms other Adaptive techniques.

事实上,如果你的数据比较稀疏,那么像SGD,NAG以及Momentum的方法往往会表现的比较差,这是因为对于模型中的不同参数,他们均使用相同的学习率,这会导致那些应该更新快的参数更新的慢,而应该更新慢的有时候又会因为数据的原因的变得快。因此,对于稀疏的数据更应该使用Adaptive方法(Adagrad、AdaDelta、Adam)。同样,对于一些深度神经网咯或者非常复杂的神经网络,使用Adam或者其他的自适应(Adaptive)的方法也能够更快的收敛。

Reference:

[1] https://towardsdatascience.com/types-of-optimization-algorithms-used-in-neural-networks-and-ways-to-optimize-gradient-95ae5d39529f “Types of Optimization Algorithms used in Neural Networks and Ways to Optimize Gradient Descent”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章