Training metrics are easier to interpret when their history is visible across epochs instead of reduced to the last line printed by model.fit(). The built-in TensorBoard callback sends a Keras run's loss and compiled metrics to event files that TensorBoard can read while training or afterward.
The callback uses the TensorFlow backend because its event writer comes from TensorFlow. Epoch-level updates capture the useful scalar trend without the synchronization overhead of writing after every batch.
Each execution writes to a UTC-stamped child of logs/tensorboard so separate experiments remain selectable in the TensorBoard interface. The final inspection checks for three recorded steps of epoch_loss and epoch_accuracy, proving that the handoff contains training data rather than an empty log directory.
$ python -m pip install --upgrade keras tensorflow tensorboard
import os from datetime import datetime, timezone from pathlib import Path os.environ["KERAS_BACKEND"] = "tensorflow" os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2" import keras import numpy as np keras.utils.set_random_seed(31) run_name = datetime.now(timezone.utc).strftime("run-%Y%m%d-%H%M%S") log_dir = Path("logs/tensorboard") / run_name
x_train = np.linspace(0.0, 1.0, 80, dtype="float32").reshape(20, 4) y_train = ((x_train[:, 0] + x_train[:, 1]) > 0.8).astype("float32") model = keras.Sequential( [ keras.Input(shape=(4,), name="features"), keras.layers.Dense(8, activation="relu"), keras.layers.Dense(1, activation="sigmoid"), ] ) model.compile( optimizer=keras.optimizers.Adam(learning_rate=0.03), loss=keras.losses.BinaryCrossentropy(), metrics=[keras.metrics.BinaryAccuracy(name="accuracy")], )
tensorboard_callback = keras.callbacks.TensorBoard( log_dir=log_dir, histogram_freq=0, update_freq="epoch", ) model.fit( x_train, y_train, epochs=3, batch_size=5, callbacks=[tensorboard_callback], verbose=0, )
A distinct log_dir keeps experiments selectable. The histogram_freq=0 and update_freq="epoch" settings avoid weight-distribution work and batch-level write overhead.
event_files = list(log_dir.rglob("events.out.tfevents.*")) print(f"Run directory: {log_dir}") print(f"TensorBoard event files: {len(event_files)}")
import os from datetime import datetime, timezone from pathlib import Path os.environ["KERAS_BACKEND"] = "tensorflow" os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2" import keras import numpy as np keras.utils.set_random_seed(31) run_name = datetime.now(timezone.utc).strftime("run-%Y%m%d-%H%M%S") log_dir = Path("logs/tensorboard") / run_name x_train = np.linspace(0.0, 1.0, 80, dtype="float32").reshape(20, 4) y_train = ((x_train[:, 0] + x_train[:, 1]) > 0.8).astype("float32") model = keras.Sequential( [ keras.Input(shape=(4,), name="features"), keras.layers.Dense(8, activation="relu"), keras.layers.Dense(1, activation="sigmoid"), ] ) model.compile( optimizer=keras.optimizers.Adam(learning_rate=0.03), loss=keras.losses.BinaryCrossentropy(), metrics=[keras.metrics.BinaryAccuracy(name="accuracy")], ) tensorboard_callback = keras.callbacks.TensorBoard( log_dir=log_dir, histogram_freq=0, update_freq="epoch", ) model.fit( x_train, y_train, epochs=3, batch_size=5, callbacks=[tensorboard_callback], verbose=0, ) event_files = list(log_dir.rglob("events.out.tfevents.*")) print(f"Run directory: {log_dir}") print(f"TensorBoard event files: {len(event_files)}")
$ python log_tensorboard.py Run directory: logs/tensorboard/run-20260713-005913 TensorBoard event files: 1
$ tensorboard --logdir logs/tensorboard Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all TensorBoard 2.21.0 at http://localhost:6006/ (Press CTRL+C to quit)
$ tensorboard --inspect --logdir logs/tensorboard ====================================================================== Processing event files... (this can take a few minutes) ====================================================================== Found event files in: logs/tensorboard/run-20260713-005913/train These tags are in logs/tensorboard/run-20260713-005913/train: ##### snipped ##### tensor epoch_accuracy epoch_learning_rate epoch_loss keras ##### snipped ##### tensor first_step 0 last_step 2 max_step 2 min_step 0 num_steps 3 outoforder_steps [] ======================================================================
The interface at http://localhost:6006/ presents the timestamped run's loss and accuracy curves.