四参数拟合之LMF法(无约束)

前言

 写到这里,已经发现了前面两篇文章的重大bug。那就是牛顿法也好,LM法也好,都是针对无约束的问题,而四参数拟合问题是一个有约束的问题,参数一般设置为0到正无穷。这也解释了为何之前的计算结果,总是和L4P的结果不同。根本原因在于完全没搞懂四参数拟合的参数意义。所以这篇重点介绍LM算法,四参数拟合结果仍然有问题
 事到如今,将错就错, 把Levenberg-Marquardt算法写完。Levenberg-Marquardt简称L-M,它的主要目的是克服了高斯牛顿法必须要求雅可比矩阵秩满列的缺点,为此,它引入了新的目标函数。

LM 算法

高斯牛顿法目标
a r g   m i n w ( F ( w ) ) = a r g   m i n w ∑ i = 1 m ∣ ∣ y i − f ( w ; x i ) ∣ ∣ 2 = a r g   m i n w 1 2 r ( w ) T r ( w ) arg \ \underset{w}{min} (F(w)) = arg \ \underset{w}{min}\sum_{i=1}^{m}||y_i-f(w;x_i)||^2 = arg \ \underset{w}{min}\frac{1}{2}r(w)^Tr(w) arg wmin(F(w))=arg wmini=1myif(w;xi)2=arg wmin21r(w)Tr(w)
r ( w ) r(w) r(w)是残差向量, r i ( w ) = y i − f ( w ; x i ) r_i(w) = y_i-f(w;x_i) ri(w)=yif(w;xi) w = [ A , B , C , D ] w = [A,B,C,D] w=[A,B,C,D]为带求参数
f ( w ; x i ) = D + A − D 1 + ( x i / C ) B f(w;x_i) = D+\frac{A-D}{1+(x_i/C)^B} f(w;xi)=D+1+(xi/C)BAD
L-M法目标

a r g   m i n w ∑ i = 1 m ∣ ∣ y i − f ( w ; x i ) ∣ ∣ 2 + λ ∣ ∣ Δ w ∣ ∣ 2 arg \ \underset{w}{min}\sum_{i=1}^{m}||y_i-f(w;x_i)||^2+\lambda||\Delta w ||^2 arg wmini=1myif(w;xi)2+λΔw2

这个目标式对 ∣ ∣ Δ w ∣ ∣ 2 ||\Delta w ||^2 Δw2的进行约束,防止 ∣ ∣ Δ w ∣ ∣ 2 ||\Delta w ||^2 Δw2,使得泰勒展开式误差过大。这个目标跟岭回归的目标式如出一辙
Δ w = − ( J f T J f + λ I ) − 1 J f T r ( w ) \Delta w = - (J_f^TJ_f+\lambda I)^{-1}J_f^Tr(w) Δw=(JfTJf+λI)1JfTr(w)
从上式可以看出, λ \lambda λ很大的时候,下降梯度接近最速下降法,很小时,则接近于高斯牛顿法。为了得到合适的 λ \lambda λ值需要引入一个评价指标 q q q
s = Δ w s =\Delta w s=Δw, L ( s ) = F ( w + Δ w ) ≈ F ( w ) + g ( w ) T s + 1 2 s T G s L(s) = F(w+\Delta w)\approx F(w)+g(w)^Ts+\frac{1}{2}s^TGs L(s)=F(w+Δw)F(w)+g(w)Ts+21sTGs
这里的 g ( w ) , G g(w),G g(w),G分为 F F F的梯度以及海赛矩阵,其中, G G G只是取一个近似值
q = F ( w ) − F ( w + Δ w ) L ( 0 ) − L ( s ) q = \frac{F(w)-F(w+\Delta w)}{L(0)-L(s)} q=L(0)L(s)F(w)F(w+Δw)
从上式可以看出, q q q越接近 1 1 1,泰勒展开的估计值越准确。 q q q只要大于0,至少说明方向是正确的,如果 q q q小于0,则要调节步长了。我们已经能看到步长 s = Δ w s =\Delta w s=Δw实际是通过 λ \lambda λ控制,调节范围在最速下降和高斯牛顿法之间。这种步长的调节方法也称为称为信赖域的方法。
具体调整策略很多,简单的做法如下:
设置参数如下 ϵ = 0.01 , η 1 = 0.01 , η 2 = 0.75 , γ 1 = 0.5 , γ 2 = 2 , λ = 1 \epsilon=0.01,\eta_1=0.01,\eta_2=0.75,\gamma_1= 0.5,\gamma _2= 2,\lambda=1 ϵ=0.01,η1=0.01,η2=0.75,γ1=0.5,γ2=2,λ=1
{ q < η 1 , λ = γ 2 λ η 2 ≤ q ≤ η 1 , λ = λ q > η 2 , λ = γ 1 λ \left\{\begin{matrix} q<\eta _1, & \lambda =\gamma_2 \lambda \\ \eta_2\leq q\leq \eta _1, & \lambda = \lambda \\ q>\eta_2, & \lambda = \gamma_1\lambda \end{matrix}\right. q<η1,η2qη1,q>η2,λ=γ2λλ=λλ=γ1λ
设置收敛条件:

  1. 决定系数R>0.997
  2. F k + 1 − F k < 10 e − 6 F_{k+1}-F_k<10e-6 Fk+1Fk<10e6
  3. ∣ ∣ J f ∗ r ( w ) ∣ ∣ 2 < ϵ ||J_f*r(w)||^2<\epsilon Jfr(w)2<ϵ
  4. 超过最大运算次数

可以多选或者选其一

Matlab代码

%Levenberg-Marquardt

clear;
load census;
x1 = cdate ;
y1 = pop ;
m = length(x1);
%parameters
eps = 0.01;
eta1 = 0.01;
eta2 = 0.75;
gama1 = 0.5;
gama2 = 2;
lamda = 1;
%init a,b,c,d
d = max(y1)+1;
a = min(y1)-0.1;
y2 = log((y1-d)./(a-y1));
x2 = log(x1);
[curve2,gof2] = fit(x2,y2, 'poly1');
b = -curve2.p1;
c = exp(curve2.p2/b);
%LMF
w=[a,b,c,d]'; 
[res,R,fit] = evaluateFit(y1,x1,w);
mse = 0.5*sum((y1-fit).^2); 
r = y1-fit;
for k = 1:1:1000
    JacobiMatrix = getJaccobiMatrix(x1,a,b,c,d);
    HessenMatrix = (JacobiMatrix)'*(JacobiMatrix)+lamda*eye(4);
    delta_w = inv(HessenMatrix)*JacobiMatrix'*r;
    w_new = w+delta_w;
    [res,R,fit_new] = evaluateFit(y1,x1,w_new);
    mse_new =0.5*sum( (y1-fit_new).^2);
    q = (mse - mse_new)/(r'*JacobiMatrix*delta_w+0.5*delta_w'*HessenMatrix*delta_w);
     if q<eta1
        lamda = lamda * gama2;
        continue;
    elseif  q>eta2
         lamda = lamda * gama1;
     end
    %coverage
    de = abs(norm(JacobiMatrix'*r));
    if de<eps
        break;
    end
    %update compution result
    fit = fit_new;
    mse = mse_new;
    r  = y1-fit;
    %update a b c d
    a = w_new(1);b = w_new(2);c = w_new(3);d= w_new(4);
    w=w_new; 

end
function [JacobiMatrix] = getJaccobiMatrix(x1,a,b,c,d)
   JacobiMatrix = ones(length(x1),4);
   for i = 1:1:length(x1)
        JacobiMatrix(i,1) = calc_pA(x1(i),a,b,c,d);
        JacobiMatrix(i,2) = calc_pB(x1(i),a,b,c,d);
        JacobiMatrix(i,3) = calc_pC(x1(i),a,b,c,d);
        JacobiMatrix(i,4) = calc_pD(x1(i),a,b,c,d);
    end
end
function [res,R2,fit] = evaluateFit(y,x,w)
fit = getFittingValue(x,w);
res =  norm(y-fit)/sqrt(length(fit));
yu =  mean(y);
R2 = 1 - norm(y-fit)^2/norm(y - yu)^2;
end
function fit = getFittingValue(x,w)
len = length(x);
fit = ones(len,1);
for i = 1:1:len
    fit(i)  = hypothesis(x(i),w);
end
end
function val  = hypothesis(x,w)
a = w(1);b= w(2);c= w(3);d= w(4);
val = d+(a-d)/(1+(x/c)^b);
end
function val = calc_pA(x,A,B,C,D)
val = 1/((x/C)^B + 1);
end
function val = calc_pB(x,A,B,C,D)
val = -(log(x/C)*(A - D)*(x/C)^B)/((x/C)^B + 1)^2;
end
function val = calc_pC(x,A,B,C,D)
val = (B*x*(A - D)*(x/C)^(B - 1))/(C^2*((x/C)^B + 1)^2);
end
function val = calc_pD(x,A,B,C,D)
val = 1 - 1/((x/C)^B + 1);
end

后面,研究一下四参数拟合的约束情况

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值