當前位置:
首頁 > 最新 > 構建多層感知器神經網路對數字圖片進行文本識別

構建多層感知器神經網路對數字圖片進行文本識別

來源:JackieFang

在Keras環境下構建多層感知器模型,對數字圖像進行精確識別。

模型不消耗大量計算資源,使用了cpu版本的keras,以Tensorflow 作為backended,在ipython交互環境jupyter notebook中進行編寫。

1.數據來源

在Yann LeCun的博客頁面上下載開源的mnist資料庫:

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

此資料庫包含四部分:訓練數據集、訓練數據集標籤、測試數據集、測試數據集標籤。由於訓練模型為有監督類型的判別模型,因此標籤必不可少。若使用該數據集做k-means聚類,則不需要使用標籤。將數據整合之後放入user.kerasdatasets文件夾以供調用。

也可以直接從keras建議的url直接下載:https://s3.amazonaws.com/img-datasets/mnist.npz

其中訓練數據集包含了60000張手寫數字的圖片和這些圖片分別對應的標籤;測試數據集包含了10000張手寫數字的圖片和這些圖片分別對應的標籤.

2.數據格式和前期處理(在此不涉及)

訓練數據集包含60000張圖片,測試數據集包含10000張,所有圖片都被當量化為28pixel*28pixel的大小。為減少向量長度,將圖片灰度處理,每個像素用一個RGB值表示(0~255),這是因為灰度處理後的RGB值加了歸一約束,向量長度相是灰度處理前的1/3。至此,每個圖片都可以用28*28的向量表示。

3.導入依賴庫

打開jupyter notebook後導入依賴庫numpy,此處的seed為隨機量的標籤,可隨意設置:

from__future__importprint_function

importnumpyasnp

繼續從keras中導入使用到的模塊:

fromkeras.datasetsimportmnist

fromkeras.modelsimportSequential

fromkeras.optimizersimportSGD,Adam,RMSprop

fromkeras.utilsimportnp_utils

mnist為之前準備的數據集,Dense為全連接神經元層,Dropout為神經元輸入的斷接率,Activation為神經元層的激勵函數設置。

導入繪圖工具,以便之後繪製模型簡化圖:

4.處理導入的數據集

處理數據集

為了符合神經網路對輸入數據的要求,原本為60000*28*28shape的三維ndarray,改變成了尺寸為60000*784的2維數組,每行為一個example,每一列為一個feature。

神經網路用到大量線性與求導運算,將輸入的feature的數值類型改變為32位float。

將feature值歸一化,原本0~255的feature歸一為0~1。

測試數據集同理。

(X_train,y_train),(X_test,y_test)=mnist.load_data()

X_train=X_train.reshape(60000,28*28)

X_test=X_test.reshape(10000,28*28)

X_train=X_train.astype( float32 )

X_test=X_test.astype( float32 )

X_train/=255

X_test/=255

處理標籤

文本識別問題本質是一個多元分類問題。將類向量轉換為二進位數表示的類矩陣,其中每一行都是每一個example對應一個label。label為10維向量,每一位代表了此label對應的example屬於特定類(0~10)的概率。此時Y_train為60000*10的向量,Y_test為10000*10的向量

Y_train=np_utils.to_categorical(y_train,nb_classes)

Y_test=np_utils.to_categorical(y_test,nb_classes)

5.用keras建立神經網路模型

batch_size=128

nb_classes=10

nb_epoch=20

model=Sequential()

model.add(Dense(500,input_shape=(28*28,)))

model.add(Activation( relu ))

model.add(Dropout(0.2))

model.add(Dense(500))

model.add(Activation( relu ))

model.add(Dropout(0.2))

model.add(Dense(500))

model.add(Activation( relu ))

model.add(Dropout(0.2))

model.add(Dense(10))

model.add(Activation( softmax ))

每次iter時,每一批次梯度下降運算所包含的example數量為128;

softmax輸出值為10維向量;

一共迭代20次iteration。

三層的神經網路,其中輸入層為28*28=784維的全連接層。

Hidden Layer有3層,每一層有500個神經元,input layer->hidden layer->output layer都是全連接方式(DENSE)。

hidden layer的激活函數採用ReLu函數,表達式:

如下圖所示:

相比與傳統的sigmoid函數,ReLU更容易學習優化。因為其分段線性性質,導致其前傳、後傳、求導都是分段線性。而傳統的sigmoid函數,由於兩端飽和,在傳播過程中容易丟棄信息。且Relu在x

文本識別本質是多元分類(此處為10元分類),因此輸出層採用softmax函數進行feature處理,如下圖所示:

其中第j個輸出層神經元輸出值與當層輸入feature的關係為:

該神經網路示意圖如圖所示:

調用summary方法做一個總覽:

model.summary()

結果如下:

該神經網路一共有898510個參數,即在後向反饋過程中,每一次用梯度下降都要求898510次導數。

用plot函數列印model:

plot(model, to_file= mlp_model.png ,show_shapes=True)

如下圖所示:

編譯模型,使用cross_entropy交叉熵函數作為loss function,公式如下圖所示:

用交叉熵可量化輸出向量與標籤向量的差異,p與q分別為輸出向量與標籤向量。對於每一個example,其交叉熵值就是要通過迭代盡量往小優化的值。優過程使用梯度演算法,計算過程中使用反向傳播演算法求導。

交叉熵的作用如下圖所示:

在此分類神經網路中,使用判別結果的accuracy作為參數值好壞的度量標準。

6.用數據訓練和測試網路

history=model.fit(X_train,Y_train,

batch_size=batch_size,nb_epoch=nb_epoch,

verbose=1,validation_data=(X_test,Y_test))

在這個地方運行碰到warning,原因是最新版的keras使用的iteration參數名改成了epoch,而非之前沿用的nb_epoch。將上面的代碼作修改即可。

訓練結果如下所示。第一次迭代,通過對60000/128個的batch訓練,已經達到了比較好的結果,accuracy已經高達0.957。之後Loss值繼續下降,精確度繼續上升。從第9個itearation開始,loss函數值(交叉熵cross_entropy)開始震蕩在0.05附近,accuracy保持在0.98以上。說明前9次迭代就已經訓練了足夠好的θ值和bias,不需要後11次訓練。

7.評估模型

用score函數列印模型評估結果:

score=model.evaluate(X_test,Y_test,verbose=)

print( Test score: ,score[])

print( Test accuracy: ,score[1])

輸出結果如下圖所示:

訓練的multi-layer_perceptron神經網路在對數字文本識別時具有98.12%的準確率。

手寫數字圖片資料庫和Iris_Flower_dataset一樣,算是dl界的基本素材,可以拿來做很多事情,比如k-means聚類,LSTM(長短記憶網路)。

看完本文有收穫?請轉發分享給更多人

關注「大數據與機器學習文摘」,成為Top 1%


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python開發者 的精彩文章:

Gevent 調度流程解析
為什麼你應該學 Python ?
入門 Python 要多久?
遺傳演算法中適值函數的標定與大變異演算法
用 Scikit-Learn 和 Pandas 學習線性回歸

TAG:Python開發者 |