TensorFlow
Keras
Model Training
Logging
Machine Learning

How to print one log line per every 10 epochs when training models with tensorflow keras?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Keras prints a progress line for every epoch by default, which is often too noisy for long training runs. If you want one log line every 10 epochs, the clean solution is to suppress the built-in epoch logging and add a small callback that prints only at your chosen interval. That gives you predictable output without losing access to metrics such as loss, accuracy, or validation loss.

Disable the Default Per-Epoch Console Noise

If you keep the default Keras verbosity and also print from a custom callback, you will get duplicate output. Set verbose=0 or verbose=2 depending on how much built-in progress you still want.

For fully custom interval logging, verbose=0 is the simplest choice:

python
1history = model.fit(
2    x_train,
3    y_train,
4    epochs=100,
5    verbose=0
6)

Now Keras trains silently unless a callback prints something.

Write a Callback That Logs Every 10 Epochs

Keras callbacks can inspect the logs dictionary at the end of each epoch. The only subtlety is that the epoch argument is zero-based, so epoch 10 is reported as epoch == 9.

python
1import tensorflow as tf
2
3class EveryNEpochsLogger(tf.keras.callbacks.Callback):
4    def __init__(self, interval=10):
5        super().__init__()
6        self.interval = interval
7
8    def on_epoch_end(self, epoch, logs=None):
9        logs = logs or {}
10        epoch_number = epoch + 1
11
12        if epoch_number % self.interval == 0:
13            loss = logs.get("loss")
14            val_loss = logs.get("val_loss")
15            print(
16                f"epoch={epoch_number} "
17                f"loss={loss:.4f} "
18                f"val_loss={val_loss:.4f}" if val_loss is not None
19                else f"epoch={epoch_number} loss={loss:.4f}"
20            )

Use it like this:

python
1model.fit(
2    x_train,
3    y_train,
4    validation_data=(x_val, y_val),
5    epochs=100,
6    verbose=0,
7    callbacks=[EveryNEpochsLogger(interval=10)]
8)

That produces one line at epochs 10, 20, 30, and so on.

Handle the Final Epoch Deliberately

Sometimes the total number of epochs is not a multiple of 10. In that case, you may still want one final summary line for the last epoch. Add a stored total and print on the last epoch as well.

python
1class EveryNEpochsLogger(tf.keras.callbacks.Callback):
2    def __init__(self, interval=10, total_epochs=None):
3        super().__init__()
4        self.interval = interval
5        self.total_epochs = total_epochs
6
7    def on_epoch_end(self, epoch, logs=None):
8        logs = logs or {}
9        epoch_number = epoch + 1
10
11        should_print = (
12            epoch_number % self.interval == 0 or
13            (self.total_epochs is not None and epoch_number == self.total_epochs)
14        )
15
16        if should_print:
17            print(f"epoch={epoch_number} loss={logs.get('loss'):.4f}")

That keeps the output sparse while ensuring the final state is still visible.

Log Only the Metrics You Actually Care About

The logs dictionary often contains more than you need. A concise training log is more useful when it highlights the metrics that drive training decisions.

Common choices:

  1. loss
  2. val_loss
  3. accuracy
  4. val_accuracy

For example:

python
1class AccuracyLogger(tf.keras.callbacks.Callback):
2    def on_epoch_end(self, epoch, logs=None):
3        logs = logs or {}
4        epoch_number = epoch + 1
5        if epoch_number % 10 == 0:
6            print(
7                f"epoch={epoch_number} "
8                f"acc={logs.get('accuracy'):.4f} "
9                f"val_acc={logs.get('val_accuracy'):.4f}"
10            )

This is often easier to scan than dumping the whole dictionary each time.

Prefer a Callback Over Manual Training Loops Unless Needed

You could also train one epoch at a time inside a Python loop and print every tenth iteration, but that is usually more awkward than necessary.

python
1for epoch in range(100):
2    model.fit(x_train, y_train, epochs=1, verbose=0)
3    if (epoch + 1) % 10 == 0:
4        print(f"epoch={epoch + 1}")

This works, but you lose some of the convenience of normal fit behavior. A callback keeps the training flow idiomatic and integrates better with other callbacks such as early stopping or model checkpointing.

Common Pitfalls

  • Forgetting that the callback epoch index is zero-based and logging at the wrong intervals.
  • Leaving verbose=1 enabled and then getting both default Keras logs and custom interval logs.
  • Assuming every metric exists in logs even when validation data was not supplied.
  • Printing the entire logs dictionary and recreating the same console noise you were trying to remove.
  • Rewriting the training loop manually when a small callback would handle the requirement cleanly.

Summary

  • Suppress the default per-epoch output if you want clean interval-based logging.
  • A custom Callback is the simplest way to print one line every 10 epochs.
  • Remember that epoch is zero-based inside on_epoch_end.
  • Print only the metrics that matter for monitoring the run.
  • Optionally log the final epoch as well when the total epoch count is not divisible by the interval.

Course illustration
Course illustration

All Rights Reserved.