EarlyStopping is ignoring my custom metrics defined. Keras model
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
Keras EarlyStopping ignores custom metrics when the monitor parameter does not match the exact metric name in the training logs. The metric name used in EarlyStopping(monitor='...') must match the name that appears in model.fit() output — for validation metrics, this is val_ prefixed to the metric name. If the custom metric function is named my_f1_score, the monitor string must be 'val_my_f1_score'. Common causes include typos in the monitor name, not passing validation_data to fit(), and the metric not being added to model.compile(metrics=[...]).
The Problem
The Fix: Match the Exact Metric Name
Finding the Correct Metric Name
Custom Metric as a Class
Using a class gives you explicit control over the name:
Setting the Correct Mode
Combining Multiple Callbacks
Common Pitfalls
- Typo in the
monitorstring:monitor='val_f1'does not match'val_f1_score'. Keras prints a warning but continues training without early stopping. Always run one epoch first and checkhistory.history.keys()to see the exact metric names available. - Forgetting
validation_datainmodel.fit(): Without validation data, theval_prefixed metrics do not exist.monitor='val_f1_score'triggers the "metric not available" warning. Either passvalidation_data=(x_val, y_val)or usevalidation_split=0.2. - Using
mode='auto'with custom metrics: Auto mode infers direction from the metric name — it recognizes'loss','acc','accuracy'but not custom names. For custom metrics, always setmode='max'ormode='min'explicitly to avoid the wrong stopping direction. - Custom function metric vs class metric state: A function metric (plain
def f1_score(y_true, y_pred)) is computed per-batch and averaged. A class metric (tf.keras.metrics.Metric) accumulates state across batches. For metrics like F1 that depend on global counts (TP, FP, FN), the class version is mathematically correct while the function version gives a biased average. - Not adding the metric to
model.compile(metrics=[]): If the custom metric is not passed tocompile, it does not appear in training logs.EarlyStopping(monitor='val_my_metric')cannot find it. Ensure the metric is listed inmodel.compile(metrics=[my_metric]).
Summary
- The
monitorstring must exactly match the metric name in training logs — check withhistory.history.keys() - For validation metrics, prefix with
val_: functionf1_scorebecomesmonitor='val_f1_score' - Always set
mode='max'ormode='min'explicitly for custom metrics —mode='auto'may guess wrong - Use
tf.keras.metrics.Metricsubclass for metrics that need per-epoch aggregation (F1, precision, recall) - Pass
validation_datatomodel.fit()— without it,val_*metrics do not exist
Related reading
- Effects of randomizing the order of inputs to a neural network
- Efficient element-wise multiplication of a matrix and a vector in TensorFlow
- Efficiently grab gradients from TensorFlow?
- ERROR Cannot uninstall 'wrapt'. when installing tensorflow-gpu1.14
- Edit tensorflow inceptionV3 retraining-example.py for multiple classificiations
- Edit tensorflow inceptionV3 retraining-example.py for multiple classificiations
- Edge TPU Compiler ERROR quantized_dimension must be in range 0, 1. Was 3
- Effective queries in machine learning
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.