Tensorflow實作_阿拉伯手寫數字分類的實作_基本功常見操作
本篇實作
使用python3.11
tensorflow2.20 ->這個裝好通常會自動把numpy2.4.6、tensorboard2.20、h5py也裝好
matplotlib3.11.1
numpy2.4.6tensorboard2.20
第一次於專案裝會要等大概10~15分鐘,會要等好一陣子。
Phase1程式碼-載入mnist資料集
嘗試透過將像素值內容非0的統一轉為1,觀察圖像張量資料。
import tensorflow as tf mnist = tf.keras.datasets.mnist # 匯入 MNIST 阿拉伯數字訓練資料 (x_train, y_train),(x_test, y_test) = mnist.load_data() # 訓練/測試資料的 X/y 維度 print("訓練資料X維度:{0}".format(x_train.shape)) print("訓練資料Y維度:{0}".format(y_train.shape)) print("測試資料X維度:{0}".format(x_test.shape)) print("測試資料X維度:{0}".format(y_test.shape)) # 訓練資料前10筆圖片的數字標準答案 print(y_train[:10]) print(x_train[0])#打印第一張訓練圖的像素值矩陣 data = x_train[0].copy() data[data>0]=1#把非0的數字轉為1,顯示第1張圖片 print("==========================================") #把轉換後二維矩陣內容印出來,可以隱約看出數字為5 text_image=[] for i in range(data.shape[0]): text_image.append(''.join(str(data[i]))) for i, row in enumerate(text_image): if i < len(text_image) - 1: print(f" {repr(row)},") else: print(f" {repr(row)}") print("==========================================")
輸出結果
60000 張圖片,每張解析度皆為 28 × 28
這邊把訓練數據集前10印出來,y_train就是(60000,)每張圖對應備標註的正確解答
index = 0 → label = 5
index = 1 → label = 0
index = 2 → label = 4
index = 3 → label = 1
index = 4 → label = 9
Phase2程式碼-進行特徵縮放(正規化到0~1之間)
import tensorflow as tf mnist = tf.keras.datasets.mnist # 匯入 MNIST 阿拉伯數字訓練資料 (x_train, y_train),(x_test, y_test) = mnist.load_data() # 訓練/測試資料的 X/y 維度 print("訓練資料X維度:{0}".format(x_train.shape)) print("訓練資料Y維度:{0}".format(y_train.shape)) print("測試資料X維度:{0}".format(x_test.shape)) print("測試資料X維度:{0}".format(y_test.shape)) # 訓練資料前10筆圖片的數字標準答案 print(y_train[:10]) print(x_train[0])#打印第一張訓練圖的像素值矩陣 data = x_train[0].copy() data[data>0]=1#把非0的數字轉為1,顯示第1張圖片 # 進行特徵縮放,正規化公式 = (x - min) / (max - min)。由於像素亮度值範圍:0~255,所以簡化為 x / 255 x_train_norm, x_test_norm = x_train / 255.0, x_test / 255.0 print(x_train_norm[0])
輸出結果
Phase3程式碼-進行訓練&繪製訓練過程準確度變化曲線
import tensorflow as tf mnist = tf.keras.datasets.mnist # 匯入 MNIST 阿拉伯數字訓練資料 (x_train, y_train),(x_test, y_test) = mnist.load_data() # 訓練/測試資料的 X/y 維度 print("訓練資料X維度:{0}".format(x_train.shape)) print("訓練資料Y維度:{0}".format(y_train.shape)) print("測試資料X維度:{0}".format(x_test.shape)) print("測試資料X維度:{0}".format(y_test.shape)) # 訓練資料前10筆圖片的數字標準答案 print(y_train[:10]) print(x_train[0])#打印第一張訓練圖的像素值矩陣 data = x_train[0].copy() data[data>0]=1#把非0的數字轉為1,顯示第1張圖片 # 進行特徵縮放,正規化公式 = (x - min) / (max - min)。由於像素亮度值範圍:0~255,所以簡化為 x / 255 x_train_norm, x_test_norm = x_train / 255.0, x_test / 255.0 print(x_train_norm[0]) # 建立模型 model = tf.keras.models.Sequential([ tf.keras.layers.Input((28, 28)), #輸入會是28*28=784二維張量 tf.keras.layers.Flatten(), #扁平層會將二為數據給攤平為一維的784的張量 tf.keras.layers.Dense(128, activation='relu'),#Dense Layer完全連接層,relu激活函數會把負數變0,正數或0維持原本結果。 tf.keras.layers.Dropout(0.2),#校正過擬合,設置0.2比例隨意丟棄中間神經元。 tf.keras.layers.Dense(10, activation='softmax')#輸出層,總共分類10個(0~9)的多元分類。輸出10個機率,用softmax激活函數。若為二元分類可用sigmoid。 ]) #設置優化器、損失函數。指定衡量效能指標為Accuracy,也可設置多個用逗號間隔。 #設置loss為sparse_categorical_crossentropy,會在背後幫忙我們針對y單一數字label做one-hot encoding,每個數字變成10個digit表示。。 model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy']) #訓練,拿20%作為validation用途。 history = model.fit(x_train_norm, y_train, epochs=5,validation_split=0.2) print(history.history.keys()) # 繪製訓練過程準確度曲線 import matplotlib.pyplot as plt plt.plot(history.history['accuracy'], 'r') plt.plot(history.history['val_accuracy'], 'g') plt.title('model accuracy') plt.ylabel('accuracy') plt.xlabel('epoch') plt.show()
Phase4程式碼-繪製訓練過程損失函數變化曲線,並進行模型分數評估,把模型另存出來並做整體模型的彙總資訊呈現
import tensorflow as tf import numpy as np mnist = tf.keras.datasets.mnist # 匯入 MNIST 阿拉伯數字訓練資料 (x_train, y_train),(x_test, y_test) = mnist.load_data() # 訓練/測試資料的 X/y 維度 print("訓練資料X維度:{0}".format(x_train.shape)) print("訓練資料Y維度:{0}".format(y_train.shape)) print("測試資料X維度:{0}".format(x_test.shape)) print("測試資料X維度:{0}".format(y_test.shape)) # 訓練資料前10筆圖片的數字標準答案 print(y_train[:10]) print(x_train[0])#打印第一張訓練圖的像素值矩陣 data = x_train[0].copy() data[data>0]=1#把非0的數字轉為1,顯示第1張圖片 # 進行特徵縮放,正規化公式 = (x - min) / (max - min)。由於像素亮度值範圍:0~255,所以簡化為 x / 255 x_train_norm, x_test_norm = x_train / 255.0, x_test / 255.0 print(x_train_norm[0]) # 建立模型 model = tf.keras.models.Sequential([ tf.keras.layers.Input((28, 28)), #輸入會是28*28=784二維張量 tf.keras.layers.Flatten(), #扁平層會將二為數據給攤平為一維的784的張量 tf.keras.layers.Dense(128, activation='relu'),#Dense Layer完全連接層,relu激活函數會把負數變0,正數或0維持原本結果。 tf.keras.layers.Dropout(0.2),#校正過擬合,設置0.2比例隨意丟棄中間神經元。 tf.keras.layers.Dense(10, activation='softmax')#輸出層,總共分類10個(0~9)的多元分類。輸出10個機率,用softmax激活函數。若為二元分類可用sigmoid。 ]) #設置優化器、損失函數。指定衡量效能指標為Accuracy,也可設置多個用逗號間隔。 #設置loss為sparse_categorical_crossentropy,會在背後幫忙我們針對y單一數字label做one-hot encoding,每個數字變成10個digit表示。。 model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy']) #訓練,拿20%作為validation用途。 history = model.fit(x_train_norm, y_train, epochs=5,validation_split=0.2) print(history.history.keys()) # 繪製訓練過程準確度曲線 import matplotlib.pyplot as plt plt.plot(history.history['accuracy'], 'r') plt.plot(history.history['val_accuracy'], 'g') plt.title('model accuracy') plt.ylabel('accuracy') plt.xlabel('epoch') plt.show() plt.plot(history.history['loss'], 'r') plt.plot(history.history['val_loss'], 'g') plt.title('model loss') plt.ylabel('loss') plt.xlabel('epoch') plt.show() #進行評估並打分數 score=model.evaluate(x_test_norm, y_test, verbose=0) print("score:{0}".format(score)) # 實際預測前 30 筆 predictions = np.argmax(model.predict(x_test_norm, verbose=False), axis=-1) # get prediction result print('prediction:', predictions[0:30]) print('actual :', y_test[0:30]) # 顯示模型的彙總資訊 model.summary() # 模型存檔 model.save('model.keras') # 顯示資料圖像 X2 = x_train[1,:,:] plt.imshow(X2.reshape(28,28), cmap='gray') plt.axis('off') plt.show() # 顯示錯誤的資料圖像 X2 = x_test[8,:,:] plt.imshow(X2.reshape(28,28), cmap='gray') plt.axis('off') plt.show()
運行輸出效果,可以看到如下清楚呈現神經網路每一層參數與維度資訊
也有人是存成model.h5 ,副檔名用.h5或.hdf5 。
.h5 是以前常見的格式,可同時儲存結構與權重,檔案的類別為HDF5。
不過這類通常會有版本相容不好情況要留意,比方TF1.x訓練存出來的.h5拿去給TF2.x載入用就會有問題。
用model.save()保存的完整模型(包含架構、權重、優化器狀態、損失函數配置等所有資訊)
之後用load_model載入完就能直接用。
拿經過正規化過後的測試資料,做模型分數評估為 97%分數
可以看到寫的5不太清楚,模型預測成 6,實際答案是 5,
import tensorflow as tf import numpy as np import matplotlib.pyplot as plt mnist = tf.keras.datasets.mnist # 匯入 MNIST 阿拉伯數字訓練資料 (x_train, y_train),(x_test, y_test) = mnist.load_data() # 訓練/測試資料的 X/y 維度 print("訓練資料X維度:{0}".format(x_train.shape)) print("訓練資料Y維度:{0}".format(y_train.shape)) print("測試資料X維度:{0}".format(x_test.shape)) print("測試資料X維度:{0}".format(y_test.shape)) x_train_norm, x_test_norm = x_train / 255.0, x_test / 255.0 # 模型載入 model = tf.keras.models.load_model('model.keras') # 顯示模型的彙總資訊 model.summary() #進行評估並打分數 score=model.evaluate(x_test_norm, y_test, verbose=0) print("score:{0}".format(score)) # 實際預測前 30 筆 predictions = np.argmax(model.predict(x_test_norm, verbose=False), axis=-1) # get prediction result print('prediction:', predictions[0:30]) print('actual :', y_test[0:30]) tf.keras.utils.plot_model(model, to_file='model.png')
效果
記得要先做以下動作才會產圖成功
Step1.額外裝graphviz (pip install graphviz)和pydotplus(pip install pydotplus)
https://www.graphviz.org/download/
Ref:
https://blog.gtwang.org/programming/keras-save-and-load-model-tutorial/
https://ithelp.ithome.com.tw/m/articles/10191627
https://blog.csdn.net/weixin_42629815/article/details/160646635
留言
張貼留言