淘先锋技术网

首页 1 2 3 4 5 6 7

🚀个人主页:欢迎访问Ali.S主页

📆 最近更新:2022年7月7日

⛽ Java框架学习系列:Mybatis框架

⛳ Java基础学习系列:面向对象飞机大战

🏆 通信仿真学习系列:【硬件】【通信】【MATLAB】【最优化】

🍄 个人简介:通信工程本硕🌈、Java程序员🚴。目前只会CURD😂

💌 点赞 👍 收藏 💗留言 💬 都是我最大的动力💯

在这里插入图片描述

一、牛顿法介绍

前面介绍过通过梯度下降法来一步步的迭代求解,得到最小化的损失函数和模型参数值,有博友评论是不是速度很慢,通过实验仿真确实如此,今天介绍一下收敛速度更快的牛顿法,进行最优化问题的求解。在最速下降法的前提下,不仅引入梯度,而且引入Hesse矩阵对函数进行二次近似估计,对迭代点进行新的迭代,直至满足精度要求,

二、牛顿法原理

设f(x)是二次可微函数,取其在迭代点Xk处的二阶泰勒展开式:
在这里插入图片描述
为求其最小值点,对其求一阶导数,并令一阶导数为0,
在这里插入图片描述
在二阶导可逆时,得到牛顿迭代公式:
在这里插入图片描述
需要注意:在这里插入图片描述
当一阶导数为 正定矩阵时:
在这里插入图片描述
所以dk为函数的下降方向。

三、牛顿法步骤

  1. 给定初始点x(0),设置允许误差ε>0
  2. 计算初始点的一阶导数,二阶导数
  3. 判断梯度范数与允许误差的大小
  4. 若梯度范数大于允许误差,则沿着下降方向进行搜索
    在这里插入图片描述
    否则停止搜索,得到最优解。
  5. 进行迭代计算
    在这里插入图片描述
  6. 迭代次数更新:k=k+1
  7. 转步骤(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

在这里插入图片描述

总结

牛顿法收敛非常快,对于精度要求不是特别高的情况,速度非常快,甚至只用了一次计算迭代就完成求解,但是另一方面,初始值的选取非常重要,初始值选得不好有可能会直接导致算法不收敛。后续介绍对牛顿法进行改进。