Enterprise AI Bootcamp Demo 3

A model trained on good parts only, catching a defect family the detector never saw

DAGM Class 3 was held out of supervised training entirely — not down-weighted, not rare, absent. On screen 2 the detector scored close to nothing on it. This screen fits a different kind of model on 600 normal Class 3 images and no defective images of any kind, then asks it about the 150 defects.

Anomaly model, good samples only
0.886
image-level ROC AUC
Supervised detector, same images
0.633
never shown this class
Defects seen during fitting
0
of any class
Fitting time
4 s
one forward pass, no gradient descent
This is the structural point The supervised detector cannot be fixed for this class by any amount of Class 1 and Class 2 data, or by any number of extra parameters, because the failure is that nobody ever showed it this defect family. The anomaly model needs no examples of the defect at all — only a description of normal. Those are different tools for different failures, and choosing between them is an engineering decision, not a modelling one.

Score distributions

Mahalanobis distance at the 99.5th percentile of the anomaly map, for 300 unseen normal images and 150 defective ones. The overlap is real and is why the AUC is 0.886 rather than 1.0.

The same images, scored by the supervised detector

Barely separated. The detector is not confused; it is answering a question it was never trained on.

Where the operating point comes from, and the mistake almost everyone makes

A plant that has not yet seen this defect family has no defective examples to tune on, so the threshold has to come from normal data alone. Which normal data decides whether the bench number survives contact with the line.

Threshold chosen fromvaluedefects caught good parts flaggedverdict
The 600 images the Gaussians were fitted to 9.30 92.7%48.0% optimistic
100 further normals, unseen by the fit 10.13 45.3%2.3% honest
Same model. Same images. Only the calibration set differs. Reading the threshold off the images the Gaussians were fitted to makes the false-alarm rate look better on the bench than it is on the line. The two operating points above are the same model; only the calibration set differs. Read the two rows carefully: the optimistic calibration appears to catch 93% of defects, and it does — while flagging 48% of good parts. The honest calibration catches 45% at a 2% false-alarm rate. Neither row is a good result. Both are the truth, and only one of them would have been discovered before deployment.

Where it is looking

Mahalanobis distance per position, over the image. White boxes are the published ground truth, which the model has never seen.

anomaly heat map C3_Test_0554
defective · anomaly 13.0 · detector 0.187
flagged by the anomaly model
anomaly heat map C3_Test_0160
defective · anomaly 12.5 · detector 0.110
flagged by the anomaly model
anomaly heat map C3_Test_0171
defective · anomaly 12.0 · detector 0.117
flagged by the anomaly model
anomaly heat map C3_Train_0673
defective · anomaly 11.9 · detector 0.094
flagged by the anomaly model
anomaly heat map C3_Test_0292
defective · anomaly 11.7 · detector 0.132
flagged by the anomaly model
anomaly heat map C3_Train_0698
defective · anomaly 11.6 · detector 0.134
flagged by the anomaly model
anomaly heat map C3_Test_0037
normal · anomaly 8.4 · detector 0.092
passed by the anomaly model
anomaly heat map C3_Train_1094
normal · anomaly 8.4 · detector 0.123
passed by the anomaly model

The method, and its licence

Method
PaDiM (Defard et al. 2020), reimplemented in ~80 lines
Backbone
torchvision ResNet-18 ImageNet, BSD-3-Clause, frozen
Statistics
32×32 position-wise Gaussians in 64 randomly selected feature dimensions, shrinkage-regularised
Training
None in the gradient-descent sense. One forward pass over the normal images, then a mean and a covariance per position.
On Anomalib. Anomalib's PaDiM is Apache-2.0 and would have been licence-clean. It was not used because of dependency weight in a 1400 MB service, not because of its licence. This reimplementation carries this repository's licence.

precomputed Built by scripts/train_anomaly.py at 2026-08-09T19:32:21+00:00. Fitted on 600 normal images of DAGM Class 3; the same statistics serve live uploads on the Live inference screen. Re-run that script to regenerate it; nothing on this page is hardcoded.