拟牛顿法(DFP、BFGS、L-BFGS)

拟牛顿法

一、牛顿法

1.1 基本介绍

牛顿法属于利用一阶和二阶导数的无约束目标最优化方法。基本思想是,在每一次迭代中,以牛顿方向为搜索方向进行更新。牛顿法对目标的可导性更严格,要求二阶可导,有Hesse矩阵求逆的计算复杂的缺点。XGBoost本质上就是利用牛顿法进行优化的。

1.2 基本原理

现在推导牛顿法。
假设无约束最优化问题是

minxf(x) min x f ( x )

对于一维 x x 的情况,可以将 f(x(t+1)) x(t) x ( t ) 附近用二阶泰勒展开近似:
f(x(t+1))=f(x(t))+f(x(t))Δx+12f(x(t))Δx2 f ( x ( t + 1 ) ) = f ( x ( t ) ) + f ′ ( x ( t ) ) Δ x + 1 2 f ″ ( x ( t ) ) Δ x 2

然后用泰勒展开的极值点近似 f(x) f ( x ) 的极值点:
f(x(t+1))x(t+1)=f(x(t))+f(x(t))Δx=0 ∂ f ( x ( t + 1 ) ) ∂ x ( t + 1 ) = f ′ ( x ( t ) ) + f ″ ( x ( t ) ) Δ x = 0

因此
Δx=x(t+1)x(t)=f(x(t))f(x(t))=gtht Δ x = x ( t + 1 ) − x ( t ) = − f ′ ( x ( t ) ) f ″ ( x ( t ) ) = − g t h t

于是得到迭代公式, g g h分别是目标在当前 x x 上的一阶和二阶导
x(t+1)=x(t)gtht

推广到 x x 是多维向量的情况,gt 仍然是向量,而 Ht H t 是Hesse矩阵
H=[2fxixj] H = [ ∂ 2 f ∂ x i ∂ x j ]

以二维 x=(x1,x2) x = ( x 1 , x 2 ) 为例:
H=2fx212fx2x12fx1x22fx22 H = [ ∂ 2 f ∂ x 1 2 ∂ 2 f ∂ x 1 x 2 ∂ 2 f ∂ x 2 x 1 ∂ 2 f ∂ x 2 2 ]

参数更新方程推广为:
x(t+1)=x(t)H1tgt x ( t + 1 ) = x ( t ) − H t − 1 g t

可见,每一次迭代的更新方向都是当前点的牛顿方向,步长固定为1。每一次都需要计算一阶导数 g g 以及Hesse矩阵的逆矩阵,对于高维特征而言,求逆矩阵的计算量巨大且耗时。

1.3 阻尼牛顿法

从上面的推导中看出,牛顿方向 H1g 能使得更新后函数处于极值点,但是它不一定是极小点,也就是说牛顿方向可能是下降方向,也可能是上升方向,以至于当初始点远离极小点时,牛顿法有可能不收敛。因此提出 阻尼牛顿法,在牛顿法的基础上,每次迭代除了计算更新方向(牛顿方向),还要对最优步长做一维搜索。

算法步骤

(1)给定给初始点 x(0) x ( 0 ) ,允许误差 ϵ ϵ
(2)计算点 x(t) x ( t ) 处梯度 gt g t 和Hesse矩阵 H H ,若|gt|<ϵ则停止迭代
(3)计算点 x(t) x ( t ) 处的牛顿方向作为搜索方向:

d(t)=H1tgt d ( t ) = − H t − 1 g t

(4)从点 x(t) x ( t ) 出发,沿着牛顿方向 d(t) d ( t ) 做一维搜索,获得最优步长:
λt=argminλf(x(t)+λd(t)) λ t = arg ⁡ min λ f ( x ( t ) + λ ⋅ d ( t ) )

(5)更新参数
x(t+1)=x(t)+λtd(t) x ( t + 1 ) = x ( t ) + λ t ⋅ d ( t )


二、拟牛顿法

2.1 提出的初衷

牛顿法中的Hesse矩阵 H H 在稠密时求逆计算量大,也有可能没有逆(Hesse矩阵非正定)。拟牛顿法提出,用不含二阶导数的矩阵 Ut 替代牛顿法中的 H1t H t − 1 ,然后沿搜索方向 Utgt − U t g t 做一维搜索。根据不同的 Ut U t 构造方法有不同的拟牛顿法。
注意拟牛顿法的 关键词

  • 不用算二阶导数
  • 不用求逆

2.2 拟牛顿条件

牛顿法的搜索方向是

d(t)=H1tgt d ( t ) = − H t − 1 g t

为了不算二阶导及其逆矩阵,设法构造一个矩阵 U U ,用它来逼近 H1
现在为了方便推导,假设 f(x) f ( x ) 是二次函数,于是 Hesse 矩阵 H H 是常数阵,任意两点 x(t) x(t+1) x ( t + 1 ) 处的梯度之差是:
f(x(t+1))f(x(t))=H(x(t+1)x(t)) ▽ f ( x ( t + 1 ) ) − ▽ f ( x ( t ) ) = H ⋅ ( x ( t + 1 ) − x ( t ) )

等价于
x(t+1)x(t)=H1[f(x(t+1))f(x(t))] x ( t + 1 ) − x ( t ) = H − 1 ⋅ [ ▽ f ( x ( t + 1 ) ) − ▽ f ( x ( t ) ) ]

那么对非二次型的情况,也仿照这种形式,要求近似矩阵 U U 满足类似的关系:
x(t+1)x(t)=Ut+1[f(x(t+1))f(x(t))]

或者写成
Δxt=Ut+1Δgt Δ x t = U t + 1 ⋅ Δ g t

以上就是 拟牛顿条件,不同的拟牛顿法,区别就在于如何确定 U U

2.3 DFP法

为了方便区分,下面把U称作 D D (表示DFP)。

DFP推导

现在已知拟牛顿条件

Δxt=Dt+1Δgt

假设已知 Dt D t ,希望用叠加的方式求 Dt+1 D t + 1 ,即 Dt+1=Dt+ΔDt D t + 1 = D t + Δ D t ,代入得到
ΔDtΔgt=ΔxtDtΔgt Δ D t Δ g t = Δ x t − D t Δ g t

假设满足这个等式的 ΔDt Δ D t 是这样的形式:
ΔDt=ΔxtqTtDtΔgtwTt Δ D t = Δ x t ⋅ q t T − D t Δ g t ⋅ w t T

首先,对照一下就能发现:
qTtΔgt=wTtΔgt=In q t T ⋅ Δ g t = w t T ⋅ Δ g t = I n

其次,要保证 ΔDt Δ D t 是对称的,参照 ΔDt Δ D t 的表达式,最简单就是令
qt=αtΔxtwt=βtDtΔgt q t = α t Δ x t w t = β t D t Δ g t

第二个条件代入第一个得到:
αt=1ΔgTtΔxtβt=1ΔgTtDtΔgt α t = 1 Δ g t T Δ x t β t = 1 Δ g t T D t Δ g t

然后代入回 ΔDt Δ D t 的表达式:
ΔDt=ΔxtΔxTtΔgTtΔxtDtΔgtΔgTtDtΔgTtDtΔgt Δ D t = Δ x t Δ x t T Δ g t T Δ x t − D t Δ g t Δ g t T D t Δ g t T D t Δ g 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 x的维数), t=0 t = 0
(2)计算搜索方向 d(t)=D1tgt d ( t ) = − D t − 1 ⋅ g t
(3)从点 x(t) x ( t ) 出发,沿着 d(t) d ( t ) 做一维搜索,获得最优步长并更新参数:

λt=argminλf(x(t)+λd(t))x(t+1)=x(t)+λtd(t) λ t = arg ⁡ min λ f ( x ( t ) + λ ⋅ d ( t ) ) x ( t + 1 ) = x ( t ) + λ t ⋅ d ( t )

(4)判断精度,若 |gt+1|<ϵ | g t + 1 | < ϵ 则停止迭代,否则转(5)
(5)计算 Δg=gt+1gt Δ g = g t + 1 − g t Δx=x(t+1)x(t) Δ x = x ( t + 1 ) − x ( t ) ,更新 H H
Dt+1=Dt+ΔxΔxTΔgTΔxDtΔgΔgTDtΔgTDtΔg

(6) t=t+1 t = t + 1 ,转(2)

2.4 BFGS法

为了方便区分,下面把 U U 称作B1(表示BFGS)。

BFGS推导

拟牛顿条件

Δxt=B1t+1ΔgtΔgt=Bt+1Δxt Δ x t = B t + 1 − 1 ⋅ Δ g t Δ g t = B t + 1 ⋅ Δ x t

推导与DFP相似,但是,可以看到BFGS这种拟牛顿条件的形式与BFP的是对偶的,所以迭代公式只要把 Δxt Δ x t Δgt Δ g t 调换一下就好。
ΔBt=ΔgtΔgTtΔxTtΔgtBtΔxtΔxTtBtΔxTtBtΔxt Δ B t = Δ g t Δ g t T Δ x t T Δ g t − B t Δ x t Δ x t T B t Δ x t T B t Δ x t

只不过有个问题,按照下面这个迭代公式,不也一样要求逆吗?这就要引入谢尔曼莫里森公式了。
Δxt=B1t+1Δgt Δ x t = B t + 1 − 1 ⋅ Δ g t

Sherman-Morrison 公式

对于任意非奇异方阵 A A u,vRn n n 维向量,若1+vTA1u0,则

(A+uvT)1=A1(A1u)(vTA1)1+vTA1u ( A + u v T ) − 1 = A − 1 − ( A − 1 u ) ( v T A − 1 ) 1 + v T A − 1 u

该公式描述了在矩阵 A A 发生某种变化时,如何利用之前求好的逆,求新的逆。
对迭代公式引入两次 Sherman-Morrison 公式就能得到
Bt+11=(InΔxtΔgtTΔxtTΔgt)Bt1(InΔgtΔxtTΔxtTΔgt)+ΔxtΔxtTΔxtTΔgt

就得到了逆矩阵之间的推导。可能有人会问,第一个矩阵不也要求逆吗?其实这是一个迭代算法,初始矩阵设为单位矩阵(对角阵也可以)就不用求逆了。
这个公式的详细推导可以参考 这里或者 这里

BFGS算法步骤

虽然下面的矩阵写成 B1 B − 1 ,但要明确,BFGS从头到尾都不需要算逆,把下面的 B1 B − 1 换成 H H 这个符号,也是一样的。
(1)给定初始点 x(0),允许误差 ϵ ϵ ,设置 B10 B 0 − 1 t=0 t = 0
(2)计算搜索 d(t)=B1tgt d ( t ) = − B t − 1 ⋅ g t
(3)从点 x(t) x ( t ) 出发,沿着 d(t) d ( t ) 做一维搜索,获得最优步长并更新参数:

λt=argminλf(x(t)+λd(t))x(t+1)=x(t)+λtd(t) λ t = arg ⁡ min λ f ( x ( t ) + λ ⋅ d ( t ) ) x ( t + 1 ) = x ( t ) + λ t ⋅ d ( t )

(4)判断精度,若 |gt+1|<ϵ | g t + 1 | < ϵ 则停止迭代,否则转(5)
(5)计算 Δg=gt+1gt Δ g = g t + 1 − g t Δx=x(t+1)x(t) Δ x = x ( t + 1 ) − x ( t ) ,更新 B1 B − 1 ,然后
B1t+1=(InΔxtΔgTtΔxTtΔgt)B1t(InΔgtΔxTtΔxTtΔgt)+ΔxtΔxTtΔxTtΔgt B t + 1 − 1 = ( I n − Δ x t Δ g t T Δ x t T Δ g t ) B t − 1 ( I n − Δ g t Δ x t T Δ x t T Δ g t ) + Δ x t Δ x t T Δ x t T Δ g t

(6) t=t+1 t = t + 1 ,转(2)

2.5 L-BFGS法(Limited-memory BFGS)

对于 d d 维参数,BFGS算法需要保存一个O(d2)大小的 B1 B − 1 矩阵,实际上只需要每一轮的 Δx Δ x Δg Δ g ,也可以递归计算出当前迭代的 B1 B − 1 矩阵,L-BFGS就是基于这种思想,实现了节省内存的BFGS。

L-BFGS推导

BFGS的递推公式:

B1t+1=(InΔxtΔgTtΔxTtΔgt)B1t(InΔgtΔxTtΔxTtΔgt)+ΔxtΔxTtΔxTtΔgt B t + 1 − 1 = ( I n − Δ x t Δ g t T Δ x t T Δ g t ) B t − 1 ( I n − Δ g t Δ x t T Δ x t T Δ g t ) + Δ x t Δ x t T Δ x t T Δ g t

现在假设 ρ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 ,则递推公式可以写成
B1t+1=VTtB1tVt+ρtΔxtΔxTt B t + 1 − 1 = V t T B t − 1 V t + ρ t Δ x t Δ x t T

给定的初始矩阵 B10 B 0 − 1 后,之后的每一轮都可以递推计算
B11=VT0B10V0+ρ0Δx0ΔxT0B12=VT1B10V1+ρ1Δx1ΔxT1=(VT1VT0)B10(V0V1)+VT1ρ0Δx0ΔxT0V1+ρ1Δx1ΔxT1 B 1 − 1 = V 0 T B 0 − 1 V 0 + ρ 0 Δ x 0 Δ x 0 T B 2 − 1 = V 1 T B 0 − 1 V 1 + ρ 1 Δ x 1 Δ x 1 T = ( V 1 T V 0 T ) B 0 − 1 ( V 0 V 1 ) + V 1 T ρ 0 Δ x 0 Δ x 0 T V 1 + ρ 1 Δ x 1 Δ x 1 T

一直到最后 B1k+1 B k + 1 − 1 可以由 t=0 t = 0 t=k t = k Δxt Δ x t Δgt Δ g t 表示:
B1t+1=++++(VTtVTt1VT1VT0)B10(V0Vt1Vt)(VTtVTt1VT2VT1)(ρ0Δx0ΔxT0)(V1Vt1Vt)VTt(ρt1Δxt1ΔxTt1)VtρtΔxtΔxTt B t + 1 − 1 = ( V t T V t − 1 T ⋯ V 1 T V 0 T ) B 0 − 1 ( V 0 ⋯ V t − 1 V t ) + ( V t T V t − 1 T ⋯ V 2 T V 1 T ) ( ρ 0 Δ x 0 Δ x 0 T ) ( V 1 ⋯ V t − 1 V t ) + ⋯ + V t T ( ρ t − 1 Δ x t − 1 Δ x t − 1 T ) V t + ρ t Δ x t Δ x t T

看起来很长,其实可以写成一个求和项
B1t+1=(i=t0VTi)B10(i=0tVi)+j=0t(i=tj+1VTi)(ρjΔxjΔxTj)(i=j+1tVi) B t + 1 − 1 = ( ∏ i = t 0 V i T ) B 0 − 1 ( ∏ i = 0 t V i ) + ∑ j = 0 t ( ∏ i = t j + 1 V i T ) ( ρ j Δ x j Δ x j T ) ( ∏ i = j + 1 t V i )

这个求和项包含了从 0 0 t的所有 Δx Δ x Δg Δ g ,而根据实际需要,可以只取最近的 m m 个,也就是:
Bt1=(i=t1tmViT)B01(i=tmt1Vi)+j=t1tm(i=tj+1ViT)(ρjΔxjΔxjT)(i=j+1tVi)

工程上的L-BFGS

我们关心的其实不是 B1t B t − 1 本身如何,算 B1t B t − 1 的根本目的是要算本轮搜索方向 B1tgt B t − 1 g t
以下算法摘自《Numerical Optimization》,它可以高效地计算出拟牛顿法每一轮的搜索方向。仔细观察一下,你会发现它实际上就是复现上面推导的那一堆很长的递推公式,你所需要的是最近 m m 轮的Δx Δg Δ g ,后向和前向算完得到最终的 r r 就是搜索方向 Bt1gt,之后要做一维搜索或者什么的都可以。
解释一下算法的符号和本文符号之间的对应关系, si=Δxi s i = Δ x i yi=Δgi y i = Δ g i Hk=B1k H k = B k − 1
代码实现可以参考这里

图片名称
L-BFGS算法步骤

(1)给定初始点 x(0) x ( 0 ) ,允许误差 ϵ ϵ ,预定保留最近 m m 个向量,设置 B01 t=0 t = 0
(2)用Algorithm 9.1计算搜索方向 d(t)=B1tgt d ( t ) = − B t − 1 ⋅ g t
(3)从点 x(t) x ( t ) 出发,沿着 d(t) d ( t ) 做一维搜索,获得最优步长并更新参数:

λt=argminλf(x(t)+λd(t))x(t+1)=x(t)+λtd(t) λ t = arg ⁡ min λ f ( x ( t ) + λ ⋅ d ( t ) ) x ( t + 1 ) = x ( t ) + λ t ⋅ d ( t )

(4)判断精度,若 |gt+1|<ϵ | g t + 1 | < ϵ 则停止迭代,否则转(5)
(5)判断 t>m t > m ,删掉存储的 Δxtm Δ x t − m Δgtm Δ g t − m
(5)计算 Δg=gt+1gt Δ 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到底意味着什么,并不是你英文差,而是因为这个简称真的没有意义。。。。。



参考资料

  1. 【博客】LBFGS方法推导-慢慢的回味
  2. 【博客】数值优化:理解L-BFGS算法
  3. 【博客】无约束优化算法——牛顿法与拟牛顿法(DFP,BFGS,LBFGS)
  4. 【博客】无约束最优化方法——牛顿法、拟牛顿法、BFGS、LBFGS
  5. 【博客】Numerical Optimization: Understanding L-BFGS
  6. 【论文】A Stochastic Quasi-Newton Method for Online Convex Optimization
  7. 【书籍】Numeric Optimization
拟牛顿法求解无约束优化问题中的一种方法,它通过构建和更新目标函数的Hessian矩阵(或其逆)的近似来逼近牛顿法。C语言中有很多可以用来实现拟牛顿法的库,比如L-BFGSDFPBFGS等。 其中,L-BFGS(Limited-memory Broyden-Fletcher-Goldfarb-Shanno)是使用最广泛的拟牛顿法之一。它可以根据目标函数的梯度和Hessian矩阵的逆,利用有限的内存空间进行高效的迭代优化。 在C语言中,可以使用一些开源库来实现L-BFGS算法,如LIBLBFGS。这个库提供了一系列的函数用于设置优化问题的参数、计算梯度和目标函数的值,并进行优化迭代的操作。 具体使用LIBLBFGS库实现拟牛顿法的步骤如下: 1. 引入LIBLBFGS库头文件,并声明相关的数据结构和函数。 2. 定义目标函数的计算方法,包括函数值和梯度的计算。 3. 初始化优化参数和设置迭代停止的准则。 4. 调用LIBLBFGS库中的函数进行优化迭代操作,直到满足停止准则。 5. 获取优化结果,包括最优的函数值和参数值。 通过以上步骤,我们可以在C语言环境中实现拟牛顿法,并得到优化问题的解。实现过程中需要注意合理设置参数和停止准则,以及对目标函数的适当处理。LIBLBFGS库提供了丰富的函数和选项,可以根据具体的问题进行适配和调试。 总之,使用C语言实现拟牛顿法需要引入相应的库,并根据库的接口和函数实现所需的计算过程。可以根据具体的问题选择合适的库,并进行相应的参数设置和优化过程控制,从而得到所需的优化结果。
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值