神經網路程式設計入門【轉】

Old發表於2014-11-18

參考:http://www.cnblogs.com/heaad/archive/2011/03/07/1976443.html

 神經網路程式設計入門

本文主要內容包括: (1) 介紹神經網路基本原理,(2) AForge.NET實現前向神經網路的方法,(3) Matlab實現前向神經網路的方法 。

 

0節、引例 

       本文以Fisher的Iris資料集作為神經網路程式的測試資料集。Iris資料集可以在http://en.wikipedia.org/wiki/Iris_flower_data_set  找到。這裡簡要介紹一下Iris資料集:

有一批Iris花,已知這批Iris花可分為3個品種,現需要對其進行分類。不同品種的Iris花的花萼長度、花萼寬度、花瓣長度、花瓣寬度會有差異。我們現有一批已知品種的Iris花的花萼長度、花萼寬度、花瓣長度、花瓣寬度的資料。

  一種解決方法是用已有的資料訓練一個神經網路用作分類器。

  如果你只想用C#或Matlab快速實現神經網路來解決你手頭上的問題,或者已經瞭解神經網路基本原理,請直接跳到第二節——神經網路實現。

 

第一節、神經網路基本原理 

1. 人工神經元( Artificial Neuron )模型 

       人工神經元是神經網路的基本元素,其原理可以用下圖表示:

圖1. 人工神經元模型

 

       圖中x1~xn是從其他神經元傳來的輸入訊號,wij表示表示從神經元j到神經元i的連線權值,θ表示一個閾值 ( threshold ),或稱為偏置( bias )。則神經元i的輸出與輸入的關係表示為:

 

  圖中 yi表示神經元i的輸出,函式f稱為啟用函式 ( Activation Function )或轉移函式 ( Transfer Function ) ,net稱為淨啟用(net activation)。若將閾值看成是神經元i的一個輸入x0的權重wi0,則上面的式子可以簡化為:

 

  若用X表示輸入向量,用W表示權重向量,即:

X = [ x0 , x1 , x2 , ....... , xn ]

 

  則神經元的輸出可以表示為向量相乘的形式:

 

 

       若神經元的淨啟用net為正,稱該神經元處於啟用狀態或興奮狀態(fire),若淨啟用net為負,則稱神經元處於抑制狀態。

       圖1中的這種“閾值加權和”的神經元模型稱為M-P模型 ( McCulloch-Pitts Model ),也稱為神經網路的一個處理單元( PE, Processing Element )

 

2. 常用啟用函式 

       啟用函式的選擇是構建神經網路過程中的重要環節,下面簡要介紹常用的啟用函式。

(1) 線性函式 ( Liner Function )

 

(2) 斜面函式 ( Ramp Function )

 

(3) 閾值函式 ( Threshold Function )

 

 

 

       以上3個啟用函式都屬於線性函式,下面介紹兩個常用的非線性啟用函式。

(4) S形函式 ( Sigmoid Function )

  該函式的導函式:

(5) 雙極S形函式 

  該函式的導函式:

  S形函式與雙極S形函式的影象如下:


圖3. S形函式與雙極S形函式影象

  雙極S形函式與S形函式主要區別在於函式的值域,雙極S形函式值域是(-1,1),而S形函式值域是(0,1)。

  由於S形函式與雙極S形函式都是可導的(導函式是連續函式),因此適合用在BP神經網路中。(BP演算法要求啟用函式可導)

 

3. 神經網路模型 

       神經網路是由大量的神經元互聯而構成的網路。根據網路中神經元的互聯方式,常見網路結構主要可以分為下面3類:

(1) 前饋神經網路 ( Feedforward Neural Networks )

       前饋網路也稱前向網路。這種網路只在訓練過程會有反饋訊號,而在分類過程中資料只能向前傳送,直到到達輸出層,層間沒有向後的反饋訊號,因此被稱為前饋網路。感知機( perceptron)與BP神經網路就屬於前饋網路。

       圖4 中是一個3層的前饋神經網路,其中第一層是輸入單元,第二層稱為隱含層,第三層稱為輸出層(輸入單元不是神經元,因此圖中有2層神經元)。

圖4. 前饋神經網路

 

  對於一個3層的前饋神經網路N,若用X表示網路的輸入向量,W1~W3表示網路各層的連線權向量,F1~F3表示神經網路3層的啟用函式。

  那麼神經網路的第一層神經元的輸出為:

O1 = F1( XW1 )

  第二層的輸出為:

O2 = F2 ( F1( XW1 ) W2 )

  輸出層的輸出為:

O3 = F3( F2 ( F1( XW1 ) W2 ) W3 )

       若啟用函式F1~F3都選用線性函式,那麼神經網路的輸出O3將是輸入X的線性函式。因此,若要做高次函式的逼近就應該選用適當的非線性函式作為啟用函式。

(2) 反饋神經網路 ( Feedback Neural Networks )

       反饋型神經網路是一種從輸出到輸入具有反饋連線的神經網路,其結構比前饋網路要複雜得多。典型的反饋型神經網路有:Elman網路和Hopfield網路。

圖5. 反饋神經網路

 

(3) 自組織網路 ( SOM ,Self-Organizing Neural Networks )

       自組織神經網路是一種無導師學習網路。它通過自動尋找樣本中的內在規律和本質屬性,自組織、自適應地改變網路引數與結構。

圖6. 自組織網路

 

4. 神經網路工作方式 

       神經網路運作過程分為學習和工作兩種狀態。

(1)神經網路的學習狀態 

       網路的學習主要是指使用學習演算法來調整神經元間的聯接權,使得網路輸出更符合實際。學習演算法分為有導師學習( Supervised Learning )無導師學習( Unsupervised Learning )兩類。

       有導師學習演算法將一組訓練集 ( training set )送入網路,根據網路的實際輸出與期望輸出間的差別來調整連線權。有導師學習演算法的主要步驟包括:

1)  從樣本集合中取一個樣本(Ai,Bi);

2)  計算網路的實際輸出O;

3)  求D=Bi-O;

4)  根據D調整權矩陣W;

5) 對每個樣本重複上述過程,直到對整個樣本集來說,誤差不超過規定範圍。

  BP演算法就是一種出色的有導師學習演算法。

       無導師學習抽取樣本集合中蘊含的統計特性,並以神經元之間的聯接權的形式存於網路中。

       Hebb學習律是一種經典的無導師學習演算法。

(2) 神經網路的工作狀態 

       神經元間的連線權不變,神經網路作為分類器、預測器等使用。

  下面簡要介紹一下Hebb學習率與Delta學習規則 。

(3) 無導師學習演算法:Hebb學習率 

  Hebb演算法核心思想是,當兩個神經元同時處於激發狀態時兩者間的連線權會被加強,否則被減弱。 

       為了理解Hebb演算法,有必要簡單介紹一下條件反射實驗。巴甫洛夫的條件反射實驗:每次給狗餵食前都先響鈴,時間一長,狗就會將鈴聲和食物聯絡起來。以後如果響鈴但是不給食物,狗也會流口水。

圖7. 巴甫洛夫的條件反射實驗

 

  受該實驗的啟發,Hebb的理論認為在同一時間被激發的神經元間的聯絡會被強化。比如,鈴聲響時一個神經元被激發,在同一時間食物的出現會激發附近的另一個神經元,那麼這兩個神經元間的聯絡就會強化,從而記住這兩個事物之間存在著聯絡。相反,如果兩個神經元總是不能同步激發,那麼它們間的聯絡將會越來越弱。

  Hebb學習律可表示為:

       其中wij表示神經元j到神經元i的連線權,yi與yj為兩個神經元的輸出,a是表示學習速度的常數。若yi與yj同時被啟用,即yi與yj同時為正,那麼Wij將增大。若yi被啟用,而yj處於抑制狀態,即yi為正yj為負,那麼Wij將變小。

(4) 有導師學習演算法:Delta學習規則

  Delta學習規則是一種簡單的有導師學習演算法,該演算法根據神經元的實際輸出與期望輸出差別來調整連線權,其數學表示如下:

 

       其中Wij表示神經元j到神經元i的連線權,di是神經元i的期望輸出,yi是神經元i的實際輸出,xj表示神經元j狀態,若神經元j處於啟用態則xj為1,若處於抑制狀態則xj為0或-1(根據啟用函式而定)。a是表示學習速度的常數。假設xi為1,若di比yi大,那麼Wij將增大,若di比yi小,那麼Wij將變小。

       Delta規則簡單講來就是:若神經元實際輸出比期望輸出大,則減小所有輸入為正的連線的權重,增大所有輸入為負的連線的權重。反之,若神經元實際輸出比期望輸出小,則增大所有輸入為正的連線的權重,減小所有輸入為負的連線的權重。這個增大或減小的幅度就根據上面的式子來計算。

(5)有導師學習演算法:BP演算法 

  採用BP學習演算法的前饋型神經網路通常被稱為BP網路。

圖8. 三層BP神經網路結構

 

  BP網路具有很強的非線性對映能力,一個3層BP神經網路能夠實現對任意非線性函式進行逼近(根據Kolrnogorov定理)。一個典型的3層BP神經網路模型如圖7所示。

  BP網路的學習演算法佔篇幅較大,我打算在下一篇文章中介紹。

 

第二節、神經網路實現 

 

1. 資料預處理 

       在訓練神經網路前一般需要對資料進行預處理,一種重要的預處理手段是歸一化處理。下面簡要介紹歸一化處理的原理與方法。

(1) 什麼是歸一化? 

資料歸一化,就是將資料對映到[0,1]或[-1,1]區間或更小的區間,比如(0.1,0.9) 。

(2) 為什麼要歸一化處理? 

<1>輸入資料的單位不一樣,有些資料的範圍可能特別大,導致的結果是神經網路收斂慢、訓練時間長。

<2>資料範圍大的輸入在模式分類中的作用可能會偏大,而資料範圍小的輸入作用就可能會偏小。

<3>由於神經網路輸出層的啟用函式的值域是有限制的,因此需要將網路訓練的目標資料對映到啟用函式的值域。例如神經網路的輸出層若採用S形啟用函式,由於S形函式的值域限制在(0,1),也就是說神經網路的輸出只能限制在(0,1),所以訓練資料的輸出就要歸一化到[0,1]區間。

<4>S形啟用函式在(0,1)區間以外區域很平緩,區分度太小。例如S形函式f(X)在引數a=1時,f(100)與f(5)只相差0.0067。

(3) 歸一化演算法 

  一種簡單而快速的歸一化演算法是線性轉換演算法。線性轉換演算法常見有兩種形式:

       <1>

y = ( x - min )/( max - min )

  其中min為x的最小值,max為x的最大值,輸入向量為x,歸一化後的輸出向量為y 。上式將資料歸一化到 [ 0 , 1 ]區間,當啟用函式採用S形函式時(值域為(0,1))時這條式子適用。

       <2>

y = 2 * ( x - min ) / ( max - min ) - 1

       這條公式將資料歸一化到 [ -1 , 1 ] 區間。當啟用函式採用雙極S形函式(值域為(-1,1))時這條式子適用。

(4) Matlab資料歸一化處理函式 

  Matlab中歸一化處理資料可以採用premnmx , postmnmx , tramnmx 這3個函式。

<1> premnmx

語法:[pn,minp,maxp,tn,mint,maxt] = premnmx(p,t)

引數:

pn: p矩陣按行歸一化後的矩陣

minp,maxp:p矩陣每一行的最小值,最大值

tn:t矩陣按行歸一化後的矩陣

mint,maxt:t矩陣每一行的最小值,最大值

作用:將矩陣p,t歸一化到[-1,1] ,主要用於歸一化處理訓練資料集。

<2> tramnmx

語法:[pn] = tramnmx(p,minp,maxp)

引數:

minp,maxp:premnmx函式計算的矩陣的最小,最大值

pn:歸一化後的矩陣

作用:主要用於歸一化處理待分類的輸入資料。

<3> postmnmx

語法: [p,t] = postmnmx(pn,minp,maxp,tn,mint,maxt)

引數:

minp,maxp:premnmx函式計算的p矩陣每行的最小值,最大值

mint,maxt:premnmx函式計算的t矩陣每行的最小值,最大值

作用:將矩陣pn,tn對映回歸一化處理前的範圍。postmnmx函式主要用於將神經網路的輸出結果對映回歸一化前的資料範圍。

2. 使用Matlab實現神經網路 

使用Matlab建立前饋神經網路主要會使用到下面3個函式:

newff :前饋網路建立函式

train:訓練一個神經網路

sim :使用網路進行模擬

 下面簡要介紹這3個函式的用法。

(1) newff函式

<1>newff函式語法 

       newff函式引數列表有很多的可選引數,具體可以參考Matlab的幫助文件,這裡介紹newff函式的一種簡單的形式。

語法:net = newff ( A, B, {C} ,‘trainFun’)

引數:

A:一個n×2的矩陣,第i行元素為輸入訊號xi的最小值和最大值;

B:一個k維行向量,其元素為網路中各層節點數;

C:一個k維字串行向量,每一分量為對應層神經元的啟用函式

trainFun :為學習規則採用的訓練演算法

<2>常用的啟用函式

  常用的啟用函式有:

  a) 線性函式 (Linear transfer function)

f(x) = x

  該函式的字串為’purelin’。

 

b) 對數S形轉移函式( Logarithmic sigmoid transfer function )

    該函式的字串為’logsig’。

c) 雙曲正切S形函式 (Hyperbolic tangent sigmoid transfer function )

  也就是上面所提到的雙極S形函式。

 

  該函式的字串為’ tansig’。

  Matlab的安裝目錄下的toolbox\nnet\nnet\nntransfer子目錄中有所有啟用函式的定義說明。

<3>常見的訓練函式

    常見的訓練函式有:

traingd :梯度下降BP訓練函式(Gradient descent backpropagation)

traingdx :梯度下降自適應學習率訓練函式

<4>網路配置引數

一些重要的網路配置引數如下:

net.trainparam.goal  :神經網路訓練的目標誤差

net.trainparam.show   : 顯示中間結果的週期

net.trainparam.epochs  :最大迭代次數

net.trainParam.lr    : 學習率

(2) train函式

    網路訓練學習函式。

語法:[ net, tr, Y1, E ]  = train( net, X, Y )

引數:

X:網路實際輸入

Y:網路應有輸出

tr:訓練跟蹤資訊

Y1:網路實際輸出

E:誤差矩陣

(3) sim函式

語法:Y=sim(net,X)

引數:

net:網路

X:輸入給網路的K×N矩陣,其中K為網路輸入個數,N為資料樣本數

Y:輸出矩陣Q×N,其中Q為網路輸出個數

(4) Matlab BP網路例項 

       我將Iris資料集分為2組,每組各75個樣本,每組中每種花各有25個樣本。其中一組作為以上程式的訓練樣本,另外一組作為檢驗樣本。為了方便訓練,將3類花分別編號為1,2,3 。

  使用這些資料訓練一個4輸入(分別對應4個特徵),3輸出(分別對應該樣本屬於某一品種的可能性大小)的前向網路。

       Matlab程式如下:

 

%讀取訓練資料
[f1,f2,f3,f4,class] = textread('trainData.txt' , '%f%f%f%f%f',150);

%特徵值歸一化
[input,minI,maxI] = premnmx( [f1 , f2 , f3 , f4 ]')  ;

%構造輸出矩陣
s = length( class) ;
output = zeros( s , 3  ) ;
for i = 1 : s 
   output( i , class( i )  ) = 1 ;
end

%建立神經網路
net = newff( minmax(input) , [10 3] , { 'logsig' 'purelin' } , 'traingdx' ) ; 

%設定訓練引數
net.trainparam.show = 50 ;
net.trainparam.epochs = 500 ;
net.trainparam.goal = 0.01 ;
net.trainParam.lr = 0.01 ;

%開始訓練
net = train( net, input , output' ) ;

%讀取測試資料
[t1 t2 t3 t4 c] = textread('testData.txt' , '%f%f%f%f%f',150);

%測試資料歸一化
testInput = tramnmx ( [t1,t2,t3,t4]' , minI, maxI ) ;

%模擬
Y = sim( net , testInput ) 

%統計識別正確率
[s1 , s2] = size( Y ) ;
hitNum = 0 ;
for i = 1 : s2
    [m , Index] = max( Y( : ,  i ) ) ;
    if( Index  == c(i)   ) 
        hitNum = hitNum + 1 ; 
    end
end
sprintf('識別率是 %3.3f%%',100 * hitNum / s2 )

 

 

  以上程式的識別率穩定在95%左右,訓練100次左右達到收斂,訓練曲線如下圖所示:

圖9. 訓練效能表現

 

(5)引數設定對神經網路效能的影響 

       我在實驗中通過調整隱含層節點數,選擇不通過的啟用函式,設定不同的學習率,

 

<1>隱含層節點個數 

  隱含層節點的個數對於識別率的影響並不大,但是節點個數過多會增加運算量,使得訓練較慢。

 

<2>啟用函式的選擇 

       啟用函式無論對於識別率或收斂速度都有顯著的影響。在逼近高次曲線時,S形函式精度比線性函式要高得多,但計算量也要大得多。

 

<3>學習率的選擇 

       學習率影響著網路收斂的速度,以及網路能否收斂。學習率設定偏小可以保證網路收斂,但是收斂較慢。相反,學習率設定偏大則有可能使網路訓練不收斂,影響識別效果。

 

3. 使用AForge.NET實現神經網路 

(1) AForge.NET簡介 

       AForge.NET是一個C#實現的面向人工智慧、計算機視覺等領域的開源架構。AForge.NET原始碼下的Neuro目錄包含一個神經網路的類庫。

AForge.NET主頁:http://www.aforgenet.com/

AForge.NET程式碼下載:http://code.google.com/p/aforge/

Aforge.Neuro工程的類圖如下:

 

圖10. AForge.Neuro類庫類圖

 

下面介紹圖9中的幾個基本的類:

Neuron — 神經元的抽象基類

Layer — 層的抽象基類,由多個神經元組成

Network —神經網路的抽象基類,由多個層(Layer)組成

IActivationFunction - 啟用函式(activation function)的介面

IUnsupervisedLearning - 無導師學習(unsupervised learning)演算法的介面ISupervisedLearning - 有導師學習(supervised learning)演算法的介面

 

(2)使用Aforge建立BP神經網路 

       使用AForge建立BP神經網路會用到下面的幾個類:

<1>  SigmoidFunction : S形神經網路

  建構函式:public SigmoidFunction( double alpha )

   引數alpha決定S形函式的陡峭程度。

<2>  ActivationNetwork :神經網路類

  建構函式:

  public ActivationNetwork( IActivationFunction function, int inputsCount, params int[] neuronsCount )

                         : base( inputsCount, neuronsCount.Length )

  public virtual double[] Compute( double[] input )

 

引數意義:

inputsCount:輸入個數

neuronsCount :表示各層神經元個數

<3>  BackPropagationLearning:BP學習演算法

 建構函式:

public BackPropagationLearning( ActivationNetwork network )

 引數意義:

network :要訓練的神經網路物件

BackPropagationLearning類需要使用者設定的屬性有下面2個:

learningRate :學習率

momentum :衝量因子

下面給出一個用AForge構建BP網路的程式碼。

 

// 建立一個多層神經網路,採用S形啟用函式,各層分別有4,5,3個神經元
//(其中4是輸入個數,3是輸出個數,5是中間層結點個數)
ActivationNetwork network = new ActivationNetwork(new SigmoidFunction(2), 4, 5, 3);

// 建立訓練演算法物件
BackPropagationLearning teacher = new BackPropagationLearning(network);

// 設定BP演算法的學習率與衝量係數
teacher.LearningRate = 0.1;
teacher.Momentum = 0;

int iteration = 1 ; 

// 迭代訓練500次
while( iteration < 500 ) 
{
   teacher.RunEpoch( trainInput , trainOutput ) ; 
   ++iteration ;
}

//使用訓練出來的神經網路來分類,t為輸入資料向量
network.Compute(t)[0]

 

 

       改程式對Iris 資料進行分類,識別率可達97%左右 。

 

     點選下載原始碼

 

  文章來自:http://www.cnblogs.com/heaad/  

  轉載請保留出處,thx!

 

參考文獻 

[1] Andrew Kirillov. Neural Networks on C#. [Online].   

http://www.codeproject.com/KB/recipes/aforge_neuro.aspx  2006.10

[2] Sacha Barber. AI : Neural Network for beginners. [Online].

http://www.codeproject.com/KB/recipes/NeuralNetwork_1.aspx  2007.5

[3] Richard O. Duda, Peter E. Hart and David G. Stork. 模式分類. 機械工業出版社. 2010.4

[4] Wikipedia. Iris flower data set. [Online].      

http://en.wikipedia.org/wiki/Iris_flower_data_set 

相關文章