一.BP神經網絡原理及結構
本片博客偏向於BP神經網絡的MATLAB程序實現講解,詳細原理請參考:http://www.cnblogs.com/wentingtu/archive/2012/06/05/2536425.html
1.神經元
神經元作為神經網絡的基本單元,對於外界輸入具有簡單的反應能力,在數學上表征為簡單的函數映射。如下圖是一個神經元的基本結構,

神經元結構
圖中
是神經元的輸入,
是神經元輸入的權重,
是神經元的激活函數,y是神經元的輸出,其函數映射關系為

激活函數來描述層與層輸出之間的關系,從而模擬各層神經元之間的交互反應。激活函數必須滿足處處可導的條件。常用的神經元函數有四種,分別是線性函數、指示函數、Sigmoid函數(S型函數)、徑向基函數RBF(Radial Basis Function)。本次仿真使用Sigmoid函數,其表達式為
其導數為

其相應的曲線如圖2-2

圖2-2 Sigmoid函數
2.BP神經網絡
BP神經網絡是前向多層神經網絡(Multilayer Feedforward Neural Network, MLFN),其每一層包含若干個神經元,同一層的神經元之間沒有互相聯系,層間信息的傳送只沿一個方向進行。主要包括輸入層、隱含層和輸出層,其中隱含層的數目隨精確度的要求而有所變化。BP網絡能學習和存貯大量的輸入-輸出模式映射關系,而無需事前揭示描述這種映射關系的數學方程。建立模型之后,就可以通過減少輸出誤差來訓練網絡中的參數,從而逼近正確的函數模型。
BP神經網絡主要分為信號的正向傳播和誤差反向傳播兩個過程,正向傳播是指在樣本數據輸入后,計算輸入層到隱含層,再到輸出層的數據;誤差反向傳播就是將輸出誤差以某種形式通過隱含層向輸入層逐層反傳,將誤差分攤給各層的單元,再使用梯度下降法修正各單元的權值。一般當網絡輸出的誤差減少到可接受的程度或者進行到預先設定的學習次數時,訓練結束。
這里以下圖2-2簡單的三層BP神經網絡為例:

圖2-2三層BP神經網絡
假設輸入層有n個神經元,隱含層有p個神經元,輸出層有q個神經元。定義變量:
輸入向量:
隱含層的輸入向量:
隱含層的輸出向量:
輸出層的輸入:
輸出層的輸出:
期望輸出向量:
輸入層與隱含層的連接權值:

隱含層與輸出成的連接權值:

樣本數據個數:
輸出誤差函數:
前向傳播計算與誤差反向傳播具體步驟:
第一步:會對網絡進行初始化,對各連接權值分別賦一個區間(-1,1)內的隨機數,設定誤差函數e,給定計算精度值
和最大學習次數M。
第二步:隨機選取第k個輸入樣本及對應的期望輸出


第三步:計算隱含層各神經元的輸入和輸出





第四步:利用網絡期望輸出和實際輸出,計算誤差函數對輸出層的各神經元的偏導數







第五步:利用輸出層各神經元的


第六步:計算全局誤差

第七步:當第六步計算得到的全局誤差小於可接受的程度,或訓練進行到預先設定的學習次數時,訓練結束。
通過上述的前向傳播計算與誤差反向傳播,BP神經網絡就可以實現對樣本數據的有監督訓練,得到可以實現數字圖像識別的逼近函數以及必要的參數。
3.MATLAB仿真及結果
本次BP神經網絡數字圖像識別使用MATLAB語言進行數值仿真,在進行BP神經網絡創建之前,首選需要進行數字圖像的hash特征提取。獲得樣本圖像的hash特征之后,在進行BP神經網絡的創建、訓練和測試。
特征提取
圖像的特征對於圖像的標識有着非常大的重要性,好的特征能夠大大提高圖像的識別率。
本次MATLAB仿真提取數字圖像hash特征,具體步驟如下:

Hash特征提取步驟圖
參數訓練
將數字圖像的hash特征作為網絡的輸入數據,按照第二節BP神經網絡原理建立BP神經網絡,定義各變量並設置各參數,再按照前向傳播計算和誤差反向傳播的原理計算各層的值並迭代更新輸入層和隱含層之間的權矩陣、隱含層和輸出層之間的權矩陣。知道計算的全局誤差小於允許誤差或者訓練達到預定次數。
參數測試
將測試圖像的hash特征作為網絡輸入數據,計算輸出,判斷正確與否,並統計測試識別率。
仿真結果
由於BP神經網絡的輸入數據是的64維輸入特征,故輸入層神經元個數為65(加上偏置神經元),輸出層神經元個數為10(只有一個位置輸出為1,其他位置輸出為0),設置的允許誤差為0.000001,訓練樣本數為60000,測試樣本數為10000,隱含層神經元個數在三次實驗中分別為43、101、11個,相應的訓練及測試實驗結果如下。
| 輸入層 |
隱含層 |
輸出層 |
允許誤差 |
輸出全局誤差 |
訓練次數 |
識別率 |
| 65 |
43 |
10 |
0.000001 |
6.014958e-07 |
40816 |
92.9% |
| 65 |
101 |
10 |
0.000001 |
3.678565e-07 |
34499 |
92.0% |
| 65 |
11 |
10 |
0.000001 |
1.349866e-02 |
60000 |
89.95% |
BP神經網絡仿真表格
附件為本次"基於BP神經網絡的數字圖像識別"的MATLAB程序,主要分為兩個函數,GetFeature函數提取圖像的hash特征,BpDigitsRecog函數創建、訓練BP神經網絡,並進行測試。訓練樣本數據和標簽可在網盤http://pan.baidu.com/s/1bn4h0gZ下載。
提取特征:
%2015.4.13 by anchor %This function is to get hash feature of an image clc;clear all;close inputs = load('mnist_train.mat'); inputs = inputs.mnist_train; [sample_n] = size( inputs,1); for input_n = 1:sample_n hash_feature = inputs(input_n,:); image = reshape(hash_feature,28,28); [x,y]=find(image~=0); image=image(min(x):max(x),min(y):max(y)); image = imresize(image,[8 8]); hash_features(input_n,:) = image(:)'; end save train_hash hash_features clear hash_features inputs = load('mnist_test.mat'); inputs = inputs.mnist_test; [sample_n] = size( inputs,1); for input_n = 1:sample_n hash_feature = inputs(input_n,:); image = reshape(hash_feature,28,28); [x,y]=find(image~=0); image=image(min(x):max(x),min(y):max(y)); image = imresize(image,[8 8]); hash_features(input_n,:) = image(:)'; end save test_hash hash_features
BP主程序:
1 %2015.4.25 by anchor 2 % ============= Part 1: Input Images And Get Hash Features =============== 3 %This function GetFeature is to get hash feature of 28*28 image 4 %function GetFeatures 5 %%=================== Part 2: Create BPNN And Train it===================== 6 clc;clear all; 7 inputs = load('train_hash.mat'); 8 inputs = inputs.hash_features/256; 9 class = load('mnist_train_labels.mat'); 10 class = class.mnist_train_labels; 11 [length_input,feture_length]=size(inputs); 12 num_hide=10; 13 weight_input_hide=0.0001*(rand(feture_length,num_hide)); 14 weight_hide_output=0.0001*(rand(num_hide,10)); 15 input_hide_offset = ones(num_hide,1); 16 hide_out_offset = ones(10,1); 17 fun_hide=@sigmf; %%%a need to be modulate 18 fun_out=@sigmf; 19 learn_rate=0.3; 20 allow_error = 0.000001; 21 ideal_out_list = eye(10); 22 for input_n=1:length_input %show the progress once trained 2000 images 23 % ======Multilayer Feedforward Neural Network(MLFN)====== 24 input = inputs(input_n,:)'; 25 ideal_out = ideal_out_list(1:10,class(input_n)+1); 26 hide_input = weight_input_hide'*input+input_hide_offset; 27 hide_output = fun_hide(hide_input,[1 0]); 28 out_input = weight_hide_output'*hide_output+hide_out_offset; 29 out_out = fun_out(out_input,[1,0]); 30 out_err = 1/2*sum((ideal_out-out_out).^2); 31 % ======Back Propagation of Errot to modulate weight====== 32 out_delta=(ideal_out-out_out).*out_out.*(1-out_out); %%%the derived function need to be modulate 33 hide_out_offset =hide_out_offset + learn_rate*out_delta; 34 hide_delta = weight_hide_output*out_delta.*hide_output.*(1-hide_output); 35 weight_hide_output = weight_hide_output+learn_rate*hide_output*out_delta';%update weight_hide_output 36 weight_input_hide = weight_input_hide+learn_rate*input*hide_delta';%update weight_hide_output 37 input_hide_offset = input_hide_offset + learn_rate*hide_delta; 38 if out_err<=allow_error 39 break; 40 end 41 end 42 fprintf('The error is %d ,the iteration is %d\n',out_err,input_n); 43 save weight_input_hide weight_input_hide 44 save weight_hide_output weight_hide_output 45 % ======================== Part 3: Test The BPNN=========================== 46 inputs = load('test_hash.mat'); 47 inputs = inputs.hash_features/256; 48 class = load('mnist_test_labels.mat'); 49 class = class.mnist_test_labels; 50 [length_input,feture_length]=size(inputs); 51 correct = 0; 52 corrct_rate = zeros(1,length_input); 53 % ======Multilayer Feedforward Neural Network(MLFN)====== 54 for input_n=1:length_input 55 input = inputs(input_n,:)'; 56 ideal_out = class(input_n)+1; 57 hide_input = weight_input_hide'*input+input_hide_offset; 58 hide_output = fun_hide(hide_input,[1 0]); 59 out_input = weight_hide_output'*hide_output+hide_out_offset; 60 out_out = fun_out(out_input,[1,0]); 61 similar = sum((repmat(out_out,1,10)-ideal_out_list).^2); 62 output = find(similar == min(similar)); 63 if output == ideal_out 64 correct =correct +1; 65 end 66 corrct_rate(input_n) = correct/input_n; 67 end 68 hold on; 69 plot(corrct_rate,'y') 70 xlabel('test number'); 71 ylabel('corrct rate'); 72 fprintf('The recognition rate of test is %f%% \n',corrct_rate(input_n)*100);
