Implementation:Fastai Fastbook ClassificationInterpretation
| Knowledge Sources | |
|---|---|
| Domains | Computer_Vision, Deep_Learning, Model_Evaluation |
| Last Updated | 2026-02-09 17:00 GMT |
Overview
Concrete tools for analyzing classification model performance and cleaning training data provided by fastai.interpret.ClassificationInterpretation and fastai.vision.widgets.ImageClassifierCleaner.
Description
ClassificationInterpretation computes predictions on the validation set and provides methods to visualize the confusion matrix, display the highest-loss images, and list the most confused category pairs. ImageClassifierCleaner is an interactive Jupyter widget that lets practitioners review and relabel or delete problematic images directly in the notebook.
Usage
Create a ClassificationInterpretation object after training is complete. Use its visualization methods to identify error patterns, then optionally launch the ImageClassifierCleaner widget to fix data quality issues before retraining.
Code Reference
Source Location
- Repository: fastbook
- File: translations/cn/02_production.md (lines 419-454), translations/cn/05_pet_breeds.md (lines 572-586)
Signature
# Create interpretation object from a trained Learner
ClassificationInterpretation.from_learner(learn)
# Plot the confusion matrix
ClassificationInterpretation.plot_confusion_matrix(
normalize=False, # Show raw counts or normalized percentages
title='Confusion matrix',
cmap='Blues', # Colormap
norm_dec=2, # Decimal places for normalized values
figsize=None,
**kwargs
)
# Plot the images with highest losses
ClassificationInterpretation.plot_top_losses(
k=9, # Number of top-loss images to show
largest=True, # If True, show highest losses; if False, lowest
figsize=None,
**kwargs
)
# Return list of most confused category pairs
ClassificationInterpretation.most_confused(
min_val=1 # Minimum number of confusions to include
)
# Interactive data cleaner widget
ImageClassifierCleaner(learn)
Import
from fastai.vision.all import ClassificationInterpretation
from fastai.vision.widgets import ImageClassifierCleaner
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| learn | Learner | Yes | A trained Learner whose validation set will be evaluated |
| k | int | No | Number of top-loss images to display (default: 9) |
| largest | bool | No | Show highest losses if True, lowest if False (default: True) |
| normalize | bool | No | Normalize confusion matrix rows to percentages (default: False) |
| min_val | int | No | Minimum confusion count to include in most_confused output (default: 1) |
Outputs
| Name | Type | Description |
|---|---|---|
| interp | ClassificationInterpretation | Object holding all validation predictions, losses, and decoded outputs |
| confusion matrix | matplotlib figure | Heatmap showing predicted vs. actual class counts |
| top losses | matplotlib figure | Grid of images labeled with predicted/actual/loss/probability |
| most_confused | list of tuples | List of (actual, predicted, count) triples sorted by count descending |
| cleaner widget | ImageClassifierCleaner | Interactive Jupyter widget for reviewing and relabeling images |
Usage Examples
Basic Usage: Full Interpretation Pipeline
from fastai.vision.all import *
# Assume 'learn' is a trained Learner
interp = ClassificationInterpretation.from_learner(learn)
# 1. Plot confusion matrix
interp.plot_confusion_matrix(figsize=(12, 12))
# 2. Show the 9 images with highest loss
interp.plot_top_losses(k=9, nrows=3)
# 3. List the most confused category pairs
most_confused = interp.most_confused(min_val=5)
print('Most confused pairs:')
for actual, predicted, count in most_confused:
print(f' {actual} -> {predicted}: {count} confusions')
Data Cleaning with ImageClassifierCleaner
from fastai.vision.widgets import ImageClassifierCleaner
# Launch interactive cleaner widget
cleaner = ImageClassifierCleaner(learn)
cleaner
# After reviewing images in the widget, apply changes:
# Delete images marked for deletion
for idx in cleaner.delete():
cleaner.fns[idx].unlink()
# Move images marked for category change
for idx, cat in cleaner.change():
shutil.move(str(cleaner.fns[idx]), path / cat)
Normalized Confusion Matrix
# Normalized view shows percentages instead of counts
# Useful when class sizes are imbalanced
interp.plot_confusion_matrix(normalize=True, figsize=(12, 12))
Examining Top Losses in Detail
# Get the raw top losses data
losses, idxs = interp.top_losses()
# Print details for the top 5
for i in range(5):
idx = idxs[i]
print(f'Loss: {losses[i]:.4f}')
print(f' Predicted: {interp.decoded[idx]}')
print(f' Actual: {interp.targs[idx]}')
print(f' File: {interp.dl.items[idx]}')
print()