🚀个人主页:欢迎访问Ali.S主页
📆 最近更新:2022年7月7日
⛽ Java框架学习系列:Mybatis框架
⛳ Java基础学习系列:面向对象飞机大战
🏆 通信仿真学习系列:【硬件】【通信】【MATLAB】【最优化】
🍄 个人简介:通信工程本硕🌈、Java程序员🚴。目前只会CURD😂
💌 点赞 👍 收藏 💗留言 💬 都是我最大的动力💯
一、牛顿法介绍
前面介绍过通过梯度下降法来一步步的迭代求解,得到最小化的损失函数和模型参数值,有博友评论是不是速度很慢,通过实验仿真确实如此,今天介绍一下收敛速度更快的牛顿法,进行最优化问题的求解。在最速下降法的前提下,不仅引入梯度,而且引入Hesse矩阵
对函数进行二次近似估计,对迭代点进行新的迭代,直至满足精度要求,
二、牛顿法原理
设f(x)是二次可微函数,取其在迭代点Xk处的二阶泰勒展开式:
为求其最小值点,对其求一阶导数,并令一阶导数为0,
在二阶导可逆时,得到牛顿迭代公式:
需要注意:
当一阶导数为 正定矩阵时:
所以dk为函数的下降方向。
三、牛顿法步骤
- 给定初始点x(0),设置允许误差ε>0
- 计算初始点的一阶导数,二阶导数
- 判断梯度范数与允许误差的大小
- 若梯度范数大于允许误差,则沿着下降方向进行搜索
否则停止搜索,得到最优解。 - 进行迭代计算
- 迭代次数更新:k=k+1
- 转步骤(2)继续进行后续搜索,直至得到满足精度要求的最优解。
四、牛顿法代码
主函数:
clear;
clc;
x0=input('x0=');
eps=input('eps=');
tic
X=newton_1(x0,eps);
t=toc
fprintf('牛顿法所得的极小值点为:%f\n',X);
fprintf('牛顿法所得的极小值为:%f\n',f(X));
牛顿迭迭代函数
function y=newton_1(x0,eps)
x(1)=x0;
b=1;
i=1;
while (abs(b)>eps)
i=i+1;
x(i)=x(i-1)-df(x(i-1))/df2(x(i-1));
b=x(i)-x(i-1);
fprintf('所得的极小值点为:%f\n',x(i));
end
y=x(i);
fprintf('总共迭代%f次\n',i-1);
end
梯度函数
function y=df(n)
y=2*n+2;
end
Hesse函数
function y=df2(n)
y=2;
end
五、牛顿法测试
测试以二元函数发f(n)=nn+2n+6为例:
function y=f(n)
y=n*n+2*n+6;
end
经过两次迭代,误差小于允许误差,用时0.0088秒。
x0=1
eps=0.001
所得的极小值点为:-1.000000
所得的极小值点为:-1.000000
总共迭代2.000000次
t = 0.0088
牛顿法所得的极小值点为:-1.000000
牛顿法所得的极小值为:5.000000
总结
牛顿法收敛非常快,对于精度要求不是特别高的情况,速度非常快,甚至只用了一次计算迭代就完成求解,但是另一方面,初始值的选取非常重要,初始值选得不好有可能会直接导致算法不收敛。后续介绍对牛顿法进行改进。