Skip to main content

SigOrbit Trainer

Offline, auditable training workflows for SigOrbit. The project trains the 257 px SO(2)-canonicalized signature encoder from random initialization without requiring an unpublished initializer. C8 and C4 steerable backbones are supported; the C4 variant trains 2.7× faster with comparable margin.

Code-only boundary: MIT covers this repository's code only. This project contains no signatures, datasets, embeddings, checkpoints, or trained weights, and does not grant rights to any of them. A public dataset listing or Hugging Face card is not evidence of permission.

Status

Alpha. The source is published on GitHub; there is no PyPI release yet. The three-stage trainer, epoch-boundary resume, strict provenance records and a completed from-scratch 257 px run are implemented. Historical checkpoint metrics remain historical evidence, not a reproduction claim.

Architecture and pipeline

The trainer does not define a second neural network. It pins sigorbit==0.1.0 and imports the runtime package's ModelConfig, SteerableEncoder and CanonicalizedEncoder classes:

flowchart TB
    subgraph Input["Preprocessing"]
        IMG["Cropped signature image"]
        GRAY["Grayscale → 257×257 bicubic → [-1, 1]"]
        IMG --> GRAY
    end

    subgraph Canon["OrientationCanonicalizer (SO(2))"]
        direction TB
        CC1["Conv2d 1→16 k5 s2 p2<br/>+ ReLU + BatchNorm2d"]
        CC2["Conv2d 16→32 k5 s2 p2<br/>+ ReLU + BatchNorm2d"]
        CC3["Conv2d 32→64 k3 s2 p1<br/>+ ReLU + BatchNorm2d"]
        CCP["AdaptiveAvgPool2d(1) → Flatten"]
        CLIN["Linear 64→2<br/>→ (cos θ, sin θ), L2-normalized"]
        CAFF["affine_grid + grid_sample<br/>(bicubic, rotation only)"]
        CC1 --> CC2 --> CC3 --> CCP --> CLIN --> CAFF
    end

    subgraph Backbone["SteerableEncoder (C4 or C8-steerable CNN, e2cnn)"]
        direction TB
        STEM["Stem<br/>R2Conv 1→24·N regular k7 p3<br/>+ InnerBatchNorm + ReLU<br/>+ BlurPool /2 (N = group_order)"]
        L1["Layer 1 (/4)<br/>R2Conv 24→48 k5 p2 + IBN + ReLU<br/>R2Conv 48→48 k5 p2 + IBN + ReLU<br/>+ BlurPool /2"]
        L2["Layer 2 (/8)<br/>R2Conv 48→96 k5 p2 + IBN + ReLU<br/>R2Conv 96→96 k5 p2 + IBN + ReLU<br/>+ BlurPool /2"]
        L3["Layer 3 (/16)<br/>R2Conv 96→128 k5 p2 + IBN + ReLU<br/>R2Conv 128→128 k5 p2 + IBN + ReLU<br/>+ BlurPool /2"]
        GP["GroupPooling<br/>max over C4/C8 fiber<br/>→ 128 invariant channels"]
        STEM --> L1 --> L2 --> L3 --> GP
    end

    subgraph Head["Embedding head"]
        direction TB
        POOL["AdaptiveAvgPool2d(1)<br/>→ Flatten → 128"]
        FC1["Linear 128→512<br/>+ BatchNorm1d + ReLU<br/>+ Dropout 0.3"]
        FC2["Linear 512→256<br/>+ BatchNorm1d"]
        NORM["L2-normalize"]
        POOL --> FC1 --> FC2 --> NORM
    end

    GRAY --> CC1
    CAFF --> STEM
    GP --> POOL
    NORM --> OUT["256-D L2-normalized embedding"]

    style Input fill:#1a2a3c,color:#fff
    style Canon fill:#1a3a5c,color:#fff
    style Backbone fill:#2d5a2d,color:#fff
    style Head fill:#4a3a1c,color:#fff
    style OUT fill:#5c1a1a,color:#fff

The end-to-end workflow wraps three training stages:

  1. validate an immutable local manifest and a separate rights attestation;
  2. train the C4 or C8 backbone from random weights with PK sampling, discrete rotation augmentation and a temporary ArcFace head;
  3. restore the best backbone and train only the SO(2) canonicalizer against known synthetic angles;
  4. jointly optimize canonicalizer, backbone and ArcFace head using identity, circular-orientation and cosine-consistency objectives;
  5. evaluate on signer-disjoint validation identities, restore the best joint checkpoint and export an inference-only SigOrbit artifact.

There are no reflections: the symmetry is SO(2)+C_N (N = group_order), not O(2)/D_N. The ArcFace classifier, optimizers and schedulers exist only in recovery checkpoints; the deployable artifact contains the canonicalizer and backbone.

Install for development

git clone https://github.com/jordi-murgo/SigOrbit-trainer.git
cd SigOrbit-trainer
uv sync --extra dev

Safe smoke test

The smoke source generates non-person synthetic strokes in memory:

uv run sigorbit-train config validate configs/smoke.toml
uv run sigorbit-train run configs/smoke.toml

Interrupted runs can resume from the directory named by RUN/checkpoints/latest.json:

sigorbit-train resume CONFIG.toml --checkpoint RUN/checkpoints/stage=...-epoch=...-step=...

Resume is exact at a completed epoch boundary when the configuration, dataset, class map, architecture, device topology, optimizer, scheduler, and RNG schema match. The current alpha does not checkpoint mid-epoch.

Runtime controls keep the optimization schedule separate from resource-saving stops. joint.epochs remains the cosine-scheduler horizon, while joint.min_epochs prevents patience from stopping the joint stage before that floor. runtime.precision = "bf16" autocasts CUDA training forwards after a startup capability check; parameters and exported weights remain FP32.

The checkpoint directory retains only targets referenced by latest.json and the per-stage best-*.json pointers. Superseded epoch checkpoints are removed after each atomic pointer update.

Training with authorized local data

Training never downloads data inside the trainer process. A standalone script downloads, deduplicates, and materializes an authorized Hugging Face imagefolder dataset into the offline contract in one step:

HF_TOKEN=hf_... scripts/prepare_dataset.sh

Options: HF_DATASET, HF_REVISION, DATASET_ID, DEDUPLICATE, OUTPUT_DIR, WORK_DIR. See scripts/prepare_dataset.sh --help for details.

If an authorized dataset is already saved as a local Hugging Face DatasetDict, materialize it manually:

sigorbit-train dataset import-hf-disk \
  /secure/source-dataset \
  /secure/sigorbit-dataset \
  --dataset-id authorized-signatures \
  --revision IMMUTABLE_SOURCE_REVISION \
  --assert-genuine-only

sigorbit-train dataset attest \
  /secure/sigorbit-dataset/dataset.toml \
  /secure/sigorbit-dataset/rights.attestation.json \
  --purpose research-only \
  --authorization-reference APPROVAL_REFERENCE \
  --assert-authorized-use

sigorbit-train dataset validate \
  /secure/sigorbit-dataset/dataset.toml \
  --attestation /secure/sigorbit-dataset/rights.attestation.json

uv run sigorbit-train run configs/c8-257-final.toml

The importer only reads an already-local directory. attest records the operator's assertion and does not create legal rights. Keep both materialized data and attestation outside the repository.

The historical CEDAR/BHSig260-derived aggregate may only be used after acquiring the sources under applicable terms and documenting authorization. Its trained weights must not be published or used commercially without a separate legal, privacy, and model-release review.

Read docs/DATA_POLICY.md, docs/REPRODUCIBILITY.md, and docs/MODEL_RELEASE_POLICY.md before training.

The validated configurations and observed runs are documented in docs/TRAINING_RECIPE.md, docs/RESULTS_c8-257-final.md, and docs/RESULTS_c4-257-b64.md.

Randomized splits

Manifest splits can be repartitioned by writer before training, which is the recommended way to check that a result is not an artefact of one partition:

sigorbit-train dataset split-preview CONFIG.toml --random-seed 1234
sigorbit-train run CONFIG.toml --random-seed 1234

Splits move whole signers, never individual samples, and the seed enters the dataset fingerprint so a resume cannot silently change the partition. See docs/DATASET_MANIFEST.md.

Evaluation

Training reports clean leave-one-out retrieval plus per-angle top-1, median margin, and fragile rate on validation identities. The manifest test split is never used for selection and requires an explicit opt-in:

sigorbit-train evaluate CONFIG.toml \
  --checkpoint RUN/sigorbit-c8-257-retrained-v1.pt --split validation
sigorbit-train evaluate CONFIG.toml \
  --checkpoint RUN/sigorbit-c8-257-retrained-v1.pt --split test --allow-test-split

Relationship with SigOrbit

sigorbit-trainer owns data manifests, augmentation, losses, optimization, resume state, evaluation, and run provenance. sigorbit owns the encoder architecture, inference preprocessing, and runtime checkpoint compatibility. The trainer pins sigorbit==0.1.0; architecture changes require a new trainer release and model identifier.

Licence

MIT for this repository's code. Dataset, model-weight, privacy, and third-party rights are separate. See NOTICE.

Download files

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

Source Distribution

sigorbit_trainer-0.2.0.tar.gz (317.5 kB view details)

Uploaded Source

Built Distribution

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

sigorbit_trainer-0.2.0-py3-none-any.whl (47.7 kB view details)

Uploaded Python 3

File details

Details for the file sigorbit_trainer-0.2.0.tar.gz.

File metadata

  • Download URL: sigorbit_trainer-0.2.0.tar.gz
  • Upload date:
  • Size: 317.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sigorbit_trainer-0.2.0.tar.gz
Algorithm Hash digest
SHA256 0791f91b687438559ebd829722bcf1df901b9301c6fb26633e8cab3089c5dd45
MD5 f0e2da168ed7e42a1039b65cd877c1be
BLAKE2b-256 9f733eb72d26fea787fdbe08aec98f7a4df1686019e0dd25184edf1f70955133

See more details on using hashes here.

Provenance

The following attestation bundles were made for sigorbit_trainer-0.2.0.tar.gz:

Publisher: publish.yml on jordi-murgo/SigOrbit-trainer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sigorbit_trainer-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for sigorbit_trainer-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dfe98a3838a59d58b13ec39b0896b5467dd6b1cf8935f9dd7c719e44d3433105
MD5 aa66b3f6810e06173b47dbf91d85fe23
BLAKE2b-256 40becd3a9c0e570b8b403aff78c689b4522d740e1ba8c628b4019398fa4509c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for sigorbit_trainer-0.2.0-py3-none-any.whl:

Publisher: publish.yml on jordi-murgo/SigOrbit-trainer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

This release

0.2.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page