Dive into Deep Learning-优化算法(2)_dive into deeplearning
作者:运维做开发 | 2024-06-27 10:08:34
赞
踩
dive into deeplearning
梯度下降
为什么梯度下降可以优化目标函数:以一维梯度下降为例
f
:
R
→
R
f:\mathbb{R}\rightarrow\mathbb{R}
f:R→R,利用泰勒展开,可以得到:
f
(
x
+
ϵ
)
=
f
(
x
)
+
ϵ
f
′
(
x
)
+
O
(
ϵ
2
)
f(x + \epsilon) = f(x) + \epsilon f'(x) + O(\epsilon^2)
f(x+ϵ)=f(x)+ϵf′(x)+O(ϵ2),此时假定步长
η
>
0
\eta>0
η>0,取
ϵ
=
−
η
f
′
(
x
)
\epsilon = -\eta f'(x)
ϵ=−ηf′(x),代入泰勒展开式中可以得到
f
(
x
−
η
f
′
(
x
)
)
=
f
(
x
)
−
η
f
′
2
(
x
)
+
O
(
η
2
f
′
2
(
x
)
)
f(x - \eta f'(x)) = f(x) - \eta f'^2(x) + O(\eta^2f'^2(x))
f(x−ηf′(x))=f(x)−ηf′2(x)+O(η2f′2(x)),由于式中
η
f
′
2
(
x
)
>
0
\eta f'^2(x)>0
ηf′2(x)>0,所以总可以调整
η
\eta
η使得高阶项影响变小,
f
(
x
−
η
f
′
(
x
)
)
<
f
(
x
)
f(x - \eta f'(x)) < f(x)
f(x−ηf′(x))<f(x),所以如果我们使用
x
←
x
−
η
f
′
(
x
)
x\leftarrow x - \eta f'(x)
x←x−ηf′(x)就可以使得函数
f
(
x
)
f(x)
f(x)的值减小;
学习率:上式中的
η
\eta
η,需要在更新缓慢和迭代震荡中选择合适的值;
多元梯度下降,和上面类似,只是对于输入
x
=
[
x
1
,
x
2
,
⋯
,
x
d
]
T
x=[x_1,x_2,\cdots,x_d]^T
x=[x1,x2,⋯,xd]T,目标函数
f
:
R
d
→
R
f:\mathbb{R}^d\rightarrow \mathbb{R}
f:Rd→R,相应的梯度也是多元的,
∇
f
(
x
)
=
[
∂
f
(
x
)
∂
x
1
,
∂
f
(
x
)
∂
x
2
,
⋯
,
∂
f
(
x
)
∂
x
d
]
T
\nabla f(x) = [\frac{\partial f(x)}{\partial x_1},\frac{\partial f(x)}{\partial x_2},\cdots,\frac{\partial f(x)}{\partial x_d}]^T
∇f(x)=[∂x1∂f(x),∂x2∂f(x),⋯,∂xd∂f(x)]T,对应的泰勒展开
f
(
x
+
ϵ
)
=
f
(
x
)
+
ϵ
T
∇
f
(
x
)
+
O
(
∣
∣
ϵ
∣
∣
2
)
f(x + \epsilon) = f(x) + \epsilon^T\nabla f(x) + O(||\epsilon||^2)
f(x+ϵ)=f(x)+ϵT∇f(x)+O(∣∣ϵ∣∣2)
自适应方法(牛顿法):上面的例子可以看出学习率比较敏感,需要仔细调整,借助泰勒展开,
f
(
x
+
ϵ
)
=
f
(
x
)
+
ϵ
T
∇
f
(
x
)
+
1
2
ϵ
T
∇
2
f
(
x
)
ϵ
+
O
(
∣
∣
ϵ
∣
∣
3
)
f(x + \epsilon) = f(x) + \epsilon^T\nabla f(x) + \frac{1}{2}\epsilon^T\nabla^2f(x)\epsilon + O(||\epsilon||^3)
f(x+ϵ)=f(x)+ϵT∇f(x)+21ϵT∇2f(x)ϵ+O(∣∣ϵ∣∣3),其中将
H
=
∇
2
f
(
x
)
H = \nabla^2 f(x)
H=∇2f(x)定义为
f
f
f的Hessian矩阵,
d
×
d
d\times d
d×d,其中H的储存代价对于深度学习来说很高,不适用,现在暂时不考虑适用性问题,
f
f
f的最小值处
∇
f
=
0
\nabla f=0
∇f=0,可以得到
∇
f
(
x
)
+
H
ϵ
=
0
\nabla f(x) + H\epsilon = 0
∇f(x)+Hϵ=0,得到
ϵ
=
−
H
−
1
∇
f
(
x
)
\epsilon = -H^{-1}\nabla f(x)
ϵ=−H−1∇f(x),更新
x
:
x
=
x
−
η
H
−
1
∇
f
(
x
)
x:x = x - \eta H^{-1}\nabla f(x)
x:x=x−ηH−1∇f(x)
随机梯度下降
深度学习中目标函数是训练数据集中每个样本损失函数的平均值即
f
(
x
)
=
1
n
∑
i
=
1
n
f
i
(
x
)
f(x) = \frac{1}{n}\sum_{i=1}^nf_i(x)
f(x)=n1∑i=1nfi(x),其中
n
n
n是样本数目,对应的梯度计算为
∇
f
(
x
)
=
1
n
∑
i
=
1
n
∇
f
i
(
x
)
\nabla f(x) = \frac{1}{n}\sum_{i = 1}^n\nabla f_i(x)
∇f(x)=n1∑i=1n∇fi(x),一次迭代的计算代价为
O
(
n
)
O(n)
O(n);
随机梯度下降
S
G
D
SGD
SGD在每次迭代中都随机采样一个索引
i
i
i,之后计算梯度
x
←
x
−
η
∇
f
i
(
x
)
x\leftarrow x - \eta\nabla f_i(x)
x←x−η∇fi(x)来进行更新,每次迭代的复杂度降为
O
(
1
)
O(1)
O(1),而且随机梯度
∇
f
i
(
x
)
\nabla f_i(x)
∇fi(x)是完整梯度
∇
f
(
x
)
\nabla f(x)
∇f(x)的无偏估计
E
i
∇
f
i
(
x
)
=
1
n
∑
i
=
1
n
f
i
(
x
)
=
∇
f
(
x
)
\mathbb{E}_i\nabla f_i(x) = \frac{1}{n}\sum_{i=1}^nf_i(x) = \nabla f(x)
Ei∇fi(x)=n1∑i=1nfi(x)=∇f(x),但是此时梯度下降每次迭代都存在噪声,而且当迭代到最小值附近的时候仍然会收到噪声的影响,需要动态的调整学习率;
动态学习率:与时间相关的学习率
η
(
t
)
\eta(t)
η(t)来取代常量
η
\eta
η
小批量随机梯度下降
核心是为了计算效率;
平均梯度减小了方差;
动量法
v
t
=
β
v
t
−
1
+
g
t
,
t
−
1
v_t = \beta v_{t - 1} + g_{t,t-1}
vt=βvt−1+gt,t−1,其中
g
t
,
t
−
1
g_{t,t-1}
gt,t−1为此时的梯度,
v
t
v_t
vt是动量,累加了过去的梯度,每次迭代
x
t
←
x
t
−
1
−
η
t
v
t
x_t\leftarrow x_{t - 1}-\eta_tv_t
xt←xt−1−ηtvt
一个解决办法是记录看到的特定特征的次数,并以此来调整学习率,例如
s
(
i
,
t
)
s(i,t)
s(i,t)表示截止
t
t
t时观察到的功能
i
i
i的次数,学习率由原来
η
=
η
0
t
+
c
→
η
0
s
(
i
,
t
)
+
c
\eta=\frac{\eta_0}{\sqrt{t + c}}\rightarrow \frac{\eta_0}{\sqrt{s(i,t) + c}}
η=t+cη0→s(i,t)+cη0,允许每个维度拥有自己的学习率;
AdaGrad算法就是将粗略的计数器
s
(
i
,
t
)
s(i,t)
s(i,t)替换为先前观察所得梯度的平方之和来解决这个问题,使用
s
(
i
,
t
+
1
)
=
s
(
i
,
t
)
+
(
∂
i
f
(
x
)
)
2
s(i,t+1)=s(i,t)+(\partial_if(x))^2
s(i,t+1)=s(i,t)+(∂if(x))2来调整学习率;
g
t
=
∂
w
l
(
y
t
,
f
(
x
t
,
w
)
)
,
s
t
=
s
t
−
1
+
g
t
2
,
w
t
=
w
t
−
1
−
η
s
t
+
ϵ
⋅
g
t
g_t = \partial_wl(y_t,f(x_t,w)),s_t = s_{t - 1} + g^2_t,w_t = w_{t - 1}-\frac{\eta}{\sqrt{s_t + \epsilon}}\cdot g_t
gt=∂wl(yt,f(xt,w)),st=st−1+gt2,wt=wt−1−st+ϵη⋅gt;
RMSProp算法
Adagrad算法中
s
t
s_t
st是梯度平方的累加,会持续增长,几乎是线性递增,迭代后期学习率下降很快,加爵该问题按照动量的方式,公式如下:
s
t
←
γ
s
t
−
1
+
(
1
−
γ
)
g
t
2
,
x
t
←
x
t
−
1
−
η
s
t
+
ϵ
⊙
g
t
s_t\leftarrow \gamma s_{t - 1} + (1 - \gamma)g_t^2,x_t\leftarrow x_{t - 1} - \frac{\eta}{\sqrt{s_t + \epsilon}}\odot g_t
st←γst−1+(1−γ)gt2,xt←xt−1−st+ϵη⊙gt;
Adadelta算法
是AdaGrad的另一种变体,使用了两个状态变量,
s
t
s_t
st用于存储梯度二阶导数的泄露平均值,
Δ
x
t
\Delta x_t
Δxt用于存储模型本身中参数变化二阶导数的泄露平均值,也就是调整之后梯度的平方泄露平方值,公式如下:
s
t
=
ρ
s
t
−
1
+
(
1
−
ρ
)
g
t
2
s_t = \rho s_{t - 1} + (1 - \rho)g_t^2
st=ρst−1+(1−ρ)gt2,调整之后的梯度为
g
t
′
=
Δ
x
t
−
1
+
ϵ
s
t
+
ϵ
⊙
g
t
g'_t = \frac{\sqrt{\Delta x_{t - 1}+\epsilon}}{\sqrt{s_t + \epsilon}}\odot g_t
gt′=st+ϵΔxt−1+ϵ⊙gt,
Δ
x
t
=
ρ
Δ
x
t
−
1
+
(
1
−
ρ
)
g
t
′
2
\Delta x_t = \rho \Delta x_{t - 1} + (1 - \rho)g_t'^{2}
Δxt=ρΔxt−1+(1−ρ)gt′2,然后使用缩放之后的梯度进行更新
x
t
=
x
t
−
1
−
g
t
′
x_t = x_{t - 1}-g'_t
xt=xt−1−gt′;
在某种程度上,Adadelta没有学习率参数。相反,它使用参数本身的变化率来调整学习率
Adam算法
公式如下:
动量和二次矩的指数加权移动平均值计算
v
t
←
β
1
v
t
−
1
+
(
1
−
β
1
)
g
t
,
s
t
←
β
2
s
t
−
1
+
(
1
−
β
2
)
g
t
2
v_t\leftarrow \beta_1 v_{t - 1} + (1 - \beta_1)g_t,s_t\leftarrow \beta_2 s_{t - 1} + (1 - \beta_2)g_t^2
vt←β1vt−1+(1−β1)gt,st←β2st−1+(1−β2)gt2,因为如果初始化
v
0
=
s
0
=
0
v_0=s_0=0
v0=s0=0会获得一个相当大的初始偏差,所以通过使用
∑
i
=
0
t
β
i
=
1
−
β
t
1
−
β
\sum_{i = 0}^t\beta^i = \frac{1 - \beta^t}{1 - \beta}
∑i=0tβi=1−β1−βt来解决,相应的标准化状态变量
v
^
t
=
v
t
1
−
β
1
t
,
s
^
t
=
s
t
1
−
β
2
t
\widehat{v}_t = \frac{v_t}{1 - \beta_1^t},\widehat{s}_t = \frac{s_t}{1 - \beta_2^t}
vt=1−β1tvt,st=1−β2tst,有了这两个状态之后,对梯度进行重新缩放
g
t
′
=
η
v
^
t
s
^
t
+
ϵ
g'_t = \frac{\eta \widehat{v}_t}{\sqrt{\widehat{s}_t} + \epsilon}
gt′=st+ϵηvt,最后对变量进行更新
x
t
←
x
t
−
1
−
g
t
′
x_t\leftarrow x_{t - 1} - g'_t
xt←xt−1−gt′