Add the anchor-free, center-heatmap detector CLAUDE.md §3.3 specifies: - targets.py: encodes ground-truth boxes into a per-class Gaussian heatmap + wh regression target + center mask, using the standard CornerNet/CenterNet gaussian-radius formulation. - model.py: a small conv backbone (stride 4) with heatmap (sigmoid) and wh regression heads - exactly the two outputs CLAUDE.md specifies, sized with the 66ms/tick budget in mind. - losses.py: modified focal loss (heatmap) + masked L1 (wh), combined with the standard CenterNet wh_weight=0.1. - client.py / dataset.py: pull a promoted dataset version + its set's class list from the labeling backend and turn it into a torch.utils.data.Dataset, reading images from local disk (same machine as FRAMES_ROOT). - train.py: wires it into a basic DataLoader -> train loop -> per-epoch checkpoint. The exact loss weighting/architecture sizing is a reasonable, standard v1 default, not a tuned final answer - CLAUDE.md's own roadmap flags the exact formulation as still open; this is the starting point to iterate from. 16/16 unit tests pass on CPU with synthetic data (target/model/loss correctness, dataset-version parsing). Beyond that, ran a real end-to-end smoke test: live labeling backend -> promoted dataset version -> `spelunkai-train` actually training one real epoch against it and writing a checkpoint. Not verified: multi-epoch convergence on real data, which needs jai's GPU and real labeled frames. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Detection Model Training
Per-set training pipeline for the anchor-free, center-heatmap-based (CenterNet-style) CNN detectors — one model per label set (Enemy, Items, Traps, ...). Custom, small/ efficient architectures sized around the overall 66ms/tick inference budget.
See CLAUDE.md §3.3–3.4 for full requirements.
Status: core v1 implemented — target encoding, model, loss, dataset loader
(pulls a promoted dataset version from labeling/backend), and a training script.
Not yet implemented/verified: actual multi-epoch training on a real dataset
(needs jai's GPU and real labeled data — nothing to train on yet), KPI evaluation
(precision/recall/mAP-equivalent), and inference/export (ONNX etc. for the runtime
loop). The exact loss weighting and architecture sizing are a reasonable v1 default,
not a tuned final answer — CLAUDE.md's own roadmap flags the exact formulation as an
open item; treat this as the starting point to iterate from once real training runs
are possible.
How it works
targets.py— encodes ground-truth boxes into training targets: a per-class Gaussian center-point heatmap (radius scaled to box size via the standard CornerNet/CenterNet formula, so overlap penalties roughly track IoU) plus a width/height regression target and a mask marking which pixels are actual object centers.model.py—CenterNetDetector: a small conv backbone (stride 4 output, matchingOUTPUT_STRIDE) with two 1x1-conv heads — a per-class heatmap (sigmoid) and a width/height regression head — exactly the two outputs CLAUDE.md §3.3 specifies, nothing extra (no separate offset head).losses.py— modified focal loss for the heatmap + masked L1 loss for width/height (masked to object-center pixels only), combined with the standard CenterNetwh_weight=0.1.client.py— pulls a promoted dataset version (GET /dataset-versions/{id}) and its set's class list (GET /sets/{id}) from the labeling backend over plain HTTP (stdliburllib, no extra dependency for two GET requests).dataset.py—CenterNetDataset: atorch.utils.data.Datasetthat reads each frame's image straight from local disk (training runs on the same machine/FRAMES_ROOTas the labeling backend, so no need to re-download images) and encodes its labels viatargets.py.train.py— wires it all together: fetch →DataLoader→ train loop → checkpoint (checkpoints/last.pt) after every epoch.
Setup
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
On a machine without an NVIDIA GPU (e.g. for running the tests), install the CPU build explicitly to avoid pulling a multi-GB CUDA wheel:
pip install torch --index-url https://download.pytorch.org/whl/cpu
pip install -e ".[dev]"
On jai, install the CUDA build matching its driver/CUDA version instead (see
pytorch.org).
Training
spelunkai-train \
--backend-url http://127.0.0.1:8000 \
--set-id 1 --dataset-version-id 1 \
--images-root /path/to/FRAMES_ROOT \
--output-dir checkpoints
Testing
pytest
Everything here is testable on CPU with synthetic data and doesn't need the labeling
backend running: target encoding (peak placement, wh/mask correctness), the model's
forward-pass output shapes, loss behavior (zero for a perfect prediction, masked
correctly), the dataset-version JSON parsing, and CenterNetDataset.__getitem__
against a tiny generated image. Not verified here: an actual multi-epoch training
run converging on real data — that needs jai's GPU and a real promoted dataset.