多層感知器識別手寫數字
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, //定義“輸出層”神經元個數爲10(0~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)