This repository contains the official implementation of the paper:
SubspaceAD: Training-Free Few-Shot Anomaly Detection via Subspace Modeling (CVPR2026)
Figure 1. SubspaceAD consists of two training-free stages: (1) extracting DINOv2 patch features from a few normal exemplars, and (2) estimating a low-dimensional PCA subspace to model normal appearance. Anomalies are detected via reconstruction residuals.
Detecting visual anomalies in industrial inspection often requires operating with only a few normal exemplars per category. While many recent approaches rely on large memory banks, auxiliary datasets, or multi-modal tuning, SubspaceAD introduces a minimalist, training-free alternative.
SubspaceAD consists of two stages:
- Feature Extraction: Patch-level features are extracted from a small set of normal images using a frozen DINOv2 backbone.
- Subspace Modeling: A PCA model is fit to these features to estimate the low-dimensional manifold of normal appearance.
At inference time, anomalies are detected using the reconstruction residual with respect to this learned subspace. Despite its simplicity, SubspaceAD achieves state-of-the-art performance in one-shot and few-shot settings.
Main Results (1-Shot)
- MVTec-AD: 98.0% Image AUROC; 97.6% Pixel AUROC
- VisA: 93.3% Image AUROC; 98.3% Pixel AUROC
MVTec-AD |
VisA |
Figure 2. Qualitative comparison on VisA and MVTec-AD (1-shot). SubspaceAD produces sharper and more precise anomaly maps than PromptAD and AnomalyDINO, with fewer false activations and better alignment with ground-truth defects across both datasets.
- Training method upgraded 🎉 to DINOv3
- Added
save_model.pyfor PCA parameter model persistence andinference.pyfor convenient model inference - Added comprehensive project documentation and usage guides
# 1. Create environment
uv venv
source venv/bin/activate
# 2. Install dependencies and the package
uv pip install -r requirements.txt
uv pip install -e .pip install modelscope
mkdir -p DINO
modelscope download --model facebook/dinov3-vitl16-pretrain-lvd1689m --local_dir ./DINO
Training Directory Requirements:
- The directory should contain normal (defect-free) sample images
- Supported image formats:
.png,.jpg - Images will be automatically shuffled, then trained using the number specified by the
--k_shotparameter
Validation Set Support:
If you need to use a validation set to calculate detection thresholds in a custom directory, you can create a val/ directory at the same level as the training directory:
your_datasets/
├── train/ # Training images (normal samples)
│ ├── 001.png
│ ├── 002.png
│ └── ...
└── val/ # Validation set (optional)
├── good/ # Normal samples (for threshold calculation)
│ ├── 001.png
│ └── ...
└── defect/ # Defective samples (optional)
└── ...
python save_model.py \
--dataset_name phone_screen \
--train_dir your_datasets \
--model_ckpt DINO/dinov3-vitl16-pretrain-lvd1689m \
--image_res 1024 \
--k_shot 10 \
--layers="-7,-8,-9,-10" \
--aug_count 10 \
--aug_list rotate hflip vflip affine \
--pca_ev 0.99 \
--score_method reconstruction \
--img_score_agg mtop1ppython inference.py \
--model_path models/phone_screen_train_k10 \
--image_path datasets/phone_screen/val/defect_croped \
--output_dir results/inference \
--visualize \
--save_summary| Setting | Method | MVTec-AD | VisA |
|---|---|---|---|
| 1-Shot | PromptAD | 94.2 | 86.9 |
| AnomalyDINO | 96.6 | 87.4 | |
| SubspaceAD | 98.0 | 93.3 | |
| 2-Shot | PromptAD | 95.7 | 88.3 |
| AnomalyDINO | 96.9 | 89.7 | |
| SubspaceAD | 98.1 | 94.1 | |
| 4-Shot | PromptAD | 96.6 | 89.1 |
| AnomalyDINO | 97.7 | 92.6 | |
| SubspaceAD | 98.4 | 94.5 |
| Method | MVTec-AD | VisA |
|---|---|---|
| MuSc | 97.8 | 94.1 |
| AnomalyDINO | 94.2 | 90.7 |
| SubspaceAD | 96.6 | 97.7 |
If you find this repository useful, please consider citing:
@misc{lendering2026subspaceadtrainingfreefewshotanomaly,
title={SubspaceAD: Training-Free Few-Shot Anomaly Detection via Subspace Modeling},
author={Camile Lendering and Erkut Akdag and Egor Bondarev},
year={2026},
eprint={2602.23013},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2602.23013},
}

