scikit-learn
machine learning
model training
loss visualization
Python

How to show loss values during training in scikit-learn?

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Scikit-learn does not have one universal training-progress API that prints loss for every estimator. Whether you can see loss during training depends on the model class. Some estimators expose a loss curve after fitting, some can print progress with verbose, and some require a manual training loop.

First Decide Which Estimator You Are Using

This question only has a clean answer if the estimator is iterative. For example:

  • 'MLPClassifier trains over iterations and exposes loss_curve_'
  • 'SGDClassifier can print progress with verbose'
  • tree models and many closed-form estimators do not train in epochs, so there is no per-epoch loss stream to show

That means the right answer is not "how do I show loss in scikit-learn" but "how do I show loss for this estimator."

MLPClassifier: Read loss_curve_

MLPClassifier stores the loss at each iteration after fitting. That is the easiest built-in option.

python
1from sklearn.datasets import make_classification
2from sklearn.model_selection import train_test_split
3from sklearn.neural_network import MLPClassifier
4
5X, y = make_classification(
6    n_samples=1000,
7    n_features=20,
8    n_informative=10,
9    random_state=42,
10)
11
12X_train, X_test, y_train, y_test = train_test_split(
13    X, y, test_size=0.2, random_state=42
14)
15
16clf = MLPClassifier(
17    hidden_layer_sizes=(32, 16),
18    max_iter=50,
19    random_state=42,
20    verbose=True,
21)
22clf.fit(X_train, y_train)
23
24print(clf.loss_)
25print(clf.loss_curve_[:5])

Here you get both:

  • console output during fitting when verbose=True
  • the full recorded curve afterward in loss_curve_

That is the closest scikit-learn gets to the familiar deep-learning training log.

SGDClassifier: Use verbose or a Manual Loop

For SGD-based estimators, verbose can print training progress:

python
1from sklearn.datasets import make_classification
2from sklearn.linear_model import SGDClassifier
3
4X, y = make_classification(n_samples=1000, n_features=20, random_state=42)
5
6clf = SGDClassifier(loss="log_loss", max_iter=20, tol=None, verbose=1, random_state=42)
7clf.fit(X, y)

This is useful for quick inspection, but it does not always give you a neat loss-history list. If you want to record values explicitly, use partial_fit and compute the loss yourself after each epoch.

python
1import numpy as np
2from sklearn.datasets import make_classification
3from sklearn.linear_model import SGDClassifier
4from sklearn.metrics import log_loss
5
6X, y = make_classification(n_samples=1000, n_features=20, random_state=42)
7
8clf = SGDClassifier(loss="log_loss", random_state=42)
9classes = np.unique(y)
10losses = []
11
12for epoch in range(10):
13    clf.partial_fit(X, y, classes=classes)
14    probabilities = clf.predict_proba(X)
15    losses.append(log_loss(y, probabilities))
16
17print(losses)

This pattern works because partial_fit lets you drive the training loop manually.

Plot the Values

Once you have a list of losses, plotting is straightforward.

python
1import matplotlib.pyplot as plt
2
3plt.plot(losses, marker="o")
4plt.xlabel("Epoch")
5plt.ylabel("Log loss")
6plt.title("Training loss")
7plt.show()

For MLPClassifier, you can plot clf.loss_curve_ directly.

When Loss Is Not Available

Some estimators in scikit-learn do not expose an iterative loss history because they are not optimized in a way that naturally produces one for users. Decision trees are a good example. Asking for a Keras-style live loss readout from those estimators is the wrong expectation.

In those cases, look at:

  • cross-validation scores
  • training and validation metrics
  • learning curves over dataset size or model settings

That gives meaningful visibility even when there is no epoch-by-epoch loss stream.

Choose the Right Tool for the Goal

If your main goal is rich per-batch training metrics, scikit-learn may not be the best fit. Frameworks like Keras and PyTorch are designed around exposed training loops and callbacks. Scikit-learn is optimized more for consistent estimator APIs and fast experimentation than for detailed deep-learning-style logging.

That is not a weakness. It just means the monitoring strategy depends heavily on the estimator.

Common Pitfalls

Expecting every scikit-learn estimator to expose loss_curve_ is a common mistake. Only certain iterative models do.

Turning on verbose and assuming you will automatically get a reusable Python list of losses is also incorrect. Sometimes you only get console output.

Computing loss on the test set after every partial_fit step mixes training monitoring with evaluation leakage. Track training loss on the training data or keep a separate validation split.

Comparing scikit-learn progress logging directly to deep-learning frameworks leads to the wrong expectations about the API design.

Summary

  • Loss visibility in scikit-learn depends on the estimator.
  • 'MLPClassifier exposes loss_curve_ and can also print progress with verbose=True.'
  • 'SGDClassifier can print progress, and partial_fit lets you compute loss manually per epoch.'
  • Some models do not provide a meaningful per-iteration loss history at all.
  • Start by asking what your estimator supports before trying to build a generic loss-monitoring solution.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track 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.

Practice ML system design

All Rights Reserved.