用“Keras”11行代碼構建CNN
更多深度文章,請關注:https://yq.aliyun.com/cloud
我曾經演示過如何使用TensorFlow創建卷積神經網絡(CNN)來對MNIST手寫數字數據集進行分類。TensorFlow是一款精湛的工具,具有強大的功能和靈活性。然而,對於快速原型製作工作,可能顯得有些麻煩。Keras是一個運行在TensorFlow或者Theano的更高級別的庫,旨在流線化構建深度學習網絡的過程。事實上,在上一篇TensorFlow教程中 ,TensorFlow大約需要42行完成的內容,在Keras中隻需11行就可以完成類似的功能。接下來我將向你展示如何通過Keras做到這一點。
該Keras教程將向你展示如何使用MNIST數據集構建CNN並實現> 99%的準確性。它與我之前的卷積神經網絡教程中構建的結構完全相同 ,下圖顯示了網絡的架構:
這個Keras教程的完整代碼可以在這裏找到。
Keras教程中的主要代碼講解:
下麵的代碼是在此Keras教程中使用的CNN結構的“膽量”
model = Sequential()
model.add(Conv2D(32, kernel_size=(5, 5), strides=(1, 1),
activation='relu',
input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(64, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(1000, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
接下來我們一步一步的來解釋:
Model = Sequential()
Keras中的模型可以有兩種——序貫和通過API函數。對於構建的大多數深度學習網絡,序貫模型是最常用的。它允許你從輸入到輸出整個過程都能輕鬆地堆疊網絡層(甚至循環層)。而API函數可以幫助你構建更複雜的網絡體係結構,本教程將不介紹它。
第一行將模型類型聲明為Sequential()。
model.add(Conv2D(32, kernel_size=(5, 5), strides=(1, 1),
activation='relu',
input_shape=input_shape))
接下來,我們添加一個2D卷積層來處理2D MNIST輸入的圖像。傳遞給Conv2D() 函數的第一個參數是輸出通道的數量。這裏我們設置為我們有32個輸出通道,下一個輸入是kernel_size,我們選擇了一個5×5移動窗口,其次是x和y方向(1,1)的步態。接著,激活函數是整流線性單元,最後我們必須與輸入層的大小提供模型。
還要注意,我們不必聲明任何權重或偏差變量,Keras會幫助我們進行完成。
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
接下來我們添加一個2D max pooling層。層的定義很簡單。在這種情況下,我們隻是簡單地指定在x和y方向上的池的大小 和(2,2)的步。
model.add(Conv2D(64, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
接下來,我們添加另一個卷積層+最大池化層,具有64個輸出通道。在Keras中Conv2D()函數的參數默認的步伐是(1,1),在Keras 中默認步伐是使它等於池的大小。
該層的輸入張量是(batch_size,28,28,32)28×28是圖像的大小,32是來自上一層的輸出通道數。但是,我們不必明確說明輸入的形狀是什麼,Keras也能自動識別。這樣可以快速組合網絡架構,而不用擔心網絡周圍張量的大小。
model.add(Flatten())
model.add(Dense(1000, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
現在我們已經在Keras中構建了卷積層,我們希望將這些輸出平坦化,以完全進入我們的連接層。在TensorFlow中,我們為了平坦化必須弄清楚卷積層的輸出張量的大小,還要明確我們的權重和偏差變量的大小。
接下來的兩行聲明了我們的完全連接層,使用Keras中的Dense()層。首先我們指定大小,根據我們的架構,我們指定了1000個節點,每個節點都是由ReLU功能激活。第二個是我們softmax分類或輸出層,這是我們類數量的大小。就這樣 - 我們已經成功地開發了CNN的架構,隻有8行代碼。現在讓我們來訓練模型並執行預測。
訓練和評估卷積神經網絡
我們已經開發了Keras的CNN架構,但是我們還沒有指定損失函數,或者告訴框架使用哪種類型的優化器(即梯度下降,Adam optimiser等)。在Keras中,這些可以在一個命令中執行:
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.SGD(lr=0.01),
metrics=['accuracy'])
Keras提供了許多損失函數(或者你可以建立自己的),這裏可以看到的keras所有的損失函數。我們將使用標準交叉熵來進行分類(keras.losses.categorical_crossentropy)。Keras還提供了許多優化器,可以在這裏看到。在這種情況下,我們使用Adam優化器(keras.optimizers.Adam)。最後,我們可以在模型上運行evaluate()時計算的度量。
接下來,我們要訓練我們的模型。這可以通過在Keras中再次運行下麵這個命令來完成:
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test),
callbacks=[history])
該命令看起來類似於非常受歡迎的Python機器學習庫中scikit learn 使用的語法。我們首先傳遞我們的所有訓練的數據,x_train和y_train,下一個參數是批量大小,我們不必在Keras訓練期間明確我們數據的批量處理,而是指定批量大小。在這種情況下,我們使用的批量大小為128。接下來我們設置訓練周期(在這種情況下為10)。詳細標誌在此處設置為1,指定設定是否要在控製台中打印詳細信息以了解訓練進度。
3328/60000 [>.............................] - ETA: 87s - loss: 0.2180 - acc: 0.9336
3456/60000 [>.............................] - ETA: 87s - loss: 0.2158 - acc: 0.9349
3584/60000 [>.............................] - ETA: 87s - loss: 0.2145 - acc: 0.9350
3712/60000 [>.............................] - ETA: 86s - loss: 0.2150 - acc: 0.9348
最後,我們將驗證或測試數據傳遞給擬合函數,因此Keras知道在模型上運行evaluate()時,會測量指標的數據。
一旦模型被訓練,我們可以評估它並打印結果:
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
在上述模型培訓10個周期之後,我們實現了99.2%的準確度,你可以看到每個周期的準確性的改善如下圖所示:
Kersa讓事情很更加簡單了,你不覺得嗎?我希望這個Keras教程已經展示了它如何成為深度學習解決方案的有用框架。
作為一種附錄,我會告訴你如何跟蹤我們通過訓練時期的準確性,這使我能夠生成上麵的圖表。
在Keras中記錄網絡性能
Keras有一個實用的程序,名為“回調”,可用於跟蹤訓練期間的各種變量。你還可以使用它來創建檢查點,將模型在訓練的不同階段進行保存,以幫助你避免工作結果丟失。整個結果會被傳遞到.fit()函數,如上所述。我會向你顯示一個相當簡單的用例,其中記錄了準確性。
要創建一個回調,我們創建一個繼承的類,它繼承自keras.callbacks.Callback:
class AccuracyHistory(keras.callbacks.Callback):
def on_train_begin(self, logs={}):
self.acc = []
def on_epoch_end(self, batch, logs={}):
self.acc.append(logs.get('acc'))
上麵代碼繼承的Callback超類有一些可以在我們的回調定義中覆蓋的方法,例如 on_train_begin,on_epoch_end,on_batch_begin和on_batch_end。這些方法的名稱就是代表了訓練過程中我們可以“做事情”的時刻。在上麵的代碼中,在訓練開始時,我們初始化一個列表self.acc = []來存儲我們的精度結果。使用on_epoch_end ()方法,我們可以從日誌中提取我們想要的變量,這是一個字典,默認情況下保留了訓練過程中的丟失和準確性。然後我們實例化這樣的回調:
history = AccuracyHistory()
現在我們可以使用回調參數名將曆史記錄傳遞給.fit()函數。請注意,.fit()需要一個回調參數的列表,所以你必須傳遞這樣的曆史:[history]。要訪問我們在訓練完成後創建的準確性列表,你可以簡單地調用history.acc:
plt.plot(range(1,11), history.acc)
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.show()
本文由@阿裏雲雲棲社區組織翻譯。
文章原標題《Keras tutorial – build a convolutional neural network in 11 lines》
文章為簡譯,更為詳細的內容,請查看原文
最後更新:2017-08-18 11:02:45