各种梯度下降

Gradient descent (梯度下降)

来自维基百科,https://en.wikipedia.org/wiki/Gradient_descent


在数学中,梯度下降 gradient descent(也叫做最速下降 steepest descent)是一种一阶迭代优化算法,用于寻找可微函数的局部最小值。它的思路是,在当前点求出函数的梯度(或者近似梯度),然后向着梯度的反方向走一小步,因为这个方向是最陡的。然后不断地重复这个过程。相反地,朝着梯度的方向走,会把你带往函数的局部最大值,这个过程被称为梯度上升(gradient ascent

梯度下降通常归功于柯西(Augustin-Louis Cauchy),它在1847年首次提出。- -《Cauchy and the Gradient Method》
阿达马(Jacques Solomon Hadamard)在1907年独立提出了类似的方法。
库里(Haskell Curry)与1944年首先研究了它对非线性优化问题的收敛性 - - 《The Method of Steepest Descent for Non-linear Minimization Problems》

描述

梯度下降基于这样一种观察:如果定义一个多变量函数 F ( x ) \pmb{F}(\textbf{x}) FFF(x) ,它在点 a \mathbf{a} a 的邻域是可微的,在点 a \mathbf{a} a 处求出函数 F \pmb{F} FFF 的梯度,如果向着梯度的反方向走: − ∇ F ( a ) -\nabla\pmb{F}(\textbf{a}) FFF(a),则 F ( x ) \pmb{F}(\textbf{x}) FFF(x) 是下降得最快的。

由此可见,对于式子 a n + 1 = a n − γ ∇ F ( a n ) \textbf{a}_{n+1} = \textbf{a}_n - \gamma \nabla \pmb{F}(\textbf{a}_n) an+1=anγFFF(an),如果有足够小的学习率 (或者叫步长) γ ∈ R + \gamma \in \mathbb{R}_+ γR+,那么就有 F ( a n + 1 ) ≤ F ( a n ) \pmb{F}(\textbf{a}_{n+1}) \leq \pmb{F}(\textbf{a}_n) FFF(an+1)FFF(an)。为什么是减去梯度呢,之前写的文章(https://blog.csdn.net/Yemiekai/article/details/119081873)有个例子里有个图片做了简单的解释。

考虑到上述观察,为了得到 F \pmb{F} FFF 的局部最小值,我们从一个猜测的初始值 x 0 \textbf{x}_0 x0 开始,考虑序列:
x 0 , x 1 , x 2 , … \textbf{x}_0,\textbf{x}_1,\textbf{x}_2,\dots x0,x1,x2, ,满足 x n + 1 = x n − γ n ∇ F ( x n ) ,    n ≥ 0 \textbf{x}_{n+1} = \textbf{x}_n - \gamma_n \nabla \pmb{F}(\textbf{x}_n), \; n \geq0 xn+1=xnγnFFF(xn),n0
则我们会得到一个单调序列:
F ( x 0 ) ≥ F ( x 1 ) ≥ F ( x 2 ) ≥ ⋯   , \pmb{F}(\textbf{x}_0) \geq \pmb{F}(\textbf{x}_1) \geq \pmb{F}(\textbf{x}_2) \geq \cdots, FFF(x0)FFF(x1)FFF(x2),
所以这个序列( x n \textbf{x}_n xn)会如期收敛到所需要的局部最小值。 注意步长 γ \gamma γ 的值可以在每次迭代中改变。
在这里插入图片描述
这个过程如上图所示,假设 F \pmb{F} FFF 被定义在一个平面上,它的形状就像一个碗状。蓝色的的曲线是等高线,即在同一条等高线上的 F \pmb{F} FFF 的值是相同恒定的。每个点上有一个红色的箭头,表示该点梯度相反的方向。每个点的梯度与穿过该点的等高线正交。可以看到梯度下降把我们带到了碗底,在那里能得到 F \pmb{F} FFF 的最小值。


例子

线性方程组的解凸二次优化问题
(来自知乎:https://zhuanlan.zhihu.com/p/330267047

A ∈ R n × n \pmb{A} \in \pmb{R}^{ \textbf{\textit{n}}\times \textbf{\textit{n}}} AAARRRn×n 是实对称正定矩阵, b ∈ R n \textbf{\textit{b}} \in \textbf{\textit{R}}^{\textbf{\textit{n}}} bRn,则求解凸二次优化问题: min ⁡ f ( x ) = 1 2 x T A x − b T x \min f(x)=\dfrac{1}{2} \textbf{\textit{x}}^{\textbf{\textit{T}}} \pmb{A} \textbf{\textit{x}} - \textbf{\textit{b}}^{\textbf{\textit{T}}} \pmb{x} minf(x)=21xTAAAxbTxxx等价于求解线性方程组 A x = b \pmb{A} \pmb{x} = \pmb{b} AAAxxx=bbb

证明:
二次型二阶可导,极小值点处梯度为零,现对优化的目标函数求梯度。
二次型本质上具有: f ( x ) = 1 2 x T A x − b T x = 1 2 ∑ i = j a i i x i 2 + 1 2 ∑ i ≠ j a i j x i x j − ∑ i b i x i \begin{aligned} f(x) &=\dfrac{1}{2} \textbf{\textit{x}}^{\textbf{\textit{T}}} \pmb{A} \textbf{\textit{x}} - \textbf{\textit{b}}^{\textbf{\textit{T}}} \pmb{x} \\[1.5em] &= \dfrac{1}{2}\sum_{i=j} \pmb{a}_{ii} \pmb{x}_i^2 + \dfrac{1}{2}\sum_{i\neq j}\pmb{a}_{ij} \pmb{x}_i \pmb{x}_j - \sum_{i} \pmb{b}_i \pmb{x}_i \end{aligned} f(x)=21xTAAAxbTxxx=21i=jaaaiixxxi2+21i=jaaaijxxxixxxjibbbixxxi

计算梯度的分量表达式: ∇ f ( x ) i = ∂ f ∂ x i = a i i x i + ∑ j ≠ i a i j x j − b i = ∑ j a i j x j − b i \begin{aligned} \nabla f(\pmb{x})_i &= \dfrac{\partial \pmb{f}}{ \partial \pmb{x}_i} \\[1.5em] &= \pmb{a}_{ii} \pmb{x}_{i} + \sum_{j\neq i} \pmb{a}_{ij} \pmb{x}_j -\pmb{b}_i \\[1.5em] &= \sum_{j} \pmb{a}_{ij} \pmb{x}_j - \pmb{b}_i \end{aligned} f(xxx)i=xxxifff=aaaiixxxi+j=iaaaijxxxjbbbi=jaaaijxxxjbbbi

合在一起写成矩阵形式:
∇ f ( x ) = A x − b = 0 \nabla f(\pmb{x}) = \pmb{Ax} - \pmb{b} = 0 f(xxx)=AxAxAxbbb=0

显然,凸二次优化问题的极值条件等价于该线性方程组。凸二次优化问题在建模中十分常见,这说明讨论线性方程组的求解方法具有普遍的实用价值。然而对于规模较大的问题,使用线性代数中的克莱姆法则暴力展开将导致时间开销巨大,而高斯消元法算法流程又较为复杂。这里用一种常见的数值分析方法,求得线性方程组的数值近似解。

最速梯度下降法:
称优化目标函数的梯度为残量(Residue),即是当前解对于线性方程组的不满足量:
r ( x ) = A x − b \pmb{r}(\pmb{x}) = \pmb{Ax} - \pmb{b} rrr(xxx)=AxAxAxbbb
由于函数是凸函数,极值点一定存在。当前解处函数的梯度值表示了函数值上升最快的方向(梯度方向上方向导数最大)。那么沿着相反的方向每迭代一步就会更加靠近最优的极小值解。于是,我们定义迭代关系:
x ( k + 1 ) = x ( k ) − α k ∇ f ( x ( k ) ) = x ( k ) − α k ( A x ( k ) − b ) \begin{aligned} \pmb{x}^{(k+1)} &= \pmb{x}^{(k)} - \alpha_k \nabla \pmb{f} (\pmb{x}^{(k)}) \\[1.5em] &= \pmb{x}^{(k)} - \alpha_k \left( \pmb{A} \pmb{x}^{(k)} - \pmb{b }\right)\\[1.5em] \end{aligned} xxx(k+1)=xxx(k)αkfff(xxx(k))=xxx(k)αk(AAAxxx(k)bbb)

其中 x ( k ) \pmb{x}^{(k)} xxx(k) 表示迭代第 k k k 轮的解, α k \alpha_k αk 表示每轮迭代的步长,即每一步下降多少的权重。步长应当随着 k k k 而变化,因为越靠近驻点的梯度会越小,接近于 0 0 0 的时候收敛。最后应当减小步长,不然在梯度附近会来回震荡,在最优解之间左右摇摆。

在最速下降法中,将 x ( k + 1 ) \pmb{x}^{(k+1)} xxx(k+1) 作为自变量代回原函数,并看做 α k \alpha_k αk 的函数,对其进行最小化:
min ⁡ h ( α ) = f ( x ( k + 1 ) ) = f ( x ( k ) − α k ( A x ( k ) − b ) ) \begin{aligned} \min h(\alpha) &= f \left( \pmb{x}^{(k+1)} \right) \\[1.5em] &= f \left( \pmb{x}^{(k)} - \alpha_k \left( \pmb{A} \pmb{x}^{(k)} - \pmb{b} \right) \right) \end{aligned} minh(α)=f(xxx(k+1))=f(xxx(k)αk(AAAxxx(k)bbb))
同样的,驻点处梯度为零。根据链式求导法则:

在这里插入图片描述
最后一步由于 A \pmb{A} AAA 是正定矩阵,所以分母也是一个正定二次型,值不为零,可以直接除过来。由此,我们最终得到了解的迭代关系:
在这里插入图片描述



Stochastic Gradient descent (SGD,随机梯度下降)

它可以被当做是梯度下降随机近似
原本的梯度下降是把整个数据集的数据扔进去,算出一个梯度。
假如我们有 500 500 500 万个样本,那么我们每迈一步,就要算 500 500 500 万个样本的梯度,这样效率太低了。

随机梯度下降是用随机选择数据子集来计算梯度。尤其是在高维优化问题中,这减少了计算负担,实现更快的迭代以换取更低的收敛速度。

虽然单个样本或者一小批样本不能反映整体的趋势,甚至把你的求解带偏,损失会波动。但是长远来看,只要迭代次数足够多,最终还是收敛的。

本质上它还是梯度下降,只是每次计算用多少数据的问题。
有的人说 SGD \text{SGD} SGD 每次只用 1 1 1 个样本,有的人说是用 1 1 1 批(mini-batch)样本。
知道意思就行了,不要纠结到底用多少样本。


随机梯度下降的过程如下:
∙ \bullet 选择一个初始的参数向量 w \pmb{w} www 和学习率 η \eta η.
∙ \bullet 重复下面步骤,直至获得最小值:
   ∙ \bullet 把训练集打乱。
   ∙ \bullet 对于 i = 1 , 2 , … , n , i = 1, 2, \dots, n, i=1,2,,n, 做:
     ∙ \bullet w : = w − η ∇ F i ( w ) \pmb{w} := \pmb{w} - \eta \nabla \pmb{F}_i (\pmb{w}) www:=wwwηFFFi(www)


Batch Gradient Descent (批梯度下降)

Mini Batch Gradient Descent (小批量梯度下降)

其实意思也一样,只是每一个 step 用多少样本的问题。
有的人说 Batch Gradient descent 是用整个样本,有的人说是用一批(此时等同于 Mini Batch Gradient Descent)。



Momentum Gradient descent (动量梯度下降)

它是随机梯度下降的一种改进。这种方法最早出现在 Rumelhart,Hinton 和 Williams 等人关于反向传播学习的论文中。《Learning representations by back-propagating errors》

这是一种带动量的随机梯度下降,它会在每次迭代中记住上一次的更新量 Δ w \Delta \pmb{w} Δwww,然后与当前的梯度做一个线性组合,以决定最终参数更新多少:
Δ w : = α Δ w − η ∇ F i ( w ) w : = w + Δ w \begin{aligned} & \Delta \pmb{w} := \alpha \Delta \pmb{w} - \eta \nabla \pmb{F}_i (\pmb{w}) \\ & \pmb{w} :=\pmb{w} + \Delta \pmb{w} \end{aligned} Δwww:=αΔwwwηFFFi(www)www:=www+Δwww w : = w − η ∇ F i ( w ) + α Δ w \pmb{w} :=\pmb{w} - \eta \nabla \pmb{F}_i (\pmb{w}) + \alpha \Delta \pmb{w} www:=wwwηFFFi(www)+αΔwww

其中你要解决的最小化问题是 F ( w ) \pmb{F}(\pmb{w}) FFF(www) w \pmb{w} www 是它的参数。
η \eta η 是步长(也叫学习率)。
α \alpha α 是指数衰减因子, α ∈ ( 0 , 1 ) \alpha \in (0,1) α(0,1),决定你更新参数 w \pmb{w} www 时,当前梯度和以往的梯度各自占多少贡献。



Averaged Stochastic Gradient Descent (平均随机梯度下降)

由 Ruppert 和 Polyak 在1980 年代后期提出。《Acceleration of stochastic approximation by averaging》

它是一种普通的随机梯度下降,在当前迭代中用随机梯度下降更新参数,得到 w i \pmb{w}_i wwwi,记录下来。然后对过往时刻求平均: w ˉ = 1 t ∑ i = 1 t − 1 w i \bar{\pmb{w}} = \dfrac{1}{t} \sum^{t-1}_{i=1} \pmb{w}_i wwwˉ=t1i=1t1wwwi

然后把当前网络参数换成这个平均后的 w ˉ \bar{\pmb{w}} wwwˉ,继续下一个迭代。



AdaGrad (Adaptive Gradient,自适应梯度)

g τ = ∇ F i ( w ) \pmb{g}_{\tau} = \nabla \pmb{F}_i (\pmb{w}) gggτ=FFFi(www) 表示第 τ \tau τ 次 iteration 算出来的梯度。每个 iteration 的梯度都会保存起来。参数数量是 j j j,有 j j j 个梯度。
到了第 τ \tau τ 次迭代的时候,对过往每个时刻的 g \pmb{g} ggg 求平方,把所有时刻的平方的结果都加起来,用 G j , j = ∑ τ = 1 t g τ , j 2 G_{j,j} = \sum\limits^t_{\tau = 1} g^2_{\tau, j} Gj,j=τ=1tgτ,j2 表示。
然后开根号, G j , j = ∑ τ = 1 t g τ , j 2 \sqrt{G_{j,j}} = \sqrt{ \sum\limits^t_{\tau = 1} g^2_{\tau, j} } Gj,j =τ=1tgτ,j2 ,学习率为 η G j , j \dfrac{\eta}{\sqrt{G_{j,j}}} Gj,j η

为了防止分母为 0 0 0,有时候会加上一个很小的值 ϵ = 1 0 − 8 \epsilon = 10^{-8} ϵ=108

最终的参数更新式子为: w j : = w j − η G j , j + ϵ g j w_j := w_j - \frac{\eta}{\sqrt{G_{j,j} + \epsilon } } g_j wj:=wjGj,j+ϵ ηgj

这说明什么?学习率除以一个东西,这个东西是过往梯度的积累。
也就是说,过往梯度越大,学习率就会越小。

SGD系列的都没有用到二阶动量。二阶动量的出现,才意味着“自适应学习率”优化算法时代的到来。SGD及其变种以同样的学习率更新每个参数,但深度神经网络往往包含大量的参数,这些参数并不是总会用得到。
∙ \bullet 对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;
∙ \bullet 对于偶尔更新的参数,我们了解的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些。
因此,Adagrad 非常适用于稀疏数据。

Dean 等人发现 Adagrad 能够大幅提高 SGD 的鲁棒性,并在 Google 用其训练大规模神经网络,这其中就包括 在 YouTube 中学习识别猫。除此之外,Pennington 等人用 Adagrad 来训练 GloVe 词嵌入,因为罕见的词汇需要比常见词更大的更新。

参数更新越频繁,二阶动量越大,学习率就越小。有趣的是,如果去掉开方操作,算法性能会大幅下降。



RMSProp (Root Mean Square Propagation)

参考
https://zh.d2l.ai/chapter_optimization/rmsprop.html
https://keras.io/zh/optimizers/#rmsprop
https://paddlepedia.readthedocs.io/en/latest/tutorials/deep_learning/optimizers/rmsprop.html

上面 AdaGrad 那个 G j , j G_{j,j} Gj,j,原本等于 g 0 2 + g 1 2 + g 2 2 + ⋯ + g τ 2 g_0^2 + g_1^2 + g_2^2 + \cdots + g_{\tau}^2 g02+g12+g22++gτ2

按照递归的方式可以写成: v τ = v τ − 1 + g τ 2 v_{\tau} = v_{\tau-1} + g_{\tau}^2 vτ=vτ1+gτ2,其中( v τ − 1 = g 0 2 + ⋯ + g τ − 1 2 v_{\tau -1} = g_0^2 + \cdots + g_{\tau -1}^2 vτ1=g02++gτ12

由于 AdaGrad 简单粗暴地累计过往的所有梯度,用于更新学习率。
这样做缺乏规范化,没有约束力。

RMSProp 对 AdaGrad 做了修改,以在非凸情况下表现更好,它改变梯度累积为指数加权的移动平均值,从而丢弃距离较远的历史梯度信息关注最近的梯度信息

现在用移动平均(或者说动量法)的方式来积累根号里面那个东西。在 t t t 时刻:
v t = γ v t − 1 + ( 1 − γ ) g t 2 v_t = \gamma v_{t-1} + (1-\gamma) g_{t}^2 vt=γvt1+(1γ)gt2
其中 g t = ∇ F i ( w ) g_t = \nabla F_i (w) gt=Fi(w) 表示当前时刻的梯度。

然后就是和 Adagrad 一样:
w : = w − η v t + ϵ g t w:= w - \frac{\eta}{\sqrt{ v_t + \epsilon } } g_t w:=wvt+ϵ ηgt

这里作者推荐 γ \gamma γ 0.9 0.9 0.9,学习率 η \eta η 0.001 0.001 0.001



Adam (Adaptive Moment Estimation)

它是 RMSProp 的升级版,也是 RMSProp 和 Momentum Gradient descent 的结合体。
把动量梯度下降的一阶动量和 RMSProp 的二阶动量都拿来了。

对于当前训练迭代次数 t t t,给定参数 w ( t ) w^{(t)} w(t) 和损失函数 L ( t ) L^{(t)} L(t),Adam 的更新过程如下:

m w ( t + 1 ) ← β 1 m w ( t ) + ( 1 − β 1 ) ∇ w L ( t ) v w ( t + 1 ) ← β 2 v w ( t ) + ( 1 − β 2 ) ( ∇ w L ( t ) ) 2 m^{(t+1)}_{w} \leftarrow \beta_1 m^{(t)}_{w} + (1-\beta_1) \nabla_w L^{(t)} \\[1em] v^{(t+1)}_{w} \leftarrow \beta_2 v^{(t)}_{w} + (1-\beta_2) \left( \nabla_w L^{(t)} \right)^2 \\[1em] mw(t+1)β1mw(t)+(1β1)wL(t)vw(t+1)β2vw(t)+(1β2)(wL(t))2以上分别表示一阶动量(可以说是均值,mean)和二阶动量(可以说是方差,variance)。
其中 β 1 \beta_1 β1 通常取 0.9 0.9 0.9 β 2 \beta_2 β2 通常取 0.999 0.999 0.999
初始时刻 m m m v v v 可能为 0 0 0,代进去算出来下一时刻的 m m m v v v 也接近 0 0 0 ,这样不好。
于是我们这样弄一下: m ^ w = m w ( t + 1 ) 1 − β 1 t v ^ w = v w ( t + 1 ) 1 − β 2 t \hat{m}_w = \frac{ m^{(t+1)}_{w} }{ 1- \beta_1^{t} } \\[1em] \hat{v}_w = \frac{ v^{(t+1)}_{w} }{ 1- \beta_2^{t} } \\[1em] m^w=1β1tmw(t+1)v^w=1β2tvw(t+1)最后: w t + 1 ← w ( t ) − η m ^ w v ^ w + ϵ w^{t+1} \leftarrow w^{(t)} - \eta \frac{ \hat{m}_w }{ \sqrt{\hat{v}_w } + \epsilon } wt+1w(t)ηv^w +ϵm^w

以上 5 5 5 条式子合起来就是 Adam 的步骤。

优点:
—— 通过一阶动量和二阶动量,有效控制学习率步长和梯度方向,防止梯度的振荡和在鞍点的静止。
—— 实现简单,计算高效,对内存需求少。
—— 参数的更新不受梯度的伸缩变换影响。
—— 超参数具有很好的解释性,且通常无需调整或仅需很少的微调。
—— 更新的步长能够被限制在大致的范围内(初始学习率)。
—— 能自然地实现步长退火过程(自动调整学习率)。
—— 很适合应用于大规模的数据及参数的场景。
—— 适用于不稳定目标函数。
—— 适用于梯度稀疏或梯度存在很大噪声的问题。

缺点:
—— 可能不收敛:二阶动量是固定时间窗口内的累积,随着时间窗口的变化,遇到的数据可能发生巨变,使得 v t v_t vt 可能会时大时小,不是单调变化。这就可能在训练后期引起学习率的震荡,导致模型无法收敛。
—— 可能错过全局最优解:自适应学习率算法可能会对前期出现的特征过拟合,后期才出现的特征很难纠正前期的拟合效果。后期Adam的学习率太低,影响了有效的收敛。
—— 对于具有显著差异的梯度,我们可能会遇到收敛性问题。我们可以通过使用更大的小批量或者切换到改进的估计值 v t v_t vt 来修正它们。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值