Home

Awesome

Industrial KNN-based Anomaly Detection

<img src="docs/example_anomaly_maps.png" width="500"/>

This repo aims to reproduce the results of the following KNN-based anomaly detection methods:

  1. SPADE (Cohen et al. 2021) - knn in z-space and distance to feature maps spade schematic
  2. PaDiM* (Defard et al. 2020) - distance to multivariate Gaussian of feature maps padim schematic
  3. PatchCore (Roth et al. 2021) - knn distance to avgpooled feature maps patchcore schematic

* actually does not have any knn mechanism, but shares many things implementation-wise.


Install

$ pipenv install -r requirements.txt

Usage

CLI:

$ python run.py METHOD [--dataset DATASET]

Results can be found under ./results/.

Code example:

from indad.model import SPADE

model = SPADE(k=5, backbone_name="resnet18")

# get some training data
class_name = "bottle"
train_ds, test_ds = MVTecDataset(class_name).get_dataloaders()

model.fit(train_ds)

# evaluate
image_rocauc, pixel_rocauc = model.evaluate(test_ds)
print(image_rocauc, pixel_rocauc)

Custom datasets

<details> <summary> πŸ‘οΈ </summary>

Check out one of the downloaded MVTec datasets. Naming of images should correspond among folders. Right now there is no support for no ground truth pixel masks.

πŸ“‚datasets
 β”— πŸ“‚your_custom_dataset
  ┣ πŸ“‚ ground_truth/defective
  ┃ ┣ πŸ“‚ defect_type_1
  ┃ β”— πŸ“‚ defect_type_2
  ┣ πŸ“‚ test
  ┃ ┣ πŸ“‚ defect_type_1
  ┃ ┣ πŸ“‚ defect_type_2
  ┃ β”— πŸ“‚ good
  β”— πŸ“‚ train/good
$ python run.py METHOD --dataset your_custom_dataset
</details>

Results

πŸ“ = paper, πŸ‘‡ = this repo

Image-level

classSPADE πŸ“SPADE πŸ‘‡PaDiM πŸ“PaDiM πŸ‘‡PatchCore πŸ“PatchCore πŸ‘‡
bottle-98.899.8β– 100.0β– β– 100.0β– 
cable-76.593.3β– 99.5β– 96.2
capsule-84.688.398.195.3
carpet-84.3β– 99.498.798.7
grid-37.198.2β– 98.2β– 93.0
hazelnut-88.783.7β– 100.0β– 100.0
leather-97.199.9β– 100.0β– 100.0
metal_nut-74.699.4β– 100.0β– 98.3
pill-72.689.0β– 96.6β– 92.8
screw-53.183.098.196.7
tile-97.898.698.7β– 99.0β– 
toothbrush-89.497.2β– 100.0β– 98.1
transistor-89.296.8β– 100.0β– 99.7
wood-98.398.9β– 99.2β– 98.8
zipper-96.789.5β– 99.4β– 98.4
averages85.582.695.3*94.3β– 99.1β– 97.7

Pixel-level

classSPADE πŸ“SPADE πŸ‘‡PaDiM πŸ“PaDiM πŸ‘‡PatchCore πŸ“PatchCore πŸ‘‡
bottle97.597.798.397.8β– 98.6β– 97.8
cable93.794.396.796.1β– 98.5β– 97.4
capsule97.698.698.598.3β– 98.9β– 98.3
carpet87.499.099.198.6β– 99.1β– 98.3
grid88.596.197.397.2β– 98.7β– 96.7
hazelnut98.498.198.297.5β– 98.7β– 98.1
leather97.299.299.298.7β– 99.3β– 98.4
metal_nutβ– 99.0β– 96.197.296.598.496.2
pillβ– 99.1β– 93.595.793.297.698.7
screw98.198.998.597.8β– 99.4β– 98.4
tileβ– 96.5β– 93.394.194.895.994.0
toothbrushβ– 98.9β– β– 98.9β– 98.898.398.798.1
transistorβ– 97.9β– 96.397.597.296.497.5
wood94.194.494.793.6β– 95.1β– 91.9
zipper96.598.298.597.4β– 98.9β– 97.6
averages96.996.897.596.9β– 98.1β– 97.2

PatchCore-10 was used.

Hyperparams

The following parameters were used to calculate the results. They more or less correspond to the parameters used in the papers.

spade:
  backbone: wide_resnet50_2
  k: 50
padim:
  backbone: wide_resnet50_2
  d_reduced: 250
  epsilon: 0.04
patchcore:
  backbone: wide_resnet50_2
  f_coreset: 0.1
  n_reweight: 3

Progress

Design considerations


Streamlit demo

Run $ streamlit run streamlit_app.py


Acknowledgements

References

SPADE:

@misc{cohen2021subimage,
      title={Sub-Image Anomaly Detection with Deep Pyramid Correspondences}, 
      author={Niv Cohen and Yedid Hoshen},
      year={2021},
      eprint={2005.02357},
      archivePrefix={arXiv},
      primaryClass={cs.CV}
}

PaDiM:

@misc{defard2020padim,
      title={PaDiM: a Patch Distribution Modeling Framework for Anomaly Detection and Localization}, 
      author={Thomas Defard and Aleksandr Setkov and Angelique Loesch and Romaric Audigier},
      year={2020},
      eprint={2011.08785},
      archivePrefix={arXiv},
      primaryClass={cs.CV}
}

PatchCore:

@misc{roth2021total,
      title={Towards Total Recall in Industrial Anomaly Detection}, 
      author={Karsten Roth and Latha Pemula and Joaquin Zepeda and Bernhard SchΓΆlkopf and Thomas Brox and Peter Gehler},
      year={2021},
      eprint={2106.08265},
      archivePrefix={arXiv},
      primaryClass={cs.CV}
}

MVTec dataset:

@article{Bergmann2021,
 author = {Paul Bergmann and Kilian Batzner and Michael Fauser and David Sattlegger and Carsten Steger},
 title = {The MVTec Anomaly Detection Dataset: A Comprehensive Real-World Dataset for Unsupervised Anomaly Detection},
 journal = {International Journal of Computer Vision},
 year = {2021},
 volume = {129},
 number = {4},
 pages = {1038-1059},
 doi = {10.1007/s11263-020-01400-4}
}
@inproceedings{Bergmann2019,
 author = {Paul Bergmann and Michael Fauser and David Sattlegger and Carsten Steger},
 title = {MVTec AD β€” A Comprehensive Real-World Dataset for Unsupervised Anomaly Detection},
 booktitle = {IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},
 year = {2019},
 pages = {9584-9592},
 doi = {10.1109/CVPR.2019.00982}
}