摘要:
之前写过一篇关于常见优化算法的总结,但是当时由于时间的关系,没有做太多细节的总结。这篇文章结合上一篇文章,做更加细节的总结。
梯度下降法
在优化算法里面,梯度下降法是最为核心的一个算法,我们熟知,所谓的梯度下降法就是形如下式的式:
wt:=wt−1−λ∂L∂w(0)
(0)
w
t
:=
w
t
−
1
−
λ
∂
L
∂
w
这个式子的背后支撑是负梯度方向是函数值下降最快的方向。
以一个二元函数
f(x,y)
f
(
x
,
y
)
说明一下。
f(x,y)
f
(
x
,
y
)
的方向导数为
grad(f)=∂f(x,y)∂xcosθ+∂f(x,y)∂ysinθ
g
r
a
d
(
f
)
=
∂
f
(
x
,
y
)
∂
x
c
o
s
θ
+
∂
f
(
x
,
y
)
∂
y
s
i
n
θ
写成向量的形式==>
∂f(x,y)∂xcosθ+∂f(x,y)∂ysinθ=(∂f(x,y)∂y,∂f(x,y)∂x)(cosθ,sinθ)
∂
f
(
x
,
y
)
∂
x
c
o
s
θ
+
∂
f
(
x
,
y
)
∂
y
s
i
n
θ
=
(
∂
f
(
x
,
y
)
∂
y
,
∂
f
(
x
,
y
)
∂
x
)
(
c
o
s
θ
,
s
i
n
θ
)
进一步的有:
grad(f)=f⃗ ⋅e⃗ =|f||e|cosϕ
g
r
a
d
(
f
)
=
f
→
⋅
e
→
=
|
f
|
|
e
|
c
o
s
ϕ
,
ϕ
ϕ
是两个向量的夹角。
可以看到当
cosϕ
c
o
s
ϕ
取=1方向导数升上的最快。
当
cosϕ
c
o
s
ϕ
取-1时,方向导数下降的最快(负梯度方向)
举一个例子,对于线性回归问题,采用MSE做损失函数时有:
L(yi,ŷ i)=∑mi=112(yi−ŷ i)2
L
(
y
i
,
y
^
i
)
=
∑
i
=
1
m
1
2
(
y
i
−
y
^
i
)
2
==>其中
ŷ i=wTxi
y
^
i
=
w
T
x
i
,代入上式
==>
L(yi,ŷ i)=∑mi=112(yi−wTxi)2
L
(
y
i
,
y
^
i
)
=
∑
i
=
1
m
1
2
(
y
i
−
w
T
x
i
)
2
==>对
wj
w
j
求导,
∂L(yi,ŷ i)∂wj=∑mi=1(yi−wTxi)xj(1)
(1)
∂
L
(
y
i
,
y
^
i
)
∂
w
j
=
∑
i
=
1
m
(
y
i
−
w
T
x
i
)
x
j
对
wj利用梯度下降迭代求解
w
j
利
用
梯
度
下
降
迭
代
求
解
:
wj:=wj−λ∂L∂wj(2)
(2)
w
j
:=
w
j
−
λ
∂
L
∂
w
j
(1)式代入(2)有,
wj:=wj−λ∑mi=1(yi−wTxi)xj(3)
(3)
w
j
:=
w
j
−
λ
∑
i
=
1
m
(
y
i
−
w
T
x
i
)
x
j
可以看到,每次在迭代的时候,需要计算m条样本。一般当样本量太大时,这个方法效率不太高。所以对这里改进有以下几种梯度下降法。
1.随机梯度下降法(SGD)
随机梯度下降法一般的做法是只随机选取一条来计算梯度值,也就是(3)式简化为:
wj:=wj−λ(yi−wTxi)xj(4)
(4)
w
j
:=
w
j
−
λ
(
y
i
−
w
T
x
i
)
x
j
2.小批量批梯度下降法(Mini-batch GD)
随机k条样本来计算梯度值,(3)式简化为:
wj:=wj−λ∑ki(yi−wTxi)xj(5)
(5)
w
j
:=
w
j
−
λ
∑
i
k
(
y
i
−
w
T
x
i
)
x
j
简单对比一下这几个方法:
对于训练速度比较:
显然,随机梯度下降每次只均匀选取一个样本来计算梯度值,训练速度自然比梯度下降法要快。
对于收敛速度比较:
随机梯度下降由于每次只选取了一个样本来计算梯度值,所以每次梯度方向可能会有很大的变化,所以收敛速度自然也慢于梯度下降法。
对于准确率比较:
随机梯度下降法每次只选取一个样本来计算平均值,导致当前梯度值只是局部的具体值,导致解可能不是局部最优的解。
3.SAG(Stochastic Average Gradient,随机平均梯度下降法)
SAG在SGD的基础上进化而来。主要思想是这样的:
SGD每次随机选一条样本计算梯度值。
而SAG每次利用两条样本来计算梯度值,而这里两条样本不是在同一次迭代中选择的。而是前一条来自于上一次迭代(算法流程中的
yi
y
i
),后一条则是当前迭代(算法流程中的
f′i(x)
f
i
′
(
x
)
)的时候选择的。具体算法流程如下:
具体参考文章:梯度下降法-知乎
4.Adagrad
下面再简单的补充几种优化算法的思想,这些优化算法大多数都是应用在神经网络的训练里面的。
Adagrad算法能够自适应地调整学习率。对于出现次数比较多的特征采用小的学习率,对于出现次数比较少的特征才用大的学习率。这里的出现次数其实应该理解成特征稀疏程度。
具体来说,按照下式进行迭代更新:
θt+1,i=θt,i−ηGt,i+ϵ√gt,i
θ
t
+
1
,
i
=
θ
t
,
i
−
η
G
t
,
i
+
ϵ
g
t
,
i
。
η
η
是固定设定的学习率,通常为0.01。
在每次迭代的时候会调整
η
η
,调整的因子为
1Gt,i√
1
G
t
,
i
。
ϵ
ϵ
是平滑项,防止分母出现0。
其中关键是
Gt,i‾‾‾√
G
t
,
i
的计算:
Gt,i‾‾‾√
G
t
,
i
表达在第t次迭代的时候,模型的第i个参数历史梯度平方和。
比如对于参数
w2
w
2
,第一次迭代时候
g1,2=0.001
g
1
,
2
=
0.001
,第二次迭代时
g2,2=0.004
g
2
,
2
=
0.004
,那么在第三次迭代时
g3,2=0.003
g
3
,
2
=
0.003
,
G3,2‾‾‾‾√=g21,2+g22,2+g23,3
G
3
,
2
=
g
1
,
2
2
+
g
2
,
2
2
+
g
3
,
3
2
Adagrad的问题主要体现在,随着 Gt,i‾‾‾√ G t , i 的积累,其值不断的增大。部分特征会提前的结束训练。
牛顿法
首先我考虑只有一个变量的情况,我们对某函数
f(x)
f
(
x
)
在
x=x0
x
=
x
0
处做二阶泰勒展开。
f(x)=f(x0)+f′(x0)(x−x0)+12f″(x0)(x−x0)2
f
(
x
)
=
f
(
x
0
)
+
f
′
(
x
0
)
(
x
−
x
0
)
+
1
2
f
″
(
x
0
)
(
x
−
x
0
)
2
(忽略无穷小项)
假设 x0 x 0 出是函数 f(x) f ( x ) 的极小值点,我们试图通过对 f(x) f ( x ) 二阶泰勒展开,然后选找到下一个极小值点。这种思路就是牛顿法。
既然需要求极小值,我们对
f(x)
f
(
x
)
求导。求导后有:
f′(x)=f′(x0)+(x−x0)f″(x0)
f
′
(
x
)
=
f
′
(
x
0
)
+
(
x
−
x
0
)
f
″
(
x
0
)
令导数
f′(x)=0
f
′
(
x
)
=
0
后有:
f′(x0)+(x−x0)f″(x0)=0
f
′
(
x
0
)
+
(
x
−
x
0
)
f
″
(
x
0
)
=
0
==>
x−x0=−f′(x0)f″(x0)
x
−
x
0
=
−
f
′
(
x
0
)
f
″
(
x
0
)
也就是所有得迭代关系:
x=x0−f′(x0)f″(x0)(5)
(5)
x
=
x
0
−
f
′
(
x
0
)
f
″
(
x
0
)
(5)式表达的意思为:从极小值点
x0
x
0
出发,每迭代一次可以逼近f(x)的极小值点。
相比于梯度下降法,牛顿法用了函数
f(x)
f
(
x
)
的二阶导数值。
下面可以把牛顿法推广到多维空间上,只不过这里需要知道多元函数的二阶泰勒展开表达式:
以二元函数
f(x,y)在xk,yk处二阶泰勒展开
f
(
x
,
y
)
在
x
k
,
y
k
处
二
阶
泰
勒
展
开
为例:
f(x,y)=f(xk,yk)+fx(xk,yk)(x−xk)+fy(xk,yk)(y−yk)+12fxx(xk,yk)(x−xk)2+12fxy(xk,yk)(x−xk)(y−yk)+12fyx(xk,yk)(x−xk)(y−yk)+12fyy(xk,yk)(y−yk)2
f
(
x
,
y
)
=
f
(
x
k
,
y
k
)
+
f
x
(
x
k
,
y
k
)
(
x
−
x
k
)
+
f
y
(
x
k
,
y
k
)
(
y
−
y
k
)
+
1
2
f
x
x
(
x
k
,
y
k
)
(
x
−
x
k
)
2
+
1
2
f
x
y
(
x
k
,
y
k
)
(
x
−
x
k
)
(
y
−
y
k
)
+
1
2
f
y
x
(
x
k
,
y
k
)
(
x
−
x
k
)
(
y
−
y
k
)
+
1
2
f
y
y
(
x
k
,
y
k
)
(
y
−
y
k
)
2
推广到多元函数 f(x)=f(x1,x2,...xn) f ( x ) = f ( x 1 , x 2 , . . . x n ) 写成矩阵表达式的结果
f(x)=f(xk)+∇f(xk)⋅(x−xk)+12(x−xk)⋅∇2f(xk)⋅(x−xk)(6) (6) f ( x ) = f ( x k ) + ∇ f ( x k ) ⋅ ( x − x k ) + 1 2 ( x − x k ) ⋅ ∇ 2 f ( x k ) ⋅ ( x − x k )
把
∇f(xk)
∇
f
(
x
k
)
记为
gk
g
k
,把
∇2f(xk)
∇
2
f
(
x
k
)
记为
Hk
H
k
,则(6)可以有:
f(x)=f(xk)+gk⋅(x−xk)+12(x−xk)⋅Hk⋅(x−xk)(6)
(6)
f
(
x
)
=
f
(
x
k
)
+
g
k
⋅
(
x
−
x
k
)
+
1
2
(
x
−
x
k
)
⋅
H
k
⋅
(
x
−
x
k
)
下面做法和一元函数的情况一样,我们求多元函数
f(x,y)
f
(
x
,
y
)
的驻点,即对
x
x
求偏导,并令偏导为0,可以得到到:
gk+Hk⋅(x−xk)=0(7)
(7)
g
k
+
H
k
⋅
(
x
−
x
k
)
=
0
当hessian矩阵
Hk
H
k
可逆时有:
x=xk−H−1k⋅gk(8)
(8)
x
=
x
k
−
H
k
−
1
⋅
g
k
值得注意的是,其中
−H−1k⋅gk
−
H
k
−
1
⋅
g
k
为牛顿的搜索方向,通常记为
dk
d
k
BFGS
通过上面的推导可以发现,牛顿法在迭代寻找解的时候需要计算hessian矩阵的逆,这个运算的代价是非常大的,所以对牛顿法进行改进工作很多都是在对求hessian矩阵下手的。比如对于BFGS算法就是一种拟牛顿法。
BFGS是以四个人的名字缩写命名的(Broyden,Fletcher,Goldfarb,Shanno)。
这里介绍一下BFGS的主要思想,详细推导过程参考本文末尾的文献。
BFGS才用迭代方式直接逼近hessian矩阵。
算法步骤2里面的 dk=−Dk⋅gk d k = − D k ⋅ g k 和我们前面推导的公式很类似,只是在 D D 的地方一样,这里的,其他具体计算方式为步骤6的递归关系。