Skip to main content

Constraint-based CNN generator and trainer. Describe what you need — not how to build it.

Project description

coldet

Describe constraints, not networks.

coldet is a minimal Python package for building and training vision models without touching a single line of architecture code. You express what you need — size, speed, accuracy tradeoff — and the system generates a valid CNN for you.

coldet is classification-only. All detection, segmentation, and open-vocabulary tasks have been intentionally removed to keep the surface area small and the output format predictable.


Why constraint-based modelling?

Traditional ML frameworks ask you to design networks: choose a backbone, wire up layers, pick kernel sizes, set strides. This works when you have expertise and time. Most of the time, you just need a model that is fast enough and accurate enough for your problem.

coldet flips the question. Instead of:

"I want ResNet-50 with a 4-layer head…"

You say:

"I want something medium-sized that leans toward speed."

The architecture is derived automatically from those constraints. You never see layer names, channel counts, or backbone identifiers — because they are not your concern.

Benefits:

  • No architecture expertise required.
  • Constraints are reproducible: same inputs → same model.
  • Easier to reason about tradeoffs (speed_bias=0.9 is faster than speed_bias=0.3 — always).

Installation

pip install coldet

Or from source:

git clone https://github.com/yourorg/coldet
cd coldet
pip install -e .

Dataset formats

coldet supports two dataset layouts. The right one is auto-detected.

1. Flat — subfolder-per-class

Each subfolder is a class. Simple and fast to set up.

dataset/
    red/
        img001.jpg
        img002.png
        ...
    blue/
        img001.jpg
        ...
    green/
        ...

Supported image formats: .jpg, .jpeg, .png, .ppm, .bmp, .tiff, .webp.

2. Hierarchical — parent/sub-class layout

Use this when your classes have natural sub-categories (e.g. "red" → "crimson", "scarlet"). Each parent folder contains one or more sub-class folders.

dataset/
    red/
        crimson/
            img001.jpg
            ...
        scarlet/
            img001.jpg
            ...
    blue/
        img001.jpg    ← images directly in a parent are labelled with the parent name
        ...
    green/
        olive/
            img001.jpg
        ...

How labels are assigned:

  • Each unique sub-class folder name becomes a label (e.g. crimson, scarlet, olive).
  • Images placed directly inside a parent folder (not in any sub-class folder) are assigned a synthetic sub-class label identical to the parent name (e.g. blue).
  • The hierarchy {parent: [sub, ...]} is saved in every .coldet checkpoint and used at inference time to aggregate parent-level probabilities.

Inference output for a hierarchical model (see coldet.infer):**

predicted_class:     crimson
confidence:          61.2%
probabilities:       {crimson: 61.2%, scarlet: 13.3%, red: 10.1%, ...}
predicted_parent:    red
parent_probabilities: {red: 74.5%, blue: 18.2%, green: 7.3%}

The parent_probabilities are computed by summing all sub-class probabilities that belong to each parent. They always sum to 1.0.


Quickstart

Classification — flat layout

import coldet

trainer = coldet.Trainer(
    size="medium",       # "nano" | "small" | "medium" | "large"
    speed_bias=0.7,      # 0 = prefer accuracy, 1 = prefer speed
    dataset="dataset/",
    batch_size=32,
    image_size=224,
)
# [coldet] dataset 'dataset/' — 3 classes discovered: ['blue', 'green', 'red']

trainer.train(epochs=10)
trainer.summary()
trainer.save("checkpoints/run1.coldet")

Classification — hierarchical layout

import coldet

trainer = coldet.Trainer(
    size="medium",
    speed_bias=0.5,
    dataset="hier_dataset/",  # contains sub-class subfolders → hierarchical mode
    batch_size=16,
    image_size=256,
)
# [coldet] hierarchical dataset 'hier_dataset/' — 5 sub-classes across 3 parent classes: ['blue', 'green', 'red']

trainer.train(epochs=20)
trainer.summary()
trainer.save("checkpoints/hier_run.coldet")

Manual DataLoader

import coldet
from torch.utils.data import DataLoader

trainer = coldet.Trainer(size="medium", speed_bias=0.7, num_classes=3)
trainer.train(my_dataloader, epochs=10)
trainer.summary()

Loading a checkpoint

# Load into an existing Trainer (constraints must match)
trainer.load("checkpoints/run1.coldet")

# Reconstruct from scratch — no constructor arguments needed.
# Use this in inference scripts.
trainer = coldet.Trainer.from_checkpoint("checkpoints/run1.coldet")

import torch
images = torch.rand(4, 3, 224, 224)
logits = trainer.predict(images)   # shape (4, num_classes)

Inference — coldet.infer

The recommended way to run a trained model on a single image. No Trainer setup needed.

import coldet

result = coldet.infer(
    image_path="photo.jpg",
    model_path="checkpoints/run1.coldet",
    temperature=1.0,   # optional, default 1.0
)

print(result["predicted_class"])   # e.g. "crimson"
print(f"{result['confidence']:.1%}")  # e.g. "61.2%"

# Full probability breakdown
for cls, prob in result["probabilities"].items():
    print(f"  {cls}: {prob:.1%}")

# Hierarchical models also include parent-level aggregation
if result["parent_probabilities"]:
    print(f"\nParent: {result['predicted_parent']}")
    for par, prob in result["parent_probabilities"].items():
        print(f"  {par}: {prob:.1%}")

Temperature

The temperature parameter scales the logits before the final softmax:

Value Effect
< 1.0 Sharper distribution — the top prediction dominates more. Use when you want decisive, high-confidence outputs.
1.0 (default) Standard softmax probabilities.
> 1.0 Flatter distribution — probabilities are more spread out. Use to see how uncertain the model is across all classes.

Useful range: 0.15.0.

Return value

Key Type Description
predicted_class str Sub-class with the highest probability
confidence float Probability of the predicted class (0–1)
probabilities dict[str, float] All sub-class probabilities, sorted descending
parent_probabilities dict[str, float] or None Parent-class probabilities (hierarchical models only)
predicted_parent str or None Parent of the predicted sub-class (hierarchical only)
temperature float Temperature used
image_path str Echoed input path

API Reference

coldet.load_dataset

loader, class_names, hierarchy = coldet.load_dataset(
    dataset_path,        # root folder
    image_size=224,
    batch_size=32,
    shuffle=True,
    num_workers=0,
)

Returns a (DataLoader, list[str], dict or None) tuple.

  • class_names — sorted list of all leaf (sub-class) labels; index = integer label.
  • hierarchy{parent: [sub, ...]} for hierarchical datasets, None for flat.

Called internally by Trainer when dataset= is supplied.


coldet.Trainer

Trainer(
    size="small",           # capacity tier
    speed_bias=0.5,         # float [0, 1]
    accuracy_bias=None,     # float [0, 1] — defaults to 1 - speed_bias
    dataset=None,           # path to dataset (either layout)
    image_size=224,
    batch_size=32,
    num_classes=1000,       # ignored when dataset= is supplied
    lr=1e-3,
    device=None,            # auto-detected (CUDA if available)
)
Method Description
train(dataloader=None, epochs=1, verbose=True) Train for N epochs. Returns list of epoch losses. Cosine annealing is applied automatically.
summary(output_dir=".") Writes sum.md and graph.png. Returns info dict.
predict(images) Forward pass, eval mode. images is (B, 3, H, W). Returns (B, num_classes) logits.
save(path) Save checkpoint as a .coldet file.
load(path) Restore weights and training state into an already-constructed Trainer.
Trainer.from_checkpoint(path, device=None) Class method. Reconstruct a complete Trainer from a .coldet file — no other arguments needed.

summary() return value

{
    'size_label':       'medium',
    'total_params':     214_832,
    'trainable_params': 214_832,
    'model_size_mb':    0.859,
    'speed_tier':       'balanced',
    'trained_epochs':   10,
    'num_classes':      5,
    'class_names':      ['blue', 'crimson', 'green', 'red', 'scarlet'],
    'hierarchy':        {'blue': ['blue'], 'green': ['green'], 'red': ['crimson', 'red', 'scarlet']},
    # hierarchy is None for flat datasets
}

summary() output files

File Contents
sum.md Constraints, parameter counts, class list (with parent column for hierarchical models), training history.
graph.png Training loss curve. Written only after at least one epoch.

coldet.infer

result = coldet.infer(
    image_path,          # str — path to image file
    model_path,          # str — path to .coldet file
    temperature=1.0,     # float > 0
    device=None,         # str or None
)

See the Inference section above for full documentation.


coldet.build_model

Lower-level function for the raw nn.Module:

model = coldet.build_model(
    size="large",
    speed_bias=0.3,
    accuracy_bias=0.8,
    num_classes=10,
)

Returns a torch.nn.Module. Architecture is generated, not predefined.


The .coldet file format

.coldet files are PyTorch checkpoints (readable with torch.load). They contain:

  • Model weights and optimiser state.
  • All constraint parameters (size, speed_bias, accuracy_bias, lr, image_size).
  • The resolved architecture dict (so the model can be reconstructed exactly, even if the constraint-to-arch mapping ever changes).
  • Class names and the hierarchy dict (if applicable).
  • Full training loss history.

The extension .coldet is conventional. You can use any extension — torch.save / torch.load don't care.


Constraint guide

Goal Recommended settings
Edge / mobile deployment size="small", speed_bias=0.9
Balanced production model size="medium", speed_bias=0.5
Maximum accuracy, offline size="large", speed_bias=0.1, accuracy_bias=0.9
Rapid prototyping size="small", speed_bias=0.7
Hierarchical fine-grained recognition size="medium", speed_bias=0.4

What is hidden (intentionally)

coldet deliberately does not expose:

  • Layer names, channel counts, or kernel sizes.
  • Backbone / neck / head terminology.
  • Depthwise vs standard convolution choices.
  • Dropout values or batch norm parameters.

These are implementation details derived from your constraints. Exposing them would reintroduce the complexity the package is designed to remove.


Philosophy

Describe constraints, not networks.

Good abstractions hide decisions that don't belong to the user. Network architecture is an implementation concern — it should be derived from requirements, not specified by them. coldet treats the model as an output of a constraint-solving process, not an input from the user.


License

MIT

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

coldet_trainer-0.1.2.tar.gz (19.9 kB view details)

Uploaded Source

Built Distribution

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

coldet_trainer-0.1.2-py3-none-any.whl (16.2 kB view details)

Uploaded Python 3

File details

Details for the file coldet_trainer-0.1.2.tar.gz.

File metadata

  • Download URL: coldet_trainer-0.1.2.tar.gz
  • Upload date:
  • Size: 19.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for coldet_trainer-0.1.2.tar.gz
Algorithm Hash digest
SHA256 5b1bac2f89364193a2942b42d825c076f882eb4dd3662d9bf2bdc57abf2e3b95
MD5 e606627281e15718fa252c29818501af
BLAKE2b-256 aedf34d0a31b6d42ba4417e6723a36cf300f888760b087e5cd71af9ac6486b9f

See more details on using hashes here.

File details

Details for the file coldet_trainer-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: coldet_trainer-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 16.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for coldet_trainer-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c5001c6d8c88d96459fe3253a5abcd73407df20740ada783c27f0eaf64c10dc0
MD5 2e92cbaa885123fea3f39237b3ce322a
BLAKE2b-256 f2af3f54dbf7f2fc4158286411788f2b1ceeaae3975c9586794be7af5f557aac

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