A Keras utility for measuring training loss and metrics in evaluation mode for clearer comparison with validation performance.
Project description
trueloss
trueloss is a Python library for measuring and plotting a Keras model's loss and metrics on the training data under evaluation conditions.
It adds these values to the normal Keras training history, making training-data performance more directly comparable with validation performance.
Why trueloss?
Training loss and validation loss are not always measured under identical conditions.
During training:
- the model operates in training mode;
- dropout and other training-only behaviour may be active;
- model weights change between batches;
- the epoch loss is accumulated throughout optimization.
Validation is measured in evaluation mode using the model weights available after the epoch.
trueloss evaluates the model on the training data after every epoch using:
model.evaluate(...)
The results are added to the Keras history with the base_ prefix:
loss
=
loss reported during training
base_loss
=
loss evaluated on the training data after the epoch
val_loss
=
loss evaluated on the validation data
Because base_loss and val_loss are both measured under evaluation conditions, they are generally more directly comparable.
However, base_loss is not guaranteed to contain only the data loss. Keras evaluation may still include regularizers or losses added through add_loss(), depending on the model.
trueloss does not replace the normal Keras training loss. It provides an additional view of training-data performance.
Features
- Supports classification and regression models.
- Adds
base_lossandbase_<metric_name>values to the Keras history. - Supports multiple compiled metrics.
- Automatically creates separate plots for loss and each detected metric.
- Supports arrays, TensorFlow datasets, and other Keras-compatible inputs.
- Returns the same Keras
Historyobject produced bymodel.fit(). - Supports TensorFlow Keras and Keras 3-based TensorFlow installations.
Installation
pip install trueloss
Basic Usage
import tensorflow as tf
from trueloss import trueloss
Create and compile the model normally:
model = tf.keras.models.Sequential([
tf.keras.layers.Input(shape=(784,)),
tf.keras.layers.Dense(64, activation="relu"),
tf.keras.layers.Dense(10, activation="softmax"),
])
model.compile(
optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"],
)
Create a trueloss instance and use its fit() method:
true_loss_instance = trueloss(
model=model,
plot=True,
)
history = true_loss_instance.fit(
x=x_train,
y=y_train,
validation_data=(x_val, y_val),
epochs=10,
batch_size=32,
verbose=1,
)
Instead of:
history = model.fit(...)
use:
history = true_loss_instance.fit(...)
The returned object is the normal Keras History object.
Using Multiple Metrics
You can compile the model with multiple compatible metrics:
model.compile(
optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=[
"accuracy",
tf.keras.metrics.SparseTopKCategoricalAccuracy(
k=3,
name="top_3_accuracy",
),
],
)
trueloss detects the available metric names automatically. No metric name is hard-coded into the plotting function.
Recommended Parameter Style
Positional arguments are supported:
history = true_loss_instance.fit(
x_train,
y_train,
epochs=10,
)
However, keyword arguments are recommended, especially when using several fit() parameters:
history = true_loss_instance.fit(
x=x_train,
y=y_train,
validation_data=(x_val, y_val),
epochs=10,
batch_size=32,
verbose=1,
)
If parameters do not behave as expected through the wrapper, use explicit keyword arguments instead of passing many optional parameters positionally.
Callbacks
When callbacks are required, pass them as a list:
history = true_loss_instance.fit(
x=x_train,
y=y_train,
epochs=10,
callbacks=[
early_stopping,
model_checkpoint,
],
)
When callbacks are not required, omit the parameter.
Do not pass:
callbacks=None
with the current version of trueloss.
Training History
For a model compiled with accuracy, the history may contain:
history.history["loss"]
history.history["accuracy"]
history.history["val_loss"]
history.history["val_accuracy"]
history.history["base_loss"]
history.history["base_accuracy"]
For multiple metrics, corresponding base_ values are added:
history.history["base_loss"]
history.history["base_accuracy"]
history.history["base_top_3_accuracy"]
For regression models, the history may contain:
history.history["base_mean_absolute_error"]
history.history["base_mean_squared_error"]
View all available values with:
print(history.history.keys())
Automatic Plotting
Set plot=True to display the plots automatically:
true_loss_instance = trueloss(
model=model,
plot=True,
)
The plotting function:
- creates one plot for loss;
- detects every additional metric;
- creates a separate subplot for each metric;
- plots training, validation, and
base_values when available.
For example, a model using accuracy and top-3 accuracy can produce:
Loss
Accuracy
Top 3 Accuracy
Manual Plotting
For greater control, disable automatic plotting:
true_loss_instance = trueloss(
model=model,
plot=False,
)
Train the model and inspect the history:
history = true_loss_instance.fit(
x=x_train,
y=y_train,
validation_data=(x_val, y_val),
epochs=10,
)
print(history.history.keys())
You can then create a custom plot:
import matplotlib.pyplot as plt
epochs = range(1, len(history.history["loss"]) + 1)
plt.plot(
epochs,
history.history["loss"],
label="Training Loss",
)
plt.plot(
epochs,
history.history["base_loss"],
label="Training-Data Evaluation Loss",
)
if "val_loss" in history.history:
plt.plot(
epochs,
history.history["val_loss"],
label="Validation Loss",
)
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.legend()
plt.show()
This gives full control over the selected values, labels, colours, and layout.
Important Notes
Prefer Explicit Validation Data
Using explicit validation data is recommended:
history = true_loss_instance.fit(
x=x_train,
y=y_train,
validation_data=(x_val, y_val),
epochs=10,
)
Be careful when using:
validation_split=0.2
Keras creates this split internally, while the current trueloss callback receives the original input arrays. The base_ values may therefore be evaluated on the complete original data rather than only the portion used for training.
Dataset Inputs
A TensorFlow dataset can be passed directly:
train_dataset = tf.data.Dataset.from_tensor_slices(
(x_train, y_train)
).batch(32)
validation_dataset = tf.data.Dataset.from_tensor_slices(
(x_val, y_val)
).batch(32)
history = true_loss_instance.fit(
x=train_dataset,
validation_data=validation_dataset,
epochs=10,
)
The training dataset is evaluated again after every epoch, so it should be finite and reusable.
Regression Usage
Regression models use the same workflow:
regression_model = tf.keras.models.Sequential([
tf.keras.layers.Input(shape=(20,)),
tf.keras.layers.Dense(64, activation="relu"),
tf.keras.layers.Dense(32, activation="relu"),
tf.keras.layers.Dense(1),
])
regression_model.compile(
optimizer="adam",
loss="mean_squared_error",
metrics=[
"mean_absolute_error",
"mean_squared_error",
],
)
true_loss_instance = trueloss(
model=regression_model,
plot=True,
)
history = true_loss_instance.fit(
x=x_train,
y=y_train,
validation_data=(x_val, y_val),
epochs=20,
batch_size=32,
)
The history may include:
history.history["loss"]
history.history["val_loss"]
history.history["base_loss"]
history.history["mean_absolute_error"]
history.history["val_mean_absolute_error"]
history.history["base_mean_absolute_error"]
history.history["mean_squared_error"]
history.history["val_mean_squared_error"]
history.history["base_mean_squared_error"]
The plotting function automatically creates separate plots for loss, mean absolute error, and mean squared error.
This can also be used with regression outputs in more complex models, including bounding-box coordinate regression, provided the model works normally with model.evaluate().
Plotting an Existing History
An existing compatible Keras history can be plotted directly:
true_loss_instance = trueloss()
true_loss_instance.plot_fn(history)
The function reads the available values from:
history.history
Complete Classification Example
import tensorflow as tf
from trueloss import trueloss
# Load and preprocess the data
(x_train, y_train), (x_val, y_val) = (
tf.keras.datasets.mnist.load_data()
)
x_train = x_train.astype("float32") / 255.0
x_val = x_val.astype("float32") / 255.0
# Create the model
model = tf.keras.models.Sequential([
tf.keras.layers.Input(shape=(28, 28)),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation="relu"),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation="softmax"),
])
# Compile the model
model.compile(
optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=[
"accuracy",
tf.keras.metrics.SparseTopKCategoricalAccuracy(
k=3,
name="top_3_accuracy",
),
],
)
# Initialize trueloss
true_loss_instance = trueloss(
model=model,
plot=True,
)
# Train the model
history = true_loss_instance.fit(
x=x_train,
y=y_train,
validation_data=(x_val, y_val),
epochs=10,
batch_size=32,
verbose=1,
)
# View available values
print(history.history.keys())
# Access the additional values
print(history.history["base_loss"])
print(history.history["base_accuracy"])
print(history.history["base_top_3_accuracy"])
View the example notebook.
Project Links
Contributing
Contributions, compatibility reports, bug reports, and pull requests are welcome through the GitHub repository.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Contact
For questions or support, use the GitHub issue tracker or contact Siddique Abusaleh at trueloss.py@gmail.com.
Citation
@misc{trueloss,
author = {Siddique Abusaleh},
title = {trueloss: Comparable Training Loss and Metrics for Keras Models},
year = {2026},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/trueloss/trueloss}}
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file trueloss-0.2.1.tar.gz.
File metadata
- Download URL: trueloss-0.2.1.tar.gz
- Upload date:
- Size: 5.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7cc5f98bd1f49c1b72b50a55303a4577a35aa354f492c2d6d1c1f19ff902b377
|
|
| MD5 |
db4d9bbf27f12ff4a6941544448890cd
|
|
| BLAKE2b-256 |
ab5b322e0d02243cd402ee7f07cc8704b800a6ad3ba03a37560769be5fda963a
|
File details
Details for the file trueloss-0.2.1-py3-none-any.whl.
File metadata
- Download URL: trueloss-0.2.1-py3-none-any.whl
- Upload date:
- Size: 4.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7c050068e75bf8504a4dee5481d7bb08e8b1e152f2d782bab5c133a2942d99c
|
|
| MD5 |
133af265fc7026a86268a5300d906e5f
|
|
| BLAKE2b-256 |
91e3db81d7f7a022f65885b0bbf9b03d55d61397866692171442835457e3c766
|