牛頓法的思想是利用目標函數的二次Taylor展開模型的極小點去逼近目標函數的極小點。
設f(x)二次連續可微,Hesse矩陣正定,在xk附近展開f
令等式取0,得牛頓迭代公式
,即
當初始點距離最優解較遠時,Gk不一定正定,迭代不一定收斂,因此引入了步長因子α
帶步長因子的牛頓法,即阻尼牛頓法,迭代格式如下:
其中α由線性搜索得到。
牛頓法的關鍵是計算Hesse矩陣,但對於一般的函數Hesse矩陣不容易計算,為克服這個缺陷,提出了擬牛頓法和修正牛頓法
修正牛頓法的思想是用G+μI來代替G,因為只要μ充分大,就能保證G+μI正定
擬牛頓法與牛頓法的區別在於用Hesse矩陣的近似B來代替G,其中B是對稱正定的
擬牛頓法的一般步驟如下:
其中擬牛頓條件為
關於Bk的校正有兩種方法——DFP校正和BFGS校正
DFP校正公式為
BFGS校正公式為
下面給出這幾種方法的python實現
阻尼牛頓法:
from linear_search.wolfe import * from linear_search.Function import * from numpy import * def newton(f, start): fun = Function(f) x = array(start) g = fun.grad(x) while fun.norm(x) > 0.01: G = fun.hesse(x) d = (-dot(linalg.inv(G), g)).tolist()[0] alpha = wolfe(f, x, d) x = x + alpha * array(d) g = fun.grad(x) return x
擬牛頓法:
# coding=utf-8 from linear_search.wolfe import * from linear_search.Function import * from numpy import * # 擬牛頓法 def simu_newton(f, start): n=size(start) fun = Function(f) x = array(start) g = fun.grad(x) B=eye(n) while fun.norm(x) > 0.01: d = (-dot(linalg.inv(B), g)).tolist() alpha = wolfe(f, x, d) x_d=array([alpha * array(d)]) x = x + alpha * array(d) g_d=array([fun.grad(x)-g]) g = fun.grad(x) B_d=dot(B,x_d.T) B=B+dot(g_d.T,g_d)/dot(g_d,x_d.T)-dot(B_d,B_d.T)/dot(x_d,B_d) return x