我正在尝试最小化一个函数,该函数采用长度为 N 的 1d数组并通过 Levenberg-Marquardt (:= LM( 返回标量。
它在 Matlab 中工作:
beta_initial = [-0.7823, -0.1441, -0.7669];
% substitution for my long, convoluted function
% but it also works with the proper function
F = @(beta) sum(exp(beta))+3;
options = optimset('Algorithm','Levenberg-Marquardt');
beta_arma = lsqnonlin(F,beta_initial,[],[],options) % -21.7814 -15.9156 -21.5420
F(beta_arma) % 3
当我在 Python 中尝试时,我遇到了一个值错误:
值错误:当残差数小于变量数时,方法"lm"不起作用。
import numpy as np
from scipy.optimize import least_squares as lsq
# substitution for my long, convoluted function
F = lambda beta: np.sum(np.exp(beta))+3
beta_initial = [-0.7823, -0.1441, -0.7669]
beta_arma = lsq(F, beta_initial,method='lm')['x']
我理解错误 scipy 的方式要求
out = F(in(,使得 len(out(>= len(in( ,但 matlab 没有
我已经查看了文档,scipy和matlab。
来自 scipy 文档:
方法'lm'(Levenberg-Marquardt(调用MINPACK(lmder,lmdif(中实现的最小二乘算法的包装器。它运行 Levenberg-Marquardt 算法,该算法被表述为信任区域类型算法。该实现基于纸张[JJMore],它非常健壮和高效,有很多聪明的技巧。它应该是您解决不受约束问题的首选。请注意,它不支持边界。当 m 。
看起来没有LM实现在m>=n时有效
我的问题是:
如何使用 LM 获得非线性最小二乘最小化,例如 Python 中的 Matlab?
我通过将函数一分为二找到了解决方法:
- 第一个函数接受一个数组并返回一个数组
- 第二个函数从第一个函数获取已处理的数组并返回标量输出
然后,我让优化器在第一个函数上运行。
在上面最小示例的上下文中:
import numpy as np
from scipy.optimize import least_squares as lsq
F1 = lambda beta: np.exp(beta)
F2 = lambda processed_beta: np.sum(np.exp(processed_beta))+3
beta_initial = [-0.7823, -0.1441, -0.7669]
# parameters that minimze F1
beta_arma = lsq(F1, beta_initial,method='lm')['x']
F2(beta_arma) # 3.0