在上一篇博客:數據挖掘入門系列教程(十點五)之DNN介紹及公式推導中,詳細的介紹了DNN,並對其進行了公式推導。原本這篇博客是準備直接介紹CNN的,可是想了一下,以爲仍是使用keras構建一個DNN網絡,而後進行必定的分類操做,這樣可以更加的直觀一點。html
在這篇博客中將介紹:python
此次咱們將使用keras庫去構建神經網絡,而後默認使用tensorflow做爲後端,我是用的python庫版本以下:git
這篇博客並不會講keras,tensorflow的安裝,不過值得注意的是,若是本身電腦有英偉達的顯卡就儘可能去裝gpu版本的tensorflow,而後安裝對應版本的cuda。通常來講使用GPU可以大幅度提升程序計算的速度(個人mx250哭暈在廁所)。至於AMD的顯卡,emm,我就不知道支不支持了。github
關於keras的具體使用,能夠去看一看官方文檔,可是目前官方文檔的目錄欄有一點問題,所以建議你們去看這個keras 中文文檔,這個是根據官方文檔生成的。算法
這裏咱們使用keras提供MNIST數據集,訓練集爲 60,000 張$ 28\times 28 = 784$像素灰度圖像,測試集爲 10,000 同規格圖像,總共 10 類數字標籤。後端
from keras.datasets import mnist (x_train, y_train), (x_test, y_test) = mnist.load_data()
而後咱們能夠看一看數據集的shape:網絡
print(x_train.shape, 'x_train samples') print(x_test.shape, 'x_test samples') print(y_train.shape, 'y_trian samples') print(y_test.shape, 'Y_test samples')
此時,咱們就已經加載好數據集了。咱們能夠稍微的看一看數據集長什麼樣子:函數
import matplotlib.pyplot as plt %matplotlib inline plt.figure(figsize=(12,10)) x, y = 8, 6 for i in range(x*y): plt.subplot(y, x, i+1) plt.imshow(x_train[i],interpolation='nearest') plt.show()
由於數據集並不能可以直接進行訓練或者訓練效果很差,在這裏咱們將數據進行一下變換。好比說歸一化,onehot編碼(這個必須作)。測試
首先,咱們的DNN的設計以下:優化
輸入層是由784
個神經元構成的,可是在前面咱們已經知道x_train.shape
是(6000,28,28)
。輸出層由10
個神經元構成,而y_train.shape
是(6000,)
,毋庸置疑,咱們須要對x,y
數據進行編碼。
對於x
數據來講,咱們須要將它變成(6000,784)
的類型,對於y
咱們進行onehot編碼就好了(one hot編碼在前面已經介紹過了,這裏就很少作介紹了),同時在這裏咱們還將數據進行歸一化(能夠提升模型的準確率)。
import keras x_train = x_train.reshape(60000, 784) x_test = x_test.reshape(10000, 784) # 將數據變成float類型,這樣可以被255除 x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 # one hot 編碼,將類向量(整數)轉換爲二進制類矩陣。 y_train = keras.utils.to_categorical(y_train, 10) y_test = keras.utils.to_categorical(y_test, 10)
首先咱們導入Sequential
。
from keras.models import Sequential
Sequential
是一個順序模型:多個網絡層的線性堆疊,每一層接受上一層的輸入,向下一層進行輸出,示意圖以下:
這裏,再說一個概念,全鏈接層
,很簡單理解,就是某一層用數學公式來表達就是\(output = W\times input\),好比說下圖中的layer2和layer3
就是全鏈接的,也就是說layer2
是全鏈接層。在keras中,可使用Dense去建立一個全鏈接層。
關於Dense的參數,截取官方文檔以下:
參數
- units: 正整數,輸出空間維度。
- activation: 激活函數 (詳見 activations)。 若不指定,則不使用激活函數 (即,「線性」激活:
a(x) = x
)。- use_bias: 布爾值,該層是否使用偏置向量。
- kernel_initializer:
kernel
權值矩陣的初始化器 (詳見 initializers)。- bias_initializer: 偏置向量的初始化器 (see initializers).
- kernel_regularizer: 運用到
kernel
權值矩陣的正則化函數 (詳見 regularizer)。- bias_regularizer: 運用到偏置向的的正則化函數 (詳見 regularizer)。
- activity_regularizer: 運用到層的輸出的正則化函數 (它的 "activation")。 (詳見 regularizer)。
- kernel_constraint: 運用到
kernel
權值矩陣的約束函數 (詳見 constraints)。- bias_constraint: 運用到偏置向量的約束函數 (詳見 constraints)。
然咱們來看一看具體的使用(裏面涉及的幾個激活函數隨便去網上搜一下就知道了):
from keras.layers import Dense, Dropout # 建立一個網絡模型 model = Sequential() # 建立輸入層 512表明的是輸出維度爲512,也就是第二層神經元有512個,輸入維度爲(784,),激活函數爲Relu model.add(Dense(512, activation='relu', input_shape=(784,))) model.add(Dropout(0.2)) # 建立layer2,而後向下層輸出的空間維度爲512 model.add(Dense(512, activation='relu')) model.add(Dropout(0.2)) # 輸出層,由於只有10個數字,因此輸出空間維度爲10,激活函數爲softmax。 model.add(Dense(10, activation='softmax')) # 網絡模型的介紹 print(model.summary())
Dropout
應用於輸入。Dropout 包括在訓練中每次更新時, 將輸入單元的按比率隨機設置爲 0, 這有助於防止過擬合。
簡單點來講,他就是這樣的,隨機(按比率)將某一個輸入值變成0,這樣他就沒辦法向下一層傳遞信息。
打印的網絡結構模型以下所示,仍是有蠻多參數的:
接着咱們就來說一下如何配置這個模型,在keras中,配置一個模型至少須要兩個參數loss
和optimizer
。其中loss
就是損失函數,optimizer
就是優化器,也就是前篇博客提到的優化方法,好比說梯度降低法,牛頓法等等,metrics
表明在訓練和測試期間的模型評估標準。
from keras.optimizers import RMSprop model.compile(loss='categorical_crossentropy', optimizer=RMSprop(), metrics=['accuracy'])
這裏咱們選擇RMSprop
,具體內容能夠參考Day 69: rmsprop,而後loss咱們選擇categorical_crossentropy
,由於它是多分類任務。其表達式爲:
\(C E(x)=-\sum_{i=1}^{C} y_{i} \log f_{i}(x)\)
其中, \(x\)表示輸入樣本, \(C\)爲待分類的類別總數。 \(y_{i}\) 爲第\(i\)個類別對應的真實標籤, \(f_{i}(x)\) 爲對應的模 型輸出值。
最後咱們可使用這個模型來訓練數據了,代碼:
# history保存了每一次訓練的loss,accuracy history = model.fit(x_train, y_train, batch_size=128, epochs=32, verbose=1, validation_data=(x_test, y_test))
x_train, y_train
這個就不必解釋了,很簡單,就是訓練的數據集。
batch_size
表明每一次梯度更新的樣本數,默認32。如何理解這個這一個參數呢?意思就是說每次一訓練的時候訓練batch_size
個樣本,針對每個樣本咱們均可以求出它對應的loss,而後咱們求和而後取平均\(C E(x)_{\text {final}}=\frac{\sum_{b=1}^{batch\_size} C E\left(x^{(b)}\right)}{N}\),而後再使用BP算法。epochs
: 訓練模型迭代輪次。verbose
: 0, 1 或 2。日誌顯示模式。 0 = 安靜模式, 1 = 進度條, 2 = 每輪一行。validation_data
:用來評估損失,以及在每輪結束時的任何模型度量指標。 模型將不會在這個數據上進行訓練。部分打印數據以下:
在個人筆記本i5十代u,mx250的狀況下,訓練了大概1分多鐘,畢竟數據集仍是比較小的,而後參數也不是不少。
# 這裏的verbose和fit中的含義同樣 score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1])
最後結果以下圖:
這裏咱們將每一次輪訓練以及測試對應的loss和accuracy畫出來:
# 繪製訓練過程當中訓練集和測試集合的準確率值 plt.plot(history.history['accuracy']) plt.plot(history.history['val_accuracy']) plt.title('Model accuracy') plt.ylabel('Accuracy') plt.xlabel('Epoch') plt.legend(['Train', 'Test'], loc='upper left') plt.show() # 繪製訓練過程當中訓練集和測試集合的損失值 plt.plot(history.history['loss']) plt.plot(history.history['val_loss']) plt.title('Model loss') plt.ylabel('Loss') plt.xlabel('Epoch') plt.legend(['Train', 'Test'], loc='upper left') plt.show()
ok,這篇博客就結束了。總的來講仍是蠻順利的,由於不須要去推數學公式,基本上沒有什麼難度(固然,若是想更好的提升準確率仍是蠻難的,能夠去kaggle裏面看一下大佬的解決方案)。這篇博客簡單的介紹了keras使用,我力求將每個用到的函數都講清楚,可是實際上很難,由於可能我認爲講清楚了,可是實際上你可能仍是沒有明白。這個時候能夠去多看一下官方文檔,或者別人的博客,固然,私信我也是🆗的。
項目地址:Github