高中AI多元選修

Week 12 手寫數字識別的圖像識別模型(下)

張傑帆

Natinal Taiwan University

Alt1Alt2

NTU
目錄

手寫數字識別的圖像識別模型(下)

  1. 實際應用範例
    • 如何顯示資料集的圖像?
    • 輸入我們自己的圖片
    • 把模型存下來
    • 能抓考卷上的數字嗎?
  2. 如何提升模型的辦識率?
  3. 作業
NTU

實際應用範例

  • 範例程式
  • 如何顯示資料集的圖像?
  • 把模型存下來重復使用
  • 輸入我們自己的圖片
  • 能抓考卷上的數字嗎?
NTU

顯示資料集的圖像

alt

NTU

把模型存下來重復使用

  • 要將訓練好的模型存檔,可以使用 Keras 提供的 model.save() 方法將模型儲存為 .h5 檔案。
  • 或使用 model.save_weights() 只存儲權重。

存儲整個模型(包括結構和權重)

  1. # 將模型存檔為 .h5 檔案
  2. model.save('my_model.h5')
  3. print("模型已成功存檔為 my_model.h5")

僅存儲模型的權重

  1. # 只存儲模型的權重
  2. model.save_weights('my_model_weights.h5')
  3. print("模型權重已成功存檔為 my_model_weights.h5")
NTU
  • Keras 推出了.keras 格式,有更好的兼容性和可擴展性,適用於未來的 Keras 版本。
  • 只需要在保存模型時使用 .keras 副檔名即可。Example
  1. # 使用新的 Keras 格式來存檔
  2. model.save('my_model.keras')
  3. print("模型已成功存檔為 my_model.keras")

alt

把模型載下來備用

https://drive.google.com/file/d/1npukME5_MfkuiT97avQuN8K65rAqEGBv/

NTU

上傳存好的模型

  • 其它用到的資料也可以解壓縮一併上傳。

alt text

NTU

載入存儲的模型

要載入存儲的模型,可以使用 load_model()

  1. from tensorflow.keras.models import load_model
  2. # 載入已存儲的模型
  3. loaded_model = load_model('my_model.h5')#新版用'my_model.keras'
  4. print("模型已成功載入")
  5. # 驗證模型是否載入成功
  6. loaded_model.summary()

僅載入模型權重

如果只載入權重,需要先構建模型結構,再載入權重:

  1. # 假設你已經定義了與原始模型相同的結構
  2. model.load_weights('my_model_weights.h5')
  3. print("模型權重已成功載入")
NTU

讀我們手寫的圖片

  • 結果有準確嗎?
  • 造成它結果不準的原因是什麼?

alt

NTU

抓考卷上手寫的數字

alt

NTU

寫個一兩張來看看!

alt

Alt1

NTU

對的根本沒幾個?

alt
Alt1

NTU

修正後與上面的差在哪? 該怎麼修正?

alt
Alt1

NTU

修正後準確率是差一點點

  • 為什麼正確率(87.5)還是不如訓練與測試好?
    image-5.png
    alt text
    image-6.png
    alt text
NTU

如何提升模型的辦識率?

之前的99%辦識率難道是假的?

NTU

如何提升模型的辦識率?

增強數據預處理與擴充

  • 數據增強:使用 ImageDataGenerator 或其他方法對訓練圖像進行隨機旋轉平移縮放等變換,以增加訓練樣本的多樣性,幫助模型更好地泛化。
  • 標準化與歸一化:確保數據在模型輸入前已經標準化或歸一化。

增加模型的複雜度

  • 更多卷積層:增加卷積層和過濾器的數量,使模型能夠學習更複雜的特徵。
  • 更深的全連接層:增加 Dense 層,或增加每層的神經元數量。
  • 使用 Dropout:在訓練過程中隨機丟棄一部分神經元,減少過擬合。
NTU
  1. from tensorflow.keras import layers
  2. model = models.Sequential([
  3. layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
  4. layers.MaxPooling2D((2, 2)),
  5. layers.Conv2D(64, (3, 3), activation='relu'),
  6. layers.MaxPooling2D((2, 2)),
  7. layers.Conv2D(128, (3, 3), activation='relu'),
  8. layers.MaxPooling2D((2, 2)),
  9. layers.Flatten(),
  10. layers.Dense(128, activation='relu'),
  11. layers.Dropout(0.5), # 增加 Dropout
  12. layers.Dense(10, activation='softmax')
  13. ])
NTU

調整超參數

  • 調整學習率:調整 Adam 優化器的學習率或使用其他優化器(如SGD加上動量)。
  • 使用學習率調度:根據訓練過程動態調整學習率,如使用 ReduceLROnPlateau
  1. from tensorflow.keras.callbacks import ReduceLROnPlateau
  2. lr_scheduler = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=3, min_lr=1e-5)

增大訓練數據集

  • 如果可能,使用更大的數據集進行訓練。你可以考慮將 MNIST 擴展到其他手寫數據集,如 EMNIST。

使用預訓練模型

  • 使用在更大數據集(如 ImageNet)上預訓練的模型並對其進行遷移學習,可以加快訓練過程並提升準確率。
NTU

交叉驗證

  • 使用交叉驗證來獲取模型在不同資料劃分上的穩定性能評估。

更長時間訓練

  • 增加 epochs 並使用 EarlyStopping 回調函數來避免過擬合。

調整網絡架構

  • 嘗試不同的激活函數、添加正則化(如 L2 正則化)、批正則化(Batch Normalization)等。

實際上的建議:

  • 其實不同的類型的資料,情況都不相同,遇見棘手的資料還是很難提升,有很多學者都致力於此。
NTU

作業

NTU

作業

  • 使用 MNIST 資料集進行手寫數字訓練。
  • 請訓練你的模型,使其變得更加強健,可以有較好的真實情況手寫的資料的準確率。
  • 請上傳你訓練好的模型 校名_學號_姓名.keras
  • 這裡會套用以下程式幫你批改,系統將會把你上傳的校名_學號_姓名.keras轉換成my_model.keras
  • 請勿上傳老師提供給你的模型,系統會發現的喔!
NTU
  • 準確率越高者得分越高:
  1. # 導入必要的套件
  2. from tensorflow.keras.models import load_model
  3. # 載入已存儲的模型
  4. model = load_model('my_model.keras')
  5. # 載入我們的資料集
  6. # 這裡請助教幫忙製作資料集與作業詳情
  7. # 評估模型
  8. test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)
  9. print(f'Test accuracy: {test_acc:.4f}')
NTU

作業提示

  • 數據增強
  • 大一點的 CNN 模型
  • 增加 Dropout 層來減少過擬合
  • 學習率調整回調函數
  • 使用數據增強訓練模型
NTU

思考

  • 只能識別1個位數的數字,若想識別多個位數呢?
  • 只能辦識數字仍然是很有限,能否辦識其他的文字呢?
  • 能否自動抓出有手寫數字的位置而非自己去訂固定的位置呢?
  • https://www.kaggle.com/datasets/crawford/emnist
NTU

alt3

NTU

-----------------------------------------

 主題:手寫數字識別的圖像識別模型  生活議題:建立一個圖像識別模型來識別手寫數字,用於自動化處理表單或考試卷。  內容綱要: • 卷積神經網絡(CNN)的基本概念。 • 使用 CNN 模型進行手寫數字識別,講解如何處理和分析手寫圖像數據。 • 模型的訓練和評估,以及如何將模型應用於實際問題中,如表單自動化處理。  預計使用的資料集:MNIST 數據集。  影片時長估計:20 分鐘

```python from tensorflow.keras.callbacks import EarlyStopping early_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True) ```

```python layers.BatchNormalization() ```