Clean reproduction of PatchCore (Roth et al., CVPR 2022) on MVTec-AD with image-level AUROC, pixel-level AUROC, and pixel-level AUPRO.
Paper: Towards Total Recall in Industrial Anomaly Detection - Roth et al., CVPR 2022
End-to-end reproduction of PatchCore using a frozen WideResNet-50 backbone, mid-layer feature aggregation, greedy coreset subsampling, and nearest-neighbour anomaly scoring. First in a series of visual anomaly detection reproductions I'm building during May–June 2026.
Implementation complete: code reproduces PatchCore end-to-end on MVTec-AD.
Empirical results pending GPU access. Numbers will be added to the table below once experiments run.
You can clone and reproduce locally today just see Installation, Dataset, and Run below. The walkthrough notebook in notebooks/ is the fastest way to verify the pipeline on a single category.
Match the paper's reported numbers within ±0.5 points on MVTec-AD across all 15 categories:
| Image-AUROC | Pixel-AUROC | Pixel-AUPRO | |
|---|---|---|---|
| Paper (mean) | 99.1 | 98.1 | 94.3 |
| This repo | TBD | TBD | TBD |
Full per-category table will land here as runs complete.
Clone and create the environment:
git clone https://github.com/hammadhaideer/patchcore-reproduced.git
cd patchcore-reproduced
conda env create -f environment.yml
conda activate patchcoreOr with pip in an existing environment:
pip install -r requirements.txtDownload MVTec-AD from the official page (registration required, free for non-commercial use). Extract it anywhere on your machine, then point the code to it via an environment variable:
export PATCHCORE_DATA_ROOT=/path/to/mvtec_adExpected layout:
$PATCHCORE_DATA_ROOT/
├── bottle/
│ ├── train/good/*.png
│ ├── test/<defect>/*.png
│ └── ground_truth/<defect>/*_mask.png
├── cable/
└── ... (15 categories)
The 15 categories: bottle, cable, capsule, carpet, grid, hazelnut, leather, metal_nut, pill, screw, tile, toothbrush, transistor, wood, zipper.
Single category:
python scripts/run_patchcore.py --config configs/default.yaml --category bottleAll 15 categories sequentially (~30 minutes on a single GPU):
python scripts/run_all.pyBuild the comparison table after runs complete:
python scripts/aggregate_results.py --results_dir resultsPer-category results land in results/<category>.json. The aggregated table prints to stdout, comparing your numbers against the paper's.
For an interactive end-to-end walkthrough on a single category with feature extraction visualization and qualitative heatmaps:
jupyter notebook notebooks/01_walkthrough.ipynbRun cells top-to-bottom. The notebook reads the same config and dataset path as the scripts.
- Repo scaffold, configs, dataset loader
- Feature extractor, memory bank, coreset subsampling
- Image-AUROC, pixel-AUROC, AUPRO metrics
- Single-category and all-category runners
- Results aggregation script with paper comparison
- Walkthrough notebook
- Empirical reproduction across all 15 categories (pending GPU)
- Qualitative heatmap figures
- Medium walkthrough post
- Roth et al., Towards Total Recall in Industrial Anomaly Detection, CVPR 2022
- Bergmann et al., MVTec-AD, CVPR 2019
- Official PatchCore repo: https://github.com/amazon-science/patchcore-inspection
MIT