Skip to main content
This quickstart guide will help you train and evaluate your first PatchCore model on the MVTec AD dataset.

Prerequisites

Make sure you have:
  • Python 3.8 or higher
  • CUDA-compatible GPU (recommended)
  • At least 11GB of GPU memory

Quick Setup

1

Install Dependencies

Clone the repository and install required packages:
git clone https://github.com/amazon-science/patchcore-inspection.git
cd patchcore-inspection
pip install -r requirements.txt
click>= 8.0.3
faiss-cpu
matplotlib>= 3.5.0
pillow>= 8.4.0
pretrainedmodels>= 0.7.4
torch>= 1.10.0
scikit-image>= 0.18.3
scikit-learn>= 1.0.1
scipy>= 1.7.1
torchvision>= 0.11.1
tqdm>= 4.62.3
2

Download MVTec AD Dataset

Download the MVTec AD dataset from the official website and extract it.Your dataset structure should look like:
mvtec/
├── bottle/
│   ├── ground_truth/
│   ├── test/
│   │   ├── good/
│   │   ├── broken_large/
│   │   └── ...
│   └── train/
│       └── good/
├── cable/
└── ...
The dataset contains 15 categories: bottle, cable, capsule, carpet, grid, hazelnut, leather, metal_nut, pill, screw, tile, toothbrush, transistor, wood, and zipper.
3

Set Environment Variable

Set the PYTHONPATH to include the source directory:
export PYTHONPATH=src:$PYTHONPATH
4

Train Your First Model

Train PatchCore on a single category (e.g., “bottle”) using WideResNet50:
datapath=/path/to/mvtec

python bin/run_patchcore.py --gpu 0 --seed 0 --save_patchcore_model \
  --log_group IM224_WR50_L2-3_P01_D1024-1024_PS-3_AN-1_S0 \
  --log_project MVTecAD_Results results \
  patch_core -b wideresnet50 -le layer2 -le layer3 --faiss_on_gpu \
  --pretrain_embed_dimension 1024 --target_embed_dimension 1024 \
  --anomaly_scorer_num_nn 1 --patchsize 3 \
  sampler -p 0.1 approx_greedy_coreset \
  dataset --resize 256 --imagesize 224 -d bottle mvtec $datapath
  • --gpu 0: Use GPU 0
  • --seed 0: Set random seed for reproducibility
  • --save_patchcore_model: Save the trained model
  • -b wideresnet50: Use WideResNet50 backbone (pretrained on ImageNet)
  • -le layer2 -le layer3: Extract features from layer2 and layer3
  • --faiss_on_gpu: Run similarity search on GPU for speed
  • --pretrain_embed_dimension 1024: Backbone feature dimension
  • --target_embed_dimension 1024: Final PatchCore embedding dimension
  • --anomaly_scorer_num_nn 1: Use 1 nearest neighbor for scoring
  • --patchsize 3: Local aggregation neighborhood size
  • -p 0.1: Keep 10% of patches via coreset subsampling
  • --resize 256 --imagesize 224: Resize to 256, then center crop to 224

Expected Output

During training, you’ll see output similar to:
Evaluating dataset [mvtec_bottle] (1/1)...
Training models (1/1)
Embedding test data with models (1/1)
Computing evaluation metrics.
instance_auroc: 1.000
full_pixel_auroc: 0.988
anomaly_pixel_auroc: 0.988
Expected Performance (WideResNet50 baseline on 224x224 images):
  • Instance AUROC: 99.2% (image-level anomaly detection)
  • Pixel-wise AUROC: 98.1% (defect localization)
  • PRO Score: 94.4%

Train on All Categories

To train on all 15 MVTec AD categories:
datapath=/path/to/mvtec
datasets=('bottle' 'cable' 'capsule' 'carpet' 'grid' 'hazelnut' \
          'leather' 'metal_nut' 'pill' 'screw' 'tile' 'toothbrush' \
          'transistor' 'wood' 'zipper')
dataset_flags=($(for dataset in "${datasets[@]}"; do echo '-d '$dataset; done))

python bin/run_patchcore.py --gpu 0 --seed 0 --save_patchcore_model \
  --log_group IM224_WR50_L2-3_P01_D1024-1024_PS-3_AN-1_S0 \
  --log_project MVTecAD_Results results \
  patch_core -b wideresnet50 -le layer2 -le layer3 --faiss_on_gpu \
  --pretrain_embed_dimension 1024 --target_embed_dimension 1024 \
  --anomaly_scorer_num_nn 1 --patchsize 3 \
  sampler -p 0.1 approx_greedy_coreset \
  dataset --resize 256 --imagesize 224 "${dataset_flags[@]}" mvtec $datapath

Model Output

After training, your results will be saved in:
results/MVTecAD_Results/IM224_WR50_L2-3_P01_D1024-1024_PS-3_AN-1_S0/
├── models/
│   └── mvtec_bottle/
│       ├── nnscorer_search_index.faiss
│       └── patchcore_params.pkl
└── results.csv

Evaluate a Trained Model

To evaluate your trained model:
datapath=/path/to/mvtec
loadpath=results/MVTecAD_Results/IM224_WR50_L2-3_P01_D1024-1024_PS-3_AN-1_S0

python bin/load_and_evaluate_patchcore.py --gpu 0 --seed 0 evaluated_results \
  patch_core_loader -p $loadpath/models/mvtec_bottle --faiss_on_gpu \
  dataset --resize 256 --imagesize 224 -d bottle mvtec $datapath

Next Steps

Installation Guide

Detailed installation instructions and troubleshooting

Model Architecture

Learn how PatchCore works under the hood

Training Options

Explore advanced training configurations

API Reference

Complete API documentation

Common Issues

GPU Memory Error? If you encounter out-of-memory errors:
  • Reduce --imagesize (e.g., from 224 to 192)
  • Reduce batch size with --batch_size 1
  • Use CPU FAISS by removing --faiss_on_gpu
If you get “FAISS not found”, install the GPU version:
pip uninstall faiss-cpu
pip install faiss-gpu

Build docs developers (and LLMs) love