Long Keras training runs need a checkpoint file before the final epoch finishes. ModelCheckpoint saves a model or weight file during model.fit(), which protects progress and preserves the best validation result from a run that may take minutes, hours, or longer.
The callback watches a metric from the training logs, such as val_loss or val_accuracy. With save_best_only=True, it overwrites the target checkpoint only when the monitored metric improves, so the path keeps the strongest model seen so far instead of the last epoch by default.
A whole-model checkpoint in native .keras format stores the architecture, weights, compile information, and optimizer state that Keras can reload with keras.models.load_model(). Use the weights-only mode only when the architecture will be recreated separately and the checkpoint filename ends in .weights.h5.
import keras import numpy as np keras.utils.set_random_seed(42) x_train = np.linspace(-1.0, 1.0, 160, dtype="float32").reshape(80, 2) y_train = (0.75 * x_train[:, :1]) - (0.25 * x_train[:, 1:2]) x_val = np.linspace(-0.8, 0.8, 40, dtype="float32").reshape(20, 2) y_val = (0.75 * x_val[:, :1]) - (0.25 * x_val[:, 1:2]) model = keras.Sequential( [ keras.layers.Input(shape=(2,)), keras.layers.Dense(8, activation="relu"), keras.layers.Dense(1), ] ) model.compile( optimizer=keras.optimizers.Adam(learning_rate=0.05), loss="mse", metrics=["mae"], ) checkpoint_path = "checkpoints/best.keras" checkpoint = keras.callbacks.ModelCheckpoint( filepath=checkpoint_path, monitor="val_loss", mode="min", save_best_only=True, verbose=1, ) history = model.fit( x_train, y_train, validation_data=(x_val, y_val), epochs=4, batch_size=16, callbacks=[checkpoint], verbose=0, ) loaded = keras.models.load_model(checkpoint_path) loaded_loss, loaded_mae = loaded.evaluate(x_val, y_val, verbose=0) print(f"Saved checkpoint: {checkpoint_path}") print(f"Best val_loss: {min(history.history['val_loss']):.4f}") print(f"Loaded val_loss: {loaded_loss:.4f}") print(f"Loaded val_mae: {loaded_mae:.4f}")
Use a .keras suffix for a full-model checkpoint. Use .weights.h5 only with save_weights_only=True, and compile the model before loading weights when optimizer state needs to be restored.
$ python checkpoint_best_model.py Epoch 1: val_loss improved from None to 0.05945, saving model to checkpoints/best.keras ##### snipped ##### Saved checkpoint: checkpoints/best.keras Best val_loss: 0.0006 Loaded val_loss: 0.0006 Loaded val_mae: 0.0218
Loaded val_loss appears only after keras.models.load_model() opens the saved .keras checkpoint and evaluates it on the validation data.
$ rm -rf checkpoint_best_model.py checkpoints
Do not remove a real training checkpoint directory until the checkpoint has been copied, promoted, or replaced by a newer saved model.