數值優化方法筆記
本文對常見的數值優化方法進行總結,重點關注優化方法的原理、迭代過程和計算複雜度。常見的數值優化方法包括梯度下降法(最速梯度下降法)、牛頓法、共軛梯度下降法等。本筆記的算法思路只是便於對各種優化方法進行理解,並不是完整的邏輯推導,如果想了解其中的數學推導,建議還是查看相關教材。(文章裏公式渲染有點慢,需要等一會)
本文相關代碼在https://github.com/flztiii/numerical_optimization_test.git
梯度下降算法
算法思路
考慮到以下問題,找到一個x∗使f(x∗)<f(x),∀x∈Rn。梯度下降算法的思路很簡單:每一次迭代的點要比上一次次迭代點的值更小。用公式表達就是
$f(x_{k+1})$ < $f(x_{k}) \quad (1)$
接下來就是如何根據這個思路得到從xk到xk+1的增量Δx。可以對f(x)進行一階泰勒展開,表達式如下所示
$f(x+\Delta x) = f(x) + f^{'}(x) \cdot \Delta x \quad (2)$
再根據公式(2),可以得到
$f(x+\Delta x) - f(x) = f^{'}(x) \cdot \Delta x$ < $0 \quad (3)$
那麼,只要滿足公式(4)的條件,就可以得到f(x+Δx) < f(x)。爲了使公式(4)成立,可以令(總所周知,平方大於0)
$\Delta x = -\alpha \cdot f^{'}(x),\alpha$ > $0 \quad (4)$
所以,可以得到從xk到xk+1的迭代過程滿足
$x_{k+1} = x_k + \Delta x = x_k - \alpha \cdot f^{'}(x_k) \quad (5)$
時,始終存在f(xk+1)<f(xk)。也就是一開始談到的思路,只要不斷尋找值更小的點,就可以最終找到最小值。
算法過程
- 給出初始點x0,學習率α
- 計算x0處的梯度f′(x0)
- 判斷∣f′(x0)∣是否小於閾值δ,如果小於,停止迭代,算法結束
- 得到下一個迭代點x1=x0−α⋅f′(x0)
- 重複2-4過程
算法總結
梯度下降算法是最爲基礎的優化方法之一,它只需要知道梯度方法,不需要計算海森矩陣。計算複雜度較低。但是此方法容易陷入局部極小值,收斂結果對初始點和學習率的要求較高。
最速梯度下降
算法思路
最速梯度下降算法與梯度下降算法思路相似,都是希望每一次迭代的點要比上一次次迭代點的值更小。但是最速梯度下降算法與梯度下降算法的不同之處在於,它對學習率進行了調整,使學習率並不是一個固定值,而是不斷變化的。
最速梯度下降算法希望在xk處沿梯度方法f(xk)下降時,找到一個學習率αk,使得沿f(xk)下降量比選擇其他α都要大。用公式表達就是
$\alpha_k = argmin_{\alpha} f(x_k - \alpha \cdot f^{'}(x_k)) \quad (6)$
以上就是最速梯度下降算法的核心。接下來,使用二次型爲例子,繼續進行說明。(因爲二次型具有比較好的性質)我們假設
$f(x) = \frac{1}{2} x^T A x - b^T x \quad (7)$
則可以計算得到f(x)的梯度和海森矩陣分別爲
$f^{'}(x) = Ax - b \quad (8)$
$f^{''}(x) = A \quad (9)$
同時我們可以令
$g(\alpha) = f(x_{k+1})= f(x_k - \alpha f^{'}(x_k)) \quad (10)$
則公式(6)的必要條件爲dαdg(α)=0。因此,我們通過公式(10)中可以得到
$ g^{'}(\alpha) = -f^{'}(x_{k+1})^T f^{'}(x_k)=0 \quad (11)$
將公式(8)代入公式(11)可以得到
$ f^{'}(x_{k+1})^T f^{'}(x_k) = (Ax_{k+1} - b)^T f^{'}(x_k) $
$ f^{'}(x_{k+1})^T f^{'}(x_k) = (A(x_k - \alpha f^{'}(x_k)) - b)^T f^{'}(x_k) $
$ f^{'}(x_{k+1})^T f^{'}(x_k) = (A x_k - b)^T f^{'}(x_k) - \alpha f^{'}(x_k)^T A f^{'}(x_k)$
$ f^{'}(x_{k+1})^T f^{'}(x_k) = f^{'}(x_k)^T f^{'}(x_k) - \alpha f^{'}(x_k)^T A f^{'}(x_k) = 0$
$ \alpha = \frac{f^{'}(x_k)^T f^{'}(x_k)}{ f^{'}(x_k)^T A f^{'}(x_k)} \quad (12) $
所以當待優化函數爲二次型時,每一次的學習率的計算公式爲公式(12)。梯度下降方法就變成最速梯度下降算法。
算法過程
- 給出初始點x0
- 計算x0處的梯度f′(x0)
- 判斷∣f′(x0)∣是否小於閾值δ,如果小於,停止迭代,算法結束
- 計算當前梯度f^{’}(x_0)下的學習率,計算公式爲α0=argminαf(x0−α⋅f′(x0))(如果f(x)爲二次型,則計算公式爲α0=f′(x0)TAf′(x0)f′(x0)Tf′(x0))(也可以使用Armijo-Goldstein準則或Wolfe-Powell準則)
- 得到下一個迭代點x1=x0−α0⋅f′(x0)
- 重複2-5過程
算法總結
最速梯度下降算法是在梯度下降算法基礎上的改進,通過修改學習率,可以提高算法的收斂速度。但是仍然無法避免梯度下降容易被困於局部極小值的問題。
牛頓法
算法思路
牛頓法的思想與梯度下降不同,它並不是尋找比當前點具有更小值的點,而是從極小值的必要條件出發。我們知道,極小值的必要條件爲梯度爲0,也就是
$ f^{'}(x) = 0 \quad (13) $
從這一點出發,我們可以對f(x)進行二階泰勒展開,如下所示
$ f(x + \Delta x) = f(x) + f^{'}(x) \Delta x + \Delta x^T f^{''}(x) \Delta x \quad (14)$
如果滿足公式(13),則可以得到f(x+Δx)=f(x)。將其代入公式(14)可以得到
$ f^{'}(x) \Delta x + \Delta x^T f^{''}(x) \Delta x = 0$
$ \Delta x = -\frac{f^{'}(x)}{f^{''}(x)} \quad (15)$
這樣可以得到每一次迭代的更新量。隨着迭代的不斷進行,最終可以找到待優化函數的極小值。
算法過程
- 給出初始點x0
- 計算x0處的梯度f′(x0)和海森矩陣f′′(x0)
- 判斷∣f′(x0)∣是否小於閾值δ,如果小於,停止迭代,算法結束
- 得到下一個迭代點x1=x0−f′′(x0)f′(x0)
- 重複2-4過程
算法總結
相比於梯度下降方法,牛頓法收斂速度更快。但是,它需要計算海森矩陣,計算複雜度較高。如果待優化函數爲最小二乘,則可以利用高斯-牛頓法,避免計算海森矩陣。
共軛梯度下降算法
算法思路
共軛梯度下降算法也是一種梯度下降。但與普通梯度下降、最速梯度下降不同之處在於,它下降的方向並不是梯度方向。其思路涉及到線性代數相關知識,比普通梯度下降要更加複雜。爲了簡化後續的說明,我們還是以二次型作爲例子進行講解,即
$f(x) = \frac{1}{2} x^T A x - b^T x \quad (16)$
在講解之前,需要先說明一下什麼是共軛。設A爲n階實對稱正定矩陣,如果有兩個n維向量d1和d2滿足
$d_1^T A d_2 = 0$
則稱向量d1和d2對於矩陣A共軛。若一組非零向量d0,d1,...,dn−1滿足
$d_i^T A d_j = 0, i \neq j$
則稱向量系di,(i=0,1,...,n−1)爲關於矩陣A共軛。瞭解了共軛向量的概念後,可以很容易知道一組共軛向量di,(i=0,1,...,n−1)是線性無關的,證明如下。我們構造一組參數ai,(i=0,1,...,n−1),計算以下表達式成立時的ai。只要ai全部爲0,則di,(i=0,1,...,n−1)是線性無關的。
$a_0 d_0 + a_1 d_1 + ... + a_{n-1} d_{n - 1} = 0$
我們讓等式兩邊左側同時乘上diTA,∀i,根據共軛的條件可以得到
$a_i d_i^T A d_i = 0, \forall i$
由於A爲正定矩陣,diTAdi>0必然成立,因此,要讓等式成立,必須ai=0,∀i。則可以證明di,(i=0,1,...,n−1)是線性無關的。
再回到待優化函數f(x)上。其中,x是n維向量,且公式(16)中的矩陣A爲正定矩陣。我們可以假設,待優化函數f(x)取得最小值時的x爲x∗,並且存在一組di,(i=0,1,...,n−1)關於矩陣A共軛。由之前的描述可以得到di是線性無關的。則可以使用di對x∗進行表達,表達式爲
$x^* - x_0= \alpha_0 d_0 + \alpha_1 d_1 + ... + \alpha_{n-1} d_{n-1} \quad (17)$
那麼,可以這樣來看,從初始點x0開始,不斷在上一個點基礎上增加αidi,經過n次迭代,就可以得到最終解x∗,用公式表達就是
$x_{k+1} = x_k + \alpha_k d_k \quad (18)$
可以看到,與梯度下降的迭代公式一致。其中αk就是第k次迭代的學習率,而dk是下降方向。那麼,下一步就是找到一組關於矩陣A共軛的方向向量dk。經過推導可以認爲
$d_{k+1} = -g_{k+1} + \beta_k d_k \quad (19)$
$g_{k+1} = f^{'}(x_{k+1})$
接下來只要計算出βk即可。在公式(19)左側同時乘上dkTA可以得到
$d_k^T A d_{k+1} = -d_k^T A g_{k+1} +\beta_k d_k^T A d_k=0 $
$\beta_k = \frac{-d_k^T A g_{k+1}}{d_k^T A d_k} \quad (20)$
下降方向已經得到了,迭代過程中唯一未知的量還有學習率αk。學習率的計算方法與公式(12)相同,最後計算得到的學習率爲
$\alpha_k = -\frac{g_k^T d_k}{d_k^T A d_k}$
當然,以上公式只有在f(x)是二次型的時候才成立,路過不是二次型,需要藉助其他方法進行求解。
算法過程
如果f(x)是二次型
- 設定k:=0,選擇優化初始點x0
- 計算x0處的梯度g0=f′(x0),判斷g0是否爲0,如果是,結束迭代;反之,令d0=−g0
- 計算學習率αk=−dkTAdkgkTdk
- 得到新的點xk+1=xk+αkdk
- 計算梯度gk+1=f′(xk+1),判斷gk+1是否爲0,如果是,結束迭代
- 計算新的下降方向參數βk=dkTAdkgk+1TAdk
- 計算新的梯度下降方向dk+1=−gk+1+βkdk
- 重複3-7過程
如果f(x)不是二次型
- 設定k:=0,選擇優化初始點x0
- 計算x0處的梯度g0=f′(x0),判斷g0是否爲0,如果是,結束迭代;反之,令d0=−g0
- 計算學習率αk=argminαf(xk+α⋅dk)(可以使用Armijo-Goldstein準則或Wolfe-Powell準則)
- 得到新的點xk+1=xk+αkdk
- 計算梯度gk+1=f′(xk+1),判斷gk+1是否爲0,如果是,結束迭代
- (a) 計算新的下降方向參數βk=gkTgkgk+1Tgk+1(Fletcher-Reeves Formula) (b) 計算新的下降方向參數βk=gkTgkgk+1T(gk+1−gk)(Polak-Ribiere Formula) © 計算新的下降方向參數βk=dkT(gk+1−gk)gk+1T(gk+1−gk)(Hestenes-Stiefel Formula)
- 計算新的梯度下降方向dk+1=−gk+1+βkdk
- 重複3-7過程
算法總結
共軛梯度下降算法對傳統梯度下降算法的下降方向進行了優化,其收斂速度介於梯度下降算法和牛頓法之間。並且只需要計算梯度方向,計算複雜度較低。