This repository contains the code and pre-computed results for the paper:
Patch purification for contaminated few-shot memory banks Sergio Villanueva, Emilio Soria-Olivas, Manuel Sanchez-Montañés
Memory-bank methods for visual anomaly detection store patch descriptors from a few normal reference images and score test patches by nearest-neighbor distance. In few-shot settings (5–20 references), even a single defective support image can inject anomalous patches into the bank and degrade performance. We address this with a training-free, patch-level self-purification step that removes suspicious patches before test-time scoring using leave-one-out consistency, Mahalanobis distance, or their ensemble.
- Python 3.11
- CUDA-compatible GPU (for feature extraction only)
- ~45 GB disk space for datasets
- ~88 GB disk space for cached features (all 35 categories)
Install dependencies:
pip install -r requirements.txtInstall PyTorch (+ torchvision) separately depending on your hardware (CPU/CUDA):
Optional (speed): if you have FAISS available, experiments run faster. The code falls back to scikit-learn if FAISS is not installed.
Download and extract the following datasets into a data/ directory:
| Dataset | Categories | Download |
|---|---|---|
| MVTec AD | 15 | Link |
| VisA | 12 | Link |
| BTAD | 3 | Link |
| MVTec LOCO AD | 5 | Link |
Expected structure:
data/
├── mvtec_AD/
│ ├── bottle/
│ │ ├── train/good/
│ │ └── test/{good,broken_large,...}/
│ ├── cable/
│ └── ...
├── VisA/
│ ├── candle/
│ ├── split_csv/1cls.csv
│ └── ...
├── btad/
│ ├── 01/
│ └── ...
└── mvtec_loco_AD/
├── breakfast_box/
└── ...
You can reproduce the paper plots/tables directly from the pre-computed CSVs in output/:
python analysis_statistical_tests.py
python analysis_figures.pyExtract DINOv3 and/or CLIP features for all datasets:
python precache_features.py # DINOv3 ViT-L (default)
python precache_features.py --backbone clip # CLIP ViT-L/14Features are saved to output/feature_cache/ (DINOv3) or output/feature_cache_clip/ (CLIP). This step takes ~2 hours per backbone on a single GPU.
# Main experiments: 35 categories, 5 seeds, contamination rates 10-30%
python run_experiments.py
# With CLIP backbone
python run_experiments.py --backbone clip
# LOF baseline (appends to main results)
python run_lof_baseline.py
# Ablation studies
python run_experiments.py --ablation percentile
python run_experiments.py --ablation knn_k
# Quick debug run (2 categories, 1 seed)
python run_experiments.py --debugResults are saved as CSV files in output/exp_p3_002_full/ (DINOv3) or output/exp_p3_002_full_clip/ (CLIP).
python analysis_figures.py
python analysis_statistical_tests.py
python analysis_heatmaps.py # requires feature cache + ground-truth masksOutput figures and tables are saved to output/analysis/.
The output/ directory contains all pre-computed CSV results used in the paper. These are the same files that would be generated by running the experiments above, so the analysis scripts can read them directly without re-running experiments.
DINOv3 backbone (output/exp_p3_002_full/):
| File | Description |
|---|---|
results_v2.csv |
Main results: 35 categories, 5 seeds, TL={10,20}, c={0,0.1,0.2,0.3}, all methods |
results_extra_cont.csv |
Extended contamination rates (c up to 50%) |
results_tl5.csv |
N=5 support set results |
results_pixel_auroc.csv |
Pixel-level AUROC and AUPR metrics |
results_leakage_check.csv |
Data integrity verification (Pool A/B split) |
ablation_full_percentile.csv |
Percentile threshold ablation (35 categories) |
ablation_percentile.csv |
Percentile threshold ablation (6 categories) |
ablation_knn_k.csv |
KNN k ablation |
CLIP backbone (output/exp_p3_002_full_clip/):
| File | Description |
|---|---|
results_v2.csv |
CLIP backbone results (same structure as DINOv3) |
At contamination rate c=0.3 with N=10 support images (DINOv3 backbone):
| Method | Mean AUROC | Delta vs Clean | Recovery |
|---|---|---|---|
| No purification | 81.1% | -8.9 | -- |
| LOO consistency | 84.7% | -5.3 | 40% |
| Mahalanobis | 84.0% | -6.0 | 32% |
| Ensemble (LOO+Mahal) | 85.7% | -4.3 | 51% |
| Oracle (clean bank) | 90.0% | 0.0 | 100% |
@article{villanueva2025patchpurification,
title={Patch purification for contaminated few-shot memory banks},
author={Villanueva, Sergio and Soria-Olivas, Emilio and Sanchez-Monta{\~n}{\'e}s, Manuel},
year={2025}
}This project is licensed under the MIT License. See LICENSE for details.