Skip to content

Latest commit

 

History

History
377 lines (260 loc) · 32.6 KB

File metadata and controls

377 lines (260 loc) · 32.6 KB

Wheels Model — Vehicle Make/Model/Year Recognition, with the Wheel as a Fine-Grained Tie-Breaker

Architecture & Build Plan v2.0 — 2026-07-07


0. What Changed in v2.0 (read this first)

This revision corrects a central factual error and restructures the plan so the premise is tested cheaply before it is built expensively.

  • The "0.8pp" evidence was misused and is removed as a backbone. The number (91.2% → 92.02%) comes from Ghanem & Kerekes, Robust Wheel Detection for Vehicle Re-Identification (Sensors 2023, PMC9824802 / MDPI 23(1):393) — a vehicle re-identification paper (matching the same physical car across cameras via hubcap Siamese matching). Its 0.8pp delta compares a wheel-selection+alignment post-processing step against naively picking the two highest-confidence wheel crops — both already use wheels. It does not measure how much a wheel contributes to make/model/year. The same paper's 0.94→0.89 OOD drop is also from that Siamese setting and is not a valid calibration for MMY degradation. The structural argument that wheels are weak for MMY survives on its own; the borrowed number does not.
  • The honest ceiling is a number we must MEASURE. It is the gap between a whole-car MMY baseline (~95%) and any wheel-crop-only accuracy we obtain ourselves.
  • New Phase −1 kill-switch gate runs two cheap experiments (visual separability; marginal value over a body-only baseline) before any dataset build.
  • The body-only baseline is now the FIRST deliverable, not a Phase-3 afterthought — it is the null hypothesis the wheel branch must beat.
  • Use case is now fixed up front — it determines whether fusion is even possible.
  • Year is explicitly scoped out of the wheel-only path (a scope negotiation with the stakeholder).
  • The aftermarket "gate" is reframed from an infeasible binary classifier to calibrated abstention + fitment-DB plausibility checks.
  • SEMA figure corrected: custom wheels are ~$1.58B, a slice of the $12.38B wheel+tire+suspension segment (SEMA 2023) — not a "$12.4B wheel market."

1. Feasibility Verdict

Build a whole-car MMY classifier first; add a wheel branch only if two cheap experiments prove it earns its place. A wheel-only exact-MMY classifier is not achievable; a wheel branch is at best a modest fine-grained tie-breaker for cases where body cues are ambiguous (badge-engineered platform twins).

1.1 Why the body, not the wheel, is the system

Whole-car MMY is near-solved: ~94–97% top-1 on Stanford Cars with plain CNNs — DenseNet-161 94.6%, WS-DAN ~93–94.5%, Coarse2Fine ~94.7% (fine-grained vehicle classification survey). The discriminative signal lives in body outline, greenhouse/window shape, and proportions. Any wheel branch must justify itself against this ~95% baseline, which the plan now runs as its first deliverable.

1.2 Three structural facts that cap wheel-only accuracy (reasoning from structure, not from the re-ID number)

Fact Basis Consequence
One design → many vehicles OEM wheel-sharing across generations and platform/brand families is real (BMW reuses styles across many models/years; platform sharing across VW AG, Stellantis, GM, Toyota/Lexus, Hyundai/Kia; bolt-pattern standardization like 5×114.3). Specific model lists / counts to be verified against a BMW style reference before formal citation. A wheel maps to a set of {make,model,year}, not one. Many-to-many by design.
One model-year → many wheels A mainstream model-year ships several sizes/designs across trims (base steel/cover, mid alloy, top two-tone). Exact per-trim size/design mappings to be confirmed against OEM spec sheets. The label relation is one-to-many in both directions. No canonical wheel per label.
Aftermarket/replica severs the link Custom wheels are ~$1.58B within SEMA's $12.38B wheel+tire+suspension segment (SEMA 2023). Replicas mimic a specific OEM style but fit any compatible car and are visually indistinguishable from OEM in a photo. A wheel photo can carry zero or misleading MMY signal. Replicas cause confident false positives — the most dangerous failure mode.

1.3 What this leaves us

The wheel is a strong-but-fallible fine-grained prior, valuable mainly where the body is ambiguous. The most likely real outcome: a few points of top-k lift on platform-twin classes, ~zero (or misleading) elsewhere. That is a legitimate but modest contribution — far narrower than "novel wheel-first MMY system." Absence of a published wheel-first MMY system is at least as much a red flag (people may have tried and failed to beat whole-car) as an opportunity.

Milestone 1 reframed: the first-milestone wheel dataset + encoder is worth building as an ablation study answering "does a wheel branch add measurable top-k lift over a whole-car baseline, and for which vehicle classes?"not as a standalone product.

1.4 The go/no-go gate (Phase −1)

Two experiments, each cheaper than Phase 1, gate the whole project:

  • (a) Visual separability — embed CWD1500/WHEEL22 labeled rim-design classes with an off-the-shelf encoder; measure inter-design vs intra-design cosine across viewpoints. If different designs are not more separable than the same design at different angles/dirt, the approach is dead. (Note: this is a different failure mode from label ambiguity — a design can be visually separable yet map to many MMY labels, or vice-versa. We instrument both.)
  • (b) Marginal value — train/borrow the ~95% body-only MMY baseline; test whether body+wheel beats body-only on a held set. If not, the wheel-first premise is dead regardless of engineering polish.

1.5 Year: an explicit scope cut

The brief asks for make, model, and year. The wheel structurally cannot deliver exact year — designs persist 10–15 years. At best the wheel gives a generation/range, and only fusion + a fitment DB narrow it further. This is a scope decision to make up front, not a footnote: the wheel-only path cannot satisfy the year requirement.


2. Use Case & Input Distribution (fix this in ONE sentence before building)

Every downstream decision depends on the input. Pin exactly one:

Input Honest system Fusion available? Default here
Full-car photo Whole-car MMY classifier + wheel as optional fine-grained tie-breaker for platform-twins Yes (body in frame) ✅ DEFAULT — smallest, most defensible build
Wheel-only crop Pure wheel retrieval → ranked top-k design-ids → candidate MMY set No (no body in frame) — drop the fusion story entirely Hardest; only if the product truly gets bare wheel crops
Fixed traffic-cam angle Domain-specific; rectification assumptions change Partial BoxCars/VeRi become in-domain here

Contradiction the use case resolves: fusion needs the whole car visible to compute body/greenhouse/size — which is impossible if the input is a tight wheel crop. If the whole car is in frame, the wheel is a tie-breaker on top of a ~95% body classifier, not the primary key. The architecture below assumes the full-car default and treats the wheel branch as an ablation-gated add-on.


3. Dataset Inventory & Licenses

(License/size figures match commonly reported values; re-confirm each at download — especially the "MIT covers annotations, not photos" nuance and CompCars' revocable research terms.)

3.1 Primary MMY corpora (train privately)

Dataset Size / Labels Wheel usability License Verdict
VMMRdb 291,752 imgs, 9,170 MMY classes (1950–2016), US in-the-wild No wheel annotations; large fraction show a full wheel across varied angles → detect+crop; measure yield empirically MIT (repo/annotations; scraped photos may carry residual third-party copyright) Primary bulk corpus + the noisy real-world distribution you want.
CompCars 136,726 full-car + 27,618 part imgs; 1,716 models, 163 makes; viewpoint labels Best fit — side/front-side views expose full wheels, directly croppable Non-commercial research only; CVPR 2015 citation; revocable Primary for wheel-bearing angles.
Stanford Cars (=Cars196) 16,185 imgs, 196 MMY classes, bbox/image Wheel visible in most, not annotated; frontal shots often partial Informal non-commercial research; original host 404 → Kaggle/TFDS/torchvision mirrors Clean body/shape baseline source. Cars196 == Stanford Cars — do not double-count.

3.2 Clean rim-crop sources (experimentation / licensed core)

Dataset Size / Labels Notes License
DVM-CAR 1,451,784 imgs, 899 UK models; predicted-viewpoint field v2.0 removed backgrounds (may clip wheel context — check crops); UK skew CC BY-NC 4.0 (non-commercial)
The Car Connection (~64k) Dealer/press studio, MMY in filenames; excellent crops Visually excellent; legally riskiest NONE — scraped press photos. Research prototype only; never ship.

3.3 Wheel-detection auxiliary (bootstrap Stage 0)

Dataset Size / Labels License
CWD1500 / WHEEL22 / RB600 (Kerepecky & Kybic, arXiv:2304.06560) Car+wheel detection; 22 rim-DESIGN classes (NOT MMY); bolt detection CC-BY-4.0 — best Stage-0 pretraining + the Phase −1 separability testbed
Roboflow "Wheel Rims Detection" ~132 imgs, wheel/rim bboxes Confirm in UI; small; detector pretraining
3DRealCar (2024) 2,500 cars, ~200 dense 360° RGB-D views each Multi-angle wheel augmentation / view-invariance; check license

3.4 Do NOT use as primary wheel source

  • Surveillance/re-ID sets (BoxCars116k, VeRi-776, VehicleID): oblique, low-res, foreshortened wheels — mine only as extra wheel-detection data unless deploying at a fixed traffic-cam angle (then they are in-domain).
  • Aftermarket fitment galleries (Fitment Industries, Custom Offsets): wheels are deliberately non-OEM — the wheel→car mapping is inverted. Use only for detection domain adaptation, negatives, or a separate aftermarket-brand classifier.

3.5 The gallery ground-truth problem (on the critical path — do NOT defer)

Retrieval needs a trustworthy design-id → MMY mapping. CWD1500/WHEEL22 has 22 rim designs NOT mapped to MMY. VMMRdb/CompCars give MMY but the design must be inferred by cropping — so bootstrapping the design-id↔MMY map from noisy auto-crops of the same corpus you train on is a circularity that can manufacture apparent accuracy.

Resolution: the only real clean source is OEM-retailer catalogs (Finish Line Wheels, OE Wheels LLC, OriginalWheels.com, OEM Wheel Shop) — each organizes make → model → year with a single-wheel studio photo + factory part# + specs (e.g. a Camry entry with part#, 17×7.5, 5×114.3). This is the exact (image + make + model + year-range + part# + specs) tuple. Decide this mapping strategy in Phase 0, not Phase 4 — the gallery ground truth is on the critical path. Caveats: one part# often spans several years/trims (coarse year); OE design only; OEM product photos may carry manufacturer copyright even when a retailer hosts them — review robots.txt/ToS before scraping.

3.6 Label-space skeleton

Wheel-Size.com free sandbox API (300 hits/day) enumerates make/model/year → OE rim spec (diameter, width, offset, PCD, bore) for many modifications and makes. Use it for the label-space skeleton and design-sharing detection, and later as a fusion constraint — it is a spec source, not an image source.


4. Legally-Defensible Data-Sourcing & Labeling

Not legal advice. AI-training copyright law is unsettled and moving fast. Case summaries below track known holdings directionally but must be lawyer-verified; do not treat any as settled. Get an IP-attorney opinion before any commercialization or public release.

4.1 Two separate legal gates — clear both

  1. Access legality (can you fetch it?) — CFAA + contract/tort. Public, logged-out data is likely not CFAA "unauthorized" (hiQ; Meta v. Bright Data). But creating an account / accepting ToS binds you contractually; a C&D + IP block makes continued access "unauthorized" (Craigslist v. 3Taps); server burden = trespass to chattels (eBay v. Bidder's Edge).
  2. Copyright (can you use/redistribute it?) — a listing photo is owned by whoever took it. Bypassing robots.txt grants no license. Training privately has fair-use footing (Bartz v. Anthropic, Kadrey v. Meta found training can be transformative; Thomson Reuters v. Ross rejected it for commercial non-transformative use; Copyright Office guidance cautions on commercial use where licensing is available). Redistributing a folder of scraped photos does not.

4.2 Tiered sourcing (by risk)

  • TIER 1 — build here first (lowest risk): VMMRdb (MIT) as bulk + Stanford Cars-196 as clean complement + CompCars for wheel-bearing angles. Gets Milestone 1 with no scraping.
  • TIER 2 — redistributable augmentation: Wikimedia Commons (CC-BY / CC-BY-SA / PD; no NC/ND). The only bulk source you can also redistribute. Auto-capture license+author+URL; flag CC-BY-SA copyleft (share-alike may argue onto a derivative dataset/model — legally untested for weights).
  • TIER 3 — licensed premium seed: Manufacturer press libraries (Ford Media Center, Heritage Vault) are pristine + labeled but "editorial use only" — an ML set is neither editorial nor covered. Use only as a class-reference set after written permission.
  • AVOID: Cars.com / AutoTrader / CarGurus — robots.txt disallows target paths and (in several cases) explicitly names AI crawler user-agents. Google/Bing image search = discovery layer only, never direct ingest.

4.3 Bright-line operating rules

  • Never create an account or accept ToS on a site you scrape.
  • Only logged-out, robots.txt-permitted, public pages, low rate, respect crawl-delay.
  • Stop immediately on any C&D or IP block.
  • Separate "train privately" from "distribute publicly" in every plan and artifact.

4.4 Provenance ledger (single best legal defense — day one)

Every image gets a row: source_url, license, author, retrieval_date, robots_txt_state_at_retrieval, tier. It (a) auto-satisfies CC-BY attribution, (b) flags CC-BY-SA obligations, (c) enables instant purge of any tier if the law shifts, (d) proves a non-pirated, defensible process. Implemented on the WheelImage record from the first ingested image.

4.5 Redistribution rule

A public release contains only: (a) permissive images (Tier-1 MIT / Tier-2 Commons), or (b) URLs+labels (ImageNet "links not pixels" model), or (c) derived embeddings/features. Never a redistributed folder of scraped copyrighted photos.

4.6 Labeling loop (cold-start → model-in-the-loop)

  1. Grounding-DINO / YOLO-World, prompt "car wheel"/"rim" → candidate boxes (zero labels).
  2. Human-verify/correct in CVAT (nested make>model>year attributes).
  3. After ~2–5k verified boxes, train a small YOLOv11 detector.
  4. Deploy as a CVAT Nuclio auto-label function; switch to correct-only pre-labeling. Reserve manual-from-scratch for hard/rare cases.

5. Label Taxonomy & Schema

Label on wheel DESIGN, not size or year. Wheel-Size.com is keyed on spec (a 17×7.5 ET45 maps to several visually different designs) — it gives the fitment skeleton, not visual identity. Model many-to-many from the start.

5.1 Entities

DesignId            # first-class: one physical rim design, deduped across
                    # models/years/brands (OEM part# = closest universal design key)
  ├─ visual_ref_images[]        # canonical + noisy reference shots
  ├─ embedding[512]             # gallery prototype (mean of ref embeddings)
  └─ fits: [VehicleConfig, ...] # the SET this design legitimately appears on

VehicleConfig       # (make, model, generation, model_year, trim)
  ├─ make, model
  ├─ generation                 # PRIMARY temporal key (design persists across a gen)
  ├─ model_year                 # WEAK/derived — a RANGE, not exact (see year scope cut)
  ├─ trim
  └─ oem_wheel_options: [DesignId, ...]   # one config -> MANY designs

FitmentSpec         # from Wheel-Size.com: diameter, width, ET/offset, PCD/bolt
                    # pattern, center bore — gates physical interchange; constrains
                    # candidates in fusion; does NOT identify design

5.2 Hierarchy & the year problem

Organize labels at (make, model-family/platform, generation, design-id). Model-year is a derived, many-to-one attribute, not a primary label — the noisiest, hardest tier (see §1.5 scope cut). Supervise/evaluate at the granularity the data supports: start make+model, add year only as a coarse range / generation refinement, and only via fusion + fitment.

5.3 Year-source reconciliation (a naive union creates noise)

  • CompCars = year-of-manufacture · VMMRdb = production year · DVM-CAR = UK registration year · BoxCars = model year.

Reconcile before merging: normalize to a canonical model_year + a year_source provenance field.

5.4 TWO ceilings — measure both (they are different failure modes)

  • Label-ambiguity ceiling — per design, count distinct MMY labels sharing it → bounds top-1 by label ambiguity.
  • Visual-separability ceiling (the Phase −1 gate) — can the encoder even tell designs apart across viewpoints? → bounds top-1 by visual confusability.

A design can be perfectly separable yet map to 40 MMY tuples (label ceiling bites), or perfectly unambiguous yet unrecognizable at 30° with brake dust (visual ceiling bites). Instrument both.


6. Model Approach (detailed)

6.1 Why metric-learning retrieval, not softmax

The label space is ever-growing, long-tailed, and needs "unknown." A softmax head forces a retrain per new class and can never abstain. Metric learning maps images so same-design images are close (cosine) → recognition = kNN against a labeled gallery; new designs enroll few-shot as a prototype (no retrain); it degrades gracefully to ranked top-k with calibrated scores and an explicit reject.

6.2 Stage 0 — Detection & rectification (rectification is an ABLATION, not a given)

  • Bootstrap: Grounding-DINO or the faster YOLO-World (zero-shot "car wheel"/"rim"; published speed/AP numbers to be verified before relied on).
  • Production: YOLOv11 on CWD1500 + verified crops; SAM2 mask refine.
  • Rectification — run raw vs rectified as an experiment: single-view ellipse→frontal warp is a hard, ambiguous CV problem — the ellipse-to-circle homography has a two-fold pose ambiguity, spokes self-occlude exactly where warping is most needed, and resampling can destroy the fine detail the encoder depends on. Ship rectification only if the ablation shows it measurably helps; it could easily hurt.

6.3 Stage 1 — Wheel embedding encoder (the ablation subject)

  • Backbone — empirical bake-off, no "ceiling" claims: ConvNeXtV2-Tiny / EfficientNet-B4 (fast) vs ViT-B/16 + part-attention. Do not frame transformers as the ceiling — DenseNet/WS-DAN/Coarse2Fine match or exceed transformer methods on Stanford Cars. Benchmark via timm.
  • Loss: Sub-center ArcFace (K sub-centers absorb intra-design variance: trim rims, dirt, brake dust, angle, refinish). Starting config to re-tune: 512-d L2-normalized, s=64, m=0.5.
  • Resolution: 384–448px on tight rim crops (discriminative detail — spoke count, hub geometry — is small; highest-leverage FGVC lever).
  • Augmentation: heavy pose/scale/rotation, dirt/occlusion synthesis, 3DRealCar 360° views for view-invariance.
  • At inference discard the classifier head; keep the encoder.

6.4 Retrieval index (FAISS — scale by gallery size, don't over-engineer early)

Gallery size Index Rationale
hundreds–low thousands (start here) IndexFlat (exact) No training, guaranteed correct; don't eat recall you don't need.
~100k–1M IVF{K},Flat, K = 4–16·√N Sub-linear, small recall trade.
1M–10M+ IVF+HNSW Best recall/latency.
RAM-bound add OPQ+IVFPQ 4–8× memory savings — only when RAM binds.

6.5 Stage 2 — Fusion (full-car use case ONLY, and ONLY after the ablation proves lift)

The re-rankers are the system (body carries ~95%); the wheel is a weak prior on top. Specify them, don't hand-wave:

  • The body-only MMY baseline (Phase 1 deliverable, timm backbone, ~95% target) is a concrete artifact and doubles as the silhouette / greenhouse / size feature source.
  • Late (score-level) fusion re-ranks the wheel's top-k candidate set with weighted signals — body-outline/silhouette (highest weight, where the real signal lives), size/proportion, greenhouse/window shape, color (lowest, unreliable on dusty/refinished wheels).
  • Fitment DB (Wheel-Size.com) constrains candidates by physical interchange.
  • Wheel lift = fused-system minus body-only baseline, reported per vehicle class. This is the honest replacement for the removed 0.8pp number.

6.6 Stage 3 — Aftermarket/replica: ABSTENTION, not a binary classifier

The structural logic ("replicas visually indistinguishable from OEM") argues a binary OEM-vs-aftermarket pixel classifier cannot reliably work. Honest mitigation:

  • Calibrated low confidence + abstention on OEM-style matches — return "unknown — closest candidates X, Y, Z" rather than a confident wrong label.
  • Fitment-DB plausibility checks — does this exact wheel size/offset/PCD physically fit the candidate car? Implausible fitment lowers the candidate.
  • Any weak aftermarket signal (e.g. specs outside every OEM catalog entry) is used only to lower confidence, never to force a label.
  • Open-set rejection via a calibrated cosine reject threshold; few-shot enrollment enforces a minimum reference count/quality.

6.7 Backward-compatible embeddings (later)

Naive encoder swaps invalidate stored vectors → force a full re-embed. Add a backward-compatibility/alignment loss and version the embedding space; retain reference images for offline backfill. Early on just re-index (cheap); adopt this once the gallery is large.

6.8 Evaluation — honest baseline + defined bar

  • Always report against the body-only baseline: wheel lift = system − baseline, per vehicle class.
  • Metrics: Recall@k, mAP, top-1/top-5, open-set AUROC, candidate-set-size reduction.
  • Numeric go/no-go bar (set with the stakeholder): the wheel branch must add ≥ a stated top-k lift over body-only on platform-twin classes to proceed past Phase 2.
  • Validate on held-out REAL photos (OOD). Do NOT use the re-ID paper's 0.94→0.89 to set expectations — it is a different task.
  • Define the consumer (§7 output contract): a candidate set of "40 cars across 6 makes" may be worse-than-useless for security/valuation/parts-lookup; state the target actionable set size and evaluate against it.

7. Output Contract (who consumes the ranked set?)

A many-to-many "candidate set" is only valuable if a downstream step or human can act on it. Specify per use case, in Phase 3:

Consumer Actionable set size Behavior when ambiguous
Human reviewer (triage) ~5–10 ranked with confidences Show top-k + evidence crops; human picks
Parts lookup 1 (must resolve to a fitment) Abstain + ask for a second photo/angle rather than guess
Security / valuation 1 with calibrated confidence, else abstain Never force a label; escalate to human

If the realistic output is "one of 40 across 6 makes," that is a signal the wheel-only framing is wrong for this consumer — fall back to the full-car body classifier.


8. ML Stack (right-sized; defer scale tooling)

Layer Choice Why
Annotation CVAT (self-hosted) Free/no cap; nested make>model>year attributes; Nuclio auto-label
Cold-start labels Grounded-SAM-2 Text-prompt zero-shot boxes → verify → train YOLO
Detector YOLOv11 (prod); YOLO-World/Grounding-DINO bootstrap Real-time, easy export
Encoder timm (ConvNeXtV2 / EfficientNet / ViT) One API for the backbone bake-off
Metric-learning PyTorch Metric Learning Ready Sub-center ArcFace / proto-net
Index FAISS Flat → IVF → IVF+HNSW → IVFPQ by scale
Data versioning DVC (start) → lakeFS (only at millions) DVC fine < ~10k objects; don't adopt lakeFS in Milestone 1
Storage format individual files (start) → WebDataset shards (only at scale) Don't shard prematurely
Experiment tracking MLflow (self-hosted) Free, model registry
Baseline classifier timm whole-car MMY (~95% target) The null hypothesis; first deliverable

Class imbalance is a first-class concern (long-tailed, fine-grained): per-(make,model,year) count dashboard, tail-collection targets, focal loss + class-balanced sampling / logit adjustment, curate head redundancy.


9. Compute, Team & Cost (rough sizing)

Order-of-magnitude, to right-size scope; refine against actual resources.

Item Milestone 1 (Phases −1→2) Full plan (Phases 3–5)
GPU 1× 24GB GPU for detector + one encoder at 384–448px; Phase −1 needs only inference on a pretrained encoder Multi-GPU or short cloud bursts for full-make encoders + million-vector FAISS
Human labeling ~2–5k CVAT boxes hand-verified for ONE make (days, not weeks, with auto-label) Scales with make coverage; auto-label keeps it correct-only
Storage tens of GB (thousands–tens of thousands of crops), individual files + DVC TB-scale at millions → object store + lakeFS + WebDataset
Wall-clock Phase −1: 1 week · Phases 0–2: ~10 weeks Phases 3–5: months, contingent on the go/no-go
Recurring ~$20/mo VPS (MLflow); Wheel-Size.com free sandbox Wheel-Size.com Basic (~$450/yr) if commercial; attorney fees before release

Milestone 1 is deliberately small — one make, one GPU, thousands of images. The million-vector / lakeFS / backward-compat machinery is the ambition, gated behind the Phase −1/2 results. Do not commit the multi-month build before the premise is tested.


10. Repository Structure (target)

wheels-model/
├─ README.md · pyproject.toml
├─ docs/
│  ├─ architecture.md            # this document
│  ├─ use-case.md                # the ONE-sentence input definition (§2)
│  ├─ sourcing-policy.md         # legal tiers + provenance ledger schema (§4)
│  └─ taxonomy.md                # design-id ontology, year reconciliation, two ceilings
├─ experiments/
│  └─ phase_minus_1/             # (a) separability + (b) marginal-value kill-switches
├─ data/                         # gitignored; DVC-tracked (lakeFS only at scale)
│  ├─ raw/                       # immutable originals + provenance ledger
│  ├─ interim/                   # detected/rectified wheel crops
│  └─ processed/                 # training-ready crops + manifest
├─ src/wheels_model/
│  ├─ sourcing/                  # tier fetchers, robots guard, ledger writer
│  ├─ baseline/                  # whole-car MMY classifier (the null hypothesis)
│  ├─ detect/                    # YOLO-World bootstrap, YOLOv11, SAM2
│  ├─ rectify/                   # ellipse fit + frontal warp (ABLATION, off by default)
│  ├─ encode/                    # timm + Sub-center ArcFace
│  ├─ index/                     # FAISS build/query, prototype enrollment, versioning
│  ├─ fuse/                      # body/size/greenhouse/color late fusion (full-car only)
│  ├─ gate/                      # abstention + fitment-DB plausibility (NOT a binary head)
│  ├─ labeling/ (taxonomy)       # design-id map, fitment join, year reconcile
│  └─ eval/                      # Recall@k, mAP, AUROC, BOTH ceilings, wheel-lift-vs-baseline
├─ configs/  · pipelines/  · notebooks/  · tests/

(The v0 scaffold uses data / labeling / detect / train / infer / utils; the modules above are the target decomposition, migrated as each phase lands.)


11. Risks & Mitigations

# Risk Severity Mitigation
1 Wheel adds ~nothing over a ~95% body baseline High Phase −1 marginal-value gate + Phase-2 body-only-vs-body+wheel ablation, per class; measure lift, never assume it. The 0.8pp re-ID number is removed.
2 Designs not visually separable across angles High Phase −1 separability gate on CWD1500/WHEEL22 across viewpoints; kill the project if it fails.
3 Many-to-many labels cap top-1 High Design-id first entity; predict design-id → fuse → fitment DB; quantify label-ambiguity ceiling before training.
4 Aftermarket/replica false positives (indistinguishable in-pixel) High Abstention + fitment-DB plausibility, not an infeasible binary head; calibrated low confidence; body/silhouette fallback.
5 Year unrecoverable from wheel High Explicit scope cut; deliver generation/range via fusion+fitment only.
6 Legal exposure (scraped photos, unsettled fair use, redistribution) High Tier-1 permissive first; provenance ledger day one; train-private vs distribute-public; links+labels+embeddings for release; attorney sign-off before commercialization.
7 Gallery ground-truth circularity (design↔MMY from same corpus) High Bring OEM-catalog design-id→MMY ground truth online in Phase 0, not Phase 4; keep it off the training corpus.
8 Rectification hurts (pose ambiguity, resampling) Med-High Treat as an ablation (raw vs rectified); ship only if it helps.
9 Viewpoint/occlusion/dirt degrade rims Med-High Heavy augmentation, Sub-center ArcFace, 3DRealCar view-invariance, OOD validation.
10 Wheel-crop yield unknown Med Empirically measure usable-crop fraction over VMMRdb/CompCars in Phase 1 before scaling.
11 Candidate set not actionable to the consumer Med Define consumer + target set size (§7); abstain rather than emit a useless 40-tuple set.
12 Over-scoping the pilot (lakeFS/PQ/backward-compat/fusion too early) Med Milestone 1 = one make, DVC + FAISS Flat + individual files; scale tooling gated behind Phase −1/2.
13 Long-tail imbalance Med Per-class dashboard + tail targets; focal loss / class-balanced sampling.
14 Access revocation / C&D on gated sets Low-Med Confirm terms at download; MIT VMMRdb as durable core; ledger enables instant purge.

12. Corrections Ledger (claims fixed vs the initial v1 framing)

v1 claim Correction
"Wheel adds ~0.8pp (91.2→92.02%) to MMY" Removed as evidence. PMC9824802 is re-identification; both numbers already use wheels; the delta is a wheel-selection/alignment trick, not the wheel's MMY contribution.
"0.94→0.89 OOD drop" anchors expected MMY degradation Not valid — same re-ID Siamese setting, different task.
"$12.4B wheel market" ~$1.58B custom wheels, a slice of the $12.38B wheel+tire+suspension segment.
"ViT+part-attention = accuracy ceiling (94.8%)" Overstated; DenseNet/WS-DAN/Coarse2Fine match/exceed it. Backbone = empirical bake-off, no "ceiling."
"No published wheel-first MMY → novel opportunity" Presented neutrally: absence is at least as much a red flag as an opportunity.
Specific BMW style lists / exact per-trim Camry wheels / CompCars ~98% / YOLO-World AP·FPS / TransFG 94.8% Flagged unverified; confirm against primary sources before formal citation. The structural points they support remain valid.

Key correction sources: Ghanem & Kerekes, Sensors 2023 (PMC9824802 / MDPI 23(1):393); SEMA 2023 Wheel/Tire/Suspension market report; Stanford Cars SOTA figures per the fine-grained vehicle classification survey.