tensorflow
tensorflow-summary
machine-learning
deep-learning
data-visualization

How do I add an arbitrary value to a TensorFlow summary?

Master System Design with Codemia

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

Introduction

TensorFlow summaries let you log scalar values, images, histograms, and more for monitoring in TensorBoard. Adding arbitrary values is useful for custom metrics that are not built into Keras callbacks. The key is to write summaries with consistent step values and clear tag names.

Log Custom Scalars with tf.summary.scalar

In TensorFlow two style code, create a summary writer and record values inside its context.

python
1import tensorflow as tf
2import time
3
4logdir = f"logs/custom/{int(time.time())}"
5writer = tf.summary.create_file_writer(logdir)
6
7for step in range(1, 6):
8    custom_value = step * 0.75
9    with writer.as_default():
10        tf.summary.scalar("my_metric/custom_score", custom_value, step=step)
11    writer.flush()
12
13print("wrote summaries to", logdir)

Run TensorBoard on that log directory to visualize the metric timeline.

Integrate Custom Values into Training Loop

In custom training loops, log loss and arbitrary values together so diagnostics remain aligned.

python
1import tensorflow as tf
2
3x = tf.random.normal((32, 4))
4y = tf.random.normal((32, 1))
5model = tf.keras.Sequential([tf.keras.layers.Dense(1)])
6opt = tf.keras.optimizers.Adam(1e-2)
7
8writer = tf.summary.create_file_writer("logs/train_loop")
9
10for step in range(1, 101):
11    with tf.GradientTape() as tape:
12        pred = model(x)
13        loss = tf.reduce_mean(tf.square(pred - y))
14
15    grads = tape.gradient(loss, model.trainable_variables)
16    opt.apply_gradients(zip(grads, model.trainable_variables))
17
18    grad_norm = tf.linalg.global_norm(grads)
19
20    with writer.as_default():
21        tf.summary.scalar("train/loss", loss, step=step)
22        tf.summary.scalar("train/grad_norm", grad_norm, step=step)
23
24writer.flush()

This gives immediate visibility into optimization stability.

Add Arbitrary Values in Keras Callback

If you use model.fit, custom callbacks are a clean way to emit extra summaries.

python
1class CustomSummaryCallback(tf.keras.callbacks.Callback):
2    def __init__(self, writer):
3        super().__init__()
4        self.writer = writer
5
6    def on_epoch_end(self, epoch, logs=None):
7        logs = logs or {}
8        score = float(logs.get("loss", 0.0)) * 1.2
9        with self.writer.as_default():
10            tf.summary.scalar("custom/epoch_score", score, step=epoch)
11
12writer = tf.summary.create_file_writer("logs/fit")

Use stable naming so dashboards stay consistent across experiments.

Logging Non-Scalar Arbitrary Data

For distributions, use histogram summaries. For images, use image summaries. Keep payload sizes reasonable to avoid heavy log directories.

python
1values = tf.random.normal((256,))
2with writer.as_default():
3    tf.summary.histogram("debug/weights_sample", values, step=1)
4writer.flush()

Choose summary type based on what you need to diagnose.

Step Management and Global Step Counters

Summary charts are only useful when step values are consistent across metrics. In custom loops, use one shared counter and increment once per optimization step.

python
1step = tf.Variable(0, dtype=tf.int64)
2
3for _ in range(5):
4    value = tf.random.uniform(())
5    with writer.as_default():
6        tf.summary.scalar("debug/random_value", value, step=step)
7    step.assign_add(1)
8
9writer.flush()

This avoids misaligned curves where one metric appears shifted from others.

Logging from Distributed Training

In distributed setups, write summaries only from chief worker to prevent duplicated event files.

python
1is_chief = True
2if is_chief:
3    with writer.as_default():
4        tf.summary.scalar("dist/loss", 0.42, step=1)

The exact chief detection depends on your orchestration environment, but the principle is stable.

Custom Scalar from Non-Tensor Data

You can summarize external measurements by converting to tensor or Python float.

python
1import psutil
2
3cpu_usage = float(psutil.cpu_percent(interval=0.1))
4with writer.as_default():
5    tf.summary.scalar("system/cpu_percent", cpu_usage, step=1)
6writer.flush()

This is useful for correlating model behavior with system conditions.

Keep Logs Manageable

Rotate log directories per run and add retention cleanup in experiments. Large stale logs slow down TensorBoard and make comparison harder.

python
1import shutil
2from pathlib import Path
3
4old = Path("logs/old_run")
5if old.exists():
6    shutil.rmtree(old)

Operational hygiene is part of effective summary usage.

Consistent monitoring improves experiment reliability and speeds up debugging during model iteration.

Repeatable instrumentation matters.

Common Pitfalls

  • Writing summaries without incrementing step values.
  • Using inconsistent tag naming across runs.
  • Forgetting to flush writer in short-lived scripts.
  • Logging huge tensors and slowing training unnecessarily.
  • Mixing multiple experiments in one log directory.

Summary

  • Use tf.summary API to log arbitrary metrics.
  • Keep step values and tag names consistent.
  • Integrate custom summaries into loops or callbacks.
  • Use scalar, histogram, or image summaries appropriately.
  • Organize log directories per experiment for clear analysis.

Course illustration
Course illustration

All Rights Reserved.