拟牛顿法
一、牛顿法
1.1 基本介绍
牛顿法属于利用一阶和二阶导数的无约束目标最优化方法。基本思想是,在每一次迭代中,以牛顿方向为搜索方向进行更新。牛顿法对目标的可导性更严格,要求二阶可导,有Hesse矩阵求逆的计算复杂的缺点。XGBoost本质上就是利用牛顿法进行优化的。
1.2 基本原理
现在推导牛顿法。
假设无约束最优化问题是
对于一维 x x 的情况,可以将 在 x(t) x ( t ) 附近用二阶泰勒展开近似:
然后用泰勒展开的极值点近似 f(x) f ( x ) 的极值点:
因此
于是得到迭代公式, g g 和分别是目标在当前 x x 上的一阶和二阶导
推广到 x x 是多维向量的情况, 仍然是向量,而 Ht H t 是Hesse矩阵
以二维 x=(x1,x2) x = ( x 1 , x 2 ) 为例:
参数更新方程推广为:
可见,每一次迭代的更新方向都是当前点的牛顿方向,步长固定为1。每一次都需要计算一阶导数 g g 以及Hesse矩阵的逆矩阵,对于高维特征而言,求逆矩阵的计算量巨大且耗时。
1.3 阻尼牛顿法
从上面的推导中看出,牛顿方向 能使得更新后函数处于极值点,但是它不一定是极小点,也就是说牛顿方向可能是下降方向,也可能是上升方向,以至于当初始点远离极小点时,牛顿法有可能不收敛。因此提出 阻尼牛顿法,在牛顿法的基础上,每次迭代除了计算更新方向(牛顿方向),还要对最优步长做一维搜索。
算法步骤
(1)给定给初始点
x(0)
x
(
0
)
,允许误差
ϵ
ϵ
(2)计算点
x(t)
x
(
t
)
处梯度
gt
g
t
和Hesse矩阵
H
H
,若则停止迭代
(3)计算点
x(t)
x
(
t
)
处的牛顿方向作为搜索方向:
(4)从点 x(t) x ( t ) 出发,沿着牛顿方向 d(t) d ( t ) 做一维搜索,获得最优步长:
(5)更新参数
二、拟牛顿法
2.1 提出的初衷
牛顿法中的Hesse矩阵
H
H
在稠密时求逆计算量大,也有可能没有逆(Hesse矩阵非正定)。拟牛顿法提出,用不含二阶导数的矩阵 替代牛顿法中的
H−1t
H
t
−
1
,然后沿搜索方向
−Utgt
−
U
t
g
t
做一维搜索。根据不同的
Ut
U
t
构造方法有不同的拟牛顿法。
注意拟牛顿法的 关键词:
- 不用算二阶导数
- 不用求逆
2.2 拟牛顿条件
牛顿法的搜索方向是
为了不算二阶导及其逆矩阵,设法构造一个矩阵 U U ,用它来逼近
现在为了方便推导,假设 f(x) f ( x ) 是二次函数,于是 Hesse 矩阵 H H 是常数阵,任意两点 和 x(t+1) x ( t + 1 ) 处的梯度之差是:
等价于
那么对非二次型的情况,也仿照这种形式,要求近似矩阵 U U 满足类似的关系:
或者写成
以上就是 拟牛顿条件,不同的拟牛顿法,区别就在于如何确定 U U 。
2.3 DFP法
为了方便区分,下面把称作 D D (表示DFP)。
DFP推导
现在已知拟牛顿条件
假设已知 Dt D t ,希望用叠加的方式求 Dt+1 D t + 1 ,即 Dt+1=Dt+ΔDt D t + 1 = D t + Δ D t ,代入得到
假设满足这个等式的 ΔDt Δ D t 是这样的形式:
首先,对照一下就能发现:
其次,要保证 ΔDt Δ D t 是对称的,参照 ΔDt Δ D t 的表达式,最简单就是令
第二个条件代入第一个得到:
然后代入回 ΔDt Δ D t 的表达式:
观察一下两项分式,第一项仅涉及向量乘法,时间复杂度是 O(n) O ( n ) ,第二项涉及矩阵乘法,时间复杂度是 O(n2) O ( n 2 ) ,综合起来是 O(n2) O ( n 2 ) 。
DFP算法步骤
(1)给定初始点
x(0)
x
(
0
)
,允许误差
ϵ
ϵ
,令
D0=In
D
0
=
I
n
(
n
n
是的维数),
t=0
t
=
0
(2)计算搜索方向
d(t)=−D−1t⋅gt
d
(
t
)
=
−
D
t
−
1
⋅
g
t
(3)从点
x(t)
x
(
t
)
出发,沿着
d(t)
d
(
t
)
做一维搜索,获得最优步长并更新参数:
(4)判断精度,若 |gt+1|<ϵ | g t + 1 | < ϵ 则停止迭代,否则转(5)
(5)计算 Δg=gt+1−gt Δ g = g t + 1 − g t , Δx=x(t+1)−x(t) Δ x = x ( t + 1 ) − x ( t ) ,更新 H H
(6) t=t+1 t = t + 1 ,转(2)
2.4 BFGS法
为了方便区分,下面把 U U 称作(表示BFGS)。
BFGS推导
拟牛顿条件
推导与DFP相似,但是,可以看到BFGS这种拟牛顿条件的形式与BFP的是对偶的,所以迭代公式只要把 Δxt Δ x t 和 Δgt Δ g t 调换一下就好。
只不过有个问题,按照下面这个迭代公式,不也一样要求逆吗?这就要引入谢尔曼莫里森公式了。
Sherman-Morrison 公式
对于任意非奇异方阵
A
A
,是
n
n
维向量,若,则
该公式描述了在矩阵 A A 发生某种变化时,如何利用之前求好的逆,求新的逆。
对迭代公式引入两次 Sherman-Morrison 公式就能得到
就得到了逆矩阵之间的推导。可能有人会问,第一个矩阵不也要求逆吗?其实这是一个迭代算法,初始矩阵设为单位矩阵(对角阵也可以)就不用求逆了。
这个公式的详细推导可以参考 这里或者 这里。
BFGS算法步骤
虽然下面的矩阵写成
B−1
B
−
1
,但要明确,BFGS从头到尾都不需要算逆,把下面的
B−1
B
−
1
换成
H
H
这个符号,也是一样的。
(1)给定初始点 ,允许误差
ϵ
ϵ
,设置
B−10
B
0
−
1
,
t=0
t
=
0
(2)计算搜索
d(t)=−B−1t⋅gt
d
(
t
)
=
−
B
t
−
1
⋅
g
t
(3)从点
x(t)
x
(
t
)
出发,沿着
d(t)
d
(
t
)
做一维搜索,获得最优步长并更新参数:
(4)判断精度,若 |gt+1|<ϵ | g t + 1 | < ϵ 则停止迭代,否则转(5)
(5)计算 Δg=gt+1−gt Δ g = g t + 1 − g t , Δx=x(t+1)−x(t) Δ x = x ( t + 1 ) − x ( t ) ,更新 B−1 B − 1 ,然后
(6) t=t+1 t = t + 1 ,转(2)
2.5 L-BFGS法(Limited-memory BFGS)
对于 d d 维参数,BFGS算法需要保存一个大小的 B−1 B − 1 矩阵,实际上只需要每一轮的 Δx Δ x 和 Δg Δ g ,也可以递归计算出当前迭代的 B−1 B − 1 矩阵,L-BFGS就是基于这种思想,实现了节省内存的BFGS。
L-BFGS推导
BFGS的递推公式:
现在假设 ρt=1ΔxTtΔgt ρ t = 1 Δ x t T Δ g t , Vt=In−ρtΔgtΔxTt V t = I n − ρ t Δ g t Δ x t T ,则递推公式可以写成
给定的初始矩阵 B−10 B 0 − 1 后,之后的每一轮都可以递推计算
一直到最后 B−1k+1 B k + 1 − 1 可以由 t=0 t = 0 到 t=k t = k 的 Δxt Δ x t 和 Δgt Δ g t 表示:
看起来很长,其实可以写成一个求和项
这个求和项包含了从 0 0 到的所有 Δx Δ x 和 Δg Δ g ,而根据实际需要,可以只取最近的 m m 个,也就是:
工程上的L-BFGS
我们关心的其实不是
B−1t
B
t
−
1
本身如何,算
B−1t
B
t
−
1
的根本目的是要算本轮搜索方向
B−1tgt
B
t
−
1
g
t
以下算法摘自《Numerical Optimization》,它可以高效地计算出拟牛顿法每一轮的搜索方向。仔细观察一下,你会发现它实际上就是复现上面推导的那一堆很长的递推公式,你所需要的是最近
m
m
轮的和
Δg
Δ
g
,后向和前向算完得到最终的
r
r
就是搜索方向 ,之后要做一维搜索或者什么的都可以。
解释一下算法的符号和本文符号之间的对应关系,
si=Δxi
s
i
=
Δ
x
i
,
yi=Δgi
y
i
=
Δ
g
i
,
Hk=B−1k
H
k
=
B
k
−
1
代码实现可以参考这里。
L-BFGS算法步骤
(1)给定初始点
x(0)
x
(
0
)
,允许误差
ϵ
ϵ
,预定保留最近
m
m
个向量,设置 ,
t=0
t
=
0
(2)用Algorithm 9.1计算搜索方向
d(t)=−B−1t⋅gt
d
(
t
)
=
−
B
t
−
1
⋅
g
t
(3)从点
x(t)
x
(
t
)
出发,沿着
d(t)
d
(
t
)
做一维搜索,获得最优步长并更新参数:
(4)判断精度,若 |gt+1|<ϵ | g t + 1 | < ϵ 则停止迭代,否则转(5)
(5)判断 t>m t > m ,删掉存储的 Δxt−m Δ x t − m 和 Δgt−m Δ g t − m
(5)计算 Δg=gt+1−gt Δ g = g t + 1 − g t , Δx=x(t+1)−x(t) Δ x = x ( t + 1 ) − x ( t ) ,令 t=t+1 t = t + 1 ,转(2)
最后,有时候你看不懂BFGS到底意味着什么,并不是你英文差,而是因为这个简称真的没有意义。。。。。