【轉】LM(Levenberg-Marquard)算法的實現

轉載請註明出處:http://www.codelast.com/
 

LM算法,全稱爲Levenberg-Marquard算法,它可用於解決非線性最小二乘問題,多用於曲線擬合等場合。

LM算法的實現並不算難,它的關鍵是用模型函數 f 對待估參數向量p在其鄰域內做線性近似,忽略掉二階以上的導數項,從而轉化爲線性最小二乘問題,它具有收斂速度快等優點。LM算法屬於一種“信賴域法”——所謂的信賴域法,此處稍微解釋一下:在最優化算法中,都是要求一個函數的極小值,每一步迭代中,都要求目標函數值是下降的,而信賴域法,顧名思義,就是從初始點開始,先假設一個可以信賴的最大位移s,然後在以當前點爲中心,以s爲半徑的區域內,通過尋找目標函數的一個近似函數(二次的)的最優點,來求解得到真正的位移。在得到了位移之後,再計算目標函數值,如果其使目標函數值的下降滿足了一定條件,那麼就說明這個位移是可靠的,則繼續按此規則迭代計算下去;如果其不能使目標函數值的下降滿足一定的條件,則應減小信賴域的範圍,再重新求解。

事實上,你從所有可以找到的資料裏看到的LM算法的說明,都可以找到類似於“如果目標函數值增大,則調整某係數再繼續求解;如果目標函數值減小,則調整某係數再繼續求解”的迭代過程,這種過程與上面所說的信賴域法是非常相似的,所以說LM算法是一種信賴域法。

 

LM算法需要對每一個待估參數求偏導,所以,如果你的目標函數f非常複雜,或者待估參數相當地多,那麼可能不適合使用LM算法,而可以選擇Powell算法——Powell算法不需要求導。

 

至於這個求導過程是如何實現的,我還不能給出建議,我使用過的方法是拿到函數的方程,然後手工計算出其偏導數方程,進而在函數中直接使用,這樣做是最直接,求導誤差也最小的方式。不過,在你不知道函數的形式之前,你當然就不能這樣做了——例如,你提供給了用戶在界面上輸入數學函數式的機會,然後在程序中解析其輸入的函數,再做後面的處理。在這種情況下,我猜是需要使用數值求導算法的,但我沒有親自試驗過這樣做的效率,因爲一些優秀的求導算法——例如Ridders算法——在一次求導數值過程中,需要計算的函數值次數也會達到5次以上。這樣的話,它當然要比手工求出導函數(只需計算一次,就可以得到導數值)效率要差得多了。不過,我個人估計(沒有任何依據的,只是猜的):依賴於LM算法的高效,就算添加了一個數值求導的“拖油瓶”,整個最優化過程下來,它仍然會優於Powell等方法。

文章來源:http://www.codelast.com/

這篇解釋信賴域算法的文章中,我們已經知道了LM算法的數學模型:

可以證明,此模型可以通過解方程組
(Gk+μI)s=gk確定sk表徵。
即:LM算法要確定一個
μ0,使得Gk+μI正定,並解線性方程組(Gk+μI)sk=gk求出sk
文章來源: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.25rk0.75,令μk+1=μk
  • rk0,說明函數值是向着上升而非下降的趨勢變化了(與最優化的目標相反),這說明這一步走錯了,而且錯得“離譜”,此時,不應該走到下一點,而應“原地踏步”,即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,以我目前的知識儲備,尚不能解釋好,請大家另尋資料吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章