葉曉波,秦海菲,呂永林
(1.楚雄師范學院網(wǎng)絡與信息系統(tǒng)研究所,云南 楚雄 675000;2.楚雄師范學院信息科學與技術學院,云南 楚雄 675000;3.楚雄師范學院 經(jīng)濟與管理學院,云南 楚雄 675000)
模式識別是一門以應用為基礎的學科,目的是將對象進行分類[1]。任何可測量的對象都可進行分類,這些對象可以是圖像、音頻等;根據(jù)待分類數(shù)據(jù)是否全部都有已知類別標簽,模式識別可分為有監(jiān)督模式識別(分類標簽完整)、無監(jiān)督模式識別(無分類標簽)和半監(jiān)督模式識別(分類標簽不完整)[1]。
手寫數(shù)字識別研究的對象是如何利用計算機自動識別人手寫在紙張上的阿拉伯數(shù)字[2],也就是將手寫數(shù)字進行分類。雖然數(shù)字的類別只有十種,但由于數(shù)字字形相差不大,同一數(shù)字的寫法變化多樣,給手寫數(shù)字的準確識別帶來了諸多挑戰(zhàn)[3],本文提出基于LVQ神經(jīng)網(wǎng)絡的手寫數(shù)字識別方法,神經(jīng)網(wǎng)絡訓練和測試樣本數(shù)據(jù)來自MNIST,實驗證明,該方法能有效快速地對手寫數(shù)字進行識別。
模式識別的研究過程中經(jīng)常使用神經(jīng)網(wǎng)絡對數(shù)據(jù)進行分類,其中,單層感知器是能一致逼近線性連續(xù)函數(shù)空間最簡單的神經(jīng)網(wǎng)絡,但是它對非線性樣本空間不可分;BP神經(jīng)網(wǎng)絡應用最為廣泛,但BP神經(jīng)網(wǎng)絡的缺點在于采用了基于梯度下降的非線性迭代算法,在求解的過程中有可能陷入局部最小問題,從而不能保證求出全局最小值[4]。LVQ神經(jīng)網(wǎng)絡的優(yōu)點是不需要將輸入向量進行歸一化、正交化,只需要直接計算輸入向量與競爭層之間的距離,從而實現(xiàn)分類。
LVQ神經(jīng)網(wǎng)絡又稱為學習矢量量化神經(jīng)網(wǎng)絡(Learning Vector Quantization),它是在有教師狀態(tài)(分類標簽完整)下對競爭層進行訓練的一種學習算法,廣泛應用于模式識別和優(yōu)化領域[5]。LVQ神經(jīng)網(wǎng)絡屬于有監(jiān)督模式識別,其基本構架和其他神經(jīng)網(wǎng)絡基本相同,即LVQ神經(jīng)網(wǎng)絡也是由三層神經(jīng)元組成,即輸入層、隱含層和輸出層,LVQ神經(jīng)網(wǎng)絡結構如圖1所示。
圖1 LVQ神經(jīng)網(wǎng)絡結構圖[5]
LVQ神經(jīng)網(wǎng)絡算法步驟如下[5]:
1)網(wǎng)絡初始化:對輸入層、隱含層權值、學習率η(η>0)進行初始化。
2)輸入向量:將X=(x1,x2,x3, ……,xn)T送入到輸入層。
4)選擇獲勝神經(jīng)元:根據(jù)算法步驟3)計算結果選擇獲勝神經(jīng)元,即距離最小的神經(jīng)元作為獲勝神經(jīng)元。
5)更新連接權值:如果分類正確(獲勝神經(jīng)元和已知的分類一致),權值按△wij=wij+η(xi-wij)進行更新;如果分類錯誤,權值按△wij=wij-η(xi-wij)進行更新。
6)判斷是否迭代:如果計算結果達到指定訓練目標或迭代次數(shù)達到指定最大迭代次數(shù),訓練結束,否則返回算法步驟2),進入下一輪學習。
根據(jù)以上算法步驟,LVQ神經(jīng)網(wǎng)絡的算法模型如圖2所示:
圖2 LVQ神經(jīng)網(wǎng)絡算法模型圖
其中:
(1)
a1=compet(n1)
(2)
a2=purelin(LW2,1?1)
(3)
R是輸入向量,S1是競爭神經(jīng)元,S2是線性層(隱含層)神經(jīng)元。
本實驗軟件環(huán)境為:Windows Server 2008 R2(64位);硬件環(huán)境為:Intel(R) Xeon(R) CPU E5-2660 v2 @2.20GHz(8處理器),8G內(nèi)存;實驗程序設計均在Matlab 2016b下完成,以下是整個實驗過程。
本實驗采用MNIST手寫數(shù)字數(shù)據(jù)庫(http://yann.lecun.com/exdb/mnist/)。MNIST手寫數(shù)字數(shù)據(jù)庫共包含60000個訓練樣本數(shù)據(jù),10000個測試樣本數(shù)據(jù),每一個樣本數(shù)據(jù)(圖片)都是標準化的,即圖片大小相同,圖片上的手寫數(shù)字居中,MNIST手寫數(shù)字數(shù)據(jù)庫被研究者廣泛用作測試模式識別方法的基準,也被學生用于模式識別、機器學習和統(tǒng)計方面的課堂項目。
MNIST手寫數(shù)字數(shù)據(jù)庫包含4個數(shù)據(jù)文件,每一個文件的名稱及文件包含內(nèi)容如表1所示。
表1 MNIST手寫數(shù)字數(shù)據(jù)庫文件名及文件內(nèi)容
MNIST手寫數(shù)字數(shù)據(jù)庫的訓練樣本數(shù)據(jù)文件和測試樣本數(shù)據(jù)文件的數(shù)據(jù)結構完全相同,圖3是訓練樣本數(shù)據(jù)文件的數(shù)據(jù)結構圖。
圖3 訓練樣本數(shù)據(jù)文件的數(shù)據(jù)結構圖
分析訓練樣本數(shù)據(jù)文件的數(shù)據(jù)結構可知:文件的第二個32位整數(shù)指明文件所包含的手寫數(shù)字圖片數(shù)量(訓練樣本數(shù)據(jù)文件包含60000個樣本數(shù)據(jù),測試樣本數(shù)據(jù)文件包含10000個樣本數(shù)據(jù)),第三、四個32位整數(shù)指明了每一張手寫數(shù)字圖片的行和列的像素大小,即手寫數(shù)字圖片大小是28*28像素。
MNIST手寫數(shù)字數(shù)據(jù)庫的訓練樣本標簽數(shù)據(jù)文件和測試樣本標簽數(shù)據(jù)文件的數(shù)據(jù)結構完全相同,圖4是訓練樣本標簽數(shù)據(jù)文件的數(shù)據(jù)結構圖。
圖4 訓練樣本標簽數(shù)據(jù)文件的數(shù)據(jù)結構圖
分析訓練樣本標簽數(shù)據(jù)文件的數(shù)據(jù)結構可知:文件的第二個32位整數(shù)指明文件所包含的標簽數(shù)量(訓練樣本標簽數(shù)據(jù)文件包含60000個標簽,測試樣本標簽數(shù)據(jù)文件包含10000個標簽),標簽數(shù)據(jù)的值是0―9之間的數(shù)字,與樣本數(shù)據(jù)文件中的圖片一一對應,即樣本數(shù)據(jù)文件中的第一幅圖片(手寫數(shù)字)對應的正確數(shù)字是標簽數(shù)據(jù)文件中的第一個標簽值。
圖5是部分訓練樣本數(shù)據(jù)中的手寫數(shù)字圖片。
圖5 部分訓練樣本數(shù)據(jù)中的手寫數(shù)字圖片
3.2.1實驗數(shù)據(jù)讀取方法
根據(jù)MNIST手寫數(shù)字數(shù)據(jù)庫文件的數(shù)據(jù)結構,在Matlab中使用fopen函數(shù)打開數(shù)據(jù)庫文件,使用fread函數(shù)讀取數(shù)據(jù)。以下語句是打開并讀取MNIST手寫數(shù)字數(shù)據(jù)庫訓練樣本數(shù)據(jù)文件的代碼:
f_train_img = fopen('database rain-images.idx3-ubyte','r','b');
magic_num = fread(f_train_img,1,'int32'); %Magic num,32位整數(shù)
train_img_num = fread(f_train_img,1,'int32'); %圖片數(shù)量,32位整數(shù)
row_size = fread(f_train_img,1,'int32'); %圖片的行像素值,32位整數(shù)
col_size = fread(f_train_img,1,'int32'); %圖片的列像素值,32位整數(shù)
train_img=zeros(784,train_img_num); %初始化訓練樣本矩陣,
圖片大小:row_size* col_size=784
for i=1: train_img_num %循環(huán)讀取訓練樣本數(shù)據(jù)文件中手寫數(shù)字圖片數(shù)據(jù)
train_img(:,i)=uint8(fread(f_train_img,784,'uchar'));
end
與訓練樣本數(shù)據(jù)相對應的是訓練樣本標簽數(shù)據(jù),標簽(類別)共有十類,分別從0―9,但LVQ神經(jīng)網(wǎng)絡確認獲勝神經(jīng)元是提取每一列中值為1的行號,而行號最小的是1,因此,在讀取樣本數(shù)據(jù)標簽時應該把類別標簽由0―9依次更改為1―10,也就是把類別標簽全部都加1。以下語句是讀取MNIST手寫數(shù)字數(shù)據(jù)庫訓練樣本標簽數(shù)據(jù)的代碼:
for i=1:train_index_num %循環(huán)讀取訓練樣本數(shù)據(jù)對應的真實數(shù)字值
train_index(:,i)=uint8(fread(f_train_index,1,'uchar'))+1;
end
3.2.2 PCA降維
MNIST手寫數(shù)字數(shù)據(jù)庫共有訓練用的手寫數(shù)字圖片60000幅,測試用的手寫數(shù)字圖片10000幅,每一幅圖片大小都是28*28=784像素,用于神經(jīng)網(wǎng)絡訓練的樣本矩陣大小是784*600000,用于測試的樣本矩陣大小是784*10000;這樣大小的矩陣在神經(jīng)網(wǎng)絡的訓練、測試過程中會增加運算的復雜度和運行時間,在這種情況下,一般需要進行數(shù)據(jù)降維處理。
所謂數(shù)據(jù)降維是指通過線性或非線性映射將樣本從高維空間映射到低維空間,從而獲得高維數(shù)據(jù)的一個有意義的低維表示的過程[6]。降維后的數(shù)據(jù)容易處理、更容易使用,還可去除數(shù)據(jù)噪聲,進而降低算法開銷。常見的降維算法有主成分分析(也稱PCA降維,principal component analysis)、因子分析(Factor Analysis)和獨立成分分析ICA(Independent Component Analysis),其中PCA降維是目前應用最為廣泛的降維方法。
PCA降維是通過對原始變量的相關矩陣或協(xié)方差矩陣內(nèi)部結構的研究,將多個變量轉(zhuǎn)換為少數(shù)幾個綜合變量(即主成分),從而達到降維目的的一種線性降維方法[6]。這些主成分能夠反映原始變量的絕大部分信息,它們通常表示為原始變量的線性組合,通過PCA降維可實現(xiàn)用較少的數(shù)據(jù)維度代替較多的原數(shù)據(jù)點。在本實驗中使用Matlab提供的pca函數(shù)對訓練樣本數(shù)據(jù)進行降維,測試樣本數(shù)據(jù)使用訓練樣本的降維矩陣進行降維處理;用pca函數(shù)生成的降維數(shù)據(jù)中,根據(jù)特征值的累積貢獻率不同可生成不同的降維矩陣,累積貢獻率是指降維后能保持原有數(shù)據(jù)的真實率,因此,貢獻率越大(越接近100%),則降維后的數(shù)據(jù)越能更真實的反映原始數(shù)據(jù),但貢獻率越大,則數(shù)據(jù)維度減少的就越少,從而帶來降維效果不明顯的問題;貢獻率越小,則數(shù)據(jù)維度減少的就越多,降維效果非常明顯,但降維后的數(shù)據(jù)與原始數(shù)據(jù)偏離會明顯加大。
本實驗依次選擇PCA降維貢獻率大于等于0.95、0.96、0.97、0.98所對應的降維矩陣對訓練樣本和測試樣本數(shù)據(jù)進行降維處理。
3.2.3 LVQ神經(jīng)網(wǎng)絡參數(shù)的選擇
Matlab使用lvqnet 函數(shù)創(chuàng)建LVQ神經(jīng)網(wǎng)絡,語法:net = lvqnet(S1,LR,LF),參數(shù)S1是指隱含層神經(jīng)元數(shù)量,參數(shù)LR是指神經(jīng)網(wǎng)絡學習速率,默認值是0.01,參數(shù)LF是指神經(jīng)網(wǎng)絡學習函數(shù),默認學習函數(shù)是learnlv1。
(1)隱含層單元數(shù)的確定
在神經(jīng)網(wǎng)絡應用過程中,神經(jīng)元數(shù)目太少,神經(jīng)網(wǎng)絡權值無法獲取更多有用的信息,從而無法實現(xiàn)較高的分類正確率;若神經(jīng)元數(shù)目太多,則會增加訓練時間,且分類正確率未必會隨神經(jīng)元數(shù)目的增加而增加,因此合理選擇神經(jīng)元數(shù)目非常重要。
對于神經(jīng)網(wǎng)絡訓練過程中神經(jīng)元數(shù)目的選擇,許多研究人員進行了廣泛研究,提出了多種確定神經(jīng)元數(shù)目的參考公式,根據(jù)Kolmogorov[7]定理可知,針對只有3層神經(jīng)元的人工神經(jīng)網(wǎng)絡,給出了輸入層神經(jīng)元數(shù)目Nin與隱層神經(jīng)元數(shù)目Nhid之間的等量關系[8]:
Nhid=2Nin+1
(4)
其中Nin為輸入單元數(shù),Nhid為隱含層單元數(shù)。本實驗選擇不同的PCA降維貢獻率,將得到不同的輸入單元數(shù),因此,具體的隱含層神經(jīng)元數(shù)目要根據(jù)PCA降維結果進行計算確定。
(2)學習速率的確定
在神經(jīng)網(wǎng)絡學習過程中,較大的學習速率可讓神經(jīng)網(wǎng)絡學習快速接近訓練目標,但隨后會造成神經(jīng)網(wǎng)絡學習在訓練目標附近振蕩而不會收斂;較小的學習速率會帶來神經(jīng)網(wǎng)絡學習速度慢的問題;在本實驗中,考慮到學習數(shù)據(jù)龐大,不宜選擇較小的學習速率,經(jīng)過反復研究,本實驗選擇0.05作為學習速率。
(3)學習函數(shù)的確定
神經(jīng)網(wǎng)絡可選擇不同的函數(shù)來逼近最優(yōu)解,LVQ神經(jīng)網(wǎng)絡提供了兩個學習函數(shù),分別是learnlv1和learnlv2,如果在初始化神經(jīng)網(wǎng)絡時不指定學習函數(shù),則默認使用learnlv1作為學習函數(shù),本實驗選擇learnlv1作為LVQ神經(jīng)網(wǎng)絡學習函數(shù)。
3.2.4實驗程序設計
本實驗程序設計步驟描述如下:
%=====讀取訓練樣本數(shù)據(jù)=====%
1)f_train_img = fopen('database rain-images.idx3-ubyte','r','b'); %打開訓練樣本數(shù)據(jù)集文件
2)讀取圖片數(shù)量(train_img_num)等數(shù)據(jù),初始化訓練樣本矩陣train_img
3)for i=1: train_img_num %循環(huán)讀取訓練樣本數(shù)據(jù)文件中手寫數(shù)字圖片數(shù)據(jù)
4)train_img (:,i)=uint8(fread(f_train_img,784,'uchar'));
5)End
%=====根據(jù)訓練樣本數(shù)據(jù)生成降維矩陣=====%
6)[pc,score,latent,tsquare] = pca(train_img); %獲取PCA降維數(shù)據(jù)
7)根據(jù)PCA函數(shù)運行結果,計算累計貢獻率,選擇貢獻率大于等于95%、96%、97%、98%、99%的特征值對應的特征向量,生成降維矩陣pca_matrix
8)用降維矩陣為訓練樣本數(shù)據(jù)進行降維處理,得到降維結果after_pca_train
%=====讀取訓練樣本數(shù)據(jù)標簽值=====%
9)f_train_index=fopen('database rain-labels.idx1-ubyte','r','b'); %打開訓練樣本標簽數(shù)據(jù)文件
10)讀取標簽數(shù)量(train_index_num)等數(shù)據(jù),初始化訓練樣本標簽矩陣train_index
11)for i=1: train_index_num %循環(huán)讀取訓練樣本數(shù)據(jù)對應的真實數(shù)字值
12)train_index(1,i)=uint8(fread(f_train_index,1,'uchar'))+1;
13)end
%=====讀取測試樣本數(shù)據(jù)=====%
14)f_test_img=fopen('database 10k-images.idx3-ubyte','r','b'); %打開測試樣本數(shù)據(jù)集文件
15)讀取圖片數(shù)量(test_img_num)等數(shù)據(jù),初始化測試樣本矩陣test_img
16)for i=1: test_img_num %循環(huán)讀取測試樣本文件中的相應數(shù)據(jù)
17)test_img(1,i)=uint8(fread(f_test_img,784,'uchar'));
18)end
19)用降維矩陣為測試樣本數(shù)據(jù)進行降維處理,得到降維結果after_pca_test
%=====讀取測試樣本數(shù)據(jù)標簽值=====%
20)f_test_index=fopen('database 10k-labels.idx1-ubyte','r','b'); %打開測試樣本標簽數(shù)據(jù)文件
21)讀取標簽數(shù)量(test_index_num)等數(shù)據(jù),初始化測試樣本標簽矩陣test_index
22)for i=1: test_index_num %循環(huán)讀取測試樣本數(shù)據(jù)對應的真實數(shù)字值
23)test_index(:,i)=uint8(fread(f_test_index,1,'uchar'))+1;
24)end
25)T=ind2vec(train_index);
%=====創(chuàng)建、初始化、訓練網(wǎng)絡=====%
26)net=lvqnet(隱含層神經(jīng)元數(shù)量,0.05); %創(chuàng)建LVQ神經(jīng)網(wǎng)絡
27)net=init(net); %初始化LVQ神經(jīng)網(wǎng)絡
28)net.trainparam.epochs=50; % 指定最大訓練次數(shù)
29)net.trainParam.goal=0.01; % 指定訓練目標最小誤差
30)net=train(net,after_pca_train,T);%訓練網(wǎng)絡
%=====網(wǎng)絡仿真結果=====%
31)train_result =vec2ind(net(after_pca_train'));%用訓練數(shù)據(jù)進行仿真
32)sum(train_result==train_index)/train_index_num %計算訓練樣本數(shù)據(jù)的分類正確率
33)test_result=vec2ind(net(after_pca_test')); %用測試樣本數(shù)據(jù)仿真
34)sum(test_result==test_index)/test_index_num %計算測試樣本數(shù)據(jù)的分類正確率
3.2.5 實驗結果及分析
圖6是LVQ神經(jīng)網(wǎng)絡訓練圖,參數(shù)指定為:PCA降維累積貢獻率>=0.95,神經(jīng)網(wǎng)絡輸入單元數(shù)154,隱含層神經(jīng)元數(shù)量309,迭代次數(shù):50。
圖6 LVQ神經(jīng)網(wǎng)絡訓練圖
表2 是按PCA降維累積貢獻率不同而進行的實驗結果統(tǒng)計表:
表2 基于LVQ神經(jīng)網(wǎng)絡的手寫數(shù)字識別實驗結果
其中:LVQ神經(jīng)網(wǎng)絡隱含層神經(jīng)元數(shù)量根據(jù)公式(4)計算得出,神經(jīng)網(wǎng)絡學習速率:0.05,迭代次數(shù):50。
圖7是PCA降維累積貢獻率>=0.95時訓練的均方誤差圖:
圖7 神經(jīng)網(wǎng)絡訓練結果的均方誤差圖
分析實驗結果可得:(1)LVQ神經(jīng)網(wǎng)絡對MNIST手寫數(shù)字數(shù)據(jù)庫的識別率在指定相應參數(shù)時(見表2),識別準確率大于93%,是一個較理想的識別效果。(2)隨著指定的PCA降維累積貢獻率的提高,輸入單元數(shù)也大幅度增多,但訓練樣本與測試樣本數(shù)據(jù)的識別率并未因輸入單元數(shù)的增加而明顯提高。(3)LVQ神經(jīng)網(wǎng)絡的訓練時間隨輸入單元數(shù)的增加而大幅提高。
通過實驗結果還可得出PCA降維累積貢獻率選擇的方法:在進行神經(jīng)網(wǎng)絡訓練時,如果原始數(shù)據(jù)維度較高,應該進行PCA降維處理,選擇一個合適的PCA降維累積貢獻率非常重要,本實驗選擇累積貢獻率為0.95時效果較好,不但學習訓練速度快,而且可取得滿意的分類結果。
手寫數(shù)字識別不但在實際生活中有著廣泛的應用,也是模式識別重點研究的領域之一,目前研究人員運用多種識別方法對手寫數(shù)字識別開展了廣泛的實驗研究,本文提出基于LVQ神經(jīng)網(wǎng)絡手寫數(shù)字識別的方法,采用最廣泛的手寫數(shù)字識別數(shù)據(jù)庫MNIST進行了實驗研究,實驗結果對手寫數(shù)字識別方面的研究有較好的參考價值。