04 牛顿法、高斯牛顿法及 Cpp 实现

文章目录

    • 04 牛顿法、高斯牛顿法及 Cpp 实现
      • 4.1 非线性最小二乘
      • 4.2 一阶和二阶梯度法
      • 4.3 高斯牛顿法
      • 4.4 总结
      • 4.5 代码实现
      • 4.6 三种方法优缺点

04 牛顿法、高斯牛顿法及 Cpp 实现

4.1 非线性最小二乘

考虑最小二乘问题:

min ⁡ x F ( x ) = 1 2 ∥ f ( x ) ∥ 2 2 \min _{x} F(x)=\frac{1}{2}\|f(x)\|_{2}^{2} xminF(x)=21f(x)22

对于简单的函数,我们可以令其导数 d F d x = 0 \frac{\rm{d}F}{\rm{d}\boldsymbol{x}}=0 dxdF=0,得到导数为零处的极值点。

而 SLAM 中的非线性函数形式复杂,常常难以用求导法得到最值,而采用梯度下降法,即,通过不断迭代 x k + 1 = x k + Δ x k \boldsymbol{x}_{k+1}=\boldsymbol{x}_k+\Delta\boldsymbol{x}_k xk+1=xk+Δxk,使得 ∣ ∣ f ( x k + Δ x k ) ∣ ∣ 2 ||f(\boldsymbol{x}_k+\Delta\boldsymbol{x}_k)||^2 ∣∣f(xk+Δxk)2 达到极小值,当 Δ x \Delta \boldsymbol{x} Δx 足够小时,即停止。关键在于增量 Δ x \Delta\boldsymbol{x} Δx 的选取。

过程如下:

——————————————————————————————————————————————————————

  • 给定某个初值 x 0 \boldsymbol{x}_0 x0

  • 对于第 k k k 次迭代,寻找增量 Δ x k \Delta\boldsymbol{x}_k Δxk

  • Δ x k \Delta \boldsymbol{x}_k Δxk 足够小时,即停止;否则,重复第二步,继续寻找。

——————————————————————————————————————————————————————

下面介绍几个常用的优化方法。

4.2 一阶和二阶梯度法

对于非线性函数 F ( x ) F(\boldsymbol{x}) F(x),考虑第 k k k 次迭代,将其在 x k \boldsymbol{x}_k xk 附近泰勒展开(将 Δ x k \Delta \boldsymbol{x}_k Δxk 看做未知数),

F ( x ) = F ( x k + Δ x k ) ≈ F ( x k ) + J ( x k ) T Δ x k + 1 2 Δ x k T H ( x k ) T Δ x k F(\boldsymbol{x})=F(\boldsymbol{x}_k+\Delta \boldsymbol{x}_k) \approx F(\boldsymbol{x}_k)+\boldsymbol{J}(\boldsymbol{x}_k)^T\Delta \boldsymbol{x}_k+\frac{1}{2}\Delta \boldsymbol{x}_k^T\boldsymbol{H}(\boldsymbol{x}_k)^T\Delta \boldsymbol{x}_k F(x)=F(xk+Δxk)F(xk)+J(xk)TΔxk+21ΔxkTH(xk)TΔxk

其中, J ( x k ) \boldsymbol{J}(\boldsymbol{x}_k) J(xk) F ( x ) F(\boldsymbol{x}) F(x) 关于 x \boldsymbol{x} x 的一阶导数, H ( x k ) \boldsymbol{H}(\boldsymbol{x}_k) H(xk) 是二阶导数。

(1)最速下降法

仅保留一阶导数时,取增量为反向梯度即可,即

Δ x ∗ = − J ( x k ) \Delta \boldsymbol{x}^*=-\boldsymbol{J}(\boldsymbol{x}_k) Δx=J(xk)

也被称为最速下降法

(2)牛顿法

保留二阶梯度信息。此时增量方程为

Δ x ∗ = arg ⁡ min ⁡ ( F ( x ) + J ( x ) T Δ x + 1 2 Δ x T H Δ x ) \Delta \boldsymbol{x}^{*}=\arg \min \left(F(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})^{\mathrm{T}} \Delta \boldsymbol{x}+\frac{1}{2} \Delta \boldsymbol{x}^{\mathrm{T}} \boldsymbol{H} \Delta \boldsymbol{x}\right) Δx=argmin(F(x)+J(x)TΔx+21ΔxTHΔx)

右侧各项分别为 Δ x \Delta \boldsymbol{x} Δx 的零次、一次和二次项,将其对 Δ x \Delta \boldsymbol{x} Δx 求导,并令其为零

J + H Δ x = 0 ⇒ H Δ x = − J \boldsymbol{J}+\boldsymbol{H} \Delta \boldsymbol{x}=0 \Rightarrow \boldsymbol{H} \Delta \boldsymbol{x}=-\boldsymbol{J} J+HΔx=0HΔx=J

求解这个方程,即得到增量。此方法也被称为牛顿法。但在实际中, H \boldsymbol{H} H 矩阵计算较为困难。

4.3 高斯牛顿法

f ( x ) f(\boldsymbol{x}) f(x) 一阶泰勒展开(注意不是 F ( x ) F(\boldsymbol{x}) F(x)):

f ( x + Δ x ) ≈ f ( x ) + J ( x ) T Δ x f(\boldsymbol{x}+\Delta \boldsymbol{x}) \approx f(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x} f(x+Δx)f(x)+J(x)TΔx

其中, J ( x ) \boldsymbol{J}(\boldsymbol{x}) J(x) f ( x ) f(\boldsymbol{x}) f(x) 关于 x \boldsymbol{x} x 的一阶导数,为 n × 1 n \times 1 n×1 列向量。

此时,我们的问题变为找到 Δ x \Delta \boldsymbol{x} Δx ,使得 1 2 ∥ f ( x ) + J ( x ) T Δ x ∥ 2 \frac{1}{2} \|f(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}\|^2 21f(x)+J(x)TΔx2 最小。将其展开

1 2 ∥ f ( x ) + J ( x ) T Δ x ∥ 2 = 1 2 ( f ( x ) + J ( x ) T Δ x ) T ( f ( x ) + J ( x ) T Δ x ) = 1 2 ( ∥ f ( x ∥ 2 + 2 f ( x ) J ( x ) T Δ x + Δ x T J ( x ) J ( x ) T Δ x ) \begin{aligned} \frac{1}{2} \|f(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}\|^2&=\frac{1}{2} (f(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x})^T(f(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}) \\ &=\frac{1}{2} (\|f(\boldsymbol{x}\|^2+2f(\boldsymbol{x})\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}+\Delta \boldsymbol{x}^T\boldsymbol{J}(\boldsymbol{x})\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}) \end{aligned} 21f(x)+J(x)TΔx2=21(f(x)+J(x)TΔx)T(f(x)+J(x)TΔx)=21(f(x2+2f(x)J(x)TΔx+ΔxTJ(x)J(x)TΔx)

Δ x \Delta \boldsymbol{x} Δx 看做未知数,对其求导,并令其为零:

f ( x ) J ( x ) + J ( x ) J ( x ) T Δ x = 0 f(\boldsymbol{x})\boldsymbol{J}(\boldsymbol{x})+\boldsymbol{J}(\boldsymbol{x})\boldsymbol{J}(\boldsymbol{x})^T\Delta \boldsymbol{x}=\boldsymbol{0} f(x)J(x)+J(x)J(x)TΔx=0

J ( x ) J T ⏟ H ( x ) ( x ) Δ x = − J ( x ) f ( x ) ⏟ g ( x ) \underbrace{\boldsymbol{J}(\boldsymbol{x}) \boldsymbol{J}^{\mathrm{T}}}_{\boldsymbol{H}(\boldsymbol{x})}(\boldsymbol{x}) \Delta \boldsymbol{x}=\underbrace{-\boldsymbol{J}(\boldsymbol{x}) f(\boldsymbol{x})}_{\boldsymbol{g}(\boldsymbol{x})} H(x) J(x)JT(x)Δx=g(x) J(x)f(x)

H ( x ) Δ x = g ( x ) \boldsymbol{H}(\boldsymbol{x})\Delta \boldsymbol{x}=\boldsymbol{g}(\boldsymbol{x}) H(x)Δx=g(x)

前面说到牛顿法中的二阶矩阵 H \boldsymbol{H} H 求解较为困难,所以这里用 J J ⊤ \boldsymbol{JJ}^\top JJ 作为 H \boldsymbol{H} H 的近似,从而省略了计算 H \boldsymbol{H} H 的过程。

4.4 总结

(1)最速下降法

Δ x ∗ = − J ( x k ) \Delta \boldsymbol{x}^*=-\boldsymbol{J}(\boldsymbol{x}_k) Δx=J(xk)

(2)牛顿法

H Δ x = − J \boldsymbol{H} \Delta \boldsymbol{x}=-\boldsymbol{J} HΔx=J

(3)高斯牛顿法

J ( x ) J T ⏟ H ( x ) ( x ) Δ x = − J ( x ) f ( x ) ⏟ g ( x ) \underbrace{\boldsymbol{J}(\boldsymbol{x}) \boldsymbol{J}^{\mathrm{T}}}_{\boldsymbol{H}(\boldsymbol{x})}(\boldsymbol{x}) \Delta \boldsymbol{x}=\underbrace{-\boldsymbol{J}(\boldsymbol{x}) f(\boldsymbol{x})}_{\boldsymbol{g}(\boldsymbol{x})} H(x) J(x)JT(x)Δx=g(x) J(x)f(x)

需要注意的是,最速下降法和牛顿法属于同一类型,他们的 J \boldsymbol{J} J H \boldsymbol{H} H 都是针对 F ( x ) \boldsymbol{F(x)} F(x)(也就是整个目标函数);而高斯牛顿法的 J \boldsymbol{J} J 是针对 f ( x ) \boldsymbol{f(x)} f(x) (也就是误差项)。 此外,为减小数值,目标函数 F ( x ) \boldsymbol{F(x)} F(x) 可用均方差函数 。

4.5 代码实现

考虑一条满足以下方程的曲线

y = exp ⁡ ( a x 2 + b x + c ) + w y=\exp(ax^2+bx+c)+w y=exp(ax2+bx+c)+w

其中, a , b , c a, b, c a,b,c 为曲线参数, w w w 为高斯噪声,满足 w ∼ N ( 0 , σ 2 ) w \sim N(0, \sigma^2) wN(0,σ2)。假设有 N N N 个关于 x , y x, y x,y 的观测数据点,落在该直线附近,我们想用该方程进行拟合,也就是求出使残差最小的曲线参数 a , b , c a, b, c a,b,c。定义残差

( a , b , c ) ∗ = arg ⁡ min ⁡ a , b , c 1 2 ∑ i = 1 N ∥ y i − exp ⁡ ( a x i 2 + b x i + c ) ∥ 2 2 (a, b, c)^*=\arg \min_{a, b, c} \frac{1}{2}\sum^N_{i=1}\|y_i-\exp(ax_i^2+bx_i+c)\|^2_2 (a,b,c)=arga,b,cmin21i=1Nyiexp(axi2+bxi+c)22

注意,这个问题的带估计变量是 a , b , c a, b, c a,b,c,而不是 x x x

我们先根据模型生成 x , y x, y x,y 的真值,再加入高斯噪声,构成观测数据点。定义每一项的误差

e i = y i − exp ⁡ ( a x i 2 + b i x + c ) e_i=y_i-\exp(ax_i^2+b_ix+c) ei=yiexp(axi2+bix+c)

(1)最速下降法

Δ x ∗ = − J \Delta \boldsymbol{x}^*=-\boldsymbol{J} Δx=J

其中, J = ∑ J i \boldsymbol{J}=\sum \boldsymbol{J}_i J=Ji J i = [ ∂ F ∂ a , ∂ F ∂ b , ∂ F ∂ c ] ⊤ \boldsymbol{J}_i=[\frac{ \partial \boldsymbol{F}}{ \partial a}, \frac{ \partial \boldsymbol{F}}{ \partial b}, \frac{ \partial \boldsymbol{F}}{ \partial c}]^\top Ji=[aF,bF,cF]

∂ F ∂ a = e i ( − x i 2 exp ⁡ ( a x i 2 + b x i + c ) ) ∂ F ∂ a = e i ( − x i exp ⁡ ( a x i 2 + b x i + c ) ) ∂ F ∂ a = e i ( exp ⁡ ( a x i 2 + b x i + c ) ) \frac{ \partial \boldsymbol{F}}{ \partial a}=e_i(-x_i^2\exp(ax_i^2+bx_i+c)) \\ \frac{ \partial \boldsymbol{F}}{ \partial a}=e_i(-x_i\exp(ax_i^2+bx_i+c))\\ \frac{ \partial \boldsymbol{F}}{ \partial a}=e_i(\exp(ax_i^2+bx_i+c)) aF=ei(xi2exp(axi2+bxi+c))aF=ei(xiexp(axi2+bxi+c))aF=ei(exp(axi2+bxi+c))

/***********************************************************                                          *
* Time: 2023/8/10
* Author: xiaocong
* Function: 最速下降法
* 注意这里用的是 ae * xi * xi + be * xi + sin(ce)
* 原指数函数对误差和初值敏感,造成计算无穷大。
***********************************************************/#include <iostream>
#include <eigen3/Eigen/Core>
#include <eigen3/Eigen/Dense>
#include <cmath>using namespace std;
using namespace Eigen;const int N = 100;                 // 数据点个数
const int MAX_INTER = 1000;        // 最大迭代次数void steepestDescent(const VectorXd& x_data, const VectorXd& y_data, Vector3d& params)
{double cost = 0;for (int iter = 0; iter < MAX_INTER; iter++){Vector3d J = Vector3d::Zero();           // 雅可比矩阵cost = 0;double ae = params(0);double be = params(1);double ce = params(2);for (int i = 0;i < N;i++){double xi = x_data(i), yi = y_data(i);double ei = (yi - (ae * xi * xi + be * xi + sin(ce)));    // 残差项Vector3d Ji;                                          // 雅可比矩阵Ji(0) = ei * (-xi * xi);Ji(1) = ei * (-xi);Ji(2) = ei * (-cos(ce));J += Ji;cost += ei * ei;}Vector3d dx = -J / N;          // 求解 dxif (isnan(dx[0])){cout << "result is nan!" << endl;break;}if (dx.squaredNorm() < 1e-6)      // dx 足够小{break;}// 迭代params += dx;cout << "iter= " << iter + 1 << endl;cout << dx(0) << endl;cout << dx(1) << endl;cout << dx(2) << endl;cout << "cost: " << cost << endl;cout << "estimated abc= " << params(0) << ", " << params(1) << ", " << params(2) << endl;}}int main(int argc, char** argv)
{double ar = 1.0, br = 2.0, cr = 1;         // 真实参数值Vector3d params(2.0, 1.0, 0);            // 初始参数值// 生成数据VectorXd x_data(N);VectorXd y_data(N);for (int i = 0; i < N; i++){double xi = (i / 100.0);                                     // [0~1.0]double sigma = 0.02 * (rand() % 1000) / 1000.0 - 0.01;     // 随机噪声,[-0.01, 0.01]double yi = ar * xi * xi + br * xi + sin(cr) + sigma;x_data(i) = xi;y_data(i) = yi;}steepestDescent(x_data, y_data, params);return 0;
}
iter= 454
-0.000666889
0.000694395
-0.000279458
cost: 0.0427055
estimated abc= 1.26563, 1.72471, 1.09882

(2)牛顿法

H Δ x = − J \boldsymbol{H} \Delta \boldsymbol{x}=-\boldsymbol{J} HΔx=J

这里还需要求出海森矩阵即二阶导

H i = [ ∂ 2 F ∂ a 2 ∂ 2 F ∂ a ∂ b ∂ 2 F ∂ a ∂ c ∂ 2 F ∂ b ∂ a ∂ 2 F ∂ b 2 ∂ 2 F ∂ b ∂ c ∂ 2 F ∂ c ∂ a ∂ 2 F ∂ c ∂ b ∂ 2 F ∂ c 2 ] \boldsymbol{H}_i=\left[\begin{array}{c} \frac{ \partial^2 \boldsymbol{F}}{ \partial a^2} & \frac{ \partial^2 \boldsymbol{F} }{\partial a \partial b} &\frac{ \partial^2 \boldsymbol{F}}{ \partial a \partial c} \\ \frac{ \partial^2 \boldsymbol{F}}{\partial b \partial a} & \frac{ \partial^2 \boldsymbol{F}}{\partial b^2} &\frac{ \partial^2 \boldsymbol{F}}{ \partial b \partial c} \\ \frac{ \partial^2 \boldsymbol{F}}{ \partial c \partial a} & \frac{ \partial^2 \boldsymbol{F}}{\partial c \partial b} &\frac{ \partial^2 \boldsymbol{F}}{\partial c^2} \\ \end{array}\right] Hi= a22Fba2Fca2Fab2Fb22Fcb2Fac2Fbc2Fc22F

H = ∑ H i \boldsymbol{H}=\sum \boldsymbol{H}_i H=Hi

/***********************************************************                                          *
* Time: 2023/8/10
* Author: xiaocong
* Function: 牛顿法
* 注意这里用的是 ae * xi * xi + be * xi + sin(ce)
***********************************************************/#include <iostream>
#include <eigen3/Eigen/Core>
#include <eigen3/Eigen/Dense>
#include <cmath>using namespace std;
using namespace Eigen;const int N = 100;                 // 数据点个数
const int MAX_INTER = 1000;        // 最大迭代次数void steepestDescent(const VectorXd& x_data, const VectorXd& y_data, Vector3d& params)
{double cost = 0;for (int iter = 0; iter < MAX_INTER; iter++){Vector3d J = Vector3d::Zero();           // 雅可比矩阵Eigen::MatrixXd H(3, 3);                 // 海森矩阵H.setZero();cost = 0;double ae = params(0);double be = params(1);double ce = params(2);for (int i = 0;i < N;i++){double xi = x_data(i), yi = y_data(i);double ei = (yi - (ae * xi * xi + be * xi + sin(ce))) / N;    // 残差项J(0) += ei * (-xi * xi);J(1) += ei * (-xi);J(2) += ei * (-cos(ce));H(0, 0) += xi * xi * xi * xi;H(0, 1) += xi * xi * xi;H(0, 2) += xi * xi * cos(ce);H(1, 0) += xi * xi * xi;H(1, 1) += xi * xi;H(1, 2) += xi * cos(ce);H(2, 0) += xi * xi * cos(ce);H(2, 1) += xi * cos(ce);H(2, 2) += cos(2 * ce);cost += ei * ei;}Vector3d dx = H.ldlt().solve(-J);   // 求解 dxif (isnan(dx[0])){cout << "result is nan!" << endl;break;}if (dx.squaredNorm() < 1e-6)      // dx 足够小{break;}// 迭代params += dx;cout << "iter= " << iter + 1 << endl;cout << dx(0) << endl;cout << dx(1) << endl;cout << dx(2) << endl;cout << "cost: " << cost << endl;cout << "estimated abc= " << params(0) << ", " << params(1) << ", " << params(2) << endl;}}int main(int argc, char** argv)
{double ar = 1.0, br = 2.0, cr = 1.0;         // 真实参数值Vector3d params(2.0, 1.0, 0.0);            // 初始参数值// 生成数据VectorXd x_data(N);VectorXd y_data(N);for (int i = 0; i < N; i++){double xi = (i / 100.0);                                     // [0~1.0]double sigma = 0.02 * (rand() % 1000) / 1000.0 - 0.01;     // 随机噪声,[-0.01, 0.01]double yi = ar * xi * xi + br * xi + sin(cr) + sigma;x_data(i) = xi;y_data(i) = yi;}steepestDescent(x_data, y_data, params);return 0;
}
iter= 470
-0.000656148
0.000766084
5.77874e-06
cost: 3.52463e-06
estimated abc= 1.09233, 1.89203, 1.01297

(3)高斯牛顿法

求出每个误差项关于状态变量的导数(注意 a , b , c a, b, c a,b,c 才是未知数):

∂ e i ∂ a = − x i 2 exp ⁡ ( a x i 2 + b i x + c ) ∂ e i ∂ b = − x i exp ⁡ ( a x i 2 + b i x + c ) ∂ e i ∂ c = − exp ⁡ ( a x i 2 + b i x + c ) \frac{ \partial e_i }{ \partial a}=-x_i^2\exp(ax_i^2+b_ix+c) \\ \frac{ \partial e_i }{ \partial b}=-x_i\exp(ax_i^2+b_ix+c) \\ \frac{ \partial e_i }{ \partial c}=-\exp(ax_i^2+b_ix+c) aei=xi2exp(axi2+bix+c)bei=xiexp(axi2+bix+c)cei=exp(axi2+bix+c)

J i = [ ∂ e i ∂ a , ∂ e i ∂ b , ∂ e i ∂ c ] ⊤ \boldsymbol{J}_i=[\frac{ \partial e_i }{ \partial a}, \frac{ \partial e_i }{ \partial b}, \frac{ \partial e_i }{ \partial c}]^\top Ji=[aei,bei,cei]。和前面不一样。

J ( x ) J T ⏟ H ( x ) ( x ) Δ x = − J ( x ) f ( x ) ⏟ g ( x ) \underbrace{\boldsymbol{J}(\boldsymbol{x}) \boldsymbol{J}^{\mathrm{T}}}_{\boldsymbol{H}(\boldsymbol{x})}(\boldsymbol{x}) \Delta \boldsymbol{x}=\underbrace{-\boldsymbol{J}(\boldsymbol{x}) f(\boldsymbol{x})}_{\boldsymbol{g}(\boldsymbol{x})} H(x) J(x)JT(x)Δx=g(x) J(x)f(x)

此处即为

( ∑ i = 1 100 J i J i ⊤ ) Δ x = − ∑ i = 1 100 J i e i (\sum^{100}_{i=1}\boldsymbol{J}_i\boldsymbol{J}_i^\top)\Delta \boldsymbol{x}=-\sum^{100}_{i=1}\boldsymbol{J}_ie_i (i=1100JiJi)Δx=i=1100Jiei

/***********************************************************                                          *
* Time: 2023/8/10
* Author: xiaocong
* Function: 高斯牛顿法
***********************************************************/#include <iostream>
#include <eigen3/Eigen/Core>
#include <eigen3/Eigen/Dense>
#include <cmath>using namespace std;
using namespace Eigen;const int N = 100;                // 数据点个数
const int MAX_INTER = 100;        // 最大迭代次数void gaussNewton(const VectorXd& x_data, const VectorXd& y_data, Vector3d& params)
{double cost = 0;for (int iter = 0; iter < MAX_INTER; iter++){Matrix3d H = Matrix3d::Zero();      // H=JJ^TVector3d b = Vector3d::Zero();      // b=-Jecost = 0;double ae = params(0);double be = params(1);double ce = params(2);for (int i = 0;i < N;i++){double xi = x_data(i), yi = y_data(i);double ei = yi - exp(ae * xi * xi + be * xi + ce);    // 残差项Vector3d Ji;                                          // 雅可比矩阵Ji(0) = -xi * xi * exp(ae * xi * xi + be * xi + ce);Ji(1) = -xi * exp(ae * xi * xi + be * xi + ce);Ji(2) = -exp(ae * xi * xi + be * xi + ce);H += Ji * Ji.transpose();b += -Ji * ei;cost += ei * ei;}// 求解 dxVector3d dx = H.ldlt().solve(b);if (isnan(dx[0])){cout << "result is nan!" << endl;break;}if (dx.squaredNorm() < 1e-6)      // dx 足够小{break;}// 迭代params += dx;cout << "iter= " << iter + 1 << endl;cout << dx(0) << endl;cout << dx(1) << endl;cout << dx(2) << endl;cout << "cost= " << cost << endl;cout << "estimated abc= " << params(0) << ", " << params(1) << ", " << params(2) << endl;}
}int main(int argc, char** argv)
{double ar = 1.0, br = 2.0, cr = 1.0;         // 真实参数值Vector3d params(2.0, -1.0, 5.0);            // 初始参数值// 生成数据VectorXd x_data(N);VectorXd y_data(N);for (int i = 0; i < N; i++){double xi = i / 100.0;                                     // [0~1]double sigma = 0.02 * (rand() % 1000) / 1000.0 - 0.01;     // 随机噪声,[-0.01, 0.01]double yi = exp(ar * xi * xi + br * xi + cr) + sigma;x_data(i) = xi;y_data(i) = yi;}gaussNewton(x_data, y_data, params);return 0;
}
iter= 7
-0.00134314
0.00213517
-0.000823118
cost= 0.00356444
estimated abc= 0.999314, 2.00098, 0.999659

4.6 三种方法优缺点

最速下降法、牛顿法和高斯牛顿法都是常用的优化算法,用于解决最小化问题。它们各自有不同的优缺点,下面是对这三种算法的优缺点进行总结:

最速下降法:

优点:

  1. 简单直观: 最速下降法的核心思想简单易懂,容易实现。
  2. 适用广泛: 适用于一般的优化问题,不需要太多的先验知识。
  3. 内存消耗小: 只需要存储当前参数和梯度,内存消耗相对较小。

缺点:

  1. 收敛速度慢: 最速下降法的收敛速度通常较慢,特别是在存在长轴状谷底或细长山谷的情况下。
  2. 依赖初始值: 初始参数的选择会影响收敛性能,不合适的初始值可能导致陷入局部最小值。
  3. 不适用于高维问题: 在高维问题中,计算梯度和参数更新可能变得耗时,从而影响效率。

牛顿法:

优点:

  1. 收敛速度快: 牛顿法在逼近局部最小值时的收敛速度通常比最速下降法更快。
  2. 二阶信息利用: 牛顿法利用了函数的二阶导数信息,可以更准确地估计局部几何特性。

缺点:

  1. 计算复杂: 牛顿法需要计算函数的二阶导数(Hessian矩阵),计算成本较高,特别是在高维问题中。
  2. 不稳定性: Hessian矩阵可能不是正定的,导致算法不稳定。此外,在某些情况下,牛顿法可能在非凸问题中陷入局部最小值。

高斯牛顿法:

优点:

  1. 适用于非线性问题: 高斯牛顿法适用于非线性优化问题,尤其是拟合参数化模型时效果较好。
  2. 不需要二阶导数: 高斯牛顿法不需要直接计算Hessian矩阵,而是通过近似方法来计算。

缺点:

  1. 对初始值敏感: 高斯牛顿法对初始参数的选择敏感,不合适的初始值可能导致算法发散。
  2. 可能陷入局部最小值: 高斯牛顿法有时可能陷入局部最小值,特别是在存在多个局部最小值的问题中。

综合来看,选择哪种算法取决于问题的性质和实际需求。最速下降法简单但收敛速度慢,适用于简单问题或作为其他优化算法的初始步骤。牛顿法收敛速度快,但在计算复杂和非凸问题中可能不稳定。高斯牛顿法适用于非线性问题,但对初始值敏感,需要权衡利弊。在实际应用中,可能需要结合多种算法来优化不同的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/196678.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

wpf 系统在显示器分辨率和缩放设置为非1920*1080和100%时,SelectionChanged事件响应问题分析?

系统在显示器分辨率和缩放设置为1920*1080和100%时&#xff0c;窗口四分格能正常响应SelectionChanged事件&#xff0c;但是当缩放为125%时&#xff0c;或是分辨率大于1920*1080时四分格其中一个格子的下侧和右侧点击不响应&#xff0c;什么原因&#xff1f; 描述的问题可能由以…

考研英语语法(四十)

平行结构-分类 介词短语的平行并列 ……he advocated freedom of thought and of personal expression ……he advocated freedom of thought and of personal expression Mental health allows us to view others with sympathy if…

【qml入门教程系列】:qml列表控件ListView用法介绍

作者:令狐掌门 技术交流QQ群:675120140 博客地址:https://mingshiqiang.blog.csdn.net/ 文章目录 一、ListView基本用法二、ListView delegate妙用delegate 用法1delegate 用法2三、如何获取ListView的点击项一、ListView基本用法 ListView 是 Qt Quick (QML) 中的列表控件…

TypeScript 的高级技巧

1 — 高级类型&#xff08;Advanced Types&#xff09; 使用 TypeScript 的高级类型&#xff0c;如映射类型和条件类型&#xff0c;可以基于现有类型构建新类型。通过使用这些类型&#xff0c;您可以在强类型系统中更改和操作类型&#xff0c;从而使您的代码具有更大的灵活性和…

MySQL 数字函数

1. MySQL 数字函数ABS(x) MySQL数字函数ABS(x)用于返回参数x的绝对值。 语法&#xff1a; ABS(x)参数说明&#xff1a; x&#xff1a;要处理的数字。 返回值&#xff1a; 返回参数x的绝对值。 示例&#xff1a; SELECT ABS(-5);输出结果为&#xff1a;5 2. MySQL 数字…

贝叶斯网络 (人工智能期末复习)

文章目录 贝叶斯网络&#xff08;概率图模型&#xff09;定义主要考点例题- 要求画出贝叶斯网络图- 计算各节点的条件概率表- 计算概率- 分析独立性 贝叶斯网络&#xff08;概率图模型&#xff09; 定义 一种简单的用于表示变量之间条件独立性的有向无环图&#xff08;DAG&am…

Python和Pygame绘制自动驾驶和移动机器本地规划器算法

可视化自动驾驶车辆路径规划和移动机器人中使用的众多不同的本地规划器算法。 该应用程序提供可定制的参数&#xff0c;以更好地了解每种算法的内部工作原理并探索它们的优点和缺点。 它是用 Python 编写的&#xff0c;并使用 Pygame 来渲染可视化。 基类 import sys import …

从0到1 手把手搭建spring cloud alibaba(二十二)neo4j 优势,原理,使用场景以及案例介绍

1 什么是图数据库 1.1 图关系数据库的背景,为什么会出现图数据库 上世纪80年代,随着关系型数据库的发展,越来越多的应用程序应运而生,项目的增多也伴随着需求场景的增多 应用的数据库关联都只能靠表与表的外键定义,当关系复杂度达到一定数量的时候,关联某些表的某些属性…

tanstack/react-query使用手册

1. useQuery useQuery的使用一、data是后端成功返回的数据&#xff0c; 第一次的值为undefined 二、isLoading是指数据是否正在加载的状态&#xff0c;通常用于判断请求是否还在进行中。当isLoading为true时&#xff0c;表示数据正在加载中&#xff0c;当isLoading为false时&a…

BGP基本配置

一、知识补充 1、BGP BGP是Border Gateway Protocol&#xff08;边界网关协议&#xff09;的缩写。它是用于在互联网中交换路由信息的一种协议。BGP被广泛应用于大规模的自治系统&#xff08;AS&#xff09;之间&#xff0c;用于实现跨网络的路由选择和交换。 BGP的主要功能…

基于Cocos2D-X框架闯关游戏的设计

摘 要 随着智能设备平台的普及、用户数量的增多&#xff0c;智能平台的应用&#xff0c;尤其是游戏异常火爆&#xff0c;从植物大战僵尸到愤怒的小鸟&#xff0c;移动平台游戏的开发进入了新的阶段。但是另一方面&#xff0c;平台的多样性也给开发者带来诸多不便&#xff0c;怎…

单片机第三季-第四课:STM32下载、MDK和调试器

目录 1&#xff0c;扩展板使用的STM32芯片类型 2&#xff0c;使用普中科技软件下载程序 3&#xff0c;keil介绍 4&#xff0c;JLINK调试器介绍 5&#xff0c;使用普中的调试器进行debug 6&#xff0c;使用Simulator仿真 1&#xff0c;扩展板使用的STM32芯片类型 扩展版…

什么是网络可视化?网络可视化工具有用吗

网络可视化定义是自我描述的&#xff0c;因为它在单个屏幕上重新创建网络布局&#xff0c;以图形和图表的形式显示有关网络设备、网络指标和数据流的信息&#xff0c;为 IT 运营团队提供一目了然的理解和决策。 网络是复杂的实体&#xff0c;倾向于持续进化&#xff0c;随着业…

应急电源控制系统的研究与设计

摘要 本设计基于STC89C52单片机设计得应急电源&#xff0c;以应急电源为研究对象&#xff0c;单片机设计为控制集成IC&#xff0c;ADC为模数转换控制模块&#xff0c;无源蜂鸣器作为报警电路。系统分为单片机设计最小系统&#xff0c;AD转换控制模块&#xff0c;电源电路&#…

【LeeCode】242.有效的字母异位词

给定两个字符串 *s* 和 *t* &#xff0c;编写一个函数来判断 *t* 是否是 *s* 的字母异位词。 注意&#xff1a;若 *s* 和 *t* 中每个字符出现的次数都相同&#xff0c;则称 *s* 和 *t* 互为字母异位词。 示例 1: 输入: s "anagram", t "nagaram" 输出:…

【C++】异常处理 ⑧ ( 标准异常类 | 标准异常类继承结构 | 常用的标准异常类 | 自定义异常类继承 std::exception 基类 )

文章目录 一、抛出 / 捕获 多个类型异常对象1、标准异常类2、标准异常类继承结构3、常用的标准异常类 二、自定义异常类继承 std::exception 基类1、自定义异常类继承 std::exception 基类2、完整代码示例 - 自定义异常类继承 std::exception 基类 一、抛出 / 捕获 多个类型异常…

java常用知识点记忆

类的继承与多态 类的继承不支持多重继承非private 方法才可以被覆盖覆盖的方法要求&#xff0c;子类中的方法的名字&#xff0c;参数列表&#xff0c;返回类型与父类相同方法的重载是在一个类中定义方法名字相同&#xff0c;但是参数列表不同的方法要是在子类中定义了与父类名字…

【Windows】使用SeaFile搭建本地私有云盘并结合内网穿透实现远程访问

1. 前言 现在我们身边的只能设备越来越多&#xff0c;各种智能手机、平板、智能手表和数码相机充斥身边&#xff0c;需要存储的数据也越来越大&#xff0c;一张手机拍摄的照片都可能有十多M&#xff0c;电影和视频更是按G计算。而智能设备的存储空间也用的捉襟见肘。能存储大量…

Google Protocol Buffers (proto3) 中的 DoubleValue 类型用法总结

文章目录 前言DoubleValue 的作用如何使用 DoubleValue1. 定义 .proto 文件2. 设置 DoubleValue 字段的值3. 检查字段值是否为空&#xff0c;并获取值3. demo示例 前言 这两天在做相关工作的时候&#xff0c;遇到了一个需要定义optional double 类型的proto字段&#xff0c;因…

JDBC常见的几种连接池使用(C3P0、Druid、HikariCP 、DBCP)(附上代码详细讲解)

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍JDBC常见的几种连接池使用&#xff08;C3P0、Druid、HikariCP 、DBCP&#xff09;以及部分理论知识 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主收将持续更新学…