在 Keras 中,要在訓練週期(epoch)結束時自動做事,就把回呼(callbacks)物件傳進 model.fit() 的 callbacks 參數。最常用的兩個是 ModelCheckpoint(自動儲存模型)和 EarlyStopping(驗證損失不再改善就提前停止)。這篇文章附上一次實際訓練的 log,說明兩者搭配時最容易踩到的一個坑:EarlyStopping 停下來時,模型手上的權重不一定是最好的那一組。
什麼是 Keras callbacks?為什麼需要它?
Keras callbacks 是 Keras 在訓練過程特定時間點自動呼叫的物件,例如每個 epoch 結束、每個 batch 結束、訓練開始或結束時。它讓你不用改寫訓練迴圈,就能插入儲存模型、提前停止、調整學習率、寫 log 等動作。
常見用途包括:
- ModelCheckpoint:在訓練過程中儲存模型或權重,訓練中斷也不會前功盡棄。
- EarlyStopping:被監控的指標(通常是
val_loss)連續幾個 epoch 沒有改善就停止訓練,避免過擬合(overfitting),也節省時間。 - ReduceLROnPlateau:指標停滯時自動調降學習率。
- TensorBoard:把訓練過程寫成 log,用 TensorBoard 觀察模型效能。
ModelCheckpoint 與 EarlyStopping 完整程式碼範例
Keras 3 的寫法是把兩個回呼放進同一個 list,傳給 model.fit() 的 callbacks 參數,並且一定要提供驗證資料,否則 val_loss 不存在,兩個回呼都沒有東西可以監控。
import keras
callbacks = [
keras.callbacks.ModelCheckpoint(
"best.keras", # Keras 3 建議用 .keras 格式
monitor="val_loss",
save_best_only=True, # 只在 val_loss 創新低時覆寫檔案
verbose=1,
),
keras.callbacks.EarlyStopping(
monitor="val_loss",
patience=3, # 連續 3 個 epoch 沒改善就停
restore_best_weights=True, # 停下來時把權重還原成最佳那一輪
verbose=1,
),
]
model.fit(
X_train, y_train,
epochs=50, # 上限可以設大一點,交給 EarlyStopping 決定何時停
batch_size=32,
validation_data=(X_val, y_val),
callbacks=callbacks,
)
這份範例和舊版寫法有三個差別:
| 項目 | 舊寫法(Keras 2 時代) | Keras 3 建議寫法 |
|---|---|---|
| import | from keras.callbacks import ... | keras.callbacks.ModelCheckpoint(...) |
| 儲存格式 | model.h5 | best.keras(.h5 仍可用,但會出現「legacy 格式」警告) |
| 訓練函式 | fit() 或 fit_generator() | 只有 fit(),Keras 3 已經移除 fit_generator() |
實際跑一次:EarlyStopping 在第幾輪停下來?
以下是用 Keras 3.15.1(JAX 後端)實際執行的結果。資料是 600 筆帶雜訊的二元分類假資料(400 筆訓練、200 筆驗證),模型是兩層各 256 個神經元的 Dense 網路,參數量刻意開大,讓它很快過擬合。epochs 設 50,patience=3。
逐輪的驗證損失如下:
| Epoch | 訓練準確率 | val_loss | ModelCheckpoint 動作 |
|---|---|---|---|
| 1 | 0.5950 | 0.5681 | 儲存 |
| 2 | 0.7975 | 0.4979 | 儲存 |
| 3 | 0.8275 | 0.4893 | 儲存 |
| 4 | 0.8575 | 0.4889 | 儲存(最佳) |
| 5 | 0.8750 | 0.5027 | 沒改善,不儲存 |
| 6 | 0.8950 | 0.5184 | 沒改善,不儲存 |
| 7 | 0.9050 | 0.5361 | 沒改善,觸發 early stopping |
最後幾輪的原始 log:
Epoch 4: val_loss improved from 0.48931 to 0.48890, saving model to best.keras
13/13 - 0s - accuracy: 0.8575 - loss: 0.3521 - val_accuracy: 0.7700 - val_loss: 0.4889
Epoch 5: val_loss did not improve from 0.48890
13/13 - 0s - accuracy: 0.8750 - loss: 0.3116 - val_accuracy: 0.7600 - val_loss: 0.5027
Epoch 6: val_loss did not improve from 0.48890
13/13 - 0s - accuracy: 0.8950 - loss: 0.2821 - val_accuracy: 0.7550 - val_loss: 0.5184
Epoch 7: val_loss did not improve from 0.48890
13/13 - 0s - accuracy: 0.9050 - loss: 0.2570 - val_accuracy: 0.7550 - val_loss: 0.5361
Epoch 7: early stopping
從表格可以看到典型的過擬合訊號:第 4 輪之後,訓練準確率還在一路往上(0.8575 → 0.9050),驗證損失卻開始變差(0.4889 → 0.5361)。EarlyStopping 在最佳輪之後又多等了 patience=3 輪,確認真的沒有改善,才在第 7 輪停下來。原本設定的 50 輪只跑了 7 輪。
restore_best_weights 沒開會怎樣?
restore_best_weights 預設是 False。沒開的話,EarlyStopping 停下來時,模型保留的是最後一輪(第 7 輪)的權重,而不是最佳的第 4 輪。
同一份資料、同一個亂數種子,只切換這個參數,訓練結束後直接對驗證集呼叫 model.evaluate():
| 設定 | 停止時的權重來自 | 訓練結束後模型的 val_loss |
|---|---|---|
restore_best_weights=False(預設) | 第 7 輪 | 0.5361 |
restore_best_weights=True | 第 4 輪 | 0.4889 |
開啟後,Keras 會印出 Restoring model weights from the end of the best epoch: 4.,手上的模型直接就是最佳版本。
如果沒開 restore_best_weights,但有搭配 ModelCheckpoint(save_best_only=True),最佳模型仍然存在 best.keras 裡,只是要記得用 keras.models.load_model("best.keras") 重新載入,而不是直接拿記憶體中的 model 去預測或匯出。這是兩個回呼搭配使用時最常見的誤會。
patience 和其他參數要怎麼設?
patience 設太小,模型可能在驗證損失短暫波動時就被誤判停止;設太大,則會多跑很多無效的 epoch。一般可以先從 3 到 10 之間開始,再依照 val_loss 曲線的抖動程度調整。
EarlyStopping 常用參數(依 Keras 3 的函式簽名整理):
| 參數 | 預設值 | 作用與設定建議 |
|---|---|---|
monitor | "val_loss" | 要監控的指標。改成 val_accuracy 這類越大越好的指標時,mode 會自動判斷 |
patience | 0 | 允許連續幾個 epoch 沒有改善。資料少、val_loss 抖動大時設大一點 |
min_delta | 0 | 至少要進步多少才算「改善」。設成像 0.001 可以忽略微小雜訊 |
restore_best_weights | False | 停止時是否還原成最佳那一輪的權重,多數情況建議開啟 |
start_from_epoch | 0 | 前幾個 epoch 不檢查。模型需要暖身期(例如搭配學習率 warmup)時使用 |
baseline | None | 指標必須先達到這個基準值,否則會提前停止 |
ModelCheckpoint 常用參數:
| 參數 | 預設值 | 作用與設定建議 |
|---|---|---|
filepath | 必填 | 存完整模型用 .keras;只存權重時必須以 .weights.h5 結尾 |
save_best_only | False | 設 True 才會只保留最佳模型,否則每個 epoch 都會覆寫 |
save_weights_only | False | 只存權重,檔案較小,但載入時要先建好相同結構的模型 |
save_freq | "epoch" | 也可以設成整數,每 N 個 batch 存一次,適合單一 epoch 很長的訓練 |
常見設定錯誤有哪些?
下面幾個錯誤都會讓回呼「看起來有設定,其實沒有照預期運作」:
- 沒有傳
validation_data或validation_split。 監控val_loss卻沒有驗證資料,Keras 只會發出UserWarning: Early stopping conditioned on metric `val_loss` which is not available警告,訓練照樣跑完全部 epoch,EarlyStopping 永遠不會觸發。 - 只存權重卻沒用
.weights.h5副檔名。 在 Keras 3.15.1 實測,ModelCheckpoint("model.weights", save_weights_only=True)會直接丟出ValueError,錯誤訊息要求檔名必須以.weights.h5結尾。 - 沿用舊教學的
model.h5。 可以執行,但會出現 HDF5 是 legacy 格式的警告,官方建議改成.keras。 - 照舊教學呼叫
fit_generator()。 Keras 3 已經沒有這個方法,generator 或tf.data.Dataset直接傳給fit()就可以。 - 以為 EarlyStopping 停下來就是最佳模型。 沒開
restore_best_weights=True時不是,見上一節的對照表。 save_best_only沒開,最佳模型被後面的 epoch 覆寫。 檔案最後存的是最後一輪,不是最佳一輪。
如何自訂 callback 或組合多個回呼?
自訂回呼的做法是繼承 keras.callbacks.Callback,覆寫 on_epoch_end()、on_train_begin() 等方法。每個方法都會收到 logs 字典,裡面有當輪的 loss、val_loss 等指標。
class PrintValLoss(keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs=None):
print(f"epoch {epoch + 1}: val_loss={logs['val_loss']:.4f}")
多個回呼放進同一個 list 就會一起運作,例如「ModelCheckpoint 儲存最佳模型+EarlyStopping 提前停止+ReduceLROnPlateau 調降學習率」。回呼會依照 list 裡的順序被呼叫。
常見問題
Keras 的 callback 是什麼?
Keras callback 是一個會在訓練過程特定時間點(epoch 結束、batch 結束等)被 Keras 自動呼叫的物件,用來插入儲存模型、提前停止訓練、調整學習率等操作。
EarlyStopping 的 patience 參數是什麼意思?
patience 是允許被監控指標連續幾個 epoch 沒有改善的次數。本文實測設 patience=3,最佳結果出現在第 4 輪,之後連續 3 輪沒有改善,所以在第 7 輪停止。
EarlyStopping 停止後,模型是最好的那一版嗎?
預設不是。restore_best_weights 預設為 False,模型保留的是最後一輪的權重。本文實測中,沒開時 val_loss 是 0.5361,開啟後是 0.4889。
ModelCheckpoint 一定要搭配 EarlyStopping 嗎?
不需要,兩者可以獨立使用。實務上常一起使用:ModelCheckpoint 負責把最佳模型存到檔案,EarlyStopping 負責在不再進步時結束訓練。
Keras 3 還能用 .h5 格式存模型嗎?
可以,但 Keras 會提示 HDF5 是 legacy 格式,建議改用 .keras。只存權重時,檔名必須以 .weights.h5 結尾,否則會出現 ValueError。
參考資料
延伸閱讀
- Keras model.fit() 參數設定:batch_size、epochs、validation 與 callbacks 怎麼用?:
validation_data和epochs的設定會直接影響 EarlyStopping 的效果。 - 如何判讀機器學習訓練結果:loss、accuracy、val_loss、val_accuracy 完整解讀:判斷 loss 與 val_loss 曲線是不是過擬合。
- 梯度下降法介紹:一階最佳化算法如何找到局部極小值?:每個 epoch 裡權重實際是怎麼被更新的。
最後更新
2026-09-25:改用 Keras 3 寫法(.keras 格式、移除 fit_generator()),補上實際訓練 log、restore_best_weights 前後對照、參數設定表與常見設定錯誤。原文發布於 2023-01-11。
關於作者
Claire Chang | 企業 AI 導入與流程轉型顧問。專注於 AI Agent 架構設計、ERP 系統整合與企業 AI 治理。
首次發布:2023-01-11
