Getting precision, recall and F1 score per class in Keras
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
If you want precision, recall, and F1 score per class in Keras, the most practical approach is usually to compute predictions first and then evaluate them outside the training loop. Keras provides built-in metrics, but per-class metrics for multiclass classification are much easier and more reliable to obtain with a post-processing step such as classification_report.
Core Sections
Why built-in Keras metrics are not the whole answer
Keras has metrics such as Precision and Recall, but those are not automatically "per class" for a multiclass softmax model in the way many people expect. They are usually threshold-oriented or aggregate over predictions, which makes them less convenient when you want a class-by-class table.
For per-class reporting, the normal workflow is:
- run
model.predict(...) - convert probabilities to predicted class IDs
- compare predictions against the true labels
- calculate per-class metrics using a reporting library
That keeps evaluation explicit and avoids confusion about what the training-time metric actually means.
Post-training evaluation with classification_report
For multiclass problems, scikit-learn is the easiest way to get per-class precision, recall, and F1.
In a real Keras workflow, y_pred_proba comes from model.predict(x_val). This produces a table with one row per class, which is usually what people mean by "precision, recall and F1 per class."
Full Keras example
That gives you per-class metrics after training or validation without needing fragile custom metric code inside the model compile step.
If you want metrics after every epoch
Sometimes you want class-level metrics on the validation set after each epoch. A callback is a good place for that.
This is heavier than scalar metrics, but it is useful when you care about minority-class behavior during training.
Binary versus multiclass details
Be careful with label shape and prediction conversion:
- binary sigmoid output usually needs thresholding, such as
pred > 0.5 - multiclass softmax output usually needs
argmax - one-hot labels may need
argmaxbefore comparison
If the shapes do not match, the metric report can look wrong even though the model itself is fine.
When custom Keras metrics still make sense
If you only need macro-averaged precision or recall during training, a custom Keras metric can be reasonable. But true per-class reporting is usually easier outside the compiled metric system because it naturally produces a table instead of one scalar.
That separation also makes evaluation reproducible across frameworks and easier to compare with other models.
Common Pitfalls
- Expecting built-in Keras
PrecisionandRecallmetrics to automatically give per-class multiclass reports. - Forgetting to convert softmax probabilities to class IDs with
argmaxbefore computing the report. - Comparing one-hot encoded labels directly to integer class predictions without reshaping or decoding first.
- Reporting metrics on the training set only and assuming they reflect real validation behavior.
- Printing per-class reports every epoch on huge validation sets without considering the extra evaluation cost.
Summary
- Per-class precision, recall, and F1 are usually easiest to compute after
model.predict(...). - For multiclass models, convert predicted probabilities to class IDs with
argmax. - '
classification_reportfromscikit-learnis the most practical tool for class-by-class evaluation.' - Use a callback only if you need those reports during training rather than after it.
- Keep training-time scalar metrics and detailed evaluation reports as separate concerns.
Related reading
- Getting reproducible results using tensorflow-gpu
- Getting reproducible results using tensorflow-gpu
- Getting tensorflow is not a supported wheel on this platform
- Getting Tensorflow s is not valid scope name error while I am trying to create a model for kaggle competition
- Getting the current learning rate from a tf.train.AdamOptimizer
- Getting ValueError y contains new labels when using scikit learn's LabelEncoder
- Getting Tensorflow s is not valid scope name error while I am trying to create a model for kaggle competition
- Ghost line in Tensorboard scalar plot
.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.