進入算法研發部,在大致了解部門的項目構成,主要職責之后,我意識到最優化算法在各個項目組中都具有重要的作用,例如CTR預估、排序等。然而,由於自己在讀博期間除了“邏輯回歸”以外,沒有系統參與過涉及最優化的項目,因此在還沒有分配到具體任務的情況下,首先自發地對最優化算法的發展歷程進行了調研。心得體會如下:
最優化領域中的方法雖然“多如牛毛”,但是總體上還是沿着一條“主線”發展的。這里按照時間順序對這條“最優化之路”進行簡要介紹:
1.1 最速下降法(梯度法):
即以負梯度方向作為目標函數極小化方法的下降方向。首先將目標函數進行泰勒展開:
式[1]中的高階無窮小可以忽略,因此,要使[1]式取得最小值,應使取到最小,由此可得,
取
時,目標函數下降得最快,這就是負梯度方向作為“最速下降”方向的由來。
1.2 牛頓法:
最速下降法只用到了目標函數的一階導數信息,而牛頓法則用到了二階導數信息。在點處對目標函數進行泰勒展開,並只取二階導數及其之前的幾項(忽略更高階的導數項),可得:
:目標函數在
這一點的Hessian矩陣(二階導數矩陣)。
由於極小值點必然是駐點,而駐點是一階導數為0的點,所以,對 r(X) 這個函數來說,要取到極小值,應該分析其一階導數。對X求一階導數,並令其等於0:
因此,下一點的計算方法:在方向d上按步長1(1×d = d)移動到點X,方向d的計算方法:
牛頓法的基本步驟:每一步迭代過程中,通過解線性方程組得到搜索方向,然后將自變量移動到下一個點,然后再計算是否符合收斂條件,不符合的話就一直按這個策略(解方程組→得到搜索方向→移動點→檢驗收斂條件)繼續下去。由於牛頓法利用了目標函數的二階導數信息,其收斂速度為二階收斂,因此它比最速下降法要快,但是其對一般問題不是整體收斂的,只有當初始點充分接近極小點時,才有很好的收斂性。
1.3 共軛方向法:
最速下降法和牛頓法對前后兩次迭代的方向並沒有特別的相關要求,而共軛方向法則要求新的搜索方向與前面所有的搜索方向是共軛的。也就是說,這些搜索方向向量是滿足以下共軛條件的:
其中,m≠n,dm和dn分別為兩個向量(搜索方向),G為對稱正定矩陣。共軛方向法只利用了目標函數的一階導數(梯度)信息,不用計算Hessian矩陣,使得其計算量比牛頓法小很多。在每一步迭代的過程中,可以利用“Powell共軛方向集”方法構造兩兩共軛的方向。在共軛方向法中,新搜索方向的確定,需要滿足“下降”條件,即方向與梯度之積<0:
但是,並不是意味着目標函數值下降量越大,這個方向就越可取。在Powell算法的修正策略中,有一種方法通過放棄目標函數值下降最大的方向而更好地避免了各方向的線性相關。共軛方向法的過程可以總結為:選定搜索方向d,使之滿足共軛條件以及下降條件,在此搜索方向上通過精確線性搜索確定移動的步長,然后將當前點移動到下一點,再重新選定搜索方向,周而復始,直到滿足終止條件。 共軛方向法的收斂速度比最速下降法快,比牛頓法慢。
“共軛梯度法”是一種特殊的“共軛方向法”。共軛方向法與梯度的關系是——共軛方向法利用了目標函數的梯度信息(梯度與方向的積滿足“下降”條件)。共軛梯度法與此關系有所區別:用當前點的負梯度方向,與前面的搜索方向進行共軛化,以得到新的搜索方向。在推導共軛梯度法的搜索方向的公式之前,我們先假定目標函數是二次函數:
其中G為n階對稱正定矩陣。X為自變量(n維向量)。
[2]式的函數的梯度(即一階導數)為:
現在,假設初始點為X0。在每一個迭代點處,新的搜索方向都是用前面的搜索方向與當前點的負梯度方向共軛化得到的。在初始點X0處,並沒有“前面的搜索方向”,因此,初始點處的搜索方向d0簡單地定為負梯度方向:
上面的式子中,將目標函數在X0點的梯度g(X0)寫為g0,同理,g(X1)也記為g1,等等。
第二個迭代到的點為X1,它與X0滿足關系:
這表明,點X1是在d0方向上,由X0點移動一定的距離得到的。移動的步長α0,則是通過精確線搜索的方法計算得到的,X1是一個極小值點,在點X1處,目標函數的一階導數為零,即:
所以一階導數再乘以d0仍然為零:
從共軛梯度法的定義——新的搜索方向是用前面的搜索方向與當前點的負梯度方向共軛化得到的——來看,d1與d0(前面的搜索方向)有關,也與-g1(當前點的負梯度方向)有關,因此,假定d1是-g1與d0的線性組合:
其中,r0是一個實數。此外,由於每一個搜索方向與前面的搜索方向都是共軛的,因此,d1與d0還要滿足共軛條件:
計算r0的值:
首先,在同一點處,搜索方向與梯度的點積:
可以看出,在同一點處,搜索方向與梯度的點積等於負梯度與梯度的點積。
其次,在某一點處的梯度與前面所有的梯度的點積:
點X2,X3,……均為極小值點,因此,在這些點處,目標函數的梯度為零,即g(Xk)=0,因此[14],[15]式均為零,得到:
又可以看出,在某一點處的梯度與前面所有梯度的點積為零。
由上面的特例的計算,可以總結出一些規律並用這些規律來得到通用的結論。假設對所有的搜索方向和梯度,有如下規律:
即同一點處的搜索方向與梯度的點積等於該點處的負梯度與梯度的點積,某一點處的梯度與前面所有搜索方向的點積為0,某一點處的梯度與前面所有梯度的點積為0,某一點處的搜索方向與前面所有搜索方向共軛。
設方向d的通用的表達式為:
該式表示的含義是:當前點的搜索方向是當前點的負梯度方向與前面所有方向的線性組合。前文所述的方向d1,也是這樣假設之后再求出來的。[22]式的左邊是一個方向向量,在共軛梯度法中,要保證某一點的搜索方向與前面所有搜索方向是G共軛的,因此,在[22]式兩邊均左乘一個式子,形成“G共軛”的表達式:
例如,當m=4時,[22]式就是用來求d4的,此時:
對n所取的任何值,在[24]式的求和式∑中,除最后一項外,其余所有項的值均為0——這是因為任何一個方向與前面所有方向都是G共軛的(參看G共軛的定義)。所以現在可以寫出[24]式的結果了:
完全可以用rn來代替[25]式中的r的表達式:
[29]式就是r的計算方法。
共軛梯度法同樣會有與共軛方向法類似的問題:經過n步迭代之后,產生的新方向不再有共軛性。所以在實際運用中,也有很多修正方向的策略。其中一種策略是:經過n步迭代之后,取負梯度方向作為新的方向。共軛梯度法比最速下降法的收斂性要好得多。
1.5 擬牛頓(Quasi-Newton)法:
擬牛頓法是一種“模擬”的牛頓法,具體來說模擬的是牛頓法中搜索方向的生成方式。牛頓法中,在每一次要得到新的搜索方向的時候,都需要計算Hessian矩陣(二階導數矩陣)。在自變量維數非常大的時候,這個計算工作是非常耗時的,因此,擬牛頓法的誕生的意義就是:它采用了一定的方法來構造與Hessian矩陣相似的正定矩陣,而這個構造方法計算量比牛頓法小。
1.5.1 DFP算法
假設目標函數可以用二次函數進行近似(實際上很多函數可以用二次函數很好地近似):
忽略高階無窮小部分,只看前面3項,其中A為目標函數的Hessian矩陣。此式等號兩邊對X求導,可得:
於是,當 X=Xi 時,將[2]式兩邊均左乘Ai+1-1,有:
上式左右兩邊近似相等,但如果我們把它換成等號,並且用另一個矩陣H來代替上式中的A-1,則得到:
方程[4]就是擬牛頓方程,其中的矩陣H,就是Hessian矩陣的逆矩陣的一個近似矩陣.在迭代過程中生成的矩陣序列H0,H1,H2,……中,每一個矩陣Hi+1,都是由前一個矩陣Hi修正得到的。DFP算法的修正方法如下,設:
再設:
其中,m和n均為實數,v和w均為N維向量。將[6]代入[5]式,再將[5]式代入[4]式,可得:
得到的m,n,v,w值如下:
將[8]~[11]代入[6]式,然后再將[6]代入[5]式,就得到了Hessian矩陣的逆矩陣的近似陣H的計算方法:
通過上述描述,DFP算法的流程大致如下:
已知初始正定矩陣H0,從一個初始點開始(迭代),用式子 來計算出下一個搜索方向,並在該方向上求出可使目標函數極小化的步長α,然后用這個步長,將當前點挪到下一個點上,並檢測是否達到了程序終止的條件,如果沒有達到,則用上面所說的[13]式的方法計算出下一個修正矩陣H,並計算下一個搜索方向……周而復始,直到達到程序終止條件。
值得注意的是,矩陣H正定是使目標函數值下降的條件,所以,它保持正定性很重要。可以證明,矩陣H保持正定的充分必要條件是:
在迭代過程中,這個條件也是容易滿足的。
1.5.2 BFGS算法
BFGS算法和DFP算法有些相似,但是形式上更加復雜一些。BFGS算法目前仍然被認為是最好的擬牛頓算法。BFGS算法中矩陣H的計算公式如下所示:
在[14]式中的最后一項(藍色部分)就是BFGS比DFP多出來的部分,其中w是一個n×1的向量。
在目標函數為二次型時,無論是DFP還是BFGS——也就是說,無論[14]式中有沒有最后一項——它們均可以使矩陣H在n步之內收斂於A-1。
BFGS算法有一個變種,叫作“Limited-memory BFGS”,簡稱“L-BFGS”。使用L-BFGS算法來編寫程序時,它會比BFGS算法占用的內存小。
另外,還有“面向象限”的OWLQN算法(Orthant-Wise Limited-memory Quai-Newton),這里不再贅述。