Anomaly Detection for Manufacturing Quality Control
Module: Computer Vision | Difficulty: Premium
Anomaly Score
where is encoder, is reconstruction.
PatchCore Memory Bank
where is the set of normal patch features.
reconstruction-based Anomaly Detection
Classification-Based (PaDiM)
where are per-channel statistics from training.
| Method | MVTec AUROC | Image AUROC | Speed | Category |
|---|---|---|---|---|
| Autoencoder | 83.2% | 78.1% | Fast | Reconstruction |
| PaDiM | 97.9% | 95.2% | Fast | Statistics |
| PatchCore | 99.1% | 97.5% | Medium | Memory |
| FastFlow | 98.5% | 96.8% | Fast | Flow |
| AnomalyGPT | 99.3% | 98.1% | Slow | LLM |
import torch
import torch.nn as nn
import torch.nn.functional as F
class PatchCoreAnomalyDetector:
def __init__(self, backbone, coreset_ratio=0.1):
self.backbone = backbone
self.memory_bank = None
self.coreset_ratio = coreset_ratio
def fit(self, normal_images):
features = []
for img in normal_images:
with torch.no_grad():
feat = self.extract_features(img)
features.append(feat)
features = torch.cat(features, dim=0)
self.memory_bank = self.coreset_subsample(features)
def extract_features(self, x):
self.backbone.eval()
feats = []
def hook(module, input, output):
feats.append(output.mean(dim=[2, 3]))
handle = self.backbone.layer3.register_forward_hook(hook)
self.backbone(x)
handle.remove()
return feats[-1]
def coreset_subsample(self, features, num_samples=None):
if num_samples is None:
num_samples = int(len(features) * self.coreset_ratio)
idx = [0]
distances = torch.cdist(features, features[idx])
for _ in range(num_samples - 1):
max_dist, max_idx = distances.max(dim=0)
idx.append(max_idx[max_dist.argmax()])
new_dist = torch.cdist(features, features[idx[-1:]])
distances = torch.min(distances, new_dist)
return features[idx]
def predict(self, x):
feat = self.extract_features(x)
distances = torch.cdist(feat.unsqueeze(0),
self.memory_bank.unsqueeze(0))
return distances.min(dim=-1)[0].mean()
Research Insight: Industrial anomaly detection has shifted from reconstruction-based methods (autoencoders, GANs) to feature-based methods (PaDiM, PatchCore) that model the distribution of normal features. PatchCore achieved near-perfect detection by maintaining a coreset subsample of normal patch features and computing anomaly scores as nearest-neighbor distances. The key challenge is few-shot industrial deployment: obtaining sufficient defective samples is impractical, so methods must learn from normal data alone. AnomalyGPT explores using large language models for interpretable defect description.