目前,深度網絡(Deep Nets)權值訓練的主流方法還是梯度下降法(結合BP算法),當然在此之前可以用無監督的方法(比如說RBM,Autoencoder)來預訓練參數的權值,而梯度下降法應用在深度網絡中的一個缺點是權值的迭代變化值會很小,很容易收斂到的局部最優點;另一個缺點是梯度下降法不能很好的處理有病態的曲率(比如Rosenbrock函數)的誤差函數。而本文中所介紹的Hessian Free方法(以下簡稱HF)可以不用預訓練網絡的權值,效果也還不錯,且其適用范圍更廣(可以用於RNN等網絡的學習),同時克服了上面梯度下降法的那2個缺點。HF的主要思想類似於牛頓迭代法,只是並沒有顯示的去計算誤差曲面函數某點的Hessian矩陣H,而是通過某種技巧直接算出H和任意向量v的乘積Hv(該矩陣-向量的乘積形式在后面的優化過程中需要用到),因此叫做”Hessian Free”。本文主要是讀完Martens的論文Deep learning via Hessian-free optimization記下的一些筆記(具體內容請參考論文部分)。
Hessian Free方法其實在多年前就已經被使用,但為什么Martens論文又重提這個方法呢?其實它們的不同在於H矩陣”free”的方式不同,因為隱式計算H的方法可以有很多種,而算法的名字都可以叫做HF,因此不能簡單的認為Martens文章中在Deep Learning中的HF方法就是很久以前存在的方法了(如果真是如此,Deep Learning在N年前就火了!),只能說明它們的思想類似。將HF思想應用於DL網絡時,需要用到各種技巧,而數學優化本身就是各種技巧、近似的組合。Matrens主要使用2個大思想+5個小技巧(論文給出的大概是5個,但是其code里面還有不少技巧論文中沒有提到)來完成DL網絡的訓練。
idea 1:利用某種方法計算Hv的值(v任意),比如說常見的對誤差導函數用有限差分法來高精度近似計算Hv(見下面公式),這比以前只是用一個對角矩陣近似Hessian矩陣保留下來的信息要多很多。通過計算隱式計算Hv,可以避免直接求H的逆,一是因為H太大,二是H的逆有可能根本不存在。
idea 2:用下面二次項公式來近似得到θ值附近的函數值。且最佳搜索方向p由CG迭代法(該算法簡單介紹見前面博文:機器學習&數據挖掘筆記_12(對Conjugate Gradient 優化的簡單理解))求得。
技巧1:計算Hv時並不是直接用有限差分法,而是利用Pearlmutter的R-operator方法(沒看懂,但是該方法優點有很多)。
技巧2:用Gauss-Newton矩陣G來代替Hessian矩陣H,所以最終隱式計算的是Gv.
技巧3:作者給出了用CG算法(有預條件的CG,即先對參數θ進行了一次線性坐標變換)求解θ搜索方向p時的迭代終止條件,即:
技巧4:在進行處理大數據學習時,用CG算法進行線性搜索時並沒有用到所有樣本,而是采用的mini-batch,因為從一些mini-batch樣本已經可以獲得關於曲面的一些有效曲率信息。
技巧5:用啟發式的方法(Levenburg-Marquardt)求得系統的阻尼系數λ,該系數在預條件的CG算法中有用到,預條件矩陣M的計算公式為:
上面的7點需要詳細閱讀Martens的paper,且結合其paper對應的code來讀(code見他的個人主頁http://www.cs.toronto.edu/~jmartens/research.html).
下面來簡單看看HF的流程圖:
流程圖說明的是:定義好系統的目標函數,見本博客中的第2個公式,接着定義一個最大權值更新次數max-epochs,每次循環時首先用BP算法求出目標函數的梯度值,接着用啟發式的方法取得λ值,然后預條件CG方法來優化參數搜索方向p(此過程需要用到Hv形式的求解函數),最后更新參數進入下一輪。
關於code部分,簡單說以下幾點:
運行該程序,迭代到170次,共用了差不多20個小時,程序的輸出如下:
maxiters = 250; miniters = 1 CG steps used: 250, total is: 28170 ch magnitude : 7.7864 Chose iters : 152 rho = 0.50606 Number of reductions : 0, chosen rate: 1 New lambda: 0.0001043 epoch: 169, Log likelihood: -54.7121, error rate: 0.25552 TEST Log likelihood: -87.9114, error rate: 3.5457 Error rate difference (test - train): 3.2901
code完成的是CURVES數據庫的分類,用的是Autoencoder網絡,網絡的層次結構為:[784 400 200 100 50 25 6 25 50 100 200 400 784]。
conjgrad_1(): 完成的是預條件的CG優化算法,函數求出了CG所迭代的步數以及優化的結果(搜索方向)。
computeGV(): 完成的是矩陣Gv的計算,結合了R操作和Gauss-Newton方法。
computeLL(): 計算樣本輸出值的log似然以及誤差(不同激發函數的輸出節點其誤差公式各異)。
nnet_train_2():該函數當然是核心函數了,直接用來訓練一個DL網絡,里面當少不了要調用conjgrad_1(),computeGV(),computeLL(),另外關於誤差曲面函數導數的求法也是用的經典BP算法。
參考資料:
Martens, J. (2010). Deep learning via Hessian-free optimization. Proceedings of the 27th International Conference on Machine Learning (ICML-10).
機器學習&數據挖掘筆記_12(對Conjugate Gradient 優化的簡單理解)
http://www.cs.toronto.edu/~jmartens/research.html
http://pillowlab.wordpress.com/2013/06/11/lab-meeting-6102013-hessian-free-optimization/