l bfgs算法java代码_理解L-BFGS算法

理解L-BFGS算法

Mar 30, 2015   #数值优化  #无约束最优化

L-BFGS(Limited-Memory BFGS)是BFGS算法在受限内存时的一种近似算法,而BFGS是数学优化中一种无约束最优化算法。本文的目的是介绍L-BFGS算法的具体原理,在此过程中附加上相关背景知识,力求简单易懂。参考文献在文后给出。

无约束优化

无约束最优化的基本形式是,给定一个多元函数f(x)f(x),求出该函数的最小值点x∗x∗。形式化地来说,即:

x∗=argminxf(x)x∗=arg⁡minxf(x)

一般称f(x)f(x)为目标函数,x∗x∗为最优解。在本文中,假定目标函数都是凸函数。由凸函数的性质,可知其局部最优解必定为全局最优解,因此保证接下来介绍的算法必定收敛到局部最优解附近。

牛顿法

在使用计算机求解一个优化问题时,通常使用迭代方法。即我们的算法不断迭代,产生一个序列x1,x2…xkx1,x2…xk,若该序列能收敛到x∗x∗,则算法是有效的。

由于目标函数(假设为凸函数)存在最小值,若上述序列为递减序列,则最后会收敛到x∗x∗(不同的算法,收敛速度有差异)。

假设现在已经有点xnxn,如何构造xn+1xn+1,使得f(xn)

牛顿法的基本思想是,在离点xnxn足够近的距离,f(x)f(x)可以近似看作一个二次函数。即,在xnxn附近使用f(x)f(x)的二次近似来寻找比xnxn处函数值更小的点。

由泰勒公式,将f(x)f(x)在固定点xnxn处展开,则有:

f(xn+Δx)≈f(xn)+ΔxT∇f(xn)+12ΔxT(∇2f(xn))Δxf(xn+Δx)≈f(xn)+ΔxT∇f(xn)+12ΔxT(∇2f(xn))Δx

其中,∇f(xn)∇f(xn)和∇2f(xn)∇2f(xn)分别为目标函数在点xnxn处的梯度和Hessian矩阵。当||Δx||→0||Δx||→0时,上面的近似展开式是成立的。

为了简化符号,我们记

hn(Δx)=f(xn+Δx)=f(xn)+ΔxTgn+12ΔxTHnΔxhn(Δx)=f(xn+Δx)=f(xn)+ΔxTgn+12ΔxTHnΔx

其中gngn和HnHn分别表示目标函数在点xnxn处的梯度和Hessian矩阵。假设,我们取xn+1=xn+Δxxn+1=xn+Δx,为了找到比xnxn处目标函数值更小的点,我们可以取f(xn+Δx)f(xn+Δx)的最小值点作为xn+1xn+1。

因此,当前任务转化为只要找到使hn(Δx)hn(Δx)最小的点ΔxΔx即可。由于HnHn为正定矩阵(凸函数任一点的Hessian矩阵为半正定),hn(Δx)hn(Δx)也是凸函数,其极小值点即为最小值点。

由下列公式,解出hn(Δx)hn(Δx)最小值点Δx∗Δx∗

∂hn(Δx)∂Δx=gn+HnΔx=0∂hn(Δx)∂Δx=gn+HnΔx=0

Δx∗=−H−1ngnΔx∗=−Hn−1gn

由此,我们就确定了下一个点xn+1xn+1的位置。实践上,通常取Δx∗Δx∗作为搜索方向,即取xn+1=xn−α(H−1ngn)xn+1=xn−α(Hn−1gn),使用一维搜索,找到合适的αα使得,f(xn+1f(xn+1比f(x)f(x)尽可能小。

下面是算法的伪代码:

NewtonRaphson(f,x0):For n=0,1,… (until converged):Compute gn and H−1n for xnd=H−1ngnα=minα≥0f(xn−αd)xn+1←xn−αdNewtonRaphson(f,x0):For n=0,1,… (until converged):Compute gn and Hn−1 for xnd=Hn−1gnα=minα≥0f(xn−αd)xn+1←xn−αd

αα即步长(step-size)的确定可以使用line search算法中的任何一种,其中最简单的方法是backtracking line search。

牛顿法的不足

上述的牛顿迭代法最大的问题是需要计算Hessian矩阵的逆。首先,当维度很高时(百万或千万级),此时计算Hessian矩阵的逆几乎是不可能的(存储都很难)。再者,有些函数很难给出Hessian矩阵的解析式。因此,实践上牛顿法很少用在大型的优化问题上。但幸运的是,我们不一定需要一个精确的H−1nHn−1,一个对其的近似,也可以是我们找到目标函数的递减方向。

拟牛顿法

基本思想

先看一下拟牛顿法的基本框架

QuasiNewton(f,x0,H−10,QuasiUpdate):For n=0,1,… (until converged):// Compute search direction and step-size d=H−1ngnα←minα≥0f(xn−αd)xn+1←xn−αd// Store the input and gradient deltas gn+1←∇f(xn+1)sn+1←xn+1−xnyn+1←gn+1−gn// Update inverse hessian H−1n+1←QuasiUpdate(H−1n,sn+1,yn+1)QuasiNewton(f,x0,H0−1,QuasiUpdate):For n=0,1,… (until converged):// Compute search direction and step-size d=Hn−1gnα←minα≥0f(xn−αd)xn+1←xn−αd// Store the input and gradient deltas gn+1←∇f(xn+1)sn+1←xn+1−xnyn+1←gn+1−gn// Update inverse hessian Hn+1−1←QuasiUpdate(Hn−1,sn+1,yn+1)

初始时,给了一个参数H−10H0−1,之后每一次迭代通过QuasiUpdateQuasiUpdate方法加上输入变量与梯度的差值(snsn和ynyn)作为参数,产生出下一个H−1H−1的估计。

可以发现,若QuasiUpdateQuasiUpdate每次都返回单位矩阵,则拟牛顿法退化为梯度下降方法(每一次都沿着梯度方向搜索)。

若QuasiUpdateQuasiUpdate能够返回∇2f(xn+1)∇2f(xn+1),则拟牛顿法与牛顿法就等价了。

从上述伪代码中可以看出,拟牛顿法仅仅需要函数值和梯度信息,并不需要二阶导信息。

QuasiUpdate & BFGS

有了上面的算法框架之后,下面的问题就是QuasiUpdate函数如何实现?

由中值定理,我们知道

(gn−gn−1)=Hn(xn−xn−1)(gn−gn−1)=Hn(xn−xn−1)

因此

H−1nyn=snHn−1yn=sn

同时,Hessian矩阵是对称矩阵。在这两个条件的基础上,我们希望HnHn相对于Hn−1Hn−1的变化并不大。形式化地讲,即

minH−1s.t. ∥H−1−H−1n−1∥2H−1yn=snH−1 is symmetric minH−1‖H−1−Hn−1−1‖2s.t. H−1yn=snH−1 is symmetric

H−1n+1=(I−ρnynsTn)H−1n(I−ρnsnyTn)+ρnsnsTnHn+1−1=(I−ρnynsnT)Hn−1(I−ρnsnynT)+ρnsnsnT

其中ρn=(yTnsn)−1ρn=(ynTsn)−1。

这种更新方式,被称为Broyden–Fletcher–Goldfarb–Shanno (BFGS)更新,由其发明者命名。

值得注意的是,为了计算H−1n+1Hn+1−1,我们只需保存H−10H0−1以及{sn−1sn−1},{yn−1yn−1}序列即可。下面是计算H−1ndHn−1d的伪代码。

BFGSMultiply(H−10,{sk},{yk},d):r←d// Compute right productfor i=n,…,1:αi←ρisTirr←r−αiyi// Compute centerr←H−10r// Compute left productfor i=1,…,n:β←ρiyTirr←r+(αn−i+1−β)sireturn rBFGSMultiply(H0−1,{sk},{yk},d):r←d// Compute right productfor i=n,…,1:αi←ρisiTrr←r−αiyi// Compute centerr←H0−1r// Compute left productfor i=1,…,n:β←ρiyiTrr←r+(αn−i+1−β)sireturn r

L-BFGS

BFGS虽然不需要计算Hessian矩阵了,但是保存snsn、ynyn的历史记录仍需要消耗大量的内存。L-BFGS,即限定内存的BFGS算法,其BFGSMultiply仅使用最近的若干次snsn、ynyn记录。由最近的m次输入变量和梯度变量的差值,和初始的H−10H0−1,近似算出当前的H−1ndHn−1d。

一般来说,取m<10即可。由此,L-BFGS可以被用来求解大型的无约束优化问题(Machine Learning中的很多问题都可以用其求解,如Logistic Regress等)。

关于L-BFGS的实现,有机会专门开一篇来讲。可以参考breeze的实现。

参考

关于数值优化的书强烈推荐 Practical Methods of Optimization 。

你可能感兴趣的:(l,bfgs算法java代码)