讀書筆記(二)多層感知器識別手寫數字

多層感知器識別手寫數字

1、介紹

1. 多層感知器模型介紹

多層感知器模型

2. 多層感知器模型的訓練與預測

建立多層感知器模型後,必須先訓練模型才能夠進行預測(識別)這些手寫數字。

訓練
MNIST數據集的訓練數據經過數據預處理後會產生Features和Labels,然後輸入多層感知器模型進行訓練,訓練完成的模型就可以作爲預測使用。
預測
輸入數字圖像,預處理後會產生Features,使用訓練完成後的模型進行預測,預測結果是0~9的數字。

3. 建立多層感知器模型的步驟

2、進行數據預處理

1. 導入所需模塊

from keras.utils import np_utils
import numpy as np
np.random.seed(10)

2. 讀取MNIST數據

from keras.datasets import mnist
(x_train_image, y_train_label),\
(x_test_image, y_test_label) = mnist.load_data()

3. 將features使用reshape轉換

將原本28x28的數字圖像以reshape轉換成784個Float數。

x_Train = x_train_image.reshape(60000, 784).astype('float32')
x_Test = x_test_image.reshape(10000, 784).astype('float32')

4. 將features標準化

將features標準化可以提高模型預測的準確度,並且更快收斂。

x_Train_normalize = x_Train/255
x_Test_normalize = x_Test/255

5. label進行One-Hot Encoding轉換

y_Train_OneHot = np_utils.to_categorical(y_train_label)
y_Test_OneHot = np_utils.to_categorical(y_test_label)

3、建立模型

1. 導入所需模塊

from keras.models import Sequential
from keras.layers import Dense

2. 建立Sequential模型

建立一個線性堆疊模型,後面可用model.add()方法將各個神經網絡層加入模型。

model = Sequential()

3. 建立“輸入層”與“隱藏層”

Dense神經網絡層的特色是:所有的上一層與下一層的神經元都完全連接。

model.add(Dense(units = 256,    //定義“隱藏層”神經元個數爲256
                input_dim = 784,    //設置“輸入層”神經元個數爲784
                kernel_initializer = 'normal',      //使用normal distribution正態分佈的隨機數來初始化weight(權重)和bias(偏差)
                activation = 'relu'))   //定義激活函數爲relu

4. 建立“輸出層”

model.add(Dense(units = 10,     //定義“輸出層”神經元個數爲100~9)
               kernel_initializer = 'normal',
               activation = 'softmax'))      //定義激活函數爲softmax,softmax可以將神經元的輸出轉換爲預測每一個數字的概率

5. 查看模型摘要

print(model.summary())

  • 隱藏層:共256個神經元,由於輸入層與隱藏層是一起建立的,所以未顯示輸入層
  • 輸出層:共10個神經單元

關於Param:

  • 每一層的Param都是超參數(Hyper-Parameters),我們需要通過反向傳播算法更新神經元連接的權重與偏差。
  • 每一層的Param計算方式:Param = (上一層的神經元個數) X (本層的神經元個數)+ (本層的神經元數量)
  • 隱藏層的Param: 200960 = 784 X 256 + 256,輸出層的Param: 2570 = 256 X 10 + 10
  • 全部必須訓練的超參數(Trainable Params)是每一層的Param總和,計算方式:2009600 + 2570 = 203530,通常Trainable Params數值越大,代表此模型越複雜,需要更多的時間訓練。

4、進行訓練

1. 定義訓練方式

model.compile(loss='categorical_crossentropy',
             optimizer='adam',metrics=['acc'])

使用compile方法隊訓練模型設置,參數含義:

loss:設置損失函數,深度學習中使用cross_entropy(交叉熵)訓練結果比較好
optimizer:設置訓練時,在深度學習中使用adam優化器可以讓訓練更快收斂,並提高準確率
metrics:設置評估模型的方式是準確率

2. 開始訓練

使用model.fit進行訓練,訓練過程會存儲在train_history變量中

train_history = model.fit(x=x_Train_normalize,  //features數字圖像的特徵值
                          y=y_Train_OneHot,     //label數字圖像真實值
                          validation_split=0.2,    //設置訓練與驗證數據比例:80%作爲訓練數據,20%作爲驗證數據
                          epochs=10,       //訓練週期數爲10
                          batch_size=200,    //每一批次200項數據
                          verbose=2)   //顯示訓練過程

3. 顯示訓練過程

import matplotlib.pyplot as plt
def show_train_history(train_history,train,validation):
    plt.plot(train_history.history[train])
    plt.plot(train_history.history[validation])
    plt.title('Train History')     //顯示圖的標題
    plt.ylabel(train)       //顯示y軸的標籤
    plt.xlabel('Epoch')     //顯示x軸的標籤是‘Epoch’
    plt.legend(['train','validation'],loc='upper left')
    plt.show()

4. 畫出準確率評估的執行結果

show_train_history(train_history,'acc','val_acc')

關於acc訓練的準確率比val_acc驗證的準確率高的原因:

acc訓練的準確率:以訓練的數據來計算準確率,因爲相同的數據已經訓練過了,又拿來計算準確率,所以準確率會比較高
val_acc驗證的準確率:以驗證的數據來計算準確率,這些驗證數據在之前訓練時並未拿來訓練,所以計算的準確率會比較低。但是,這樣計算出來的準確率比較客觀,比較符合真實情況

5. 畫出誤差執行結果

show_train_history(train_history,'loss','val_loss')

5、根據測試數據評估模型準確率

使用test測試數據來評估模型準確率

scores = model.evaluate(x_Test_normalize, y_Test_OneHot)  //使用model.evaluate評估模型的準確率,並存儲在scores中
print()
print('accuracy=', scores[1])      //顯示準確率

以上程序代碼執行結果是準確率爲0.97

6、進行預測

1. 進行預測

prediction = model.predict_classes(x_Test)

2. 顯示預測數據

prediction

運行結果是array([7,2,1,…,4,5,6]),即第一項預測結果是7,第二項預測結果是2…

3. 顯示預測結果

import matplotlib.pyplot as plt
def plot_images_labels_prediction(images,labels,prediction,idx,num=10):
    fig=plt.gcf()
    fig.set_size_inches(12,14)
    if num>25: num=25
    for i in range(0,num):
        ax=plt.subplot(5,5,1+i)
        ax.imshow(images[idx],cmap='binary')
        title="label="+str(labels[idx])
        if len(prediction)>0:
            title="label="+str(labels[idx])+",predict="+str(prediction[idx])
        ax.set_title(title,fontsize=10)
        ax.set_xticks([]);ax.set_yticks([])
        idx+=1
    
plot_images_labels_prediction(x_test_image, y_test_label, prediction, idx = 340)

7、顯示混淆矩陣

使用混淆矩陣(也稱爲誤差矩陣,一種特定的表格顯示方式,以可視化的方式瞭解有監督的學習算法的結果)顯示哪些數字的預測準確率最高,哪些數字最容易混淆(例如真實值是5,但預測值是3)

1. 建立混淆矩陣

import pandas as pd
pd.crosstab(y_test_label,prediction,rownames=['label'],colnames=['predict'])


從以上的混淆矩陣中,觀察結果如下:

  • **對角線是預測正確的數字,我們發現:**真實值是“1”,被正確預測爲“1”的項數有1124項,預測準確率最高,最不容易混淆。真實值爲“5”,預測值爲“5”的項數有854項最低,即最容易混淆。
  • **其他非對角線的數字代表將一個標籤預測錯誤,成爲另一個標籤,我們發現:**真實值是“5”,但是預測值是“3”。

2. 建立真實值與預測值DataFrame

df = pd.DataFrame({'label':y_test_label,'predict':prediction})
df[:2]

3. 查詢數據

Pandas DataFrame可以很方便的查詢數據,如找出真實值是“5”,但預測值是“3”的數據。

df[(df.label == 5)&(df.predict == 3)]

4. 查看結果

查看第340項結果。

plot_images_labels_prediction(x_test_image,y_test_label,prediction,idx=340,num=1)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章