1. 程式人生 > >Andrew Ng機器學習筆記+Weka相關演算法實現(三)神經網路和引數含義

Andrew Ng機器學習筆記+Weka相關演算法實現(三)神經網路和引數含義

神經網路是一種非常重要的機器學習模型,人們從生物學中大腦神經元連線方式得到啟發,提出了神經網路的概念,它從資訊處理角度對人腦神經元網路進行抽象, 建立某種簡單模型,按不同的連線方式組成不同的網路。
最近幾年深度學習大熱,尤其是阿爾法圍棋(AlphaGo)戰勝李世乭後,神經網路和深度學習被推到了風口浪尖的。AlphaGo主要工作原理是“深度學習”。“深度學習”是指多層的人工神經網路和訓練它的方法。一層神經網路會把大量矩陣數字作為輸入,通過非線性啟用方法取權重,再產生另一個數據集合作為輸出。這就像生物神經大腦的工作機理一樣,通過合適的矩陣數量,多層組織連結一起,形成神經網路“大腦”進行精準複雜的處理,就像人們識別物體標註圖片一樣。
人工神經網路模型主要考慮網路連線的拓撲結構、神經元的特徵、學習規則等。目前,已有近40種神經網路模型,其中有反傳網路、感知器、自組織對映、Hopfield網路、波耳茲曼機、適應諧振理論等。根據連線的拓撲結構,神經網路模型可以分為:
(1)前向網路 網路中各個神經元接受前一級的輸入,並輸出到下一級,網路中沒有反饋,可以用一個有向無環路圖表示。這種網路實現訊號從輸入空間到輸出空間的變換,它的資訊處理能力來自於簡單非線性函式的多次複合。網路結構簡單,易於實現。反傳網路是一種典型的前向網路。

(2)反饋網路 網路內神經元間有反饋,可以用一個無向的完備圖表示。這種神經網路的資訊處理是狀態的變換,可以用動力學系統理論處理。系統的穩定性與聯想記憶功能有密切關係。Hopfield網路、波耳茲曼機均屬於這種型別。
Ng的課程裡神經網路講的比較少,這次主要聽了加州理工學院的公開課:機器學習與資料探勘,地址是:
http://open.163.com/movie/2012/2/I/D/M8FH262HJ_M8FU27PID.html
我將總結老師講解的神經網路概念、反向傳播等知識進行總結,如有錯誤之處,請批評指正。

  • 問題提出

簡單的多層感知器不能夠進行復雜的分類工作。
這裡寫圖片描述
對於第一個圖中的兩類,簡單線性感知器並不能正確的分類,但是我們可以構建第二第三兩個基本感知器,將兩個感知器進行某種方式的聯結,合成一個更加強大的感知器。
這裡寫圖片描述


第一個感知器因為有一個不變的輸入1.5>1,因此必須X1,X2都是負的才能使得輸出為負,這就實現了or運算,同理第二個感知器實現了AND運算。
這裡寫圖片描述
我們把基本感知器進行組合,就可以得到複雜的感知器,理論上它可以模擬任何曲面。如圖,輸入X0,X1,X2,通過or、and感知器進行運算,可以得到複雜的輸出f,這就是多層感知器的原理。圖中是前饋網路,所謂前饋,就是輸出只能向後傳遞,不能對之前的結果產生作用。圖中一共有三層感知器,分別是輸入層,隱含層和輸出層,每一層後面的數字代表權重,也是我們要求的量。
這裡寫圖片描述
如上圖所示,通過使用16層感知器,我們可以得到一個非常接近圓的區域,這就形象的表示了為何理論上神經網路可以擬合任何複雜函式。理論上講雖然越多的感知器可以帶來更好地逼近效果,但是也會帶來兩個問題,那就是降低泛化能力和帶來優化上的困難。

  • 神經網路

這裡寫圖片描述
上圖就是一個典型神經網路的結構,每一層都是非線性的,圖中一共有三層。非線性是由感知器的激勵函式產生的,比如常用的tanh函式:
這裡寫圖片描述
從以上分析我們可以知道,我們求取的就是連線神經元之間的權重,首先我們對權重進行符號化表示:
這裡寫圖片描述
輸入之所以從0開始是因為每一層都會有一項常數,即X0。
不難看出,右邊層的輸入其實就是前一層的輸出。那麼我們可以得到表示式:
這裡寫圖片描述
其中S就是訊號,對於輸入的變數,每一層經過計算產生輸出,層層計算直到輸出層。那麼如何構建出這個神經網路呢?關鍵就在於W的計算,我們需要計算出所有的權重,並保證權重是最優的。這是一個計算量非常大的工作,必須引入高效的計算方式才能解決。

  • 反向傳播演算法

我們可以利用隨機梯度下降求取最佳的權重,但是仍然不能避免巨大的計算量,所以我們應該分析層與層之間的關係,利用這些關係簡化計算。根據前兩篇部落格的內容,我們首先表達出誤差項:
這裡寫圖片描述
接下倆就是求取梯度:
這裡寫圖片描述
對於一個神經元連線來說:
這裡寫圖片描述
我們可以發現,W權重其實是X和S之間的橋樑,也就是X通過權重作用於訊號S上,不受其他變數的影響。那麼利用求導的鏈式法則:
這裡寫圖片描述
我們可以將這種關係進行分解,不難看出,S和W之間的求導關係其實就是X,接下來我們要求的就是第二項,我們暫時令它為δ。
因為最後一層結果就是輸出,因此先分析最後一層應該是最簡單的,那麼對於最後一層,我們可以得到:
這裡寫圖片描述
其中:
這裡寫圖片描述
又有如下公式:
這裡寫圖片描述
觀察整個層與層之間的關係,我們不難發現,每一層的輸出作為下一層的輸入,這種關係層層傳遞,那麼我們可以表示出相鄰兩層之間的關係:
這裡寫圖片描述
利用求導的鏈式法則:
這裡寫圖片描述
因此我們可以得到化簡後的結果:
這裡寫圖片描述
這樣我們就得到了δ層與層之間的遞推關係,也就是說,我們知道最後一層的δ,就可以倒著推出所有的δ,這就避免了每次一個一個計算W,可以迭代進行整個過程,因此BP演算法的整個過程可以表述如下:
這裡寫圖片描述

這裡需要注意的是,初始化權重W不能全部為0,因為這樣相當於層與層之間沒有任何關聯,每次更新迭代並不會有任何效果。這就像你站在山頂,如果沒有外部力量推一把,你永遠不會滾下山,到達最低的地方。因此,初始化權重應該隨機賦值才能保證效果。事實上隨機思想還可以避免陷入到非常明顯的區域性最優解,這對演算法來說非常有效。

  • Weka中實現神經網路

首先要知道的是,每次學習之前,輸入的資料被自動分成training set、validation set 及test set 三部分,training set是訓練樣本資料,validation set是驗證樣本資料,test set是測試樣本資料,這樣這三個資料集是沒有重疊的。在訓練時,用training訓練,每訓練一次,系統自動會將validation set中的樣本資料輸入神經網路進行驗證,在validation set輸入後會得出一個誤差(不是網路的訓練誤差,而是驗證樣本資料輸入後得到的輸出誤差,可能是均方誤差),而此前對validation set會設定一個步數,比如預設是6echo,則系統判斷這個誤差是否在連續6次檢驗後不下降,如果不下降或者甚至上升,說明training set訓練的誤差已經不再減小,沒有更好的效果了,這時再訓練就沒必要了,就停止訓練,不然可能陷入過學習。
Weka中提供了多層感知器,MultilayerPerceptron,它使用的激勵函式是sigmod函式,看一下它主要的可用引數:
這裡寫圖片描述
這裡寫圖片描述

下面逐個解釋每個引數的作用:
① -L 學習速率
學習速率,也就是梯度下降的速度。
學習速率的選取很重要 ,大了可能導致系統不穩定,小了會導致訓練週期過長、收斂慢,達不到要求的誤差。一般傾向於選取較小的學習速率以保持系統穩定,通過觀察誤差下降曲線來判斷。下降較快說明學習率比較合適,若有較大振盪則說明學習率偏大。同時,由於網路規模大小的不同,學習率選擇應當針對其進行調整。採用變學習速率的方案,令學習速率隨學習進展而逐步減少,可收到良好的效果。
② -M 動量
BP神經網路在批處理訓練時會陷入區域性最小,也就是說誤差能基本不變化其返回的訊號對權值調整很小但是總誤差能又大於訓練結果設定的總誤差能條件。這個時候加入一個動量因子有助於其反饋的誤差訊號使神經元的權值重新振盪起來。從權重更新的公式上看:
這裡寫圖片描述
最後一項的α就是動量的係數。引入動量可以加快神經網路收斂。
③ -N 迭代次數
由於神經網路計算並不能保證在各種引數配置下迭代結果收斂,當迭代結果不收斂時,允許最大的迭代次數。
④ -V
Validation set的百分比,訓練將持續直到其觀測到在validation set上的誤差已經一直在變差或者不變,或者訓練的時間已經到了 。
如果validation set設定的是0那麼網路將一直訓練直到達到迭代的次數
⑤ -E
用於終止validation testing。這個值用於決定在訓練終止前在一行內的validation set error可以變差(或者不變)多少次 。
⑥ -H 每層的神經元數
通用符 ‘a’ = (attribs + classes) / 2, ‘i’ = attribs, ‘o’ = classes , ‘t’ = attribs + classes
⑦-R 重置
將允許網路用一個更低的學習速率復位。如果網路偏離了方向其將會自動的用更低的學習速率復位並且重新訓練。若沒有加這個引數,偏離方向後訓練將返回失敗資訊。
⑧ -D延遲
這個引數可以導致學習的速率的降低。其將初始的學習速率除以迭代次數(epoch number)去決定當前的學習速率。這對於停止神經網路背離目標輸出有幫助,也提高了general performance。

其他引數比較簡單,涉及到的都是資料探勘基本知識,不再贅述。
下面是程式碼示例:

class NeuralNetworkModel  {
    public NeuralNetworkModel(Instances data) throws Exception{
        String[] options = {"-L",0.1,"-M",0.1,"-N",1000,"-H",4}
        MultilayerPerceptron model = new MultilayerPerceptron();
        modeloptions = options;
        model.setOptions(options);
        model.buildClassifier(data);
    }
}

如上建立的是一個具有一個隱含層的網路,如果想建立兩個隱含層的網路,每一層都指定若干個神經元,引數應該寫成:
setHiddenLayers(“4,5”) 或者 “… -H 4,5”
代表兩個隱含層,第一層4個神經元,第二層5個神經元。

需要注意的是,神經網路一個非常難以確定的是隱含層層數和每層神經元數的選擇,一般都按照經驗進行選取,對於線性問題一般可以採用感知器或自適應網路來解決,而不採用非線性網路,因為單層不能發揮出非線性啟用函式的特長。對於非線性問題,一般採用兩層或兩層以上的隱含層,但是誤差精度的提高實際上也可以通過增加隱含層中的神經元數目獲得,其訓練效果也比增加層數更容易觀察和調整,所以一般情況下,應優先考慮增加隱含層中的神經元數。對於數量,一般按照(屬性數目+類別數目)/2來選取,並留一點餘量。
對於每個引數影響有多大,可以看下面這張圖:
這裡寫圖片描述