【转】 Levenberg-Marquardt 算法快速入门教程

原帖地址:http://blog.csdn.net/a383201241/article/details/46299861

本文附的源程序是MATLAB代码,总共不到80行,实现了 求雅克比矩阵的解析解,演示了Levenberg-Marquardt最优化迭代过程,演示了如何求解拟合问题。本文用图文介绍了LM算法。转帖来自蜜蜂电脑

什么是最优化,可分为几大类?

答:Levenberg-Marquardt算法是最优化算法中的一种。最优化是寻找使得函数值最小的参数向量。它的应用领域非常广泛,如:经济学、管理优化、网络分析 、最优设计、机械或电子设计等等。 
根据求导数的方法,可分为2大类。第一类,若f具有解析函数形式,知道x后求导数速度快。第二类,使用数值差分来求导数。根据使用模型不同,分为非约束最优化、约束最优化、最小二乘最优化。

什么是Levenberg-Marquardt算法?

它是使用最广泛的非线性最小二乘算法,中文为列文伯格-马夸尔特法。它是利用梯度求最大(小)值的算法,形象的说,属于“爬山”法的一种。它同时具有梯度法和牛顿法的优点。当λ很小时,步长等于牛顿法步长,当λ很大时,步长约等于梯度下降法的步长。在作者的科研项目中曾经使用过多次。图1显示了算法从起点,根据函数梯度信息,不断爬升直到最高点(最大值)的迭代过程。共进行了12步。(备注:图1中绿色线条为迭代过程,但是由于分辨率小,看得不太清楚,单击该图后可放大查看)。


图1 LM算法迭代过程形象描述

图1中,算法从山脚开始不断迭代。可以看到,它的寻优速度是比较快的,在山腰部分直接利用梯度大幅度提升(参见后文例子程序中lamda较小时),快到山顶时经过几次尝试(lamda较大时),最后达到顶峰(最大值点),算法终止。

如何快速学习LM算法?

学习该算法的主要困难是入门难。 要么国内中文教材太艰涩难懂,要么太抽象例子太少。目前,我看到的最好的英文入门教程是K. Madsen等人的《Methods for non-linear least squares problems》本来想把原文翻译一下,贴到这里。请让我偷个懒吧。能找到这里的读者,应该都是E文好手,我翻译得不清不楚,反而事倍功半了。 
该文链接:http://www2.imm.dtu.dk/pubdb/public/publications.php? year=&pubtype=7&pubsubtype=§ion=1&cmd=full_view&lastndays=&order=author。或者直接下载pdf原文:http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf

例子程序(MATLAB源程序)

本程序不到100行,实现了 求雅克比矩阵的解析解,Levenberg-Marquardt最优化迭代,演示了如何求解拟合问题。采用萧树铁主编的《数学试验》(第二版)(高等教育出版社)中p190例2(血药浓度)来演示。在MATLAB中可直接运行得到最优解。

    % 计算函数f的雅克比矩阵,是解析式
    syms a b y x real;
    f=a*exp(-b*x);
    Jsym=jacobian(f,[a b])


    % 拟合用数据。参见《数学试验》,p190,例2
    data_1=[0.25 0.5 1 1.5 2 3 4 6 8];
    obs_1=[19.21 18.15 15.36 14.10 12.89 9.32 7.45 5.24 3.01];

    % 2. LM算法
    % 初始猜测s
    a0=10; b0=0.5;
    y_init = a0*exp(-b0*data_1);
    % 数据个数
    Ndata=length(obs_1);
    % 参数维数
    Nparams=2;
    % 迭代最大次数
    n_iters=50;
    % LM算法的阻尼系数初值
    lamda=0.01;

    % step1: 变量赋值
    updateJ=1;
    a_est=a0;
    b_est=b0;

    % step2: 迭代
    for it=1:n_iters
        if updateJ==1
            % 根据当前估计值,计算雅克比矩阵
            J=zeros(Ndata,Nparams);
            for i=1:length(data_1)
                J(i,:)=[exp(-b_est*data_1(i)) -a_est*data_1(i)*exp(-b_est*data_1(i))];
            end
            % 根据当前参数,得到函数值
            y_est = a_est*exp(-b_est*data_1);
            % 计算误差
            d=obs_1-y_est;
            % 计算(拟)海塞矩阵
            H=J'*J;
            % 若是第一次迭代,计算误差
            if it==1
                e=dot(d,d);
            end
        end

        % 根据阻尼系数lamda混合得到H矩阵
        H_lm=H+(lamda*eye(Nparams,Nparams));
        % 计算步长dp,并根据步长计算新的可能的\参数估计值
        dp=inv(H_lm)*(J'*d(:));
        g = J'*d(:);
        a_lm=a_est+dp(1);
        b_lm=b_est+dp(2);
        % 计算新的可能估计值对应的y和计算残差e
        y_est_lm = a_lm*exp(-b_lm*data_1);
        d_lm=obs_1-y_est_lm;
        e_lm=dot(d_lm,d_lm);
        % 根据误差,决定如何更新参数和阻尼系数
        if e_lm10;
            a_est=a_lm;
            b_est=b_lm;
            e=e_lm;
            disp(e);
            updateJ=1;
        else
            updateJ=0;
            lamda=lamda*10;
        end
    end
    %显示优化的结果
    a_est
    b_est
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

本程序对应的C++实现,已经公开,点此进入。

演示程序求解的问题是《数学试验》(萧树铁,第二版,高等教育出版社)中p190例2。为了方便读者,提供该书籍的数据和目标函数照片(2012年4月1日)。 

你可能感兴趣的:(计算机视觉,计算机视觉相关数学理论,PTAMM,PTAM学术要点,计算机视觉,数学)