神經網絡學習的原理與在OpenCV中的應用

1. 神經網絡介紹  

  神經網絡的原理根本在於對人類大腦行爲的神經生物學模擬,這樣看的話克隆技術也能算一種了吧。大腦可以看做一臺精密、穩定、計算能力超強的計算機,其中的信息處理單元就是神經元(Neuron)。神經元是大腦處理信息的最小單元,它的結構如下圖(再次使用了這個圖):


Figure 1. 神經元結構

    這個圖抽象一下,由三部分組成:細胞體(Cell Body)、樹突(Dendrite)、軸突(Axon)。名字都很形象,樹突像一棵樹那樣伸展開來,這就是(這不就是趙老師說的:是你的末梢神經壞死,把上邊給憋大了)。軸突長而細,我隱約記得某篇文章裏好像曾說道軸突有2mm那麼長,對於一個看不見的細胞體帶着這樣長的軸突,還是相對較長的。神經元之間就是通過這些樹突和軸突連接進行信息交互。分工各不相同,樹突的龐大組織作爲神經元的輸入,軸突則作爲輸出。一個神經元通過其龐大的樹突結構從多個神經元處接受輸入信號。同時它的軸突也會伸展向不同神經元輸出信號。那神經元A的樹突和另一個神經元B的軸突之間是如何實現信號傳遞的呢?這就引出下一個概念:突觸(Synapse)


Figure 2. 突觸結構圖

    軸突/樹突上的信號以電信號形式傳輸,突觸在信號傳遞的過程中會把電信號轉變成化學信號,然後通過突觸間隙傳遞到下一個神經元的樹突,再次轉換成電信號,從而經歷電信號-化學信號-電信號的轉變過程。

    介紹完輸入輸出,下面就是神經元的細胞體了。細胞體接收輸入信號後,合成爲一個輸出,它的具體作用過程是我所不知的,但是後面在人工神經網絡中可以看到用Sigmoid function來模擬它的處理過程。

    這僅僅是一個信息處理單元,據估計大腦皮層擁有大約100億神經細胞和60萬億的突觸連接,這樣的網絡結構結果就是造就了大腦這樣的高效組織。大腦的能效大約是焦耳每操作每秒,而相比之下最好的計算機這一數據要指數級地增長。由此也可以看到“集羣”的力量,就好像螞蟻或者蜜蜂那樣。

2. 人工神經網絡(Artificial Neural Network)   

  2.1  神經元模型  

    現在用計算技術來模擬這樣的網絡,首先就是要實現一個神經元那樣的處理單元。來看一下人造的神經元:


Figure 3.神經元模型

    看過了前面的神經元,這個模型就不難理解是如何模擬的。同樣,它也有多個(m)輸入,突觸以及樹突上信號傳遞的過程被簡化爲加權,這裏下標的順序是神經元k的第j個輸入權重(synaptic weight)。在這裏引入一個偏置項(bias),然後共同作爲加法器(adder)的輸入。到此爲止,可以看到我們是對輸入做了一個加權和計算,偏置項的引入實際上把加權和變成了對輸入的Affine transform。而這些突觸權重在神經網絡的學習過程中承擔着主體作用,因爲神經網絡通過學習或者訓練獲得的知識表達(knowledge representation)就是這些權重和偏置項(偏置項可以看做是一個輸入爲+1、權重爲的突觸連接)的具體取值。

    加法器的輸出就是後面激活函數(Activation function)的輸入範圍,通過激活函數得到神經元的最終輸出。激活函數有多種類型,最常見的就是Threshold函數和Sigmoid函數(前面提到過)。


Figure 4. (a) Threshold function;  (b) Sigmoid function

形式分別爲:Threshold 

                      Sigmoid        其中

激活函數的作用是把輸出壓扁(squash)到一定範圍內。以Sigmoid函數爲例,輸入從負無窮到正無窮,經過sigmoid函數映射到(0,1)範圍,與Threshold函數不同的是它的連續性使得它的輸出可以看做是結果等於1的概率。當v>0時輸出爲1;v<0時輸出爲0。這對應的是神經網絡中神經元的兩種狀態:激活狀態和未激活狀態。

    最後總結起來,神經元模型是一個對輸入做Affine變換後經過激活函數的數學模型。

  2.2  網絡模型

    人工神經網絡是以層(layer)形式組織起來,包含一個輸入層、一個輸出層和一個或多個隱含層。每一層(除去輸入層)中包含多個神經元,或者叫計算單元。輸入層只是接收輸入信號,並沒有做計算。層與層之間通過神經連接(synaptic link)連接起來,如果神經元與前一層的每一個神經元之間都有連接(下圖所示),這樣的網絡叫做全連接網絡(completely-linked network),否則叫做部分連接網絡(partially-linked network)


Figure 5. 神經網絡模型

    這樣的網絡包含一個4個神經元的隱含層,一個2個神經元的輸出層,一個包含10個輸入節點的輸入層。輸入節點因爲沒有計算因爲用方塊表示,神經元用深色圓形表示。

  2.3  模擬的能力

    首先考慮一個神經元裏的輸出y與x之間的關係。激活函數的曲線在上面圖4b中已經畫出來,當輸入由x變爲ax時,曲線的平滑度將會隨之變化:a越大函數曲線越陡,當a趨於正無窮時sigmoid函數逼近到Threshold函數。而如果輸入由x變爲x+b時,對曲線做平移。因而單個神經元是對輸入的非線性映射。如圖5中的網絡模型,如果只有一個輸入x,這個只包含一個隱含層的網絡結構可以逼近x任意的非線性函數(隱含層神經元數目未必爲4)。因而一個大型的全連接網絡的模擬能力是可以想見的。

  2.4  計算的能力

    利用網絡模型計算時,由輸入層開始,每一個節點接收來自前一層中節點的輸出,然後將計算結果傳遞到後面一層直到最後的輸出層,叫做前向傳播過程。

  2.5  訓練---BP

    網絡的訓練目的就是要找到網絡中各個突觸連接的權重和偏置項。作爲有監督學習的一種,它的訓練過程是通過不斷反饋當前網絡計算結果與訓練數據的label之間的誤差來修正網絡權重。當滿足某個條件時退出訓練。

    首先取一個訓練樣例,輸入經過初始化後的網絡得到輸出,然後計算輸出與樣例的desired output的誤差,然後計算該誤差對輸出層輸入的導數,再根據對輸入層導數計算誤差函數對隱含層-輸出層權重的導數,根據此導數修正隱含層-輸出層權重。繼續這樣的過程,計算誤差函數對輸入層-隱含層權重的導數,並修正輸入層-隱含層權重……直到滿足退出條件(誤差精度或無調整),訓練過程結束。

3.  OpenCV中的神經網絡

    OpenCV中封裝了類CvANN_MLP,因而神經網絡利用很方便。

    首先構建一個網絡模型:

    CvANN_MLP ann;

    Mat structure(1,3,CV_32SC1);
    structure.at<uchar>(0) = 10;

    structure.at<uchar>(0) = 4;

    structure.at<uchar>(0) = 2;  // structure中表示每一層中神經元數目

    ann.create(structure,CvANN_MLP::SIGMOID_SYM,1,1);  // 很明顯第二個參數選擇的是激活函數的類型

    然後需要對訓練數據放在兩個Mat結構中。第一個是存儲訓練數據的Mat train,第二個是存儲類別的Mat label。其中,train的每一行代表一個訓練樣例,label的對應的一行是訓練樣例的類別。比如有25個屬於7個類別的訓練樣例,每個樣例爲16維向量。則train結構爲25*16,label結構爲25*7。需要解釋的是類別數據,label中一行表示樣例所處類別,如果屬於第一類則爲(1,0,0,0,0,0,0),第二類爲(0,1,0,0,0,0,0)...

    接下來需要給ann提供一個樣例的權重向量Mat weight,它標記的是訓練樣例的權重,這裏都初始化爲1:

    Mat weight;

    weight.ones(1,25,CV_32FC1);

    接下來可以做訓練了:

    ann.train(train,label,weight);

    訓練結束後用ann來做分類,輸入爲Mat testSample,testSample爲1*16的向量,輸出爲Mat output,output爲1*7向量:

    ann.predict(testSample,output);

    最後找到output中的最大值就知道所屬類別maxPos了:

    int maxPos;

    double maxVal;

    minMaxLoc(output,0,&maxVal,0,&maxPos);

4.  Game Over

     THANK YOU !

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