官术网_书友最值得收藏!

2.2.1 人工神經網絡

人工神經網絡是由大量的處理單元(神經元)互相連接而成的網絡,是對生物神經網絡的抽象、簡化和模擬。人工神經網絡具有大規模并行運算、分布式存儲、自組織和自學習等特點,能夠充分逼近復雜的非線性映射關系。這使得人工神經網絡在許多數字圖像模式識別領域有著非常成功的應用。

1.人工神經網絡基本原理

研究者們通過對人腦結構機理的模擬,現已提出了多種類型的人工神經網絡,并在很多領域得到了成功的應用,但這些神經網絡的基本單元——神經元的結構是基本相同的。

(1)神經元模型

圖2-3是神經元的結構示意圖,它是對生物神經元的簡化與模擬,其權值大小標志著神經元間相互影響的強弱,對應于長期記憶;而神經元應用非線性函數實現單元輸入與輸出間的非線性映射,則對應于短期記憶;偏置的作用是根據其為正或負,相應地增加或降低激活函數的網絡輸入。神經網絡模型即由大量這種神經元互相連接而成。

圖2-3 神經元的結構示意圖

圖2-3所示的神經元模型是一個多輸入、單輸出的非線性元件。其神經元的輸入輸出關系可用一個方程來描述:

式中,x1,x2,…,xm是輸入信號;wk1,wk2,…,wkm是神經元k的突觸權值;uk是輸入信號的線性組合器的輸出;bk為偏置;?(?)為激活函數,它的作用是激活神經元,使其對輸入產生影響;yk為神經元輸出信號。

(2)常用的激活函數

激活函數可以將神經元的狀態映射成神經元的輸出。可以利用許多種函數表達式來表現網絡的非線性特征,這里只介紹常用的4種激活函數。

(a)閾值型函數為

閾值函數表達了神經元的抑制和興奮特性。如對神經元k使用這種函數,其輸出可表示為

式中

此類模型又被稱為M-P模型。從上式中可以看出,對于神經元k,如果vk非負,則輸出為1,否則為0。這描述了用閾值函數實現的神經模型的皆有或皆無的特性。

(b)分段線性型函數為

這種形式的激活函數是對非線性放大器的近似。下面兩種情況可以看作是此函數的特例:

·在執行中保持運算的線性區域而使其不進入飽和狀態的情況下,就成為線性組合器。

·如果線性區的放大因子無窮大,那么此函數退化成閾值函數。i其中,k為樣本數,n1為隱單元數,n為輸入單元數。如果i>n1,其中,m為輸出神經元數,n為輸入單元數,a為[1,10]中的常數。n1=log 2 n,其中,n為輸入單元數。

(c)S型函數為

式中,C 為常數。S型函數是以轉動眼球的系統的神經元特性作為生物基礎。它反映了神經元的飽和特性,由于其函數連續可導,所以調節曲線的參數就可以得到類似閾值函數的功能,因此,S型函數是神經網絡中較常用的函數。

(d)高斯函數為

式中,參數δ稱為高斯函數的寬度或擴展函數。高斯函數體現了位于視覺區神經元的特性。高斯函數也是極為重要的一類激活函數,可以看出,δ越大,函數曲線就越平坦;反之,δ越小,函數曲線就越陡峭。

(3)神經網絡常見幾種形式

神經網絡的神經元之間的連接方式可以有任意形式,但常見的主要有如下幾種形式:

(a)前向網絡:前向網絡結構如圖2-4所示,神經元分層排列,分別由輸入層、中間層(又稱隱含層,可以由若干層組成)和輸出層組成。每一層的神經元只接收來自前一層或同一層內順序在先的神經元的輸出作為輸入,后面的層對前面層沒有信號反饋。輸入模式經過各層次的順序傳播,最后在輸出層上得到輸出。

圖2-4 前向網絡結構

(b)遞歸網絡:遞歸網絡結構如圖2-5所示,與前向網絡相似,遞歸網絡的神經元也是分層排列,由輸入層、中間層和輸出層組成,區別在于遞歸網絡至少存在一個反饋環,也就說從輸出層到輸入層有信息反饋。反饋環的存在,對網絡的學習能力和性能有著深刻的影響。遞歸網絡可用于存儲某種模式序列。

圖2-5 遞歸網絡結構

(c)橫向連接網絡:橫向連接網絡結構如圖2-6所示。橫向連接網絡通過層內神經元的相互結合,可以實現同一層內神經元之間的橫向抑制或興奮機制,這樣可以限制每層內可以同時動作的神經元素,或者把每層內的神經元分為若干組,讓每一層作為一個整體進行運作,體現了生物神經網絡的側抑制功能。例如,可利用橫向抑制機理把某層內具有最大輸出的神經元挑選出來,從而抑制其他神經元,使之處于無輸出的狀態。

圖2-6 橫向連接網絡結構

2.誤差反向傳播算法

前向神經網絡是最常用的神經網絡模型,誤差反向傳播(Back-Propogation,BP)算法是最著名的前向網絡訓練算法,其名字起源于網絡權值的調整規則,采用的是后向傳播學習算法。

三層前饋網絡的適用范圍大大超過了二層前饋網絡,但學習算法較為復雜,主要困難在于中間的隱層不直接與外界連接,無法直接計算其誤差。為解決這一問題,提出了反向傳播算法。其主要思想是從后向前(反向)逐層傳播輸出層的誤差,以間接算出隱層誤差。算法可分為兩個階段:第一階段(正向過程)輸入信息從輸入層經隱層逐層計算各單元的輸出值;第二階段(反向傳播過程)內輸出誤差逐層向前算出隱層各單元的誤差,并用此誤差修正前層權值。

在反向傳播算法中通常采用梯度法修正權值,為此要求輸出函數可微,通常采用Sigmoid函數作為輸出函數。為不失其普遍性,現假設處于某一層的第 j個計算單元,腳標i代表其前層第i個單元,腳標k代表后層第k個單元,O j代表本層輸出,wij是前層到本層的權值,如圖2-7所示。

圖2-7 反向傳播算法中的因量約定

輸入某個樣本時,從前到后對每層各單元作如下計算(正向算法):

對于輸出層而言, =Oj是實際輸出值,yj是理想輸出值,此樣本下的誤差:

為使式子簡化,定義局部梯度:

考慮權值wij對誤差的影響,可得

權值修正應使誤差最快地減小,修正量為

Δwij =-ηδj Oi

如果結點 j是輸出單元,則

如果結點 j不是輸出單元,由圖2-7所示可知,Oj對后層的全部結點都有影響。因此

對于Sigmoid函數:

或者是正切函數:

在實際計算時,為了加快收斂速度,往往在權值修正量中加上前一次的權值修正量,一般稱為慣性項,即

綜上所述,反向傳播算法步驟如下:

(a)選定權系數初始值。

(b)重復下述過程直至收斂(對各樣本依次計算)。

從前向后各層計算各單元Oj

對輸出層計算δj

從后向前計算各隱層δj

計算并保存各權值修正量:

修正權值:

以上算法是對每個樣本做權值修正,也可以對各樣本計算δj后求和,按總誤差修正權值。

反向傳播算法解決了隱層權值修正問題,但它是用梯度法求非線性函數極值,因而有可能陷入局部極小點,不能保證收斂到全局極小點。

二層前饋網絡的收斂性不受初始值影響,各權值的初始值可以全設定為零;但三層以上的前饋網絡(含有一個以上隱層)使用反向傳播算法時,如果權值初始值都為零或都相同,隱層各單元不能出現差異,運算不能正常進行。因此,通常用較小的隨機數(例如[-0.3,0.3]區間)作為權值初始值。初始值對收斂有影響,當計算不收斂時,可以改變初始值試算。

反向傳播算法中有兩個參數ηα。步長η對收斂性影響很大,而且對于不同的問題其最佳值相差很大,通常可在0.1~3之間試探,對于較復雜的問題應用較大的值。慣性項系數α影響收斂速度,在很多應用中其值可在0.9~1之間選擇(比如0.95),α 1≥ 時不收斂;有些情況下也可不用慣性項(即α=0)。

三層前饋神經網絡的輸出層與輸入層單元數是由問題本身決定的。例如,作為模式識別時輸入單元數是特征維數,輸出單元數是類數。但中間隱層的單元數如何確定則缺乏有效的方法。一般來說,問題越復雜,需要的隱層單元越多;或者說同樣的問題,隱層單元越多越容易收斂。但是隱層單元數過多會增加使用時的計算量,而且會產生“過學習”效果,使對未出現過的樣本的推廣能力變差。

3.BP網絡的設計

在進行BP網絡設計時,應從下面幾個方面進行考慮。

(1)輸入和輸出層的設計

輸入的神經元可以根據需要求解的問題和數據表示方式確定。如果輸入的是模擬信號波形,那么輸入層可以根據波形的采樣點數目決定輸入單元的維數,也可以用一個單元輸入,這時輸入樣本為采樣的時間序列;如果輸入為圖像,則輸入單元可以為圖像的像素,也可以是經過處理的圖像特征。

輸出層的維數可根據使用者的要求確定。如果將BP網絡用做分類器,且類別模式一共有m個,那么輸出層神經元的個數為m或log2 m

(2)隱層的設計

對于BP網絡,有一個非常重要的定理。即對于任何在閉區間內的一個連續函數都可以用單隱層的BP網絡逼近,因而一個三層BP網絡就可以完成任意的n維到m維的映射。

隱層的神經元數目選擇是一個十分復雜的問題,沒有哪一個表達式能完美表示它,它的確定往往需要根據設計者的經驗和多次試驗來完成。隱單元的數目與問題的要求、輸入/輸出單元的數目都有著直接關系。隱單元數目太多會導致學習時間過長、誤差不一定最佳,也會導致容錯性差、不能識別以前沒有看到的樣本,因此一定存在一個最佳的隱單元數。以下3個公式可用于選擇最佳隱單元數時的參考公式。

還有一種途徑可用于確定隱單元的數目。首先使隱單元的數目可變,或者放入足夠多的隱單元,通過學習將那些不起作用的隱單元剔除,直到不可收縮為止。同樣,也可以在開始時放入比較少的神經元,學習到一定次數后,如果不成功則再增加隱單元的數目,直到達到比較合理的隱單元數目為止。

(3)初始權值的選擇

初始權值的選擇與學習是否達到局部最小、網絡能否收斂和訓練時間的長短都有關系。初始值過大、過小都會影響學習速度。權值的初始值一般取(-1,1)之間的隨機數,有時也可選擇[-2.4/F,2.4/F]之間的隨機數,其中F為輸入特征個數。

(4)學習速率

學習速率決定每次循環和訓練時所產生的權值變化量,當速率過大時可能導致系統不穩定,速率過小又可能延長訓練時間,或導致網絡收斂過慢,使網絡誤差無法跳出局部極小值。學習速率的選取范圍一般為[0.01,0.8]。

4.BP算法的C語言實現

下面介紹BP算法的C語言實現代碼,如代碼2-1所示。

代碼2-1 BP算法程序

        CString m_result,m_result1;
        int  decimal, sign;
        char  buffer[200];
        double x_out[InputN];            //輸入層的輸出值
        double hn_out[HN];                //隱含層的輸出值
        double y_out[OutN];              //輸出層的輸出值
        double y[OutN];                   //輸出層的期望輸出值
        double w[InputN][HN];            //輸入層到隱含層的權值
        double v[HN][OutN];              //隱含層到輸出層的權值
        double deltaw[InputN][HN];
        double deltav[HN][OutN];
        double hn_delta[HN];             //隱含層的delta
        double y_delta[OutN];            //輸出層的delta
        double error;                     //全局誤差
        double errlimit=0.001;           //預設的全局誤差極限
        double alpha=0.1, beta=0.1;      //預設的學習速率
        int loop=0;                       //訓練次數
        int times=50000;                  //預設的訓練次數上限
        int i, j, m;
        double max, min;
        double sumtemp;
        double errtemp;
        struct{                           //訓練樣本對
            double input[InputN];
            double teach[OutN];
        }data[datanum];
        //初始化,將連接權值、偏置系數置為(-1,1)之間的隨機數
        for(i=0; i<InputN; i++)          //w的隨機輸入
            for(j=0; j<HN; j++){
                w[i][j] = ((double)rand()/32767.0)*2-1;
                deltaw[i][j] = 0;
            }
        for(i=0; i<HN; i++)              //v的隨機輸入
            for(j=0;j<OutN;j++){
                v[i][j] = ((double)rand()/32767.0)*2-1;
                deltav[i][j] = 0;
            }
        //訓練
        while(loop < times){
            loop++;
            error = 0.0;
            for(m=0; m<datanum; m++){    //datanum個樣本進行增量訓練,m為樣本個數
                //輸入正向傳播
                max=0.0;
                min=0.0;
                for(i=0; i<InputN; i++){ //設置輸入層的輸出
                    x_out[i] = data[m].input[i];
                    if (max < x_out[i])  //比較得出輸入的最大、最小值
                    max = x_out[i];
                if (min > x_out[i])
                        min = x_out[i];
                }
                for(i=0; i<InputN; i++){ //歸一化后的輸入值
                    x_out[i] = (x_out[i] - min) / (max-min);
                }
                for(i=0; i<OutN; i++){   //輸出層的期望輸出
                    y[i] = data[m].teach[i];
                }
                for(i=0; i<HN; i++){     //計算隱含層的輸出
                    sumtemp = 0.0;
                    for(j=0; j<InputN; j++)
                    sumtemp += w[j][i] * x_out[j];
                    hn_out[i] = tanh(sumtemp);   //隱含層作用函數為y=tanh(x)
                }
                for(i=0; i<OutN; i++){           //計算輸出層的輸出
                    sumtemp = 0.0;
                    for(j=0; j<HN; j++) sumtemp += v[j][i] * hn_out[j];
                    y_out[i] = g(sumtemp);       //輸出層作用函數為sigmod函數
                }
        //誤差反向傳播
                for(i=0; i<OutN; i++){
                    errtemp = y[i] - y_out[i];
                    y_delta[i] = errtemp * g(y_out[i]) * (1.0- g(y_out[i]));
                    error += (errtemp * errtemp);    //所有樣本的全局誤差
                }
                for(i=0; i<HN; i++){             //計算隱含層的delta
                    errtemp = 0.0;
                    for(j=0; j<OutN; j++)    errtemp += y_delta[j] * v[i][j];
                    hn_delta[i] = errtemp * (1.0 + hn_out[i]) * (1.0- hn_out[i]);
                }
                for(i=0; i<OutN; i++){           //調整輸出層的權值和偏置系數
                    for(j=0; j<HN; j++){
                        deltav[j][i] = alpha * deltav[j][i] + beta * y_delta[i] * hn_out[j];
                        v[j][i] += deltav[j][i];
                    }
                }
                for(i=0; i<HN; i++){         //調整隱含層的權值和偏置系數
                    for(j=0; j<InputN; j++){
                        deltaw[j][i] = alpha * deltaw[j][i] + beta * hn_delta[i] * x_out[j];
                        w[j][i] += deltaw[j][i];
                    }
                }
            }
        //全局誤差判斷
            error = error/2;
            if(loop%1000==0){
                m_result="全局誤差Error=";
                sprintf( buffer, "%f", error);
                m_result+=buffer;
                m_result+="\r\n";
                m_result+=m_result1;
            }
            if(error < errlimit) break;
        }
主站蜘蛛池模板: 华坪县| 内江市| 沧源| 田林县| 铜鼓县| 靖宇县| 乐都县| 农安县| 屯留县| 佳木斯市| 蛟河市| 鄂伦春自治旗| 武陟县| 磐石市| 旅游| 潜江市| 外汇| 蒙阴县| 张家港市| 泰州市| 垦利县| 仁寿县| 海城市| 拉孜县| 繁昌县| 德钦县| 伽师县| 龙山县| 杂多县| 买车| 依兰县| 都昌县| 邛崃市| 陇西县| 腾冲县| 营山县| 泉州市| 诏安县| 和林格尔县| 岱山县| 武邑县|