LM(Levenberg-Marquard)算法的实现
来源:互联网 发布:网络监控设计说明 编辑:程序博客网 时间:2024/05/17 05:05
[原创]LM(Levenberg-Marquard)算法的实现
2010年9月14日 由 learnhard 留言 »转载请注明出处: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,以我目前的知识储备,尚不能解释好,请大家另寻资料吧。
文章来源:http://www.codelast.com/
- 上一篇: [转]以前的程序安装创建了挂起的文件操作。运行安装程序之前,必须重新启动计算机
- 下一篇: 很好用的属性页控件——CTreePropSheet
7 条评论
- 【转】LM(Levenberg-Marquard)算法的实现
- LM(Levenberg-Marquard)算法的实现
- LM(Levenberg-Marquard) c语言实现
- 【转】LM(Levenberg-Marquard) Matlab及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算法的应用
- LM算法
- tomcat下部署 solr 5.3.1
- 常用知识
- works的题
- 相互激励
- 黑马程序员——流程控制语句
- LM(Levenberg-Marquard)算法的实现
- Understanding Linux /proc/cpuinfo
- LeetCode 108: Convert Sorted Array to Binary Search Tree
- http://codeforces.com/contest/34
- NOIP2014飞扬的小鸟
- Java之Timer
- [leetcode] 55. Jump Game 解题报告
- Xcode7 网络请求报错:The resource could not be loaded because the App Transport Security policy requir
- Word Embedding的通俗解释
非常感谢指点,现在我正在使用C#编写LM算法,能否告知你那个时候是用什么语言编写的lm代码吗?谢谢了!
C++
哦,这样啊,你还有代码吗?能给我传一份吗?谢谢了,我的邮箱是389454688@qq.com,谢谢了!!!!
抱歉,涉及到版权,不能发给你。不过网上到处都有此类代码下载,例如:http://www.ics.forth.gr/~lourakis/levmar/
请自行移步Google获取更多答案。
好的,非常感谢你的指导!祝你生活愉快,工作顺利!
谢谢指点,正需要了解lm算法原理,有没有别的易(或较易)编程实现的非线性拟合算法,推荐几个,想写个程序分析一下我所用环境下的优劣
单纯形法——不依赖于任何其他子算法(例如一维搜索,线性方程组求解等),在某些场合下非常有用。但为了高效及通用,建议还是使用LM、Powell等算法。