數值優化方法筆記

數值優化方法筆記

本文對常見的數值優化方法進行總結,重點關注優化方法的原理、迭代過程和計算複雜度。常見的數值優化方法包括梯度下降法(最速梯度下降法)、牛頓法、共軛梯度下降法等。本筆記的算法思路只是便於對各種優化方法進行理解,並不是完整的邏輯推導,如果想了解其中的數學推導,建議還是查看相關教材。(文章裏公式渲染有點慢,需要等一會)

本文相關代碼在https://github.com/flztiii/numerical_optimization_test.git

梯度下降算法

算法思路

考慮到以下問題,找到一個xx^*使f(x)<f(x),xRnf(x^*) < f(x), \forall x \in R^n。梯度下降算法的思路很簡單:每一次迭代的點要比上一次次迭代點的值更小。用公式表達就是

$f(x_{k+1})$ < $f(x_{k}) \quad (1)$

接下來就是如何根據這個思路得到從xkx_kxk+1x_{k+1}的增量Δx\Delta x。可以對f(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+\Delta x) < f(x)f(x)。爲了使公式(4)成立,可以令(總所周知,平方大於0)

$\Delta x = -\alpha \cdot f^{'}(x),\alpha$ > $0 \quad (4)$

所以,可以得到從xkx_kxk+1x_{k+1}的迭代過程滿足

$x_{k+1} = x_k + \Delta x = x_k - \alpha \cdot f^{'}(x_k) \quad (5)$

時,始終存在f(xk+1)<f(xk)f(x_{k+1}) < f(x_k)。也就是一開始談到的思路,只要不斷尋找值更小的點,就可以最終找到最小值。

算法過程

  1. 給出初始點x0x_0,學習率α\alpha
  2. 計算x0x_0處的梯度f(x0)f^{'}(x_0)
  3. 判斷f(x0)|f^{'}(x_0)|是否小於閾值δ\delta,如果小於,停止迭代,算法結束
  4. 得到下一個迭代點x1=x0αf(x0)x_1 = x_0 - \alpha \cdot f^{'}(x_0)
  5. 重複2-4過程

算法總結

梯度下降算法是最爲基礎的優化方法之一,它只需要知道梯度方法,不需要計算海森矩陣。計算複雜度較低。但是此方法容易陷入局部極小值,收斂結果對初始點和學習率的要求較高。

最速梯度下降

算法思路

最速梯度下降算法與梯度下降算法思路相似,都是希望每一次迭代的點要比上一次次迭代點的值更小。但是最速梯度下降算法與梯度下降算法的不同之處在於,它對學習率進行了調整,使學習率並不是一個固定值,而是不斷變化的。

最速梯度下降算法希望在xkx_k處沿梯度方法f(xk)f(x_k)下降時,找到一個學習率αk\alpha_k,使得沿f(xk)f(x_k)下降量比選擇其他α\alpha都要大。用公式表達就是

$\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)的必要條件爲dg(α)dα=0\frac{d g(\alpha)}{d \alpha} = 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)。梯度下降方法就變成最速梯度下降算法。

算法過程

  1. 給出初始點x0x_0
  2. 計算x0x_0處的梯度f(x0)f^{'}(x_0)
  3. 判斷f(x0)|f^{'}(x_0)|是否小於閾值δ\delta,如果小於,停止迭代,算法結束
  4. 計算當前梯度f^{’}(x_0)下的學習率,計算公式爲α0=argminαf(x0αf(x0))\alpha_0 = argmin_{\alpha} f(x_0 - \alpha \cdot f^{'}(x_0))(如果f(x)f(x)爲二次型,則計算公式爲α0=f(x0)Tf(x0)f(x0)TAf(x0)\alpha_0 = \frac{f^{'}(x_0)^T f^{'}(x_0)}{ f^{'}(x_0)^T A f^{'}(x_0)})(也可以使用Armijo-Goldstein準則或Wolfe-Powell準則)
  5. 得到下一個迭代點x1=x0α0f(x0)x_1 = x_0 - \alpha_0 \cdot f^{'}(x_0)
  6. 重複2-5過程

算法總結

最速梯度下降算法是在梯度下降算法基礎上的改進,通過修改學習率,可以提高算法的收斂速度。但是仍然無法避免梯度下降容易被困於局部極小值的問題。

牛頓法

算法思路

牛頓法的思想與梯度下降不同,它並不是尋找比當前點具有更小值的點,而是從極小值的必要條件出發。我們知道,極小值的必要條件爲梯度爲0,也就是

$ f^{'}(x) = 0 \quad (13) $

從這一點出發,我們可以對f(x)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)f(x + \Delta 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)$

這樣可以得到每一次迭代的更新量。隨着迭代的不斷進行,最終可以找到待優化函數的極小值。

算法過程

  1. 給出初始點x0x_0
  2. 計算x0x_0處的梯度f(x0)f^{'}(x_0)和海森矩陣f(x0)f^{''}(x_0)
  3. 判斷f(x0)|f^{'}(x_0)|是否小於閾值δ\delta,如果小於,停止迭代,算法結束
  4. 得到下一個迭代點x1=x0f(x0)f(x0)x_1 = x_0 - \frac{f^{'}(x_0)}{f^{''}(x_0)}
  5. 重複2-4過程

算法總結

相比於梯度下降方法,牛頓法收斂速度更快。但是,它需要計算海森矩陣,計算複雜度較高。如果待優化函數爲最小二乘,則可以利用高斯-牛頓法,避免計算海森矩陣。

共軛梯度下降算法

算法思路

共軛梯度下降算法也是一種梯度下降。但與普通梯度下降、最速梯度下降不同之處在於,它下降的方向並不是梯度方向。其思路涉及到線性代數相關知識,比普通梯度下降要更加複雜。爲了簡化後續的說明,我們還是以二次型作爲例子進行講解,即

$f(x) = \frac{1}{2} x^T A x - b^T x \quad (16)$

在講解之前,需要先說明一下什麼是共軛。設AAnn階實對稱正定矩陣,如果有兩個nn維向量d1d_1d2d_2滿足

$d_1^T A d_2 = 0$

則稱向量d1d_1d2d_2對於矩陣AA共軛。若一組非零向量d0,d1,...,dn1d_0, d_1, ..., d_{n-1}滿足

$d_i^T A d_j = 0, i \neq j$

則稱向量系di,(i=0,1,...,n1)d_i, (i=0, 1, ..., n-1)爲關於矩陣AA共軛。瞭解了共軛向量的概念後,可以很容易知道一組共軛向量di,(i=0,1,...,n1)d_i, (i=0, 1, ..., n-1)是線性無關的,證明如下。我們構造一組參數ai,(i=0,1,...,n1)a_i, (i=0, 1, ..., n-1),計算以下表達式成立時的aia_i。只要aia_i全部爲0,則di,(i=0,1,...,n1)d_i, (i=0, 1, ..., n-1)是線性無關的。

$a_0 d_0 + a_1 d_1 + ... + a_{n-1} d_{n - 1} = 0$

我們讓等式兩邊左側同時乘上diTA,id_i^T A, \forall i,根據共軛的條件可以得到

$a_i d_i^T A d_i = 0, \forall i$

由於AA爲正定矩陣,diTAdi>0d_i^T A d_i > 0必然成立,因此,要讓等式成立,必須ai=0,ia_i = 0, \forall i。則可以證明di,(i=0,1,...,n1)d_i, (i=0, 1, ..., n-1)是線性無關的。

再回到待優化函數f(x)f(x)上。其中,xxnn維向量,且公式(16)中的矩陣AA爲正定矩陣。我們可以假設,待優化函數f(x)f(x)取得最小值時的xxxx^*,並且存在一組di,(i=0,1,...,n1)d_i, (i=0, 1, ..., n-1)關於矩陣AA共軛。由之前的描述可以得到did_i是線性無關的。則可以使用did_ixx^*進行表達,表達式爲

$x^* - x_0= \alpha_0 d_0 + \alpha_1 d_1 + ... + \alpha_{n-1} d_{n-1} \quad (17)$

那麼,可以這樣來看,從初始點x0x_0開始,不斷在上一個點基礎上增加αidi\alpha_i d_i,經過nn次迭代,就可以得到最終解xx^*,用公式表達就是

$x_{k+1} = x_k + \alpha_k d_k \quad (18)$

可以看到,與梯度下降的迭代公式一致。其中αk\alpha_k就是第kk次迭代的學習率,而dkd_k是下降方向。那麼,下一步就是找到一組關於矩陣AA共軛的方向向量dkd_k。經過推導可以認爲

$d_{k+1} = -g_{k+1} + \beta_k d_k \quad (19)$
$g_{k+1} = f^{'}(x_{k+1})$

接下來只要計算出βk\beta_k即可。在公式(19)左側同時乘上dkTAd_k^T A可以得到

$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\alpha_k。學習率的計算方法與公式(12)相同,最後計算得到的學習率爲

$\alpha_k = -\frac{g_k^T d_k}{d_k^T A d_k}$

當然,以上公式只有在f(x)f(x)是二次型的時候才成立,路過不是二次型,需要藉助其他方法進行求解。

算法過程

如果f(x)f(x)是二次型

  1. 設定k:=0k:=0,選擇優化初始點x0x_0
  2. 計算x0x_0處的梯度g0=f(x0)g_0=f^{'}(x_0),判斷g0g_0是否爲0,如果是,結束迭代;反之,令d0=g0d_0 = -g_0
  3. 計算學習率αk=gkTdkdkTAdk\alpha_k = -\frac{g_k^T d_k}{d_k^T A d_k}
  4. 得到新的點xk+1=xk+αkdkx_{k+1} = x_k + \alpha_k d_k
  5. 計算梯度gk+1=f(xk+1)g_{k+1} = f^{'}(x_{k+1}),判斷gk+1g_{k+1}是否爲0,如果是,結束迭代
  6. 計算新的下降方向參數βk=gk+1TAdkdkTAdk\beta_{k} = \frac{g_{k+1}^T A d_k}{d_k^T A d_k}
  7. 計算新的梯度下降方向dk+1=gk+1+βkdkd_{k+1} = -g_{k+1} + \beta_{k} d_k
  8. 重複3-7過程

如果f(x)f(x)不是二次型

  1. 設定k:=0k:=0,選擇優化初始點x0x_0
  2. 計算x0x_0處的梯度g0=f(x0)g_0=f^{'}(x_0),判斷g0g_0是否爲0,如果是,結束迭代;反之,令d0=g0d_0 = -g_0
  3. 計算學習率αk=argminαf(xk+αdk)\alpha_k = argmin_{\alpha} f(x_k + \alpha \cdot d_k)(可以使用Armijo-Goldstein準則或Wolfe-Powell準則)
  4. 得到新的點xk+1=xk+αkdkx_{k+1} = x_k + \alpha_k d_k
  5. 計算梯度gk+1=f(xk+1)g_{k+1} = f^{'}(x_{k+1}),判斷gk+1g_{k+1}是否爲0,如果是,結束迭代
  6. (a) 計算新的下降方向參數βk=gk+1Tgk+1gkTgk\beta_{k} = \frac{g_{k+1}^T g_{k+1}}{g_k^T g_k}(Fletcher-Reeves Formula) (b) 計算新的下降方向參數βk=gk+1T(gk+1gk)gkTgk\beta_{k} = \frac{g_{k+1}^T (g_{k+1} - g_k)}{g_k^T g_k}(Polak-Ribiere Formula) © 計算新的下降方向參數βk=gk+1T(gk+1gk)dkT(gk+1gk)\beta_{k} = \frac{g_{k+1}^T (g_{k+1} - g_k)}{d_k^T (g_{k+1} - g_k)}(Hestenes-Stiefel Formula)
  7. 計算新的梯度下降方向dk+1=gk+1+βkdkd_{k+1} = -g_{k+1} + \beta_{k} d_k
  8. 重複3-7過程

算法總結

共軛梯度下降算法對傳統梯度下降算法的下降方向進行了優化,其收斂速度介於梯度下降算法和牛頓法之間。並且只需要計算梯度方向,計算複雜度較低。

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