路明玉
摘 ?要:數字識別技術的研究不僅可以解決當下面臨的數字識別問題,同時在圖像識別,機器學習等方面也有鋪墊作用。該文主要通過卷積神經網絡(CNN)方法實現手寫數字的識別。先設計網絡模型,再用MNIST數據集訓練,并測試網絡模型的識別準確率,接著對手寫數字進行圖像的預處理,輸入到模型中,驗證正確程度。
關鍵詞:數字識別 ?卷積神經網絡 ?數據集
中圖分類號:TP391.4 ? 文獻標識碼:A 文章編號:1672-3791(2019)07(a)-0031-02
1 ?課題意義
很多機器識別的辦公系統將產生,如:手寫字體的識別。這些對于信息的獲取有著很重要的作用,尤其在快遞分揀、銀行票據分析等方面最為突出。另外,圖像識別技術的研究為人工智能開啟了里程碑,在機器學習、機器人研究等方面起到了關鍵的作用。這方面的研究很有實用價值,重要性也是不言而喻的。
2 ?圖像預處理與數據集
圖像預處理是在不影響識別效率的前提下,對手寫數字原始圖像進行規范處理,減少無用的信息,降低計算量,提高識別率。在手寫數字界面已經設置了黑底的畫圖板和白色的畫筆,所以不需要再使用二值化處理。
2.1 圖像的灰度化
圖像灰度化的目的是降低圖像識別中的計算量,前提是灰度后的圖像沒有失去用于識別的重要信息。灰度化的本質是將一張原來看起來顏色多樣的圖像通過編程語言轉化為灰度化的圖像,其中灰度化的圖像只有一種顏色,但灰度化的過程中,可以事先設置一個值用于灰度化圖像,否則,每一張圖像進行灰度化處理都有255種選擇,每一種的灰度化程度是不一樣的。圖像的灰度化就是將3個分量設置同樣大小,不影響圖像主要特征的提取,方便數字的提取和圖像的識別。在設置灰度值過程中,有很多方法,最為常用的是利用取每個點3個分量的平均值,這樣灰度化的圖像,基本顯示了原來圖像的所有特征,識別過程更加高效。
2.2 MNIST數據集
MNIST數據集由訓練集和測試集組成。MNIST數據集的每一張圖片由28×28(pix)構成,每個圖像都經過了圖像的灰度化處理,一張完整的圖像是由幾千萬個像素點構成的,每一個像素點都有成千上萬種顏色。但是灰度化處理的圖像,每個像素點的取值只有255中,MNIST中的每一張圖像的每一個像素點都有一個灰度值。它包含了4個部分:訓練集樣本,訓練集標簽,測試集樣本,測試集標簽。
3 ?CNN網絡結構系統設計
3.1 界面設計
CNN識別顯示結果界面主要包括:左側為手寫后預處理的圖像,大小為28×28(pix)黑底白字,中間顯示該圖片被識別為0~9各個類別的概率,識別結果取各個類別的最大值,最后一行顯示識別結果。右側是統計圖表,用Matplotlib畫一個折線統計圖顯示每一個數字的概率,識別結果一目了然。
3.2 詳細設計
CNN主要是用卷積層構成的網格,卷積層跟全連接層相似,只是對之前的輸入做了卷積運算。
卷積之后要做的就是池化操作,因為卷積層每次作用在一個窗口,它對位置很敏感。池化層能夠很好地緩解這個問題。它跟卷積類似每次看一個小窗口,然后選出窗口里邊最大的元素,或者平均元素作為輸出。
卷積模塊通常是“卷積層-激活層-池化層”。然后輸出給后面的全連接層。其中激活函數一般作為卷積函數的參數使用,池化層是對卷積層的輸出按區域取最大值或者平均值,也是局部采樣過程。除此之外,還有一個Flatten層,它是卷積層和全連接層的過渡層,主要的作用是使多維輸入變為一維輸入。該課題采用了LeNet5架構。卷積神經網絡訓練和測試結構的關鍵部分如下:
前面數據的導入部分和MNIST是一樣的。
conv1 = mx.sym.Convolution(data=data, kernel=(5,5), num_filter=20)#第一層卷積操作,其中卷積核大小為(5,5),輸入數據來自數據集。
tanh1 = mx.sym.Activation(data=conv1, act_type="tanh")#激活函數
pool1 = mx.sym.Pooling(data=tanh1, pool_type="max", kernel=(2,2), stride=(2,2))#池化操作,消除卷積后的數組的空間敏感性。這里采用最大值池化。
conv2 = mx.sym.Convolution(data=pool1,kernel=(5,5), num_filter=50) )#第二層卷積操作,其中卷積核大小為(5,5),輸入數據來自數據集。
tanh2 = mx.sym.Activation(data=conv2, act_type="tanh")
pool2 = mx.sym.Pooling(data=tanh2, pool_type="max", kernel=(2,2), stride=(2,2)) #池化操作,消除卷積后的數組的空間敏感性。這里采用最大值池化。
flatten = mx.sym.flatten(data=pool2)#第一層全連接層
fc1 = mx.symbol.FullyConnected(data=flatten, num_hidden=500)
tanh3 = mx.sym.Activation(data=fc1, act_type="tanh")
fc2 = mx.sym.FullyConnected(data=tanh3, num_hidden=10)#第二層全連接層,神經元數量為10個
lenet = mx.sym.SoftmaxOutput(data=fc2, name='softmax')#交叉熵損失函數,進行參數更新
mlp_model.fit(train_iter, ?# 訓練數據
eval_data=val_iter, ?# 驗證數據
optimizer='sgd', ?# 運用SGD 訓練模型
optimizer_params={'learning_rate':0.1}, ?# 使用固定的學習效率
eval_metric='acc', ?# 訓練期間返回精確度
batch_end_callback = mx.callback.Speedometer(batch_size, 100), # 每次處理100張圖片
num_epoch=Epoch) ?# 進行10次全部數據處理
test_iter = mx.io.NDArrayIter(mnist['test_data'], None, batch_size)#測試數據
prob = mlp_model.predict(test_iter)
assert prob.shape == (10000, 10)#對圖像進行預測并分類
4 ?系統運行結果
在輸入界面寫一個數字8,看是否實現手寫功能,結果發現,書寫一個一筆可以完成的數字是可以的;接下來寫一個有斷筆的數字,可以看到書寫界面基本完成功能要求;再下來就是識別按鈕,功能是否可以?并且識別準確率如何?我們在界面輸入9,觀察結果,圖像屬于“9”這個類別的概率是99%,基本可以辨認手寫數字,功能基本實現。
參考文獻
[1] 張捷.手寫數字識別的研究與應用[D].西安建筑科技大學,2014.
[2] 曹毅.基于神經網絡的手寫體數字識別關鍵技術研究[D].西安工業大學,2014.