[杂记]深度学习基本优化算法小结

0.

在深度学习的训练过程中,容易遇到的三个主要问题是局部最小值、鞍点和梯度消失。

局部最小值: 如果训练过程中落入的局部最小值点,则很有可能最终结果就是局部最优而不是全局最优。当然,如果有一定程度的噪声,就可能可以跳出这个局部最小值。这也是小批量随机梯度下降的优点,即它可以通过小批量梯度上的变化将参数从局部最小值移出。

梯度消失:缓解梯度消失的方法有很多,例如采用ReLU激活函数、BatchNorm等。
  \space  

1. 梯度下降、随机梯度下降、小批量梯度随机下降

首先要说明的是,绝大多数的深度学习问题是非凸的.对于损失函数 l l l,其具有Heissan矩阵:
H = [ ∂ l ∂ x i ∂ x j ] n × n H=[\frac{\partial l}{\partial x_i \partial x_j}]_{n\times n} H=[xixjl]n×n
其中 n n n为变量(是向量)的维度.
假如Heissan矩阵所有特征值为负,则具有局部最大值;所有特征值为正反之. 但是对于 n n n很大的情形,很难保证所有特征值同号,此时就是鞍点. 对于凸函数,其Heissan矩阵的特征值必然是非负的,因此深度学习的优化问题并不是凸优化.

补充:凸函数:
定义(凸函数):
  \space  
给定凸集 X X X,函数 f : X → R f:X\rightarrow \mathbb R f:XR(注意:凸函数定义在凸集上)被称为凸的,如果:
λ f ( x 1 ) + ( 1 − λ ) f ( x 2 ) ≥ f ( λ x 1 + ( 1 − λ ) x 2 ) , ∀ x 1 ≤ x 2 ∈ X , λ ∈ [ 0 , 1 ] \lambda f(x_1)+(1-\lambda)f(x_2)\ge f(\lambda x_1+ (1-\lambda)x_2),\forall x_1\le x_2\in X,\lambda \in [0,1] λf(x1)+(1λ)f(x2)f(λx1+(1λ)x2),x1x2X,λ[0,1]
  \space  
凸函数具有以下性质
1.Jensen不等式(函数的均值大于等于均值的函数)
2.局部最小值就是全局最小值(证明:反证法)
3.水平集仍是凸集,即:
S ≜ { x ∣ x ∈ X , f ( x ) ≤ b } S \triangleq\{x|x\in X ,f(x)\le b\} S{ xxX,f(x)b}仍是凸的.(证明:即证 λ x + ( 1 − λ ) x ′ ∈ S , ∀ x , x ′ ∈ S , λ ∈ [ 0 , 1 ] , 即 证 f ( λ x + ( 1 − λ ) x ′ ) ≤ b \lambda x+(1-\lambda)x'\in S,\forall x,x'\in S,\lambda \in [0,1],即证f(\lambda x+(1-\lambda)x')\le b λx+(1λ)xS,x,xS,λ[0,1],f(λx+(1λ)x)b)
4.如前所述,Heissan矩阵是半正定的.
5.能够处理约束问题:
min ⁡ f ( x ) s . t . c i ( x ) ≤ 0 , i ∈ I \min f(x) \\ s.t. \quad c_i(x)\le 0,i\in I minf(x)s.t.ci(x)0,iI
处理的方法有:1.拉格朗日乘数法、2.罚项、3.投影(应是拿投影约束范围。投影的定义为:集合外元素到集合的投影等于集合内离该集合外元素距离最近的元素: P X ( x ) ≜ arg min ⁡ x ′ ∈ X ∣ ∣ x − x ′ ∣ ∣ P_X(x)\triangleq\argmin_{x'\in X}||x-x'|| PX(x)xXargminxx

1.1 梯度下降

直观上,我们通过梯度方向的反方向更新参数应该可以接近最优点,也即:
x ← x − η ∇ f ( x ) , 其 中 f : R d → R \bm x\leftarrow \bm x-\eta \nabla f(\bm x),其中f:\mathbb R^d\rightarrow \mathbb R xxηf(x),f:RdR

注意 x \bm x x代表参数.其中 η \eta η为学习率. 如果很小,则收敛较慢.如果太大,则有可能会振荡甚至发散.

牛顿法可以更新学习率,但其由于存储消耗过大而不适用,下面详细说明.

f f f的Taylor展开为(忽略加粗):
f ( x + ϵ ) = f ( x ) + ϵ ∇ f ( x ) + 1 2 ϵ T H ϵ + o ( ∣ ∣ ϵ ∣ ∣ 3 ) f(x + \epsilon)=f(x)+ \epsilon\nabla f( x)+ \frac{1}{2}\epsilon^T \bm H \epsilon+o(||\epsilon||^3) f(x+ϵ)=f(x)+ϵf(x)+21ϵTHϵ+o(ϵ3)

两边对 ϵ \epsilon ϵ求导,得:
0 = ∇ f ( x ) + 1 2 ( H + H T ) ϵ = ∇ f ( x ) + H ϵ 0=\nabla f( x)+\frac{1}{2}( \bm H + \bm H ^T)\epsilon=\nabla f( x)+H\epsilon 0=f(x)+21(H+HT)ϵ=f(x)+Hϵ
(其中利用了 d ( x T A x ) d x = ( A T + A ) x \frac{d(x^TAx)}{dx}=(A^T+A)x dxd(xTAx)=(AT+A)x以及Heissan矩阵的对称性质)

于是: ϵ = − H − 1 ∇ f ( x ) \epsilon=-\bm H^{-1}\nabla f( x) ϵ=H1f(x)

显然要按这种方式更新,确实可以更好地接近最优点,但是需要 O ( d 2 ) O(d^2) O(d2)个空间复杂度来存储Heissan矩阵.且如果对于非凸函数,万一Heissan矩阵有负特征值,则可能会按照相反的方向更新.

1.2 随机梯度下降SGD

注意上述的梯度下降法是将整个样本的损失函数作为输入, 若共有 n n n个样本, 则计算的时间复杂度是 O ( n ) O(n) O(n),很大.

如果我们一次随机取一个样本 i i i, 将该样本在参数 x \bm x x下的损失函数记为 f i ( x ) f_i(\bm x) fi(x),则我们就用 f i ( x ) f_i(\bm x) fi(x)的梯度来估计整个样本集合的梯度,按照如下方式更新:

x ← x − η ∇ f i ( x ) \bm x\leftarrow \bm x-\eta \nabla f_i(\bm x) xxηfi(x)

此外,假如整体损失函数等于每个样本损失函数的平均来表示,即 f ( x ) = 1 n ∑ i = 1 n f i ( x ) f(\bm x)=\frac{1}{n}\sum_{i=1}^nf_i(\bm x) f(x)=n1i=1nfi(x),则 ∇ f i ( x ) 是 ∇ f ( x ) \nabla f_i(\bm x)是\nabla f(\bm x) fi(x)f(x)的无偏估计,因为:
E [ ∇ f i ( x ) ] = 1 n ∑ i = 1 n f i ( x ) = ∇ f ( x ) E[\nabla f_i(\bm x)]=\frac{1}{n}\sum_{i=1}^nf_i(\bm x)=\nabla f(\bm x) E[fi(x)]=n1i=1nfi(x)=f(x)

SGD的主要缺点是不能利用硬件的并行计算,且由于只采用一个样本的梯度信息,收敛性能不算好.

1.3 小批量SGD

为了能应用好GPU可以并行计算的特点,SGD这种一次取一个样本计算有些浪费。为此,我们可以一次取一批样本的梯度,来替换原来的一个样本的梯度:

x ← x − η ∣ I t ∣ ∑ i ∈ I t ∇ f i ( x ) \bm x\leftarrow \bm x-\frac{\eta}{|I_t|} \sum_{i\in I_t}\nabla f_i(\bm x) xxItηiItfi(x)

其中 I t ⊂ I I_t\subset I ItI.

2.动量法

梯度是函数值变化最快的方向,但有时会造成抖动. 如果我们在更新权重时考虑过去时间的梯度(也就是考虑过去的更新方向), 这样就像物理中的"惯性"一样,不至于一下子跑太偏.

考虑之前的小批量SGD,记
g t , t − 1 = 1 ∣ I t ∣ ∑ i ∈ I t ∇ f i ( x t − 1 ) \bm g_{t,t-1} = \frac{1}{|I_t|} \sum_{i\in I_t}\nabla f_i(\bm x_{t-1}) gt,t1=It1iItfi(xt1)

为了方便,将时间信息加入下标. g t , t − 1 \bm g_{t,t-1} gt,t1意为从 t − 1 t-1 t1时刻到 t t t时刻的更新. x t − 1 \bm x_{t-1} xt1是上一时刻的参数.

我们定义动量:
v t = β v t − 1 + g t , t − 1 v 0 = 0 \bm v_t =\beta\bm v_{t-1}+\bm g_{t,t-1}\\ \bm v_0= \bm0 vt=βvt1+gt,t1v0=0

也即本时刻的动量由上一时刻的动量和梯度方向表示. 显然,随着时间的延长旧时刻的梯度对动量的影响会越来越小. 为了论证这一点,可以将其展开:
v t = β v t − 1 + g t , t − 1 = v t = β ( β v t − 2 + g t − 1 , t − 2 ) + g t , t − 1 = . . . = β t − 1 ( β v 0 + g 1 , 0 ) + β 0 g t , t − 1 + β g t − 1 , t − 2 + . . . β t − 2 g 2 , 1 = ∑ τ = 0 t − 1 β τ g t − τ , t − τ − 1 \bm v_t =\beta\bm v_{t-1}+g_{t,t-1}=\bm v_t =\beta(\beta\bm v_{t-2}+g_{t-1,t-2})+g_{t,t-1}\\ =...=\beta^{t-1}(\beta\bm v_{0}+g_{1,0})+\beta^0 g_{t,t-1}+\beta g_{t-1,t-2}+...\beta^{t-2}g_{2,1}\\ =\sum_{\tau=0}^{t-1}\beta^\tau g_{t-\tau,t-\tau - 1} vt=βvt1+gt,t1=vt=β(βvt2+gt1,t2)+gt,t1=...=βt1(βv0+g1,0)+β0gt,t1+βgt1,t2+...βt2g2,1=τ=0t1βτgtτ,tτ1

因此,以动量信息代替梯度信息,按照如下方式更新权重:

v t ← β v t − 1 + g t , t − 1 x t ← x t − 1 − η v t \bm v_t \leftarrow\beta\bm v_{t-1}+\bm g_{t,t-1}\\ \bm x_t \leftarrow \bm x_{t-1}-\eta \bm v_t vtβvt1+gt,t1xtxt1ηvt

β = 0 \beta=0 β=0退化为常规的小批量SGD.

3.RMSprop

AdaGrad算法按下式更新状态变量:
s t = s t − 1 + g t 2 \bm s_t= \bm s_{t-1}+\bm g_t^2 st=st1+gt2

g t g_t gt的含义与之前相同.此后按下式更新权重:
x t ← x t − 1 − η s t + ϵ ∗ g t \bm x_t \leftarrow \bm x_{t-1}-\frac{\eta}{\sqrt{\bm s_t+\epsilon}}*\bm g_t xtxt1st+ϵ ηgt

其中*代表按元素乘法.这样做意味着:对于每个参数都具有不同的学习率(学习率 η s t + ϵ \frac{\eta}{\sqrt{\bm s_t+\epsilon}} st+ϵ η为向量 每个元素值都不同)

但是随着时间的增长,很可能 s t \bm s_t st会持续增长.为了对此加以约束,可以考虑:

s t = λ s t − 1 + ( 1 − λ ) g t 2 \bm s_t= \lambda\bm s_{t-1}+(1-\lambda)\bm g_t^2 st=λst1+(1λ)gt2

这就是RMSprop和AdaGrad的唯一不同之处.

4.Adam

将前面的思想结合起来,就产生了Adam算法.

同时考虑动量和状态变量:

v t = β 1 v t − 1 + ( 1 − β 1 ) g t s t = β 2 s t − 1 + ( 1 − β 2 ) g t 2 \bm v_t =\beta_1\bm v_{t-1}+(1-\beta_1)\bm g_t\\ \bm s_t= \beta_2\bm s_{t-1}+(1-\beta_2)\bm g_t^2 vt=β1vt1+(1β1)gtst=β2st1+(1β2)gt2

一般 1 > β 2 > β 1 1>\beta_2>\beta_1 1>β2>β1,也就是说状态变量的更新比动量慢.

但是像之前那样初始化为0值,会带来比较大的偏差.因为一开始虽然有梯度,但是 v t \bm v_t vt等的值会比较小.
为了应对在 t t t较小时梯度较小的情况, 可以按如下方式标准化:

v t ^ = v t 1 − β 1 t , s t ^ = s t 1 − β 2 t \hat{\bm v_t} = \frac{\bm v_t}{1-\beta_1^t},\hat{\bm s_t} = \frac{\bm s_t}{1-\beta_2^t} vt^=1β1tvt,st^=1β2tst

分母小于1,可以在开始时对值进行扩大.

结合RMSprop的方法,对每个参数赋予不同的学习率:

g t ′ = η s t ^ + ϵ ∗ v t ^ \bm g_t'=\frac{\eta}{\sqrt{\hat{\bm s_t} }+\epsilon}*\hat{\bm v_t} gt=st^ +ϵηvt^

实践表明 s t ^ + ϵ \sqrt{\hat{\bm s_t} }+\epsilon st^ +ϵ的效果比 s t ^ + ϵ \sqrt{\hat{\bm s_t}+\epsilon} st^+ϵ 好.

最后按如下方式更新:

x t ← x t − 1 − g t ′ \bm x_t \leftarrow \bm x_{t-1}-\bm g_t' xtxt1gt

Adam对学习率非常不敏感.

猜你喜欢

转载自blog.csdn.net/wjpwjpwjp0831/article/details/122244594