Callbacks

Keras · Practical · 10 min

Callbacks add stopping, saving, scheduling and logging to training without writing a custom loop.

A callback is an object whose methods fit() calls at points in training: on_train_begin, on_epoch_begin/on_epoch_end, on_train_batch_end and so on. Pass a list with fit(..., callbacks=[...]).

The built-in ones cover most needs:

  • EarlyStopping(monitor="val_loss", patience=5, restore_best_weights=True): stop when the monitored value stops improving and roll back to the best epoch.
  • ModelCheckpoint("best.keras", save_best_only=True): save the model (or weights with a .weights.h5 path) during training.
  • ReduceLROnPlateau(factor=0.5, patience=2): lower the learning rate when progress stalls.
  • LearningRateScheduler(fn): set the rate per epoch from a function.
  • TensorBoard(log_dir), CSVLogger(path): logging.
  • BackupAndRestore(dir): resume automatically after an interruption.

To write your own, subclass keras.callbacks.Callback. Inside, self.model is the model being trained and logs is a dict of the current metrics (loss, val_loss...). Setting self.model.stop_training = True stops training.

Monitored names must match the logs exactly, including the val_ prefix, which requires validation data.

Example

import numpy as np
import keras

x = np.random.rand(500, 4).astype("float32")
y = x.sum(axis=1)
model = keras.Sequential([keras.Input((4,)),
                          keras.layers.Dense(16, activation="relu"),
                          keras.layers.Dense(1)])
model.compile(optimizer="adam", loss="mse")

class PrintEvery(keras.callbacks.Callback):
    def on_epoch_end(self, epoch, logs=None):
        if epoch % 20 == 0:
            print(f"epoch {epoch}: val_loss={logs['val_loss']:.4f}")

callbacks = [
    keras.callbacks.EarlyStopping(monitor="val_loss", patience=5, restore_best_weights=True),
    keras.callbacks.ModelCheckpoint("best.keras", monitor="val_loss", save_best_only=True),
    keras.callbacks.ReduceLROnPlateau(monitor="val_loss", factor=0.5, patience=2),
    PrintEvery(),
]
history = model.fit(x, y, epochs=300, validation_split=0.2, callbacks=callbacks, verbose=0)
print("trained for", len(history.history["loss"]), "epochs")   # fewer than 300

Remember

  • EarlyStopping + ModelCheckpoint + ReduceLROnPlateau is a solid default
  • Custom callbacks override on_* methods and read logs
  • Monitored keys must exist in logs (e.g. val_loss needs validation data)

Watch out for

  • Monitoring val_accuracy without passing validation data, so the callback never triggers (Keras only warns).

Check yourself

  1. What does restore_best_weights=True add to EarlyStopping?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: keras.io/api/callbacks/