深度学习中优化算法概览

版权声明:欢迎转载,转载请注明出处:土豆洋芋山药蛋 https://blog.csdn.net/qq_33414271/article/details/85317453

一、发展背景及基本框架

梯度下降是目前神经网络中使用最为广泛的优化算法之一。为了弥补朴素梯度下降的种种缺陷,研究者们发明了一系列变种算法,从最初的 SGD (随机梯度下降) 逐步演进到 NAdam。然而,许多学术界最为前沿的文章中,都并没有一味使用 Adam/NAdam 等公认“好用”的自适应算法,很多甚至还选择了最为初级的 SGD 或者 SGD with Momentum 等。

深度学习优化算法的发展历程:
SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam

最基本的框架——梯度下降法(GD)

梯度下降法(GD:gradient descent )或最速下降法(SD:steepest descent )是求解无约束优化问题最常用的方法,实现简单。

梯度下降是指,在给定待优化的模型参数 θ R d \theta \in \mathbb{R}^d 和目标函数 J ( θ ) J(\theta) 后,算法通过沿梯度 θ J ( θ ) \nabla_\theta J(\theta) 的相反方向更新 θ \theta 来最小化 J ( θ ) J(\theta) 。学习率 η \eta 决定了每一时刻的更新步长。对于每一个时刻 t t ,我们可以用下述步骤描述梯度下降的流程:

(1) 计算目标函数关于参数的梯度
g t = θ J ( θ ) g_t = \nabla_\theta J(\theta)
(2) 根据历史梯度计算一阶和二阶动量
m t = ϕ ( g 1 , g 2 ,   , g t ) m_t = \phi(g_1, g_2, \cdots, g_t)
v t = ψ ( g 1 , g 2 ,   , g t ) v_t = \psi(g_1, g_2, \cdots, g_t)
(3) 更新模型参数
θ t + 1 = θ t 1 v t + ϵ m t \theta_{t+1} = \theta_t - \frac{1}{\sqrt{v_t + \epsilon}} m_t
其中, ϵ \epsilon 为平滑项,防止分母为零,通常取 1e-8。

二、GD算法体系

先上图做直观对比:
在这里插入图片描述
“长谷 (Long Valley)”点——没有基于梯度信息缩放的算法在这里很难打破对称性——SGD在哪里都找不到, Nesterov Accelerated Gradient(NAG) / Momentum 在优化方向上建立速度之前会出现振荡。(此时自适应算法会更好)

在这里插入图片描述
由于大的初始梯度,基于速度的技术(SGD-M ,NAG)被发射出来并在周围反弹。其中 Adagrad、Adadelta、RMSprop 从最开始就找到了正确的方向并快速收敛;SGD 找到了正确方向但收敛速度很慢;SGD-M 和 NAG 最初都偏离了航道,但也能最终纠正到正确方向,SGD-M 偏离的惯性比 NAG 更大。

在这里插入图片描述
鞍点(Saddle Point)附近的行为:
NAG /Momentum探索周围,几乎走了不同的路径。
Adadelta/Adagrad/RMSProp像加速SGD一样运行。

2.1-朴素 SGD (Stochastic Gradient Descent)

最为简单,没有动量的概念
在这里插入图片描述
这时,更新步骤就是最简单的 θ i + 1 = θ t η g t \theta_{i+1}= \theta_t - \eta g_t

SGD 的缺点在于收敛速度慢,可能在长谷处震荡。并且,如何合理的选择学习率是 SGD 的一大难点。

2.2-SGD with Momentum

为了抑制SGD的震荡,SGDM认为梯度下降过程可以加入惯性。下坡的时候,如果发现是陡坡,那就利用惯性跑的快一些。SGDM全称是SGD with momentum,在SGD基础上引入了一阶动量:
m t = γ m t 1 + η g t m_t = \gamma m_{t-1} + \eta g_t

SGD-M 在原步长之上,增加了与上一时刻步长相关的 γ m t 1 \gamma m_{t-1} γ \gamma 通常取 0.9 左右。这意味着参数更新方向不仅由当前的梯度决定,也与此前累积的下降方向有关。
这使得参数中那些梯度方向变化不大的维度可以加速更新,并减少梯度方向变化较大的维度上的更新幅度。由此产生了加速收敛和减小震荡的效果。
在这里插入图片描述
从形式上看,动量算法(红色)引入了变量v 充当速度角色——它代表参数在参数空间移动的方向和速率。速度被设为负梯度的指数衰减平均。

2.3-Nesterov Accelerated Gradient

更进一步的,人们希望下降的过程更加智能:算法能够在目标函数有增高趋势之前,减缓更新速率。

NAG 即是为此而设计的,其在 SGD-M 的基础上进一步改进了步骤 1 中的梯度计算公式:
g t = θ J ( θ γ m t 1 ) g_t = \nabla_\theta J(\theta - \gamma m_{t-1})
在这里插入图片描述
SGD-M 的步长计算了当前梯度(短蓝向量)和动量项 (长蓝向量)。然而,既然已经利用了动量项来更新 ,那不妨先计算出下一时刻 θ \theta 的近似位置 (棕向量),并根据该未来位置计算梯度(红向量),然后使用和 SGD-M 中相同的方式计算步长(绿向量)。这种计算梯度的方式可以使算法更好的「预测未来」,提前调整更新速率。

2.4-Adagrad(自适应更新学习率)

Ada为Adaptive,自适应算法。

SGD、SGD-M 和 NAG 均是以相同的学习率去更新 θ \theta 的各个分量。而深度学习模型中往往涉及大量的参数,不同参数的更新频率往往有所区别。

对于更新不频繁的参数(典型例子:更新 word embedding 中的低频词),我们希望单次步长更大,多学习一些知识;对于更新频繁的参数,我们则希望步长较小,使得学习到的参数更稳定,不至于被单个样本影响太多。

Adagrad算法即可达到此效果。其引入了二阶动量:

Adaptive Subgradient Methods for Online Learning and Stochastic Optimization

v t = diag ( i = 1 t g i , 1 2 , i = 1 t g i , 2 2 ,   , i = 1 t g i , d 2 ) v_t = \text{diag}(\sum_{i=1}^t g_{i,1}^2, \sum_{i=1}^t g_{i,2}^2, \cdots, \sum_{i=1}^t g_{i,d}^2)

其中, v t R d × d v_t \in \mathbb{R}^{d\times d} 是对角矩阵,其元素 v t , i i v_{t, ii} 为参数第 i 维从初始时刻到时刻 t 的梯度平方和。

此时,可以这样理解:学习率等效为 η / v t + ϵ \eta / \sqrt{v_t + \epsilon} 。对于此前频繁更新过的参数,其二阶动量的对应分量较大,学习率就较小。这一方法在稀疏数据的场景下表现很好。

2.5-RMSprop

在 Adagrad 中, v t v_t 是单调递增的,使得学习率逐渐递减至 0,可能导致训练过程提前结束。为了改进这一缺点,可以考虑在计算二阶动量时不累积全部历史梯度,而只关注最近某一时间窗口内的下降梯度。根据此思想有了 RMSprop

g t g t g_t \odot g_t g t 2 g_t^2 ,有
v t = γ v t 1 + ( 1 γ ) diag ( g t 2 ) v_t = \gamma v_{t-1} + (1-\gamma) \cdot \text{diag}(g_t^2)

其二阶动量采用指数移动平均公式计算,这样即可避免二阶动量持续累积的问题。和 SGD-M 中的参数类似,\gamma 通常取 0.9 左右。

CSC321 Neural Networks for Machine Learning - Lecture 6a

2.6-Adam

Adam可以认为是 RMSprop 和 Momentum 的结合。和 RMSprop 对二阶动量使用指数移动平均类似,Adam 中对一阶动量也是用指数移动平均计算。

Adam: A Method for Stochastic Optimization

m t = η [ β 1 m t 1 + ( 1 β 1 ) g t ] m_t = \eta[ \beta_1 m_{t-1} + (1 - \beta_1)g_t ]
v t = β 2 v t 1 + ( 1 β 2 ) diag ( g t 2 ) v_t = \beta_2 v_{t-1} + (1-\beta_2) \cdot \text{diag}(g_t^2)
其中,初值
m 0 = 0 m_0 = 0
v 0 = 0 v_0 = 0
注意到,在迭代初始阶段, m t m_t v t v_t 有一个向初值的偏移(过多的偏向了 0)。因此,可以对一阶和二阶动量做偏置校正 (bias correction),
m ^ t = m t 1 β 1 t \hat{m}_t = \frac{m_t}{1-\beta_1^t}
v ^ t = v t 1 β 2 t \hat{v}_t = \frac{v_t}{1-\beta_2^t}
再进行更新,
θ t + 1 = θ t 1 v ^ t + ϵ m ^ t \theta_{t+1} = \theta_t - \frac{1}{\sqrt{\hat{v}_t} + \epsilon } \hat{m}_t
可以保证迭代较为平稳。

三、小结

在这里插入图片描述
虽然这些算法在使用的时候或许只是一句代码,但了解其发展历程和基本特点是很有必要的。

参考:
[1]从 SGD 到 Adam —— 深度学习优化算法概览(一) - 骆梁宸的文章 - 知乎
https://zhuanlan.zhihu.com/p/32626442
[2]一个框架看懂优化算法之异同 SGD/AdaGrad/Adam - Juliuszh的文章 - 知乎
https://zhuanlan.zhihu.com/p/32230623
[3]https://blog.csdn.net/u012223913/article/details/78432412
[4]Visualizing Optimization Algos

猜你喜欢

转载自blog.csdn.net/qq_33414271/article/details/85317453