![7ce630618a66cef7d1857ea1970141b3.png](https://i-blog.csdnimg.cn/blog_migrate/5cf86035f4ec0f4bac1919845a84d0b2.jpeg)
3基本牛顿法
牛顿法的基本思想是用迭代点的梯度信息和二阶导数对目标函数进行二次函数逼近,然后把二次函数的极小值作为新的迭代点,并不断重复这一过程,直到求出极小点。
假设函数
其中
如果二阶导数非奇异,可以得到下一个迭代点为(上式求出来的
如果二阶导数奇异,那么可以求解下面线性方程确定搜索方向
后计算下一个迭代点
基本牛顿法可以归结为以下四步
- 初值设置:初始点以及终止准则
- 检验是否满足终止准则
- 计算二阶导数,确定搜索方向
:
- 计算下一个迭代点
,回到步骤2
注意:牛顿法的好处在于收敛速度快,缺点在于计算二阶导数的计算量大以及求解线性方程组确定搜索方向可能是病态的。
修正牛顿法
最基础的改进是在基本牛顿法中加入线搜索方法求得步长
牛顿法面临的一个主要困难是二阶导数不正定,在这一情况下,下降方向就很难获得。Goldfeld 修正法在二阶导数不正定时对其进行修正
其中
带有线搜索的修正牛顿法可以表述为
输入:初始点,终止阈值
循环:
- 找到修正阵
使得
正定
- 求解线性方程组
得到下降方向
- 线搜法计算步长
- 更新迭代点
可以看到修正阵
Ps: 信赖域牛顿法在上一篇博文仿真案例用的就是了,感兴趣的可以去看一下。
养生的控制人:数值优化(Numerical Optimization)(2)-信赖域法zhuanlan.zhihu.com![c93f1fd205afb821a3806bb43cdf9cdf.png](https://i-blog.csdnimg.cn/blog_migrate/d16ebc6232e0f0f9376f273949600e8e.jpeg)
拟牛顿法
拟牛顿法的思想是模拟牛顿方向的生成路径,利用相邻两个点的位移和一阶导数信息构造与二阶导数阵相似的正定矩阵。所需的计算量比牛顿法少,收敛速度达到超线性。
假设函数
对上式两边求导可得
如果令
等价于
假设二阶导数矩阵的逆矩阵
上式也称为拟牛顿方程,可以看到
DFP
下面介绍一下第一个拟牛顿法,DFP算法,算法中假设
根据假设
其中
因此有
从而求出
这个公式也称为 DFP校正公式。
DFP算法流程
- 选择初值
以及收敛阈值
- 检验终止条件
- 计算搜索方向
- 确定步长
和下一个迭代点
- 根据 DFP 校正公式计算矩阵
,令
并返回步骤2
BFGS
BFGS算法的推导过程和 DFP 完全类似,令
得到的更新公式为
BFGS算法流程
- 设置初值
和收敛阈值
- 求解线性方程
- 线搜索得到步长
- 令
更新
- 更新梯度差
- 计算矩阵
在算法中
一种更有效的计算为
L-BFGS
对于 BFGS 算法,需要储存近似逆二阶导数矩阵
定义
则 BFGS 的公式可以改写为
在第
根据这个表达式我们可以推导出计算
令
循环1:
令
循环2:
输出
上面的递归算法涉及了
这里的
综上,完整的 L-BFGS 算法可以描述为
输入:初始点
循环直到收敛:
- 选择
- 根据双循环递归算法计算
- 计算下一迭代点
其中
的选择需要满足 Wolfe 条件
- 如果
- 计算并保存
,
- 令
MATLAB示例
求 Rosenbrock函数的最小点
计算梯度为
计算二阶导数为
首先把这个函数写成输入输出的函数形式
function [f,g,H] = RosenFunc(x0)
x = x0(1);
y = x0(2);
f = (1-x)^2 + 100*(y-x^2)^2;
if (nargout > 1)
g = [-2 + 2*x - 400*x*y + 400*x^3;
200*(y-x^2)];
end
if (nargout > 2)
H = [2 - 400*(y-x^2) + 800*x^2, -400*x;
-400*x, 200];
end
另外也附上 Branin 函数用于测试
function [f,g,H] = BraninFunc(x0)
x1 = x0(1);
x2 = x0(2);
f = (x2-0.129*x1^2+1.6*x1-6)^2+6.07*cos(x1)+10;
if (nargout > 1)
g = [2*(x2-0.129*x1^2+1.6*x1-6)*(-0.258*x1+1.6)-6.07*sin(x1);...
2*(x2-0.129*x1^2+1.6*x1-6)];
end
if (nargout > 2)
H = [2*(-0.258*x1+1.6)^2-0.516*(x2-0.128*x1^2+1.6*x1-6)-6.07*cos(x1),...
-0.516*x1+3.2;-0.516*x1+3.2,2];
end
阻尼牛顿法(线搜索用回溯法)
function [x_opt,x_eval,f_eval] = Newton_basic(fun,x0,epsilon,iter)
x_eval = [];
f_eval = [];
xk = x0;
[fk,gk,Hk] = fun(xk);
for k = 1:iter
if norm(gk,2) <= epsilon
break
end
x_eval = [x_eval,xk];
f_eval = [f_eval,fk];
dk = -inv(Hk)*gk;
alpha = backstracking_linesearch(fun,xk,dk);
xk = xk + alpha*dk;
[fk,gk,Hk] = fun(xk);
end
x_opt = xk;
BFGS法(线搜索用回溯法)
function [x_opt,x_eval,f_eval] = Newton_BFGS(fun,x0,epsilon,iter)
x_eval = [];
f_eval = [];
xk = x0;
n = length(x0);
Hk = eye(n);
[fk,gk] = fun(xk);
for k = 1:iter
if norm(gk,2) <= epsilon
break
end
x_eval = [x_eval,xk];
f_eval = [f_eval,fk];
dk = -Hk*gk;
% line search
alpha = backstracking_linesearch(fun,xk,dk);
x_next = xk + alpha*dk;
[f_next,g_next] = fun(x_next);
% BFGS
sk = alpha*dk;
yk = g_next - gk;
rho = 1/(yk'*sk);
Hk = (eye(n) - rho*sk*yk')*Hk*(eye(n)-rho*yk*sk') + rho*sk*sk';
% 更新
gk = g_next;
xk = x_next;
fk = f_next;
end
x_opt = xk;
L-BFGS法(线搜索用回溯法)
function [x_opt,x_eval,f_eval] = Newton_LBFGS(fun,x0,m,epsilon,iter)
x_eval = [];
f_eval = [];
n = length(x0);
S = zeros(n,m);
Y = zeros(n,m);
xk = x0;
[fk,gk] = fun(x0);
for k = 1:iter
if norm(gk,2) <= epsilon
break
end
x_eval = [x_eval,xk];
f_eval = [f_eval,fk];
if k > 1
gamma = (S(:,1)'*Y(:,1))/(Y(:,1)'*Y(:,1));
H0 = gamma*eye(n);
% two-loop
q = gk;
rho = zeros(m,1);
ALPHA = zeros(m,1);
for i = 1:min(k-1,m)
rho(i) = 1/(Y(:,i)'*S(:,i));
ALPHA(i) = rho(i)*S(:,i)'*q;
q = q - ALPHA(i)*Y(:,i);
end
dk = H0*q;
for j = 1:min(k-1,m)-1
i = min(k,m)-j+1;
beta = rho(i)*Y(:,i)'*dk;
dk = dk +S(:,i)*(ALPHA(i)-beta);
end
dk = -dk;
else
H0 = eye(n);
dk = -H0*gk;
end
% line search
alpha = backstracking_linesearch(fun,xk,dk);
x_next = xk + alpha*dk;
[f_next,g_next] = fun(x_next);
% 更新位移和梯度差
S(:,2:m) = S(:,1:m-1);
Y(:,2:m) = Y(:,1:m-1);
sk = x_next - xk;
yk = g_next - gk;
S(:,1) = sk;
Y(:,1) = yk;
% 更新
xk = x_next;
fk = f_next;
gk = g_next;
end
x_opt = xk;
选择一个比较有意思的对比展示一下,采用 Branin 函数,初始点为
![071b4143f44e9e82f76942844135b0b8.png](https://i-blog.csdnimg.cn/blog_migrate/e77aeea7d13497f90b02f5acd77d79f2.jpeg)
三种算法跑到了三个地方去了,两个局部最小点,基本牛顿法停留在一个在非常平的地段。对应的函数值也不一样。
![4ef446acb00fe5809e0041cfd1deb7f9.png](https://i-blog.csdnimg.cn/blog_migrate/fa7b6a3221c3173b3c46c5e73d4958b9.png)