【转】LM(Levenberg-Marquard)算法的实现
来源:互联网 发布:手持数据终端多少钱 编辑:程序博客网 时间:2024/04/29 01:38
转载请注明出处:http://www.codelast.com/
LM算法,全称为Levenberg-Marquard算法,它可用于解决非线性最小二乘问题,多用于曲线拟合等场合。
LM算法的实现并不算难,它的关键是用模型函数
事实上,你从所有可以找到的资料里看到的LM算法的说明,都可以找到类似于“如果目标函数值增大,则调整某系数再继续求解;如果目标函数值减小,则调整某系数再继续求解”的迭代过程,这种过程与上面所说的信赖域法是非常相似的,所以说LM算法是一种信赖域法。
LM算法需要对每一个待估参数求偏导,所以,如果你的目标函数
至于这个求导过程是如何实现的,我还不能给出建议,我使用过的方法是拿到函数的方程,然后手工计算出其偏导数方程,进而在函数中直接使用,这样做是最直接,求导误差也最小的方式。不过,在你不知道函数的形式之前,你当然就不能这样做了——例如,你提供给了用户在界面上输入数学函数式的机会,然后在程序中解析其输入的函数,再做后面的处理。在这种情况下,我猜是需要使用数值求导算法的,但我没有亲自试验过这样做的效率,因为一些优秀的求导算法——例如Ridders算法——在一次求导数值过程中,需要计算的函数值次数也会达到5次以上。这样的话,它当然要比手工求出导函数(只需计算一次,就可以得到导数值)效率要差得多了。不过,我个人估计(没有任何依据的,只是猜的):依赖于LM算法的高效,就算添加了一个数值求导的“拖油瓶”,整个最优化过程下来,它仍然会优于Powell等方法。
文章来源:http://www.codelast.com/
在这篇解释信赖域算法的文章中,我们已经知道了LM算法的数学模型:
可以证明,此模型可以通过解方程组
即:LM算法要确定一个
文章来源:http://www.codelast.com/
下面来看看LM算法的基本步骤:
- 从初始点
x0 ,μ0>0 开始迭代 - 到第
k 步时,计算xk 和μk - 分解矩阵
Gk+μkI ,若不正定,令μk=4μk 并重复到正定为止 - 解线性方程组
(Gk+μkI)sk=−gk 求出sk 并计算rk - 若
rk<0.25 ,令μk+1=4μk ;若rk>0.75 ,令μk+1=μk2 ;若0.25≤rk≤0.75 ,令μk+1=μk - 若
rk≤0 ,说明函数值是向着上升而非下降的趋势变化了(与最优化的目标相反),这说明这一步走错了,而且错得“离谱”,此时,不应该走到下一点,而应“原地踏步”,即xk+1=xk ,并且和上面rk<0.25 的情况一样对μk 进行处理。反之,在rk>0 的情况下,都可以走到下一点,即xk+1=xk+sk - 迭代的终止条件:
∥gk∥<ε ,其中ε 是一个指定的小正数(大家可以想像一下二维平面上的寻优过程(函数图像类似于抛物线),当接近极小值点时,迭代点的梯度趋于0)
文章来源:http://www.codelast.com/
从上面的步骤可见,LM求解过程中需要用到求解线性方程组的算法,一般我们使用高斯约当消元法,因为它非常稳定——虽然它不是最快最好的算法。
同时,上面的算法步骤也包含对矩阵进行分解的子步骤。为什么要先分解矩阵,再解线性方程组?貌似是这样的(数学不好的人再次泪奔):不分解矩阵使之正定,就无法确定那个线性方程组是有解的。矩阵分解有很多算法,例如LU分解等,这方面我没有看。
这里有一篇很不错的文章,解释了如何实现LM算法,大家可以参考一下。
需要说明的是,这是非线性无约束的问题,如果待估参数是有约束的(例如参数在某一范围内变动),要想用在LM算法中,那就是约束最优化问题了,这是一个big topic,以我目前的知识储备,尚不能解释好,请大家另寻资料吧。
- 【转】LM(Levenberg-Marquard)算法的实现
- LM(Levenberg-Marquard)算法的实现
- 【转】LM(Levenberg-Marquard) Matlab及C语言实现
- LM(Levenberg-Marquard) c语言实现
- Levenberg-Marquardt(LM算法)
- Levenberg-Marquardt优化算法以及基于LM的BP-ANN
- [原创]LM算法的实现
- LM算法的C++实现
- 训练数据常用算法之Levenberg–Marquardt(LM)
- sba(sparse bundle adjustment):一个基于Levenberg-Marquardt(LM)算法的通用稀疏光束法平差C/C++软件包
- 基于Levenberg-Marquardt训练算法的BP网络Python实现
- 基于Levenberg-Marquardt训练算法的BP网络Python实现
- 基于Levenberg-Marquardt训练算法的BP网络Python实现
- 基于Levenberg-Marquardt训练算法的BP网络Python实现
- Levenberg-Marquardt算法简介和C++实现
- Levenberg-Marquardt算法简介和C++实现
- Eigen中Levenberg-Marquardt算法的应用
- 【转】 Levenberg-Marquardt 算法快速入门教程
- IOS--UI--LessonUITabBarController 标签控制器
- 2015/07/17/几个小程序
- DIV CSS 上下左右滑动
- 进制转换
- pat 1006. Sign In and Sign Out (25)
- 【转】LM(Levenberg-Marquard)算法的实现
- PROGRAMMER PRODUCTIVITY STARTS WITH REQUIREMENTS, NOT TOOLS!
- 三角形判断
- 【Ray Tracing from Ground Up】Specular Reflection
- ubuntu添加用户到root组
- windows 10 - 10240版本激活问题
- STM32W108无线射频模块AD转换器应用实例
- 数据的插入与删除
- GCD—简单代码