1、牛顿法
牛顿法也是一种迭代的求解方法,相比于梯度下降法,牛顿法在搜索方向上不仅考虑一阶梯度方向,同时考虑二阶梯度,因此用牛顿法求解收敛更快。
假设有函数
f(x),x∈R,
xk为当前的极小值估计,在
xk处做二阶泰勒展开:
f(x)=f(xk)+f′(xk)(x−xk)+21f′′(xk)(x−xk)2
两边同时对
x求导:
f′(x)=f′(xk)+f′′(xk)(x−xk)
x取极值点的时候,
f′(x)=0, 因此:
f′(xk)+f′′(xk)(x−xk)=0可以推导得到:
x=xk−f′′(xk)f′(xk)
因此给定初始点
x0, 可以构造如下迭代式:
xk+1=xk−f′′(xk)f′(xk),k=0,1,2,...
如果推广到多维,假设
x∈RN, 则在
xk处的二阶泰勒展开式:
f(x)=f(xk)+∇f(xk)(x−xk)+21(x−xk)T∇2f(xk)(x−xk)
其中
∇f为
f(x)的梯度向量,
∇2f为
f(x)的海森矩阵(Hessian Matrix),
∇f=⎣⎢⎢⎢⎢⎡∂x1∂f∂x2∂f⋮∂xN∂f⎦⎥⎥⎥⎥⎤,∇2f=⎣⎢⎢⎢⎢⎢⎡∂x12∂2f∂x2∂x1∂f⋮∂xN∂x1∂2f∂x1∂x2∂2f∂x22∂2f⋮∂xN∂x2∂2f⋯⋯⋱⋯∂x1∂xN∂2f∂x2∂xN∂2f⋮∂xN2∂2f⎦⎥⎥⎥⎥⎥⎤
同样的,我们两边对
x求导,并令
f′(x)=0,得到:
∇f(xk)+∇2f(xk)(x−xk)=0得到:
x=xk−(∇2f(xk))−1∇f(xk)
一般的我们令
∇f(xk)=gk,
∇2f(xk)=Hk,可得到迭代式:
xk+1=xk−Hk−1⋅gk
这就是最原始的牛顿法,其中
dk=−Hk−1⋅gk称为牛顿方向,但是最原始的牛顿法没有步长因子,所以无法保证稳定的下降,因此有了阻尼牛顿法,阻尼牛顿法的梯度方向仍然是
dk,但是在每一轮迭代时在梯度方向上搜索最优的步长因子,即在迭代计算
xk+1之前,先得到步长
λk:
λk=argλmin(xk+λdk),λ∈R
然后才迭代得到:
xk+1=xk+λkdk, 即:
xk+1=xk−λkHk−1⋅gk
2、拟牛顿法
牛顿法收敛速度快,但是有两个缺点:
1、需要计算目标函数的二阶偏导数,计算复杂度高
2、海森矩阵无法一定保持正定,从而无法求得逆矩阵,导致牛顿法失效
因此我们有了拟牛顿法(或者准牛顿法),不用去求二阶偏导数,而是构造出近似海森矩阵的正定的对阵矩阵,然后来优化目标函数。不同的构造方法自然就产生了不同的拟牛顿法。
假设在迭代到
xk+1时,我们将目标函数在
xk+1处做二阶泰勒展开:
f(x)≈xf(xk+1)+∇f(xk+1)(x−xk+1)+21(x−xk+1)T∇2f(xk+1)(x−xk+1)
两边同时求梯度:
∇f(x)≈∇f(xk+1)+∇2f(xk+1)(x−xk+1)
令
x=xk, 得到:
∇f(xk)≈∇f(xk+1)+∇2f(xk+1)(xk−xk+1),
即:
gk+1−gk≈Hk+1(xk+1−xk)
我们引入记号:
yk=gk+1−gk,
sk=xk+1−xk, 可得到:
yk≈Hk+1sk或者sk≈Hk+1−1yk
我们用
Bk+1对海森矩阵
Hk+1做近似, 用
Dk+1对海森矩阵的逆矩阵
Hk+1−1做近似, 则有:
yk=Bk+1sk或者sk=Dk+1yk
DFP算法
DFP算法的核心思想是通过迭代的方法对
Dk+1(即
Hk+1−1)做近似,如下:
Dk+1=Dk+ΔDk
D0一般取单位矩阵,因此关键是
ΔDk如何构造, 这里我们将
ΔDk构造如下:
ΔDk=αuuT+βvvT
这样保证了
ΔDk的对称性,下面我们开始从
sk=Dk+1yk推导,可以得到:
sk=(Dk+ΔDk)yk=Dkyk+αuuTyk+βvvTyk
sk=Dkyk+u(αuTyk)+v(βvTyk)
其中
αuTyk和
βvTyk为两个数,我们可以做如下赋值:
αuTyk=1,βvTyk=−1
这样可以得到:
α=uTyk1,
β=−vTyk1
接下来我们将要确定如何构造
u和
v, 我们再回到上面
sk的表达式,将
αuTyk=1,βvTyk=−1代入,得到:
sk=Dkyk+u−v
u−v=sk−Dkyk
要确保上式成立,我们可以直接令
u=sk,
v=Dkyk,这样我们可以得到:
α=skTyk1,β=−ykTDkTyk1
最后可以得到
ΔDk的迭代式:
ΔDk=skTykskskT−ykTDkTykDkykykTDkT
这样我们可以初始
D0=I, 每轮迭代确定搜索方向为
−Dkgk,利用阻尼牛顿法确定最优的步长因子,然后迭代得到
xk+1, 在下一轮迭代前,同样迭代求得
Dk+1
BFGS算法
与DFP算法相比,BFGS算法性能更好,是目前求解无约束非线性优化问题最常用的方法之一。
与DFP算法不同的是,BFGS算法是通过构造
Bk+1来直接逼近海森矩阵
Hk+1, 同样有:
Bk+1=Bk+ΔBk
采用与DFP算法同样的推导过程,这里我们略过,最终得到矫正矩阵
ΔBk的迭代式:
ΔBk=ykTykykykT−skTBkTskBkskskTBkT
可以看到与DFP的
ΔDk的迭代式只是
sk与
yk换了个位置。
BFGS算法在每轮迭代确定搜索方为:
dk=−Bk−1gk, 为了避免矩阵求逆,更一般的做法是通过Sherman-Morrison公式在每轮迭代中直接给出
Bk+1−1与
Bk−1的关系式:
Bk+1−1=(I−ykTskskykT)Bk−1(I−ykTskykskT)+ykTskskskT
关于如何通过Sherman-Morrison公式推导得出上式,可以参考这篇文章: https://blog.csdn.net/langb2014/article/details/48915425, 附录中有对上式的详细推导。
L-BFGS
BFGS算法需要存储
N×N的矩阵
DK, 当N很大时,需要很大的内存,因此有了L-BFGS(Limited-memory BFGS), 其基本思想是不存储
DK, 而是存储计算过程用到的一系列向量{
si}和{
yi}, 需要
DK时,通过{
si}和{
yi}计算得到。当然{
si}和{
yi}只是存固定的
m个,这样内存的开销将由
O(N2)降到
O(mN)。下面我们来进行推导。
再来看BFGS的迭代式:
Bk+1−1=(I−ykTskskykT)Bk−1(I−ykTskykskT)+ykTskskskT
因为
Dk=Bk−1, 所以:
Dk+1=(I−ykTskskykT)Dk(I−ykTskykskT)+ykTskskskT
令
ρk=ykTsk1,
Vk=I−ρkykskT, 则有:
Dk+1=VkTDkVk+ρkskskT
如果给定初始
D0, 我们有:
D1=V0TD0V0+ρ0s0s0T
D2D3Dk+1=V1TD1V1+ρ1s1s1T=V1TV0TD0V0V1+V1T(ρ0s0s0T)V1+ρ1s1s1T=V2TD2V2+ρ2s2s2T=V2T(V1TV0TD0V0V1+V1T(ρ0s0s0T)V1+ρ1s1s1T)V2+ρ2s2s2T=V2TV1TV0TD0V0V1V2+V2TV1T(ρ0s0s0T)V1V2+V2T(ρ1s1s1T)V2+ρ2s2s2T⋯=(VkTVk−1T⋯V1TV0T)D0(V0V1⋯Vk−1Vk)+(VkTVk−1T⋯V1T)(ρ0s0s0T)(V1⋯Vk−1Vk)+(VkTVk−1T⋯V2T)(ρ1s1s1T)(V2⋯Vk−1Vk)+⋯+VkT(ρk−1sk−1sk−1T)Vk+ρkskskT
因此如果计算
Dk+1, 我们只需存储k个向量
si和
yi即可,但是我们事先并不知道收敛时需要的迭代次数,如果迭代次数非常大,那也会存储很大数量的向量。如果要降低内存消耗,则必须舍弃一些向量,当然我们应该首先舍弃最早生成的向量,从
s0和
y0开始,依次向后。因此,如果我们设定只能存储
m个向量, 那么
Dk+1可以用下式近似计算:
Dk+1=(VkTVk−1T⋯Vk−m+2TVk−m+1T)D0(Vk−m+1Vk−m+2⋯Vk−1Vk)+(VkTVk−1T⋯Vk−m+2T)(ρ0s0s0T)(Vk−m+2⋯Vk−1Vk)+(VkTVk−1T⋯Vk−m+3T)(ρ1s1s1T)(Vk−m+3⋯Vk−1Vk)+⋯+(VkTVk−1T)(ρk−2sk−2sk−2T)Vk−1Vk+VkT(ρk−1sk−1sk−1T)Vk+ρkskskT
参考资料
http://blog.csdn.net/itplus/article/details/21896453