本篇繼續整理 "深度學習的16堂課" 這本書的讀後筆記, 本系列之前的文章參考 :
以下是我讀第五章 "先動手實作! 5 行程式體驗神經網路模型" 的摘要筆記與測試紀錄 (此書第一篇前四章是 ML 知識介紹, 本章開始才有程式碼實作, 第二篇 5~8 章介紹深度學習核心概念) :
- Tensorflow 2 開始將原本獨立的高階 API Keras 套件納入 Tensorflow 中, 成為 tf.Keras 子套件, 使建構神經網路的程式碼更加簡潔.
- MNIST 是由 Yann LeCun, Corinna Cortes, 與微軟 AI 研究員 Burges 整理的手寫數字資料集, 含有 70000 張 28x28 解析度的手寫數字圖片, 其中 60000 張是訓練資料集 (training datatset), 10000 張是測試資料集 (test dataset).
- 基本的淺層神經網路由輸入層, 隱藏層, 與輸出層構成, 以 MNIST 來訓練手寫數字圖片辨識模型來說, 輸入層需有 28x28=784 個神經元 (用來接收每張圖的 784 個像素), 輸出層需有 10 個神經元 (表示 0~9 數字的機率, 最高者為其預測結果), 隱藏層用來學習輸入資料的特徵, 其神經元數目是超參數, 可任意指定, 一般使用 2 的次方數字 (例如 64). 由於 MNIST 資料集是以 2D 陣列表示, 因此在饋入神經網路之前須將其拉平為 1D 陣列.
- 在 Google 雲端硬碟中的 Colab 運算平台執行機器學習運算非常方便, 用法參考 :
# 方便好用的 Google Colab 運算平台
如果要在 Colab 上用 matplotlib 繪圖, 需先執行下列程式碼 :
%matplotlib inline - 在 Colab 平台進行 MNIST 資料集訓練 :
(1). 匯入模組 :
from tensorflow.keras.datasets import mnist # 匯入 MNIST 資料集
from tensorflow.keras.models import Sequential # 匯入堆疊模型
from tensorflow.keras.layers import Dense # 匯入密集層
from tensorflow.keras import optimizers # 匯入優化器
from tensorflow.keras.utils import plot_model # 匯入繪圖模型
from tensorflow.keras.utils import to_categorical # 匯入分類器
import matplotlib.pyplot as plt # 匯入繪圖模組 pyplot
import numpy as np # 匯入 Numpy
(2). 載入 MNIST 資料集 :
(X_train, y_train), (X_test, y_test)=mnist.load_data()
這會傳回兩組 tuple第一組是 6 萬筆的訓練集, X_train 是訓練集的圖片資料, y_train 是訓練集的標籤 (答案); 第二組是 1 萬筆的測試集, X_test 是測試集的圖片資料, y_test 是測試集的標籤 (答案), 結果如下 :
大寫 X 表示這是 2D 以上的向量; 而小寫 y 表示這是 1D 的向量或純量.
(3). 查看資料集內容 :
X_train.shape
(60000, 28, 28)
表示訓練集有 6 萬筆資料, 每筆圖片解析度是 28x28.
然後用 Numpy 的 set_printoptions() 設定列印寬度為無限大, 這樣才不會因為過長而跳行, 接著列印訓練集的第一筆資料圖片內容 :
np.set_printoptions(linewidth=np.inf)
X_train[0]
看起來是數字 5. 接著查看訓練集標籤內容 :
y_train[0:12]
array([5, 0, 4, 1, 9, 2, 1, 3, 1, 4, 3, 5], dtype=uint8)
可見訓練集第一張圖片確實是 5.
(4). 用 Matplotlib 繪製 MNIST 資料圖片 :
plt.figure(figsize=(5, 5)) # 設定 5吋*5吋畫布
for k in range(12): # 繪製前 12 張圖片
plt.subplot(3, 4, k+1) # 指定 3*4 網格中第 k+1 個子圖繪圖區
plt.imshow(X_train[k], cmap='gray') # 在第 k+1 個子圖繪製第 k 張圖片
plt.tight_layout()
plt.show()
上面程式碼用來繪製 MNIST 測試集的前 12 張圖片, 這裡要注意, plt.subplot() 的子圖網格系統編號是 1 起始的, 但 MNIST 的資料編號則是 0 起始的. 關於 Mplotlib 用法參考 :
# Python 學習筆記 : Matplotlib 資料視覺化 (一) 基本篇
# Python 學習筆記 : Matplotlib 資料視覺化 (二) 統計圖
# Python 學習筆記 : Matplotlib 資料視覺化 (三) 進階篇
結果如下 :
(5). 資料預處理 :
資料預處理主要有兩項, 首先要將全部資料集的圖片資料從 28*28 的 2D 陣列型態拉平為 1*784 的 1D 陣列, 這樣才能與神經網路的輸入層結構匹配 (同時也將原本 0~255 的整數像素由 uint8 改為 float32 浮點數), 這主要是依賴 Numpy 的 reshape() 與 astype() 達成. 其次是要將資料正規化, 將所有資料轉成 0~1 之間的數值, 這樣模型的訓練成效較好. 最簡單的正規化就是除以最大值 (255) :
X_train=X_train.reshape(60000, 784).astype('float32') # 2D 資料展平為 1D
X_test=X_test.reshape(10000, 784).astype('float32') # 2D 資料展平為 1D
X_train /= 255 # 正規化
X_test /= 255 # 正規化
X_train[0] # 顯示第一張圖片
(6). 標籤預處理 :
除了資料需要預處理外, 輸出標籤 (即 y_train 與 y_test) 也需要預處理, 將原本的 0~9 用 one-hot 編碼為 10 維的 1D 陣列, 這要用到 Keras 的 to_categorical() 函式 :
y_train=to_categorical(y_train, 10) # 訓練集標籤 one-hot 編碼
y_test=to_categorical(y_test, 10) # 測試集標籤 one-hot 編碼
y_train[0] # 顯示訓練集第一張圖的標籤
可見第一張圖 5 只有在 [5] 位置是 1, 其餘為 0.
(7). 建立, 編譯, 與訓練神經網路模型 :
使用 Sequential 模型建立三層神經網路 :
model=Sequential() # 建立序列式模型
model.add(Dense(64, activation='sigmoid', input_shape=(784,))) # 輸入+隱藏層
model.add(Dense(10, activation='softmax')) # 輸出層
model.compile(loss='mean_squared_error',
optimizer=optimizers.SGD(learning_rate=0.01),
metrics='accuracy') # 編譯模型
model.fit(X_train, y_train, batch_size=128, epochs=200, verbose=1,
validation_data=(X_test, y_test)) # 訓練模型
此處 model 只呼叫 add() 兩次就建立了三層模型, 因為第一次呼叫 add() 時同時建立了輸入層 (用 input_shape 參數指定 784 個神經元) 與隱藏層 (64 個神經元), 因為在 tf.Keras 中第一層是輸入層間隱藏層, 第二次呼叫 add() 建立輸出層時不需指定 input_shape, 模型會自動連結上一層的 64 個神經元. 呼叫 Dense() 函式是要建立全連接的密集層, 該層的每個神經元都會與上一層的每個神經元連接. 參數 activation 指定激活函數 (activation function), 用來增加神經元對非線性規則的學習能力. 激活函數 softmax 可將輸出層神經元的輸出限制在 0~1 之間, 而這 10 個值加起來是 1, 故 softmax 有輸出機率值的效果.
呼叫 fit() 編譯模型時傳入 loss 參數指定損失函數類型來計算模型預測值與正確答案之誤差, optimizer 參數指定優化器, 用來調整權重使誤差值能降到最低. metrics 參數則指定如何評估模型的學習成效, 'accuracy' 表示以準確度來評估.
呼叫 fit() 訓練時傳入參數 batch_size=128 表示訓練時每次從 6 萬筆資料集中取 128 筆資料進行訓練 (考量到記憶體容量, 並不是把訓練集一次全部饋入神經網路, 而是分批饋入), 依序跑完 6 萬筆稱為一個 epoch (一輪), 參數 epochs=200 表示這 6 萬筆要跑 200 輪. 參數 verbose=1 表示顯示完整的訓練過程 (包含進度條).
跑 200 個 epoch (輪) 花了 6 分鐘, 最後達到 86.4% 精確度 : - 儲存 ipynb 檔副本於 GitHub :
Colab 的執行過程除了會儲存在 Google 雲端硬碟裡, 還可以儲存副本到自己的 GitHub 儲存庫裡, 上面的程式碼 ipynb 檔的 GitHub 網址如下 :
# https://github.com/tony1966/colab/blob/main/deep_learning_illustrated_ch5_mnist.ipynb
沒有留言 :
張貼留言