牛顿法是求解最优化,理论上最好最精确的方法,公式为:
xk+1=xk−f′(xk)f″(xk)
,原理是求解导数为0的情况。如果
xk
是一个高维数据,且函数
f(x)
非常复杂,那么求解
1/f″(x)
就是很麻烦的过程。拟牛顿法的思路是,在牛顿法的基础上,对
1/f″(x)
做个近似估计就行了,不需要精确计算。这样虽然结果会有些差异,但是速度上来了。
拟牛顿法 基于原函数
f(xk+1)
关于
f(xk)
的二阶泰勒展开。设
f(xk)=f(xk+1)+f′(xk+1)(xk−xk+1)+12(xk−xk+1)Tf″(xk+1)(xk−xk+1)+o(xk+1)
令
f″(xk+1)=Bk+1
,去掉余项
o(xk+1)
,对
xk
求导有
f′(xk)=f′(xk+1)+Bk+1(xk−xk+1)
,解出
Bk+1=f′(xk)−f′(xk+1)xk−xk+1=f′(xk+1)−f′(xk)xk+1−xkxk+2=xk+1−λf′(xk+1)/Bk+1
由于包含要求解的
xk+1
,我们只能试着取一个值,随机取值风险很大,上述方程只能作为拟牛顿方程成立的一个必要条件。。
BFGS算法是一种迭代拟牛顿法,在满足上述必要条件的情况,保证了计算过程中的稳定,具体证明太难了。设 Bk+1=Bk+δB 。数学家用了一个很技巧性很偶然的方法,令 δB=αuuT+βvvT ,则
Bk+1=Bk+αuuT+βvvTBk+1(xk+1−xk)=f′(xk+1)−f′(xk)=Bk(xk+1−xk)+[αuT(xk+1−xk)]u+[βvT(xk+1−xk)]v
令
αuT(xk+1−xk)=1
,
βvT(xk+1−xk)=−1
,
u=f′(xk+1)−f′(xk)
,
v=Bk(xk+1−xk)
,刚好恒等式成立。于是有
α=1[f′(xk+1)−f′(xk)]T(xk+1−xk)β=−1[Bk(xk+1−xk)]T(xk+1−xk)=−1(xk+1−xk)TBk(xk+1−xk)
其中
Bk=BTk
,原理是我们近似认为B是二阶导,当原函数是一元函数时,B是常量,转置就是本身;当原函数是多元函数时,B近似海森矩阵,表示为
⎡⎣⎢⎢⎢⎢⎢⎢∂2f∂x21∂2f∂x2∂x1...∂2f∂x1∂x2∂2f∂x22............⎤⎦⎥⎥⎥⎥⎥⎥
显然B可以认为是一个对称矩阵。
获得上述式子后,令 sk=xk+1−xk,yk=f′(xk+1)−f′(xk 我们写得
Bk+1=Bk+sksTkyTksk−BksksTkBksTkBKsk
值得注意的是,
Bk+1
的表达式还是包含未知的
xk+1
。定义步长参数
λk
,遍历计算
f(xk+λkdk),dk=−f′(xk)/Bk
,取其中函数值最小时的
λk
,即求解
λk=argminf(xk+λdk)
,近似得到
sk=λk(−f′(xk)/Bk)
,然后代入
Bk+1
表达式即可。当然
λk
还有一些设置方法。我们用上述方法预先取的值,一般都受到BFGS本身的约束而不会太离谱。
BFGS方法步骤如下:
1、给定初值
x0
,收敛阈值
η
,初始二阶导
B0=I
,
k=0
2、计算得到
dk=f′(xk)/Bk
,一般
Bk
是可以求逆的
3、解
λk=argminf(xk+λdk)
,得到
xk+1=xk−λkdk
4、如果
|f′(xk+1)|<η
,终止运行
5、计算
yk=f′(xk+1−f′(xk)),sk=−λkdk
,代入
Bk+1
求解方程,求取
Bk+1
6、k=k+1,从步骤1开始。