1. 程式人生 > 其它 >使用Keras建立一個卷積神經網路模型,可對手寫數字進行識別

使用Keras建立一個卷積神經網路模型,可對手寫數字進行識別

在過去的幾年裡,影象識別研究已經達到了驚人的精確度。不可否認的是,深度學習在這個領域擊敗了傳統的計算機視覺技術。

神經網路應用於MNIST的資料集以識別手寫的數字這種方法將所有的影象畫素傳輸到完全連線的神經網路。該方法在測試集上的準確率為98.01%。這個成功率雖然看上去不錯,但不是完美的。

應用卷積神經網路可以產生更成功的結果。與傳統的方法相比,重點部分的影象畫素將被傳輸到完全連線的神經網路,而不是所有的影象畫素。一些濾鏡應該被應用到圖片中去檢測重點部分的畫素。

Keras是一個使用通用深度學習框架的API,並且可以更容易地構建深度學習模型。它還減少了程式碼的複雜性。我們可以編寫更短的程式碼來在Keras中實現同樣的目的。同樣,相同的Keras程式碼可以在不同的平臺上執行,比如TensorFlow或Theano。你所需要的只是更改配置,以切換深度學習框架。在本文中,我們將使用Keras來建立一個卷積神經網路模型。

首先,我們將匯入所需的Keras庫:

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.preprocessing.image import ImageDataGenerator

其次,我們將載入mnist資料集。這個資料集已經作為訓練集和測試集被分離了。訓練集和資料集包括功能部件和標籤。

(x_train, y_train), (x_test, y_test) = mnist.load_data()

第三,Keras要求我們在3D矩陣上進行輸入特徵的工作。因此,我們將把訓練集和測試集的特徵轉換為3D矩陣。輸入特徵是大小為28×28的二維矩陣。這些矩陣保持不變,我們只新增一個虛擬維度,矩陣就會被轉換成28x28x1。此外,輸入特徵必須在0到1之間。這就是為什麼,特徵會被劃分為255,從而標準化[0, 1]。

x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
 
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
 
x_train /= 255 #inputs have to be between [0, 1]
x_test /= 255

資料集標籤在0到9的範圍內。Keras讓我們在二進位制類標籤上工作。下面的塊將把標籤轉換成二進位制格式。(例如,標籤2將被表示為0010000000)

y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

這不是必須的,但我們會在結構上保持“忠誠”。卷積和合並操作將被應用兩次。在那之後,學習的功能將被轉移到一個由一個隱藏層組成的完全連線的神經網路。你可以更改網路的結構,並監視對準確性的影響。

捲進神經網路流程

現在,我們將構建卷積神經網路的結構。

model = Sequential()
 
#1st convolution layer
model.add(Conv2D(32, (3, 3) #apply 32 filters size of (3, 3)
 , input_shape=(28,28,1)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
 
#2nd convolution layer
model.add(Conv2D(64,(3, 3))) #apply 64 filters size of (3x3)
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
 
model.add(Flatten())
 
# Fully connected layer. 1 hidden layer consisting of 512 nodes
model.add(Dense(512))
model.add(Activation('relu'))
 
#10 outputs
model.add(Dense(10, activation='softmax'))

你可能會注意到,完全連線的神經網路的輸出層連線到卷積神經網路的輸出層,而非線性函式。這個函式應該是softmax函式。這樣,輸出值在[0, 1]之間標準化。而且,輸出的和總是等於1。最後,最大索引將觸發結果。

標準資料集由60000個例項組成。在個人計算機上很難處理好所有的例項。這就是為什麼,我更喜歡用隨機選擇的方法來訓練網路。如果你有時間或很好的的硬體,你也許會跳過這一步,並且希望在所有例項上工作。

gen = ImageDataGenerator()
train_generator = gen.flow(x_train, y_train, batch_size=batch_size)

現在,是時候訓練網路了。

model.compile(loss='categorical_crossentropy'
 , optimizer=keras.optimizers.Adam()
 , metrics=['accuracy']
)
 
model.fit_generator(train_generator
 , steps_per_epoch=batch_size
 , epochs=epochs,
 validation_data=(x_test, y_test))

一旦網路被訓練,我們就可以懷疑成功標準。

score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', 100*score[1])

經典的完全連通的神經網路獲得了98.01%的準確率,而卷積神經網路的準確率則超過了99%。這是一個令人難以置信的結果。所有這些測試都是在一個Core i7 CPU上執行的。此外,增加批量大小和epoch會提高準確率。

最後得分

最後,我建立了具有以下配置的模型:

batch_size = 250
epochs = 10

因此,影象識別研究將會被卷積神經網路進一步發展。

本文所用的程式碼:https://github.com/serengil/tensorflow-101/blob/master/python/HandwrittenDigitRecognitionUsingCNNWithKeras.py