反向傳播網絡(BP 網絡)

反向傳播網絡(BP 網絡)
1 .概述
前面介紹了神經網絡的結構和模型, 在實際應用中, 我們用的最廣泛的是反向傳播網絡
(BP網絡) 。下面就介紹一下BP網絡的結構和應用。
BP網絡是採用Widrow-Hoff學習算法和非線性可微轉移函數的多層網絡。 一個典型的BP
網絡採用的是梯度下降算法,也就是Widrow-Hoff算法所規定的。backpropagation就是指的
爲非線性多層網絡計算梯度的方法。 現在有許多基本的優化算法, 例如變尺度算法和牛頓算
法。 神經網絡工具箱提供了許多這樣的算法。 這一章我們將討論使用這些規則和這些算法的
優缺點。
一個經過訓練的BP網絡能夠根據輸入給出合適的結果,雖然這個輸入並沒有被訓練過。
這個特性使得BP網絡很適合採用輸入/目標對進行訓練,而且並不需要把所有可能的輸入/
目標對都訓練過。爲了提高網絡的適用性,神經網絡工具箱提供了兩個特性--規則化和早期
停止。 這兩個特性和用途我們將在這一章的後面討論。 這一章還將討論網絡的預處理和後處
理技術以提高網絡訓練效率。
2 .基礎
網絡結構
神經網絡的結構前一章已詳細討論過,前饋型BP網絡的結構結構和它基本相同,這裏
就不再詳細論述了,這裏着重說明以下幾點:
1. 常用的前饋型BP網絡的轉移函數有logsig,tansig,有時也會用到線性函數purelin。
當網絡的最後一層採用曲線函數時, 輸出被限制在一個很小的範圍內, 如果採用線性函數則
輸出可爲任意值。以上三個函數是BP網絡中最常用到的函數,但是如果需要的話你也可以
創建其他可微的轉移函數。
2. 在BP網絡中,轉移函數可求導是非常重要的,tansig、logsig和purelin都有對應的導
函數dtansig、dlogsig和dpurelin。爲了得到更多轉移函數的導函數,你可以帶字符"deriv"的轉
移函數:
tansig('deriv')
ans = dtansig
網絡構建和初始化
訓練前饋網絡的第一步是建立網絡對象。函數newff建立一個可訓練的前饋網絡。這需
要 4 個輸入參數。第一個參數是一個Rx2 的矩陣以定義R個輸入向量的最小值和最大值。第
二個參數是一個顢頇每層神經元個數的數組。 第三個參數是包含每層用到的轉移函數名稱的
細胞數組。最後一個參數是用到的訓練函數的名稱。

舉個例子,下面命令將創建一個二層網絡,其網絡模型如下圖所示。


它的輸入是兩個元素的向量,第一層有三個神經元,第二層有一個神經元。第一層的轉
移函數是tan-sigmoid,輸出層的轉移函數是linear。輸入向量的第一個元素的範圍是-1 到 2,
輸入向量的第二個元素的範圍是 0 到 5,訓練函數是traingd。
net=newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'traingd');
這個命令建立了網絡對象並且初始化了網絡權重和偏置,因此網絡就可以進行訓練了。
我們可能要多次重新初始化權重或者進行自定義的初始化。下面就是初始化的詳細步驟。
在訓練前饋網絡之前,權重和偏置必須被初始化。初始化權重和偏置的工作用命令init
來實現。 這個函數接收網絡對象並初始化權重和偏置後返回網絡對象。 下面就是網絡如何初
始化的:
net = init(net);
我們可以通過設定網絡參數net.initFcn和net.layer{i}.initFcn這一技巧來初始化一個給定
的網絡。net. initFcn用來決定整個網絡的初始化函數。前饋網絡的缺省值爲initlay,它允許
每一層用單獨的初始化函數。設定了net.initFcn ,那麼參數net.layer{i}.initFcn 也要設定用
來決定每一層的初始化函數。
對前饋網絡來說,有兩種不同的初始化方式經常被用到:initwb和initnw。initwb函數根
據每一層自己的初始化參數(net.inputWeights{i,j}.initFcn)初始化權重矩陣和偏置。前饋網絡
的初始化權重通常設爲rands,它使權重在-1 到 1 之間隨機取值。這種方式經常用在轉換函
數是線性函數時。initnw通常用於轉換函數是曲線函數。它根據Nguyen和Widrow[NgWi90]
爲層產生初始權重和偏置值, 使得每層神經元的活動區域能大致平坦的分佈在輸入空間。 它
比起單純的給權重和偏置隨機賦值有以下優點: (1)減少神經元的浪費(因爲所有神經元的
活動區域都在輸入空間內) 。 (2)有更快的訓練速度(因爲輸入空間的每個區域都在活動的
神經元範圍中) 。
初始化函數被newff所調用。因此當網絡創建時,它根據缺省的參數自動初始化。init不
需要單獨的調用。可是我們可能要重新初始化權重和偏置或者進行自定義的初始化。例如,
我們用newff創建的網絡, 它缺省用initnw來初始化第一層。 如果我們想要用rands重新初始化
第一層的權重和偏置,我們用以下命令:
net.layers{1}.initFcn = 'initwb';
net.inputWeights{1,1}.initFcn = 'rands';
net.biases{1,1}.initFcn = 'rands';
net.biases{2,1}.initFcn = 'rands';
net = init(net);
網絡模擬(SIM)
函數sim 模擬一個網絡。sim 接收網絡輸入p,網絡對象net,返回網絡輸出a,這裏是
simuff用來模擬上面建立的帶一個輸入向量的網絡。
p = [1;2];
a = sim(net,p)
a =
-0.1011
(用這段代碼得到的輸出是不一樣的,這是因爲網絡初始化是隨機的。)
下面調用sim來計算一個同步輸入 3 向量網絡的輸出:
p = [1 3 2;2 4 1];
a=sim(net,p)
a =
-0.1011 -0.2308 0.4955
網絡訓練
一旦網絡加權和偏差被初始化, 網絡就可以開始訓練了。 我們能夠訓練網絡來做函數近
似(非線性 後退) ,模式結合,或者模式分類。訓練處理需要一套適當的網絡操作的例子--
網絡輸入p和目標輸出t。在訓練期間網絡的加權和偏差不斷的把網絡性能函數
net.performFcn減少到最小。前饋網絡的缺省性能函數是均方誤差mse--網絡輸出和目標輸出t
之間的均方誤差。 這章的餘項將描述幾個對前饋網絡來說不同的訓練算法。 所有這些算法都
用性能函數的梯度來決定怎樣把權重調整到最佳。 梯度由叫做反向傳播的技術決定, 它要通
過網絡實現反向計算。 反向傳播計算源自使用微積分的鏈規則。 基本的反向傳播算法的權重
沿着梯度的負方向移動, 這將在下一節講述。 以後的章節將講述更復雜的算法以提高收斂速
度。
反向傳播算法
反向傳播算法中有許多變量, 這一章將討論其中的一些。 反向傳播學習算法最簡單的應
用是沿着性能函數最速增加的方向--梯度的負方向更新權重和偏置。這種遞歸算法可以寫
成:
xk+1 = xk- a k g k
這裏xk是當前權重和偏置向量,g k是當前梯度,a k是學習速率。有兩種不同的辦法實
現梯度下降算法:增加模式和批處理模式。在增加模式中,網絡輸入每提交一次,梯度計算
一次並更新權重。在批處理模式中,當所有的輸入都被提交後網絡才被更新。下面兩節將討
論增加模式和批處理模式。
增加模式訓練法(ADAPT )
函數adapt用來訓練增加模式的網絡,它從訓練設置中接受網絡對象、網絡輸入和目標
輸入,返回訓練過的網絡對象、用最後的權重和偏置得到的輸出和誤差。
這裏有幾個網絡參數必須被設置,第一個是net.adaptFcn,它決定使用哪一種增加模式
函數,缺省值爲adaptwb,這個值允許每一個權重和偏置都指定它自己的函數,這些單個的
學 習 函 數 由 參 數 net.biases{i,j}.learnFcn 、 net.inputWeights{i,j}.learnFcn 、
net.layerWeights{i,j}.learnFcn和Gradient Descent (LEARDGD)來決定。 對於基本的梯度最速下
降算法,權重和偏置沿着性能函數的梯度的負方向移動。在這種算法中,單個的權重和偏置
的學習函數設定爲"learngd"。下面的命令演示了怎樣設置前面建立的前饋函數參數:
net.biases{1,1}.learnFcn = 'learngd';
net.biases{2,1}.learnFcn = 'learngd';
net.layerWeights{2,1}.learnFcn = 'learngd';
net.inputWeights{1,1}.learnFcn = 'learngd';
函數learngd有一個相關的參數--學習速率lr。權重和偏置的變化通過梯度的負數乘上學
習速率倍數得到。學習速率越大,步進越大。如果學習速率太大算法就會變得不穩定。如果
學習速率太小,算法就需要很長的時間才能收斂。當learnFcn設置爲learngd時,就爲每一個
權重和偏置設置了學習速率參數的缺省值, 如上面的代碼所示, 當然你也可以自己按照意願
改變它。下面的代碼演示了把層權重的學習速率設置爲 0.2。我們也可以爲權重和偏置單獨
的設置學習速率。
net.layerWeights{2,1}.learnParam.lr= 0.2;
爲有序訓練設置的最後一個參數是net.adaptParam.passes, 它決定在訓練過程中訓練值重
復的次數。這裏設置重複次數爲 200
net.adaptParam.passes = 200;
現在我們就可以開始訓練網絡了。當然我們要指定輸入值和目標值如下所示:
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
如果我們要在每一次提交輸入後都更新權重, 那麼我們需要將輸入矩陣和目標矩陣轉變
爲細胞數組。每一個細胞都是一個輸入或者目標向量。
p = num2cell(p,1);
t = num2cell(t,1);
現在就可以用adapt來實現增加方式訓練了:
[net,a,e]=adapt(net,p,t);
訓練結束以後,我們就可以模擬網絡輸出來檢驗訓練質量了。
a = sim(net,p)
a =
[-0.9995] [-1.0000] [1.0001] [1.0000]
帶動力的梯度下降法(LEARDGDM)
除了learngd以外, 還有一種增加方式算法常被用到, 它能提供更快的收斂速度--learngdm,
帶動量的最速下降法。 動力允許網絡不但根據當前梯度而且還能根據誤差曲面最近的趨勢響
應。就像一個低通濾波器一樣,動量允許網絡忽略誤差曲面的小特性。沒有動量,網絡又可
能在一個局部最小中被卡住。 有了動量網絡就能夠平滑這樣的最小。 動量能夠通過把權重變
得與上次權重變化的部分和由算法規則得到的新變化的和相同而加入到網絡學習中去。 上一
次權重變化對動量的影響由一個動量常數來決定, 它能夠設爲 0 到 1 之間的任意值。 當動量
常數爲 0 時, 權重變化之根據梯度得到。 當動量常數爲 1 時新的權重變化等於上次的權重變
化,梯度值被忽略了。
Learngdm函數有上面所示的learngd函數觸發,除非mc和lr學習參數都被設置了。由於每
一個權重和偏置有它自己的學習參數,每一個權重和偏置都可以用不同的參數。
下面的命令將用lerangdm爲前面建立的用增加方式訓練的網絡設置缺省的學習參數:
net.biases{1,1}.learnFcn = 'learngdm';
net.biases{2,1}.learnFcn = 'learngdm';
net.layerWeights{2,1}.learnFcn = 'learngdm';
net.inputWeights{1,1}.learnFcn = 'learngdm';
[net,a,e]=adapt(net,p,t);
批處理訓練方式
訓練的另一種方式是批處理方式,它由函數train觸發。在批處理方式中,當整個訓練設
置被應用到網絡後權重和偏置才被更新。 在每一個訓練例子中的計算的梯度加在一起來決定
權重和偏置的變化。
批處理梯度下降法(TRAINGD)
與增加方式的學習函數learngd等價的函數是traingd, 它是批處理形式中標準的最速下降
學習函數。 權重和偏置沿着性能函數的梯度的負方向更新。 如果你希望用批處理最速下降法
訓練函數,你要設置網絡的trainFcn爲traingd,並調用train函數。不像以前章節的學習函數,
它們要單獨設置權重矩陣和偏置向量,這一次給定的網絡只有一個學習函數。
Traingd有幾個訓練參數:epochs,show,goal,time,min_grad,max_fail和lr。這裏的學習速率
和lerangd的意義是一樣的。訓練狀態將每隔show次顯示一次。其他參數決定訓練什麼時候
結束。如果訓練次數超過epochs,性能函數低於goal,梯度值低於mingrad或者訓練時間超過
time,訓練就會結束。
下面的代碼將重建我們以前的網絡,然後用批處理最速下降法訓練網絡。 (注意用批處
理方式訓練的話所有的輸入要設置爲矩陣方式)
net=newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'traingd');
net.trainParam.show = 50;
net.trainParam.lr = 0.05;
net.trainParam.epochs = 300;
net.trainParam.goal = 1e-5;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net=train(net,p,t);
TRAINGD, Epoch 0/300, MSE 1.59423/1e-05, Gradient 2.76799/
1e-10
TRAINGD, Epoch 50/300, MSE 0.00236382/1e-05, Gradient
0.0495292/1e-10
TRAINGD, Epoch 100/300, MSE 0.000435947/1e-05, Gradient
0.0161202/1e-10
TRAINGD, Epoch 150/300, MSE 8.68462e-05/1e-05, Gradient
0.00769588/1e-10
TRAINGD, Epoch 200/300, MSE 1.45042e-05/1e-05, Gradient
0.00325667/1e-10
TRAINGD, Epoch 211/300, MSE 9.64816e-06/1e-05, Gradient
0.00266775/1e-10
TRAINGD, Performance goal met.
a = sim(net,p)
a =
-1.0010 -0.9989 1.0018 0.9985
用nnd12sd1 來演示批處理最速下降法的性能。
帶動量的批處理梯度下降法(TRAINGDM)
帶動量的批處理梯度下降法用訓練函數traingdm觸發。這種算法除了兩個例外和
learmgdm是一致的。第一.梯度是每一個訓練例子中計算的梯度的總和,並且權重和偏置
僅僅在訓練例子全部提交以後才更新。 第二. 如果在給定重複次數中新的性能函數超過了以
前重複次數中的性能函數的預定義速率max_perf_inc(典型的是 1.04)倍,那麼新的權重和偏
置就被丟棄,並且動量係數mc就被設爲 0。
在下面的代碼重,我們重建了以前的網絡並用帶動量的梯度下降算法重新訓練。
Traingdm的訓練參數和traingd的一樣,動量係數mc和性能最大增量max_perf_inc也是如此。
(無論什麼時候,只要net.trainFcn倍設爲traingdm,訓練參數就被設爲缺省值。 )
net=newff([-1 2; 0 5],[3,1],{'tansig','purelin'},'traingdm');
net.trainParam.show = 50;
net.trainParam.lr = 0.05;
net.trainParam.mc = 0.9;
net.trainParam.epochs = 300;
net.trainParam.goal = 1e-5;
p = [-1 -1 2 2;0 5 0 5];
t = [-1 -1 1 1];
net=train(net,p,t);
TRAINGDM, Epoch 0/300, MSE 3.6913/1e-05, Gradient 4.54729/
1e-10
TRAINGDM, Epoch 50/300, MSE 0.00532188/1e-05, Gradient
0.213222/1e-10
TRAINGDM, Epoch 100/300, MSE 6.34868e-05/1e-05, Gradient
0.0409749/1e-10
TRAINGDM, Epoch 114/300, MSE 9.06235e-06/1e-05, Gradient
0.00908756/1e-10
TRAINGDM, Performance goal met.
a = sim(net,p)
a =
-1.0026 -1.0044 0.9969 0.9992
注意,既然我們在訓練前重新初始化了權重和偏置,我們就得到了一個和使用traingd
不同的均方誤差。 如果我們想用traingdm重新初始化並且重新訓練,我們仍將得到不同的軍方
誤差。 初始化權重和偏置的隨機選擇將影響算法的性能。 如果我們希望比較不同算法的性能,
我們應該測試每一個使用着的不同的權重和偏值的設置。
用nnd12mo來演示批處理最速下降法的性能。
發佈了41 篇原創文章 · 獲贊 145 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章