Skip to main content

Lightweight local experiment saver for TensorFlow/Keras and PyTorch classification runs

Project description

experiment-saver

A lightweight experiment saver for TensorFlow/Keras and PyTorch classification projects.

It helps you keep every run organized in one folder (models, logs, ROC/AUC, confusion matrix, classification report, environment info, etc.) without rewriting boilerplate saving code each time.


What this repo contains

This repo currently provides two independent savers:

1) TensorFlow / Keras

File: saver_tensorflow.py

Saves:

  • metrics.csv (via CSVLogger)
  • best_model.keras (via ModelCheckpoint)
  • final_model.keras
  • history.json
  • roc_auc.json + ROC arrays (.npy)
  • confusion_matrix.npy
  • classification_report.json
  • validation outputs (val_labels.npy, val_scores.npy, val_predictions.npy)
  • reproducibility files (random_seeds.json, environment.json, git_commit.json)
  • manifest.json

2) PyTorch

File: experiment_saver_torch.py

Includes everything above, plus extra PyTorch-specific utilities:

  • optimizer + scheduler state saving
  • last epoch saving
  • gradient norm logging
  • learning-rate history logging
  • epoch time logging
  • model summary (optional torchinfo)
  • parameter count + architecture export

Installation

Option A) Install from GitHub (editable for development)

git clone https://github.com/AhmedAbdAlKareem1/experiment_saver.git
cd experiment_saver
pip install -e .

Option B) Install as normal

pip install .

Note: dependencies depend on which backend you use (TensorFlow or PyTorch).

TensorFlow / Keras usage

import tensorflow as tf
from experiment_saver import TFExperimentSaver, TFExperimentConfig

saver = TFExperimentSaver(
    config=TFExperimentConfig(
        run_dir="runs/keras_exp001",
        monitor="val_loss",
        patience=5,
        save_best_only=True,
        verbose=1,
    ),
    class_names=["Cat", "Dog"],   # optional but recommended
)

history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=20,
    callbacks=saver.callbacks(),
    verbose=1,
)

saved_paths = saver.save_after_fit(
    model=model,
    history=history,
    val_ds=val_ds,
    extra_config={
        "backbone": "ResNet50",
        "image_size": [224, 224],
        "optimizer": "Adam",
        "lr": 1e-4,
    },
)

print("Saved artifacts:", saved_paths)

PyTorch usage

import time
import torch
from torch.utils.data import DataLoader

from experiment_saver import TorchExperimentSaver, TorchExperimentConfig

saver = TorchExperimentSaver(
    config=TorchExperimentConfig(
        run_dir="runs/torch_exp001",
        monitor="val_loss",
        patience=5,
        verbose=1,
        model_input_size=(1, 3, 224, 224),  # optional, for torchinfo summary
    ),
    class_names=["Cat", "Dog"],
)

early_stop = saver.make_early_stopping()

for epoch in range(20):
    t0 = time.time()

    # --- train ---
    model.train()
    # train_loss = ...
    # (your training code here)

    # --- validate ---
    model.eval()
    # val_loss = ...
    # val_acc = ...

    saver.log_lr(optimizer, epoch=epoch)

    metrics = {
        "train_loss": float(train_loss),
        "val_loss": float(val_loss),
        "val_acc": float(val_acc),
    }
    saver.log_epoch(epoch, metrics, model=model, epoch_time=time.time() - t0)

    if saver.should_save_best(metrics[saver.cfg.monitor]):
        saver.save_best_checkpoint(model)

    if early_stop.step(metrics[saver.cfg.monitor]):
        break

saved_paths = saver.save_after_fit(
    model=model,
    val_loader=val_loader,
    optimizer=optimizer,
    scheduler=scheduler,
    last_epoch=epoch,
)

print("Saved artifacts:", saved_paths)

Output folder structure

All outputs are saved into your run_dir, for example:

runs/torch_exp001/
├── metrics.csv
├── history.json
├── best_model.pt
├── final_model.pt
├── roc_auc.json
├── roc_fpr.npy / roc_tpr.npy / roc_thresholds.npy   (binary)
├── roc_fpr_class_0.npy ...                          (multiclass)
├── confusion_matrix.npy
├── classification_report.json
├── val_labels.npy
├── val_scores.npy
├── val_predictions.npy
├── environment.json
├── git_commit.json
├── random_seeds.json
├── manifest.json
└── ...

Notes

Binary classification is supported (sigmoid or 2-class softmax).

Multiclass classification is supported (softmax with C classes).

ROC/AUC is computed using scikit-learn. Multiclass classification is supported (softmax with C classes).

ROC/AUC is computed using scikit-learn.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

experiment_saver-0.1.0.tar.gz (15.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

experiment_saver-0.1.0-py3-none-any.whl (19.1 kB view details)

Uploaded Python 3

File details

Details for the file experiment_saver-0.1.0.tar.gz.

File metadata

  • Download URL: experiment_saver-0.1.0.tar.gz
  • Upload date:
  • Size: 15.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.4

File hashes

Hashes for experiment_saver-0.1.0.tar.gz
Algorithm Hash digest
SHA256 db4af8940459d9fe811eb02c4b091ab346461dfd33ef9f5c37941f596db90812
MD5 265a6e1022eeecfd811ad108d103a9f5
BLAKE2b-256 28609b05995e4b15ae7e920e9f375967ab115e520c23367f35af4de1d1668bc9

See more details on using hashes here.

File details

Details for the file experiment_saver-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for experiment_saver-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ab6a0b4625c36017fe671987a18cf5d9fc569bcafb1101a1319738dac148c873
MD5 e3b247c1904a460ba454c2be34a95e98
BLAKE2b-256 eacc500094215668b158f384b32e24bd52d76456e1db87dbf5416bd3936bb4ff

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page