Overview
Project summary
- What it is
- A public Python package for one frozen, reduced feature-memory anomaly-detection profile.
- My role
- I built the method contract, CLI, strict run bundles, synthetic retrieval fixture, reviewed runtime results, ONNX feature boundary, documentation and v0.1.0 release.
- Core stack
- Python 3.11 and 3.12, PyTorch, torchvision, ResNet-50, NumPy, scikit-learn and ONNX Runtime.
- Public boundary
- The accepted baseline runs cover bottle and leather, one MVTec AD category per run.
Why I built it
I wanted a small anomaly-detection runtime whose method and outputs could be inspected precisely. Method changes, hidden defaults, runtime differences and performance measurements are easy to mix together when an experiment leaves only its final metrics behind.
I built InspectRT around one frozen reduced profile, inspectrt_feature_memory_v1. It records the resolved method, environment, sample inventory and intermediate outputs so I can review an execution later without reconstructing those details from memory.
Runtime path
The profile resizes each image directly to 256 x 256, applies ImageNet normalization and extracts layer2 features from a frozen ResNet-50 with IMAGENET1K_V2 weights. Padded 3 x 3 average pooling produces row-major FP32 patch embeddings.
Every nominal train/good patch enters the memory bank. A test image follows the same feature path, then exact chunked top-1 squared-L2 retrieval produces its image score and raw anomaly map. InspectRT reports image AUROC, image AP and pixel AUROC without selecting a threshold.
Runtime path
Nominal and test images through one frozen feature path
The optional ONNX graph covers feature extraction, pooling and patch layout only. Every other stage remains outside it.Nominal path
Build the reference memory for one category.
- train/good images
Ordered nominal images from one MVTec AD category.
- Preprocessing
Decode, direct resize to 256 x 256 and ImageNet normalization.
- Optional ONNX graph
- Frozen ResNet-50 layer2
IMAGENET1K_V2 features with a fixed tensor contract.
- Pool and patch layout
Padded 3 x 3 average pooling and row-major FP32 patches.
- Frozen ResNet-50 layer2
- Complete nominal bank
Every row-major FP32 patch is retained.
Evaluation path
Score one test image through the same frozen feature path.
- Test image
One image from the selected category.
- Same preprocessing
The decode, resize and normalization contract stays fixed.
- Optional ONNX graph
- Frozen ResNet-50 layer2
IMAGENET1K_V2 features with a fixed tensor contract.
- Pool and patch layout
Padded 3 x 3 average pooling and row-major FP32 patches.
- Frozen ResNet-50 layer2
- Exact retrieval
Chunked top-1 squared-L2 search against the full bank.
- Scores and raw map
Patch distances produce the image score and anomaly map.
- Metrics and run artifacts
Threshold-free metrics and persisted run artifacts.
The deliberate reference-method trade-off
Keep the complete nominal bank
- Context
- Approximate retrieval, coreset selection or unrelated optimizations would change the method while I was trying to compare executions.
- Decision
- For v0.1.0, I kept every nominal FP32 patch and used exact chunked top-1 squared-L2 retrieval with lower-index handling for exact ties.
- Result
- The contract stays simple to inspect, but the accepted banks use 418 MiB for bottle and 490 MiB for leather. On the accepted T1000 benchmark, retrieval accounts for most of the measured batch-1 latency.
Reproducibility and run records
What the published runs include
InspectRT keeps the method, intermediate tensors and measurement scope together so each result can be interpreted against the workload that produced it.
Seven or eight files
Evaluation writes a strict seven-file bundle. Benchmarking adds benchmark.json, including its methodology and timing record.
Exact persisted outputs
A second T1000 execution reproduced the ordered inventory, bank, nearest indices, scores, distances, maps and metrics exactly on the same host and locked stack.
Six timing records
The current v2 performance record contains six descriptive timing rows across the T1000 reference and repeat, i7 CPU, RTX 4080 Super under WSL2, and M1 Pro CPU and MPS paths.
Index differences recorded
Structural gates and reviewed floating-point and metric bounds held. Some nearest-neighbour indices changed, so the four cross-device records retain drift_detected status.
Calibration and holdout
The CPU feature boundary passed in two calibration environments and an independent Ryzen 7 9700X WSL2 CPU holdout.
InspectRT records the numerical differences alongside the workload and run conditions. The full comparisons are in the cross-platform results and ONNX feature checks guides.
ONNX boundary
The optional ONNX artifact stops at the feature boundary. The reviewed direct consumer runs ONNX Runtime 1.28.0 on CPU and requests CPUExecutionProvider as its only active provider.
Generated graph and PyTorch pipeline
| Inside the ONNX graph | Outside the graph | Note |
|---|---|---|
| Frozen ResNet-50 through layer2 | Image decoding, direct resize and ImageNet normalization | Preprocessing supplies the graph input. |
| Padded 3 x 3 average pooling | Complete nominal-bank construction and exact retrieval | The retrieval contract remains in PyTorch. |
| Row-major FP32 patch embeddings | Image scoring, raw anomaly maps and threshold-free metrics | The graph returns feature tensors only. |
| Static batch 1, FP32, 256 x 256 input | Packaging or redistribution of generated model bytes | Generated model bytes stay local. |
Limits
- InspectRT implements a reduced feature-memory baseline. It is not an official or paper-compatible PatchCore reproduction.
- Accepted public baseline runs cover
bottleandleather, one category per run. Benchmarking is frozen to thebottleworkload. - The complete FP32 bank has a substantial memory and retrieval cost. Performance records apply to their named hardware, software stack and run conditions.
- Cross-device nearest-index identity is not exact, even where structures and reviewed numerical bounds hold.
- ONNX support ends at the feature boundary, and direct Python APIs remain experimental.
- InspectRT carries no production or hard-real-time certification and makes no industrial-safety claim. Users obtain MVTec AD and pretrained weights separately.