什么是Keras,為什么要學(xué)Keras
在學(xué)習(xí)深度學(xué)習(xí)的過程中,有些人用的是MatLab,有些人用的Python。而使用Python的同學(xué)必定也用過Tensorflow、PyTorch這些機器學(xué)習(xí)庫。但通過Tensorflow等這些庫來實現(xiàn)我們的深度學(xué)習(xí)模型的時候仍然需要大量的編程,對諸如前向傳遞、后向傳遞、優(yōu)化算法等方法都要自己去通過編程實現(xiàn)。這對于初學(xué)者來說簡直就是噩夢一樣。
相比來說,Keras是一個高層神經(jīng)網(wǎng)絡(luò)API,Keras由純Python編寫而成并基Tensorflow、Theano以及CNTK后端。Keras 為支持快速實驗而生,能夠把你的idea迅速轉(zhuǎn)換為結(jié)果。
Keras的Sequential模型API可以讓我們通過簡單地操作將神經(jīng)網(wǎng)絡(luò)的層加入到模型中,下面通過一個簡單的例子來看我們是怎樣通過Sequential的API來實現(xiàn)一個神經(jīng)網(wǎng)絡(luò)模型的。
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten()) # input layer
model.add(tf.keras.layers.Dense(128,activation=tf.nn.relu)) # hidden layer
model.add(tf.keras.layers.Dense(128,activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(10,activation=tf.nn.softmax))
在Keras中,通過僅僅5行代碼就可以實現(xiàn)一個MLP多層感知機的神經(jīng)網(wǎng)絡(luò)模型,而在TensorFlow中相應(yīng)的代碼往往是上百行。Keras的方便性可見一斑。
環(huán)境搭建
在學(xué)習(xí)了這么久的機器學(xué)習(xí)過后,Windows、Linux下的環(huán)境也應(yīng)該搭建了很多次。由于Keras的后端我們選擇使用TensorFlow,因此整個環(huán)境的搭建便不需要過多地浪費筆墨。
在進一步進行學(xué)習(xí)之前,我推薦大家通過VirtualEnv或者Anaconda來創(chuàng)建Python的虛擬環(huán)境,這樣我們安裝的軟件包不會相互影響,使得針對機器學(xué)習(xí)開發(fā)與桌面軟件或服務(wù)器開發(fā)的不同虛擬環(huán)境相對干凈。
這里以Anaconda為例說明環(huán)境搭建的要求。
環(huán)境要求:
1、Anaconda(要求安裝Python3版本)
2、TensorFlow*
3、Keras*
4、Jupyter Notebook*
5、CUDA和CuDNN
上述各個軟件的安裝這里不再贅述,前面的教程里面有相應(yīng)的講解。帶有星號的則是可以通過pip指令進行安裝的。
在安裝完畢之后,我們來到CMD控制臺(Windows環(huán)境下),輸入如下命令來建立虛擬環(huán)境。
conda create --name tensorflow python=3.*
python的版本具體由安裝的時候的版本來指定,如安裝的是Python3.6的Anaconda則指定python=3.6
使用如下指令激活虛擬環(huán)境
activate tensorflow
在激活虛擬環(huán)境之后,我們的控制臺提示前面會加入(tensorflow)D:\dev\pythonwork>的提示。
使用如下指令退出虛擬環(huán)境
deactivate tensorflow
在激活了環(huán)境之后通過簡單地pip install指令來安裝TensorFlow與Keras。安裝完畢之后使用jupyter notebook來打開Jupyter交互式編譯器。
Keras簡單入門——實現(xiàn)MLP手寫體識別
說到神經(jīng)網(wǎng)絡(luò)的入門,有何人想不到MNIST呢?
對于本教程的Keras的簡單入門,我們也將編寫一個多層感知機的MNIST手寫數(shù)字識別的神經(jīng)網(wǎng)絡(luò)。通過這個教程你將會真正意義上地感受到Keras的好處。
首先導(dǎo)入TensorFlow和Keras的包。
import tensorflow as tf
import keras
上述代碼在Jupyter Notebook這個交互式的筆記本中看起來是這樣的。

通過選中這一行,并且點擊Run按鈕,我們可以只運行這一行代碼,這使得當(dāng)我們需要修改代碼的時候從修改的地方開始執(zhí)行,而不是執(zhí)行全部代碼。這也是我們?yōu)楹芜x擇Jupyter Notebook來進行學(xué)習(xí),而不是選擇諸如PyCharm等IDE進行學(xué)習(xí)的原因。
在導(dǎo)入完TensorFlow和Keras兩個包之后,我們通過keras自帶的方法來加載MNIST的數(shù)據(jù)集,并通過load_data的方法解包(unpack)到訓(xùn)練集和測試集。
mnist = keras.datasets.mnist # 28x28大小的圖像的0-9數(shù)字的手寫體數(shù)據(jù)集
(x_train,y_train),(x_test,y_test) = mnist.load_data()
在準備好訓(xùn)練集和測試集之后,讓我們先來看看MNIST中的數(shù)據(jù)到底是怎樣的格式的。通過print(x_train[0])輸出訓(xùn)練集的第一個28x28的圖像數(shù)據(jù)。
[...
[ 0 0 0 0 0 0 0 0 0 0 0 0 3 18 18 18 126 136
175 26 166 255 247 127 0 0 0 0]
[ 0 0 0 0 0 0 0 0 30 36 94 154 170 253 253 253 253 253
225 172 253 242 195 64 0 0 0 0]
[ 0 0 0 0 0 0 0 49 238 253 253 253 253 253 253 253 253 251
93 82 82 56 39 0 0 0 0 0]
[ 0 0 0 0 0 0 0 18 219 253 253 253 253 253 198 182 247 241
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 80 156 107 253 253 205 11 0 43 154
0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 14 1 154 253 90 0 0 0 0
0 0 0 0 0 0 0 0 0 0]
...]
可以看到這是一個28x28的二維數(shù)組,元素的取值從0到255。也就是說,MNIST手寫數(shù)字數(shù)據(jù)集中的圖片是單通道的灰度圖片。單純地從數(shù)值的角度來看這張圖片十分燒腦,甚至看不出這是一個數(shù)字,那么這時我可以通過matplotlib.pyplot來進行繪圖。如果你有相應(yīng)的經(jīng)驗,那么可以自己繼續(xù)寫下去,然后將上面的數(shù)字顯示出來,之后再回來看下面的代碼。
在繼續(xù)進行之前,先導(dǎo)入matplotlib.pyplot的包,然后使用plt的imshow來顯示圖像。
import matplotlib.pyplot as plt
plt.imshow(x_train[0], cmap='gray')
plt.show()

通過pyplot我們可以很明顯地看到,x_train[0]是一個數(shù)值為5的手寫數(shù)字。
在繼續(xù)下去之前,我們還需要對MNIST的數(shù)據(jù)進行一些簡單地處理,將0-255的整數(shù)標準化為0-1的范圍之間的浮點數(shù)。幸運的是,Keras給我們提供了將這些數(shù)值標準化的方法。
x_train=keras.utils.normalize(x_train,axis=1)
x_test=keras.utils.normalize(x_test,axis=1)
通過keras.utils.normalize我們可以輕松地將測試集和數(shù)據(jù)集標準化。

那么接下來便是重頭戲了,也就是我們在開頭所說過的,通過Keras的Sequential模型來構(gòu)建這個多層感知機的模型。如果你對于神經(jīng)網(wǎng)絡(luò)不很了解,不知道什么是多層感知機的話,可以看一下我前面寫的機器學(xué)習(xí)相關(guān)的文章。
在Keras中,使用Sequential模型十分簡單通過
keras.models.Sequential來創(chuàng)建一個模型對象,然后依次調(diào)用add來添加層,層添加的順序則是從輸入層到輸出層的順序。最后,我們通過compile來編譯這個模型,在編譯的時候需要指定模型的優(yōu)化算法、損失函數(shù)和評價指標。
model = keras.models.Sequential()
model.add(keras.layers.Flatten()) # input layer
model.add(keras.layers.Dense(128,activation=tf.nn.relu)) # hidden layer
model.add(keras.layers.Dense(128,activation=tf.nn.relu))
model.add(keras.layers.Dense(10,activation=tf.nn.softmax))
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
上述6行代碼則完整地定義了這個MLP的模型。首先是輸入層,輸入層指定是Flatten(扁平)的,也就是把二維的圖像數(shù)據(jù)一維化,輸入多層感知機。然后通過Dense創(chuàng)建2個128個神經(jīng)元的全連接層,該全連接層使用ReLU作為激活函數(shù)。最后再創(chuàng)建一個與上一個隱藏層全連接的具有10個輸出的全連接層作為輸出層,通過SoftMax函數(shù)將輸出映射為0~9的10個概率的輸出。
最后通過model.fit(x_train,y_train,epochs=3)開始指定訓(xùn)練集、測試集和epochs來進行訓(xùn)練。訓(xùn)練時的輸出如下:
Epoch 1/3
60000/60000 [==============================] - 7s 115us/step - loss: 0.2641 - acc: 0.9229
Epoch 2/3
60000/60000 [==============================] - 5s 84us/step - loss: 0.1073 - acc: 0.9662
Epoch 3/3
60000/60000 [==============================] - 5s 84us/step - loss: 0.0726 - acc: 0.9775
可以看到,通過3個epochs的訓(xùn)練過后,網(wǎng)絡(luò)的損失達到了0.07,準確率達到了97.75%。但這只是對測試集的訓(xùn)練得到的結(jié)果,有時模型會出現(xiàn)過擬合的情況,此時便需要通過對模型沒有遇見過的驗證集的數(shù)據(jù)進行測試。
val_loss,val_acc=model.evaluate(x_test,y_test)
print(val_loss,val_acc)
運行評估之后,針對驗證集輸出如下:
10000/10000 [==============================] - 0s 47us/step
0.0927426937890239 0.9701
由此可見,針對驗證集進行評估之后,模型的損失為0.0927、準確率為97.01%。這證明模型并未出現(xiàn)過擬合。
通過predictions = model.predict([x_test])針對x_test進行預(yù)測,使用numpy的argmax方法來得到相應(yīng)預(yù)測的值應(yīng)該是多少。
將預(yù)測的結(jié)果使用pyplot可視化顯示出來便可以看出預(yù)測是否是對的。
predictions = model.predict([x_test])
import numpy as np
print(np.argmax(predictions[0]))
plt.imshow(x_test[0])
plt.show()
