人工神經網路學習筆記3——利用感知器進行數字識別

很感激在之前的文章下,有小夥伴評論,建議我我對代碼和一些名詞做出更多的解釋,我認為呢,對概念和程序增強理解最好的方法就是實戰, 所以今天我們就從一個非常簡單的機器識別的小案例入手,我們的感知器。


一. 創建單層感知器

由於我們只是做演示,本來應該是對從0-9中所有的數字都要進行識別,但是現在只拿0和1做示例,同學們了解了ANN感知器模型是如何分類0與1的,自然也就明白了分類器是如何識別0-9這十個數字的。

眾所周知,感知器的功能絕不止是二分類,但是由於其傳遞函數的特殊性,感知器大多是用來當作線性分類器使用的。當它作為一種線性分類器使用的時候,感知器結構簡單,但是能夠學習並解決相當複雜的問題。本文中,我們就拿結構最簡單的單層感知器模型進行講解。

1.1 單層感知器MATLAB模擬設計流程

  1. 創建感知器

首先根據需要解決的問題,確定輸入向量的取值範圍和維數。其次,確定網路層神經元個個數、傳遞函數和學習函數等。最後,創建初始化後的感知器神經網路。

2. 訓練創建的樣本

建立訓練樣本集,確定每個樣本的輸入向量和目標向量,訓練已創建好的感知器神經網路,並根據訓練的情況決定是否調整訓練參數,一得到滿足誤差性能指標的感知器神經網路,並儲存訓練好的感知器神經網路參數。

3. 對訓練好的感知器進行模擬

建立測試樣本集,載入訓練後的網路,對測試樣本進行模擬,檢測訓練好的網路性能。

1.2 感知器工具箱的函數介紹

1. 感知器常用函數

函數類別 名稱 用途

創建函數 newp 創建一個感知器網路

顯示函數 plotpc 在感知器向量中繪製分界線

plotpv 繪製感知器的輸入向量和目標向量

性能函數 mae 平均絕對誤差函數

2. 感知器函數使用說明

感知器生成函數newp用於創建一個感知器網路,調用格式如下所示:

net=newp
net=newp(pr,s,tf,lf)
%其中,net表示生成的包含返回參數的感知器網路
%pr表示一個R*2的矩陣(R為輸入向量的個數),由輸入向量的最大值和最小值組成
%s表示神經元的個數
%tf表示感知器的傳遞函數,默認的函數為hardlim
%lf表示感知器的學習函數,默認的函數為learnp

分界線繪製函數plotpc用於繪製感知器向量圖中的分界線,調用格式如下所示:

plotpc(W,B) %返回的是繪製分界線的控制權
plotpc(W,B,H) %包含從前一次調用中返回的句柄。他在畫新分界線之前,刪除舊線。
%W表示一個S*R的加權矩陣(R不大於3)
%B表示一個S*1的閾值向量
%H表示最後一次繪製分界線的句柄

輸入/目標向量繪製函數plotpv用於繪製感知器的輸入向量和目標向量,調用格式如下:

plotpv(P,T) %以T為標尺,繪製P的列向量
plotpv(P,T,V) %在V的範圍內,以T為標尺,繪製P的列向量
%P表示2*n或者3*n的矩陣
%T表示一個樣本點的類別,是一個n維的向量
%V表示設置坐標值範圍的一個向量,這個向量由輸入向量的最大值和最小值組成

1.3 利用感知器完成邏輯分類

嘗試建立一個感知器模型,實現電路中「或」門的功能,從而實現對輸入的分類。

給出輸入和輸出的關係:

表1 「或」門的輸入/輸出關係

>> P=[0 1 1 1;0 1 0 1]; %輸入向量
>> T=[0 1 1 1]; %輸出向量
>> net=newp(minmax(P),1); %建立感知器
>> Y=sim(net,P) %模擬
>> net.trainParam.epochs=50; %設置最大訓練步數
>> net=train(net,P,T); %訓練
>> Y=sim(net,P)
>> perf=mae(Y-T)

代碼運行結果:

Y =
1 1 1 1
Y =
0 1 1 1
perf =
0

圖1 訓練過程的誤差曲線

從代碼運行結果中就可以很明顯的看出,第一次計算得到的輸出目標與目標變數不一致,2 次訓練之後感知器的輸出已經和目標向量一致了。從上圖中也可以很明顯的看出來,2 Epochs之後感知器已經停止運行,輸出向量與目標向量達到一致。

訓練後的網路成功實現了「或」的功能,利用性能函數mae計算網路的性能,結果為0,這說明了網路的性能非常好!

上例創建的感知器只有一個神經元,所以你可能覺得這個神經網路並沒有多少卵用,但實際上在設計ANN時,網路的結構越簡單,其計算負擔越輕,運行速度越快。不過為了滿足您心裡對感知器的期望,接下來我們來考慮如何用機器識別手寫體的數字圖樣。

二. 單層感知器的數字識別

設計一個單層輸出感知器神經網路,進行二值化圖像卡片上數字的識別(只以0與1兩種數字為例)。

圖2 數字圖像構成的向量示意圖

上圖給出了數字0和1的二值化圖像卡片,每一個圖像卡片可以分成5*3的矩形方框,如果有數字的筆畫划過的每個小方塊記為1,沒有數字的筆畫划過的小方塊記為0.那麼圖像卡片上所有的小方塊表達了有0和1二值組成的一個向量,該向量就是我們要創建的感知器神經網路的輸入向量。

表2 數字0,1構成的輸入向量

需要注意的是!相同的數字的形狀不同、位置不同、筆畫的粗細不同、不同的人書寫/製作,都會引起相應的輸入向量的輕微變化。

結合以上信息,我們應該設計出滿足如下要求的感知器神經網路:

  1. 感知器有1個輸入向量,包括15個元素,元素的取值範圍為[0, 1];
  2. 設計的感知器是單層、單神經元感知器神經網路;
  3. 輸入的是一個二值向量0或1,所以傳輸函數可以取S形傳遞函數logsig函數。

下面給出如何創建、訓練和儲存感知器神經網路的詳細代碼

>> pr=[0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;0 1;];
>> %設置輸入向量每個元素的最大值和最小值
>> %創建感知器神經網路
>> net=newp(pr,1);
>> %訓練感知器神經網路
>> P=[1 1 1 1 0 1 1 0 1 1 0 1 1 1 1;0 1 0 0 1 0 0 1 1 0 1 0 1 1 1];
>> T=[0 1]; %定義目標向量
>> [net,tr]=train(net,P,T); %訓練單層感知器神經網路
>> iw1=net.iw{1,1}; %輸出權值
>> b1=net.b{1}; %輸出閾值
>> epoch1=tr.epoch; %輸出訓練過程的每一步長
>> perf1=tr.perf; %輸出每一步訓練結果的誤差
>> save net1 net

建立的感知器神經網路的模擬程序如下:

>> load net1 net
>> ptest=[1 1 1 1 0 1 1 0 1 1 0 1 1 1 1;0 1 0 0 1 0 0 1 0 0 1 0 0 1 0];
>> %數字0與訓練樣本一致,數字1與訓練樣本差別較大
>> a=sim(net,ptest)

a =

0 1

由上面運行的結果可以看出,訓練後的感知器神經網路,對應正確和不正確的訓練樣本,都可以得到正確的分類結果,具有一定的容錯能力。當然,這個小小的簡單的例子僅僅是演示了如何用計算機區別0和1這個根本不需要工作量的工作,但是這個例子完全可以引申至「利用感知器神經網路識別手寫體數字0-9」,「利用感知器神經網路對手寫卡片的奇偶分類」,包括「構建多層感知器神經網路對數字圖片進行文本識別」等等。


由於這個專欄是跟隨我的學習和大創進度不斷更新的,因此一些有意思的但是暫時對我沒有幫助的點我可能不太會去接觸,所以這些有趣的想法我可以提出,觀眾姥爺們可以試著去實現,這裡給出數據集

MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges?

yann.lecun.com

感謝各類姥爺們的觀看!我有時候因為懶和悲觀不能及時更新,但是總是會有可愛的知友私信我,給我留言,APPRECIATE!我不會斷更的,順便搭個廣告,您的贊同就是我最大的更新動力!


推薦閱讀:

數組類型
CodyNote009:索引定址系列探討(Part.1)
MATLAB教學視頻:詳解Excel文件的讀取和寫入操作
基於模型的開發方法介紹
"文字與數字混合"的新方法: string的妙用

TAG:感知器 | 神經網路 | MATLAB |