1. 程式人生 > >【MATLAB】BP神經網路識別MNIST手寫數字

【MATLAB】BP神經網路識別MNIST手寫數字

一.Summary

本文運用BP神經網路對MNIST手寫數字字元進行識別。

BP神經網路是通過樣本以及期望輸出不斷調整權值以達到訓練的目的的演算法。本文采用三層BP神經網路對MNIST字元進行訓練,然後對提供的資料進行測試。

二.Content

1. 分析BP神經網路的基本原理:通過輸入向量與權向量加權求和,得到一個下層神經元的輸入,再加上偏置,經過啟用函式計算,作下層神經元的輸出。

2. 該文采用經典的三層神經網路為例,反向傳播的過程如下:

先求出,

其中J(w)為訓練誤差,t為輸出端的期望輸出值,z為實際輸出值。

w表示網路裡所有的權值,根據J(w)調整w的大小:

繼續的推導需要基於鏈式法則,具體過程可參考

<模式分類>P237 6.3.1.最終得到隱含層到輸出曾的權值更新規則:

輸入層到隱含層權值的權值更新規則是:

具體符號含義都包含在<模式分類>中。

3. 具體訓練過程如下:

①首先產生隨機的權值w1,w2,生成偏置,初始化所用變數,設定神經網路層數及單元.

②進行前向傳遞演算法,獲得實際輸出值z,選取啟用函式為

③進行反向傳播演算法(BP),對權值w1,w2偏置值進行調整。

④迭代‘②③’過程以提高訓練的準確率。

4. 測試並收集結果.

將測試集運用前向傳遞演算法算出預測值,與實際期望預測值進行對比.

由於神經網路訓練過程中隨機生成權值,每次訓練的結果具有隨機性,因此重複文收集結果.

設定三層神經元,隱含層包含

10個神經元,進行十次迭代,測試的準確率如下:

訓練序號

準確率

1

0.9012

2

0.9000

3

0.8930

4

0.8860

5

0.8734

取平均值結果為:89.07%

5. 修改神經網路神經元數量和層數,對結果進行對比分析.

修改隱藏層神經元為20個,其他保持不變,測得平均準確率為:

91.70%

三.Conclusion

本文通過BP神經網路對MNIST手寫數字字元庫進行訓練和識別,當三層神經網路迭代十次,隱含層包含10個神經元就可以達到89.07%的準確率,當隱含層包含20個神經元時,可以達到91.70%的識別準確率(對於10000條測試用例),可以發現在層數不變提高了BP神經網路2.95%的準確率。

附錄:

MNIST字元庫官方網站:

http://yann.lecun.com/exdb/mnist/

讀取MNIST MATLAB程式碼引用(一位前輩的部落格):

https://blog.csdn.net/fuwenyan/article/details/53954615

讀取檔案程式碼:

train_ima = loadMNISTImages(url);
train_lab = loadMNISTLabels(url);
test_ima = loadMNISTImages(url);
test_lab = loadMNISTLabels(url);
%讀取四個檔案

訓練程式碼:

%三層神經網路
sam_sum = 60000;
input = 784;
output = 10;
hid = 20;
w1 = randn([input,hid]);
baocun = w1;
w2 = randn([hid,output]);
bias1 = zeros(hid,1);
bias2 = zeros(output,1);
rate1 = 0.05;
rate2 = 0.05;                %設定學習率

%用作三層神經網路的暫時儲存變數
temp1 = zeros(hid,1);
net = temp1;
temp2 = zeros(output,1);
z = temp2;

%sigmoid函式 f = 1/(e^-x + 1)   求導為 f' = f*(1-f)
for num = 1:10                        %迭代十次
for i = 1:sam_sum
    label = zeros(10,1);
    label(train_lab(i)+1,1) = 1;

    %forward
    %此處選用784*1的train_ima矩陣,因此需要加(:,1)
    temp1 = train_ima(:,i)'*w1 + bias1';
    net = sigmoid(temp1);
    %此處選用9*1的隱藏層矩陣
    temp2 = net'*w2 + bias2';
    z = sigmoid(temp2);

    %backward
    error = label - z;
    deltaZ = error.*z.*(1-z);
    deltaNet = net.*(1-net).*(w2*deltaZ);
    for j = 1:output
        w2(:,j) = w2(:,j) + rate2*deltaZ(j).*net;
    end
    for j = 1:hid
        w1(:,j) = w1(:,j) + rate1*deltaNet(j).*train_ima(:,i);
    end
    bias2 = bias2 + rate2*deltaZ;
    bias1 = bias1 + rate1*deltaNet;
   

end
end

測試程式碼:

test_sum = 10000;
count = 0;
for i = 1:test_sum
    temp1 = test_ima(:,i)'*w1 + bias1';
    net = sigmoid(temp1);
    %此處選用9*1的隱藏層矩陣
    temp2 = net'*w2 + bias2';
    z = sigmoid(temp2);
    
    [maxn,inx] = max(z);
    inx = inx -1;
    if inx == test_lab(i)
        count = count+1;
    end
end
correctRate = count/test_sum