Downloads · 30 days
0
yusufdxb/inspectnet-cx
inspectnet-cx is a image classification model from yusufdxb. Use it when you need a label for an image. It is set up for pytorch. The card lists the license as apache-2.0.
InspectNet-CX is a reproducible MVTec AD anomaly-inspection harness evaluated across 4 categories (bottle, cable, capsule, leather). It ships its own native reverse-distillation detector (the project's from-scratch mo…
Downloads · 30 days
0
Access
Public
Updated Jun 20, 2026
Repo size
—
Likes
0
Public
Click a slice to open those files.
.json187 KB · 63%
From the Hugging Face model README
InspectNet-CX is a reproducible MVTec AD anomaly-inspection harness evaluated across 4
categories (bottle, cable, capsule, leather). It ships its own native reverse-distillation
detector (the project's from-scratch model) alongside two verified reference baselines,
PaDiM and PatchCore, plus latency and ONNX/OpenVINO export-parity studies. Every number on
this card is traceable to a JSON report in reports/eval_harness/. PatchCore Lightning
checkpoints exist for all 4 categories (bottle and leather across 3 seeds each); the native
reverse-distillation detector ships as source plus eval evidence, with no trained native
checkpoint bundled. See PROVENANCE.md for the per-metric source-of-truth map.
InspectNet-CX's own from-scratch detector is a reverse-distillation model: a frozen
wide_resnet50_2 teacher, with a bottleneck plus decoder trained to reconstruct the
teacher's multi-scale features on normal images, where reconstruction failure is the anomaly
score. It is trained here, not borrowed. No trained checkpoint is bundled; the detector ships
as source plus eval evidence (reports/eval_harness/inspectnet_rd_{category}.json in the
upstream repo).
Image-level AUROC, matched train/test, the native detector against the two reference baselines:
| category | PaDiM (ResNet-18) | PatchCore | InspectNet-CX (reverse distillation, ours) |
|---|---|---|---|
| bottle | 0.998 | 1.000 | 1.000 |
| cable | 0.872 | 0.991 | 0.885 |
| capsule | 0.881 | 0.994 | 0.901 |
| leather | 0.993 | 1.000 | 1.000 |
Honest standing: the native detector ties PatchCore on bottle and leather (both
1.000) and beats PaDiM on all four categories, but it does not beat PatchCore
overall, PatchCore still leads on cable (0.991 vs 0.885) and capsule (0.994 vs 0.901).
PaDiM and PatchCore are references, not the author's results. The native numbers are read
from reports/eval_harness/inspectnet_rd_*.json. The path to this result (a vanilla
student-teacher trails badly, a wider student-teacher backbone collapses to near-chance, and
reverse distillation closes most of the gap) is documented in
docs/native_detector_ablations.md. Fully matching PatchCore on cable and capsule is
open work.
PatchCore replaces the PaDiM head from the prior baseline. The decisive wins are on the categories where PaDiM had headroom:
Both margins are large enough that single-seed measurement is sufficient at this magnitude (the gap is two orders of magnitude larger than typical PatchCore seed noise). Bottle and leather are wins at the image-AUROC ceiling: 1.0000 across 3 seeds with zero seed variance.
| category | method | coreset | image AUROC | pixel AUROC | [email protected] | image delta | pixel delta | AUPRO delta |
|---|---|---|---|---|---|---|---|---|
| bottle | PaDiM | n/a | 0.9976 | 0.9816 | 0.9406 | |||
| bottle | PatchCore | 0.01 | 1.0000 (mean, n=3, std=0) | 0.9852 +/- 0.0001 (n=3) | 0.9406 +/- 0.0005 (n=3) | +0.0024 | +0.0036 | +0.0000 |
| cable | PaDiM | n/a | 0.8720 | 0.9551 | 0.8519 | |||
| cable | PatchCore | 0.01 | 0.9910 (single seed) | 0.9834 (single seed) | 0.9281 (single seed) | +0.1190 | +0.0283 | +0.0761 |
| capsule | PaDiM | n/a | 0.8807 | 0.9849 | 0.9149 | |||
| capsule | PatchCore | 0.01 | 0.9944 (single seed) | 0.9902 (single seed) | 0.9382 (single seed) | +0.1137 | +0.0053 | +0.0233 |
| leather | PaDiM | n/a | 0.9925 | 0.9882 | 0.9682 | |||
| leather | PatchCore | 0.01 | 1.0000 (mean, n=3, std=0) | 0.9922 +/- 0.0001 (n=3) | 0.9752 +/- 0.0006 (n=3) | +0.0075 | +0.0040 | +0.0070 |
Cable and capsule PatchCore rows are single-seed (legacy seed-0, see Seed Labeling Note below); the 0.119 and 0.114 image-AUROC margins over PaDiM are far above plausible seed noise so the verdict is robust. Bottle and leather PatchCore rows are mean +/- pstdev across 3 seeds (seed 0 legacy unseeded plus explicit seeds 1 and 2).
| coreset | image AUROC | pixel AUROC | [email protected] |
|---|---|---|---|
| 0.01 | 0.9910 | 0.9834 | 0.9281 |
| 0.10 | 0.9856 | 0.9848 | 0.9304 |
| 0.25 | 0.9893 | 0.9844 | 0.9280 |
A 1% coreset matches 10% and 25% within noise on cable, so the paper-default 1% sampling ratio is sufficient for this category.
"Seed 0" refers to the legacy unseeded baseline run from Phase B (it predates the
--seed flag added in Phase Bx, so its RNG state is not pinned). Seeds 1 and 2
are pinned explicitly via the --seed flag in scripts/train_patchcore.py. All
three runs are reported as-is; we do not pretend they were drawn identically.
For bottle and leather, image AUROC is exactly 1.0000 across all three seeds, so the seed-0 ambiguity is moot at the image-classification level. Pixel AUROC and AUPRO show non-zero seed variance and are reported as mean +/- pstdev (n=3).
Per-category, per-device latency, measured on the same hardware in this session. All values in milliseconds, batch size 1, image size 256x256, 50 timed images, 10 warmup images (capsule CPU used 30 warmup images, see note).
| category | min | median | p95 | mean | std | warmup |
|---|---|---|---|---|---|---|
| bottle | 28.318 | 30.155 | 31.569 | 30.178 | 1.012 | 10 |
| cable | 30.415 | 31.297 | 32.908 | 31.463 | 0.807 | 10 |
| capsule | 28.789 | 29.749 | 32.502 | 30.173 | 1.162 | 30 |
| leather | 30.974 | 32.812 | 35.191 | 32.838 | 1.178 | 10 |
The capsule CPU row is taken from patchcore_capsule_latency_rerun2.json (30 warmup
images, std 1.162 ms). The original capsule CPU run had an unstable warm-up tail
that inflated std; the rerun is the clean number to cite.
| category | min | median | p95 | mean | std | warmup |
|---|---|---|---|---|---|---|
| bottle | 5.144 | 5.202 | 6.415 | 5.508 | 0.473 | 10 |
| cable | 5.130 | 5.290 | 6.558 | 5.513 | 0.465 | 10 |
| capsule | 5.109 | 5.354 | 6.179 | 5.474 | 0.376 | 10 |
| leather | 5.171 | 5.350 | 6.365 | 5.613 | 0.468 | 10 |
Platform: Linux-6.8.0-117-generic-x86_64-with-glibc2.35, Python 3.10.12, Torch 2.11.0+cu128, Anomalib 2.4.1.
PatchCore is more accurate than PaDiM on all 4 categories (cable +0.119 image AUROC, capsule +0.114, leather +0.0075, bottle +0.0024), but at higher inference cost: CPU median ~30 ms/image vs PaDiM's lighter coupling, and CUDA median ~5.2-5.6 ms/image. The CPU cost is dominated by the wide_resnet50_2 backbone and the memory-bank nearest-neighbor lookup. On CUDA the model is fast enough for real-time-class inspection workloads; on CPU it sits in the tens of ms.
Fresh PatchCore ONNX and OpenVINO exports were produced via Anomalib's
Engine.export(export_type=ExportType.ONNX|OPENVINO, ...) from each trained
Lightning checkpoint. Outputs were compared on N=20 real MVTec AD test images per
category (mix of normal + anomalous) under ONNX Runtime CPU (FP32) and OpenVINO
CPU with INFERENCE_PRECISION_HINT=f32. Inference precision hint matters: leaving
it at the CPU plugin default can silently engage bf16 on AVX-512-BF16 hosts and
break parity, which is why the f32 hint is explicit.
| category | max abs error (anomaly map) | max abs error (pred score) | pred_label flips (N=20) | pred_mask pixel flips (out of 1,310,720) | source JSON |
|---|---|---|---|---|---|
| bottle | 2.181e-05 | 6.020e-06 | 0/20 | 0 | reports/eval_harness/openvino_parity_patchcore_bottle.json |
| cable | 4.768e-06 | 3.278e-06 | 0/20 | 0 | reports/eval_harness/openvino_parity_patchcore_cable.json |
| capsule | 7.719e-06 | 4.053e-06 | 0/20 | 0 | reports/eval_harness/openvino_parity_patchcore_capsule.json |
| leather | 4.321e-06 | 7.299e-05 (pred_score) | 0/20 | 0 | reports/eval_harness/openvino_parity_patchcore_leather.json |
All 4 categories status parity_clean per the JSON definition (max_abs_error <=
1e-3, zero label flips, zero mask pixel flips). ONNX Runtime 1.23.2, OpenVINO
2026.1.0-21367-63e31528c62-releases/2026/1.
This is a fresh PatchCore parity measurement. The earlier commit c3594fc covered
PaDiM only and does not transfer to PatchCore by extrapolation; this measurement
replaces that.
The code in the InspectNet-CX package, this model card, the per-category result JSON files, and the parity reports are licensed under Apache-2.0.
The trained PatchCore checkpoints were fit on the MVTec AD dataset, which is distributed under CC BY-NC-SA 4.0. That license is non-commercial.
This restriction propagates to the trained checkpoints. Even though the package code is Apache-2.0, downstream commercial use of the trained PatchCore checkpoints (or any derivative model that was fit on MVTec AD images) is not permitted under MVTec AD's terms. The dataset license overrides the package license for any artifact whose weights or memory bank were built from MVTec AD pixels.
If you want commercial use, you must retrain the per-category PatchCore detector on your own commercially-licensed data using the package code, and the non-commercial restriction does not apply to the resulting weights.
PatchCore Lightning checkpoints used for the numbers in this card:
| category | seed | coreset | SHA256 | size MB |
|---|---|---|---|---|
| bottle | 0 (legacy unseeded) | 0.01 | b0eb8834ae8d2bece3270cd1ef003427f16e0a109cc6bbb3a85eea49e50461df | 107.6 |
| bottle | 1 | 0.01 | d89e12adc18b806e3da552d261c33b113422bf3e49068c73b2e1223816cabd12 | 107.6 |
| bottle | 2 | 0.01 | b4afc04f0af2dd70de8393754ed47f276cc2778a6ec9e2d87431e894dcedb725 | 107.6 |
| cable | 0 (legacy unseeded) | 0.01 | 29d451c6a03707c155adaf1e5bf33313531c9d8204d8722cbe8f9516aac930c2 | 108.5 |
| capsule | 0 (legacy unseeded) | 0.01 | 25454995713926187e9816613d0e76e8e9531d6ca99becdf2565e8e8ebda8feb | 108.2 |
| leather | 0 (legacy unseeded) | 0.01 | 5cf7c7a793ad441a9c6cd92ee27517c674df35720c1873e61ef7aab5ebc2bd29 | 109.8 |
| leather | 1 | 0.01 | 5af3f908dae9df60fe472718b588deeaaeb93ce7b7b8d286c9077df098375d65 | 109.8 |
| leather | 2 | 0.01 | 268b1d0819ef50353a0ed874dc84ce2f38d5fe1686978ed284f881c5532fbc0e | 109.8 |
Checkpoints are not bundled in this HF repo. They live in the upstream training
tree under artifacts/patchcore_{cat}[_seed{N}]/Patchcore/MVTecAD/{cat}/v0/weights/lightning/model.ckpt
and are reproducible from the documented training commands.
wide_resnet50_2 (timm).layer2, layer3.See CHECKSUMS.sha256 for SHA256 of every non-README file shipped in this repo.
Verify with:
sha256sum -c CHECKSUMS.sha256
See PROVENANCE.md for the metric-to-JSON map. Every number in the YAML
model-index block and in the ablation, coreset, latency, and parity tables
points to a specific field in a specific JSON under reports/eval_harness/.
PaDiM and PatchCore evaluation harness, latency benchmark, and parity script are in the upstream repo:
PYTHONPATH=src python3 scripts/eval_harness.py --method patchcore --dataset mvtec_ad --category cable --coreset 0.01 --output reports/eval_harness/patchcore_cable.json
PYTHONPATH=src python3 scripts/train_patchcore.py --category leather --seed 1 --output artifacts/patchcore_leather_seed1
PYTHONPATH=src python3 scripts/bench_latency.py --checkpoint artifacts/patchcore_bottle/Patchcore/MVTecAD/bottle/v0/weights/lightning/model.ckpt --category bottle --output reports/eval_harness/patchcore_bottle_latency.json
PYTHONPATH=src python3 scripts/validate_patchcore_export.py --category bottle --checkpoint artifacts/patchcore_bottle/Patchcore/MVTecAD/bottle/v0/weights/lightning/model.ckpt --output reports/eval_harness/openvino_parity_patchcore_bottle.json