LM算法初识_lm算法效果

  由于工作内容接触到点云标定,需要用到最小二乘法,所以特意花了点时间研究LM算法,但是由于大学的高等数学忘得差不多了,所以本文从最基本的一些数学概念开始;

信赖域法

  在最优化算法中,都是要求一个函数的极小值,每一步迭代中,都要求目标函数值是下降的,而信赖域法,顾名思义,就是从初始点开始,先假设一个可以信赖的最大位移,然后在以当前点为中心,以为半径的区域内,通过寻找目标函数的一个近似函数(二次的)的最优点,来求解得到真正的位移。在得到了位移之后,再计算目标函数值,如果其使目标函数值的下降满足了一定条件,那么就说明这个位移是可靠的,则继续按此规则迭代计算下去;如果其不能使目标函数值的下降满足一定的条件,则应减小信赖域的范围,再重新求解。

泰勒公式:

在这里插入图片描述在这里插入图片描述

雅可比矩阵

  雅可比矩阵几乎在所有的最优化算法中都有提及,因此我们很有必要了解一下其具到底是什么,关于这一点,下方截图说的很清楚;
在这里插入图片描述在这里插入图片描述
  从上面可以了解,雅可比矩阵实际上就是一阶偏导数所组成的矩阵,其列数由未知参数个数决定,其行数由我们提供的输入参数组决定;

各种最优化算法

在这里插入图片描述在这里插入图片描述
  需要注意的是,对于LM算法,可以具体到下种形式:
在这里插入图片描述在这里插入图片描述
  其中,r是残差;

代码实现

  LM算法的关键是用模型函数 f 对待估参数向量p在其领域内做线性近似,忽略掉二阶以上的导数项,从而转化为线性最小二乘问题,它具有收敛速度快等优点。
  LM算法需要对每一个待估参数求偏导,所以,如果你的拟合函数 f 非常复杂,或者待估参数相当地多,那么就不适合使用LM算法了,可以使用Powell算法,Powell算法不需要求导。
  需要说明的是,这是非线性无约束的问题,如果待估参数是有约束的,暂时还没有涉及到这个领域;
  就是从初始点开始,先假设一个可以信赖的最大位移,然后在以当前点为中心,以为半径的区域内,通过寻找目标函数的一个近似函数(二次的)的最优点,来求解得到真正的位移。在得到了位移之后,再计算目标函数值,如果其使目标函数值的下降满足了一定条件,那么就说明这个位移是可靠的,则继续按此规则迭代计算下去;如果其不能使目标函数值的下降满足一定的条件,则应减小信赖域的范围,再重新求解。
  在使用Levenberg-Marquart时,先设置一个比较小的μ值,当发现目标函数反而增大时,将μ增大使用梯度下降法快速寻找,然后再将μ减小使用牛顿法进行寻找。
6.阻尼系数的调整
维基百科维基百科
  当阻尼系数足够大时,使算法更接近最速下降法,所以在残差没有明显变化时可以使用;当阻尼系数足够小时,算法更接近高斯牛顿算法,此时迭代速度更快;
  有算法精度ep和上一次残差e,当e<lamda < ep时,lamda = lamda/5,当lamda > ep时,lamda = lamda*5,当lamda < ep时,lamda = lamda;

  代码如下:

% 计算函数f的雅克比矩阵
syms a b y x real;
f=a*cosb*x) + b*sina*x)
Jsym=jacobianf,[a b])

data_1=[ 0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0,3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2 ];
obs_1=[102.225 ,99.815,-21.585,-35.099, 2.523,-38.865,-39.020, 89.147, 125.249,-63.405, -183.606, -11.287,197.627, 98.355, -131.977, -129.887, 52.596, 101.193,5.412, -20.805, 6.549, -40.176, -71.425, 57.366, 153.032,5.301, -183.830, -84.612, 159.602, 155.021, -73.318, -146.955];
% 2. LM算法
% 初始猜测初始点
a0=100; b0=100;
y_init = a0*cosb0*data_1) + b0*sina0*data_1);
% 数据个数
Ndata=lengthobs_1);
% 参数维数
Nparams=2;
% 迭代最大次数
n_iters=60;
% LM算法的阻尼系数初值
lamda=0.1;
%LM算法的精度
ep=100
% step1: 变量赋值
updateJ=1;
a_est=a0;
b_est=b0;
% step2: 迭代
for it=1:n_iters
    if updateJ==1
        % 根据当前估计值,计算雅克比矩阵,雅可比矩阵只需要在第一次循环时计算一次就好
        J=zerosNdata,Nparams); % 雅可比矩阵的行数由原始输入数据个数决定,列数由待估参数个数决定
        for i=1:lengthdata_1) 
            Ji,:)=[cosb_est*data_1i))+data_1i)*b_est*cosa_est*data_1i))  -sinb_est*data_1i))*a_est*data_1i)+sina_est*data_1i)) ];  % 雅可比矩阵由偏导组成
        end
        % 根据当前参数,得到函数值
        y_est = a_est*cosb_est*data_1) + b_est*sina_est*data_1);
        % 计算误差
        d=obs_1-y_est;
        % 计算(拟)海塞矩阵
        H=J'*J;
        % 若是第一次迭代,计算误差
        if it==1
            e=dotd,d); % 可以认为e是初始值计算所估误差
        end
    end
    % 根据阻尼系数lamda混合得到H矩阵
    H_lm=H+lamda*eyeNparams,Nparams));
    % 计算步长dp,并根据步长计算新的可能的\参数估计值
    dp=invH_lm)*J'*d:))
    %求误差大小
    g = J'*d:);
    a_lm=a_est+dp1);  % 在初始值上加上所求步长,作为新的评估参数
    b_lm=b_est+dp2);
    % 计算新的可能估计值对应的y和计算残差e
    y_est_lm = a_lm*cosb_lm*data_1) + b_lm*sina_lm*data_1);
    d_lm=obs_1-y_est_lm
    e_lm=dotd_lm,d_lm)  % 这个值后面主要用于和上一次误差进行比对,从而调整阻尼系数
    
    % 根据误差,决定如何更新参数和阻尼系数
    if e_lm<e  % 如果小于上一次误差
        if e_lm<ep  % 如果小于算法精度
            break % 结束,说明该阻尼系数合理
        else
            lamda=lamda/5; % 如果小于上一次误差,但大于算法精度,那么更新阻尼系数,同时将当前评估参数作为初始值重新计算
            a_est=a_lm;
            b_est=b_lm;
            e=e_lm;
            dispe);
            updateJ=1; 
        end
    else
        updateJ=0;
        lamda=lamda*5;
    end
    
end
%显示优化的结果
a_est
b_est

plotdata_1,obs_1,'r')
hold on
plotdata_1,a_est*cosb_est*data_1) + b_est*sina_est*data_1),'g')

参考链接:
https://blog.csdn.net/a6333230/article/details/83304098
https://blog.csdn.net/baidu_38172402/article/details/82223284
https://zhuanlan.zhihu.com/p/39762178
http://www.360doc.com/content/18/0330/13/18306241_741511614.shtml
https://blog.csdn.net/xueyinhualuo/article/details/46931989?utm_medium=distribute.pc_relevant.none-task-blog-
https://www.cnblogs.com/shhu1993/p/4878992.html
https://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注