歡迎查看我的博客文章合集:我的Blog文章索引::機器學習方法系列,深度學習方法系列,三十分鐘理解系列等
擬牛頓法
擬牛頓法可以克服牛頓法計算量大的缺點,不在計算目標函數的 Hesse 矩陣,而是構造一個近似 Hesse 矩陣的對稱正定矩陣,根據近似矩陣來優化目標函數,不同的近似構造 Hesse 的方法決定了不同的擬牛頓法,構造 Hesse 矩陣是需要滿足擬牛頓條件的,擬牛頓條件是這樣求得的,首先將 f(x) 在 x k + 1 x_{k+1} x k + 1 處做二階泰勒展開(忽略高階項):
f ( x ) = f ( x k + 1 ) + ∇ f ( x k + 1 ) ( x − x k + 1 ) + 1 2 ( x – x k + 1 ) T ∇ 2 f ( x k + 1 ) ( x − x k + 1 ) f(x) = f(x_{k+1}) + \nabla f(x_{k+1}) (x-x_{k+1})+ \frac{1}{2} (x –x_{k+1})^T\nabla^2 f(x_{k+1} )(x-x_{k+1}) f ( x ) = f ( x k + 1 ) + ∇ f ( x k + 1 ) ( x − x k + 1 ) + 2 1 ( x – x k + 1 ) T ∇ 2 f ( x k + 1 ) ( x − x k + 1 )
注意在這個式子中,x x x 是變量,而x k + 1 x_{k+1} x k + 1 是一個值,對x x x 求導得到:
∇ f ( x ) = 0 + ∇ f ( x k + 1 ) + H k + 1 ( x − x k + 1 ) \nabla f(x) = 0 + \nabla f(x_{k+1}) + H_{k+1}(x -x_{k+1}) ∇ f ( x ) = 0 + ∇ f ( x k + 1 ) + H k + 1 ( x − x k + 1 ) 整理得到:
g = g k + 1 + H k + 1 ( x − x k + 1 ) g = g_{k+1}+ H_{k+1}(x -x_{k+1}) g = g k + 1 + H k + 1 ( x − x k + 1 )
令 x = x k x=x_k x = x k ,整理可得
g k + 1 – g k = H k + 1 ( x k + 1 – x k ) g_{k+1} – g_k = H_{k+1} (x_{k+1} – x_k) g k + 1 – g k = H k + 1 ( x k + 1 – x k )
這個便是擬牛頓條件了,迭代過程中對 H k + 1 H_{k+1} H k + 1 做出約束,根據約束構造一個近似矩陣 B k + 1 B_{k+1} B k + 1 ,來模擬 Hesse 矩陣就可以了,爲了簡便起見,引入記號 s k s_k s k 與 y k y_k y k ,令s k = x k + 1 – x k , y k = g k + 1 – g k s_k = x_{k+1} –x_k , y_k = g_{k+1} –g _k s k = x k + 1 – x k , y k = g k + 1 – g k
y k = B k + 1 ⋅ s k y_k = B_{k+1} \cdot s_k y k = B k + 1 ⋅ s k
因爲牛頓法中的迭代方向爲− H − 1 ⋅ g -H^{-1} \cdot g − H − 1 ⋅ g ,所以令 D k + 1 = H k + 1 − 1 D_{k+1} = H_{k+1}^{-1} D k + 1 = H k + 1 − 1 ,擬牛頓條件還可以寫作:
s k = D k + 1 ⋅ y k s_k = D_{k+1} \cdot y_k s k = D k + 1 ⋅ y k
擬牛頓法本身是一類算法,下面介紹一下BFGS,算是比較著名的方法了:
BFGS算法(Broyden–Fletcher–Goldfarb–Shanno)[3]
BFGS 是一種擬牛頓方法,通過迭代構建近似 Hesse 矩陣,省去了求解 Hesse 的複雜的步驟,而且 BFGS 構造出來的近似 Hesse 矩陣一定是正定的,這完全克服了牛頓法的缺陷,雖然搜索方向不一定最優,但始終朝着最優的方向前進的。首先初始化 Hesse 矩陣 B 0 = I B_0=I B 0 = I ,接下來每次迭代對矩陣 B k B_k B k 進行更新即可:
B k + 1 = B k + Δ B k , k = 1 , 2 , … B_{k+1} = B_k+ \Delta B_k , \ k = 1,2,… B k + 1 = B k + Δ B k , k = 1 , 2 , …
迭代構建近似矩陣的關鍵是矩陣 ΔBk 的構造了,將其寫作:
Δ B k = α u u T + β v v T \Delta B_k = \alpha uu^T + \beta vv^T Δ B k = α u u T + β v v T
這裏的向量 u 和 v 是待定的,知道了這兩個向量,就可以構造構造 ΔBk 了,且這樣構造出的矩陣是對稱的,根據擬牛頓條件:
y k = B k + 1 s k = ( B k + Δ B k ) s k = ( B k + α u u T + β v v T ) s k = B k s k + ( α u T s k ) ⋅ u + ( β v T s k ) ⋅ v \begin{aligned} y_k &= B_{k+1} s_k \\ &= (B_k + \Delta B_k)s_k \\ &= (B_k + \alpha uu^T + \beta vv^T)s_k \\ &= B_k s_k + (\alpha u^Ts_k) \cdot u+ (\beta v^Ts_k) \cdot v \end{aligned} y k = B k + 1 s k = ( B k + Δ B k ) s k = ( B k + α u u T + β v v T ) s k = B k s k + ( α u T s k ) ⋅ u + ( β v T s k ) ⋅ v
這裏 α u T s k αu^Ts_k α u T s k 與β v T s k βv^Tsk β v T s k 均爲實數,代表了 在 u 與 v 方向的拉伸程度,爲了計算簡單,做如下賦值運算:
α u T s k = 1 , β v T s k = – 1 \alpha u^Ts_k = 1 , \ \beta v^Ts_k = –1 α u T s k = 1 , β v T s k = – 1
代入上式便可得:
u − v = y k – B k s k u - v = y_k – B_ks_k u − v = y k – B k s k
這就得到得到了 u 與 v 的一個近似:
u = y k , v = B k s k u = y_k , \ v = B_k s_k u = y k , v = B k s k
繼而求 α 與 β 的值
α = 1 y T s k , β = − 1 ( B k s k ) T s k = − 1 s k T B k s k \alpha = \frac{1}{y^Ts_k}, \beta= -\frac{1}{(B_ks_k)^Ts_k} = -\frac{1}{s_k^TB_ks_k} α = y T s k 1 , β = − ( B k s k ) T s k 1 = − s k T B k s k 1
α 、 β 、 u 與 v都求得後,便得到了 ΔBk 的更新公式:
Δ B k = y k y k T y k T s k – B k s k s k T B k s k T B k s k \Delta B_k = \frac{y_ky_k^T}{y_k^Ts_k} – \frac{B_ks_ks_k^TB_k}{s_k^TB_ks_k} Δ B k = y k T s k y k y k T – s k T B k s k B k s k s k T B k
因此B k B_k B k 的迭代公式是:
B k + 1 = B k + y k y k T y k T s k – B k s k s k T B k s k T B k s k B_{k+1} = B_k +\frac{y_ky_k^T}{y_k^Ts_k} – \frac{B_ks_ks_k^TB_k}{s_k^TB_ks_k} B k + 1 = B k + y k T s k y k y k T – s k T B k s k B k s k s k T B k
由與牛頓法的方向是 – H k − 1 g k –H^{−1}_kg_k – H k − 1 g k 的,所以最好可以直接計算出 B k − 1 B^{−1}_k B k − 1 ,這樣就不用再進行求逆運算了,直接根據Sherman-Morrison 公式:可得關於矩陣B 的逆的更新方式:
B k + 1 − 1 = B k − 1 + ( 1 s k T y k + y k T B k − 1 y k ( s k T y k ) 2 ) s k s k T − 1 s k T y k ( B k − 1 y k s k T + s k y k T B k − 1 ) B^{-1}_{k+1} = B^{-1}_k + \left (\frac{1}{s_k^Ty_k}+\frac{y_k^TB_k^{-1}y_k}{(s_k^Ty_k)^2} \right )s_ks_k^T - \frac{1}{s_k^Ty_k} \left (B_k^{-1}y_ks_k^T + s_ky_k^TB^{-1}_k \right) B k + 1 − 1 = B k − 1 + ( s k T y k 1 + ( s k T y k ) 2 y k T B k − 1 y k ) s k s k T − s k T y k 1 ( B k − 1 y k s k T + s k y k T B k − 1 )
B k − 1 B^{−1}_k B k − 1 這裏用 D k D_k D k 來表示,給出最終的 BFGS 算法[3]:
停止條件爲人爲設定,可設定爲兩次迭代目標函數差的閾值或者梯度差的閾值,或者梯度本身(的模)小於閾值。
其中,步驟2.2搜索步長的方法採用[7]:
比較好理解,就是在搜索方向p上,找到步長α \alpha α 滿足Armijo條件,初始步長α 0 = 1 \alpha_0=1 α 0 = 1 是一種常用的設定。
DFP算法
DFP算法也是類似的思想,可以參考[4],寫的很詳細,我這裏簡單貼一個圖以備查閱:
稍微看下步3,選用的方法就是上面介紹過的Backtracking line search算法,只是選用的符號不一樣而已,內容是一樣的。非負整數m就是代表了迭代次數。
L-BFGS [3]
工業中實用的擬牛頓法的便是 L-BFGS (Limited-memory BFGS)了,對於近似 Hesse 矩陣 D k D_k D k :
D k + 1 = D k + ( 1 s k T y k + y k T D k y k ( s k T y k ) 2 ) s k s k T − 1 s k T y k ( D k y k s k T + s k y k T D k ) D_{k+1} = D_k + \left (\frac{1}{s_k^Ty_k}+\frac{y_k^T D_ky_k}{(s_k^Ty_k)^2} \right )s_ks_k^T - \frac{1}{s_k^Ty_k}(D_ky_ks_k^T + s_ky_k^T D_k ) D k + 1 = D k + ( s k T y k 1 + ( s k T y k ) 2 y k T D k y k ) s k s k T − s k T y k 1 ( D k y k s k T + s k y k T D k )
而是存儲向量序 s k s_k s k ,y k y_k y k ,而且向量序列也不是都存,而是存最近的 m 次的, m 爲人工指定,計算 D k D_k D k 時,只用最新的 m 個向量模擬計算即可。在第 k 次迭代,算法求得了 x k x_k x k ,並且保存的曲率信息爲 ( s i , y i ) k − 1 k − m (si,yi)_{k−1}^{k−m} ( s i , y i ) k − 1 k − m 。爲了得到 H k H_k H k ,算法每次迭代均需選擇一個初始的矩陣 H 0 K H_0^K H 0 K ,這是不同於 BFGS 算法的一個地方,接下來只用最近的 m 個向量對該初始矩陣進行修正,實踐中 H 0 K H_0^K H 0 K 的設定通常如下:
H k 0 = r k I r k = s k − 1 T y k − 1 y k − 1 T y k − 1 \begin{aligned} H_k^0 &=r_kI \\ r_k &=\frac{s{k-1}^Ty_{k-1}}{y_{k-1}^Ty_{k-1}} \end{aligned} H k 0 r k = r k I = y k − 1 T y k − 1 s k − 1 T y k − 1
其中 r k r_k r k 表示比例係數,它利用最近一次的曲率信息來估計真實海森矩陣的大小,這就使得當前步的搜索方向較爲理想,而不至於跑得“太偏”,這樣就省去了步長搜索的步驟,節省了時間。在L-BFGS算法中,通過保存最近 m 次的曲率信息來更新近似矩陣的這種方法在實踐中是很有效的,雖然 L-BFGS 算法是線性收斂,但是每次迭代的開銷非常小,因此 L-BFGS 算法執行速度還是很快的,而且由於每一步迭代都能保證近似矩陣的正定,因此算法的魯棒性還是很強的。
總結下 BFGS 與 L-BFGS 的: BFGS算法在運行的時候,每一步迭代都需要保存一個 n×n 的矩陣,現在很多機器學習問題都是高維的,當 n 很大的時候,這個矩陣佔用的內存是非常驚人的,並且所需的計算量也是很大的,這使得傳統的 BFGS 算法變得非常不適用。而 L-BFGS 則是很對這個問題的改進版,從上面所說可知,BFGS 算法是通過曲率信息$ (s_k,y_k)$ 來修正 H k H_k H k 從而得到 H k + 1 H_{k+1} H k + 1 ,L-BFGS 算法的主要思路是:算法僅僅保存最近 m 次迭代的曲率信息來計算H k + 1 H_{k+1} H k + 1 。這樣,我們所需的存儲空間就從 n×n 變成了 2m×n 而通常情況下 m << n。
其他擬牛頓算法[6]
共軛梯度法
共軛梯度法是介於梯度下降法和牛頓法,擬牛頓法之間的算法[6]。
待補充…
參考資料
[1]https://blog.csdn.net/batuwuhanpei/article/details/51979831
[2]https://blog.csdn.net/u011722133/article/details/53518134
[3]無約束優化方法(梯度法-牛頓法-BFGS- L-BFGS)
[4]優化算法——擬牛頓法之DFP算法
[5]牛頓法與擬牛頓法
[6]牛頓法,擬牛頓法, 共軛梯度法
[7]【原創】回溯線搜索 Backtracking line search
[8]【原創】牛頓法和擬牛頓法 – BFGS, L-BFGS, OWL-QN
[9]無約束最優化方法——牛頓法、擬牛頓法、BFGS、LBFGS
[10] 無約束最優化的常用方法
[11]機器學習與運籌優化(三)從牛頓法到L-BFGS
[12]ECE236C - Optimization Methods for Large-Scale Systems (Spring 2019) ,UCLA的優化課程,課件很好。