Industrial Defect Detection
Module: Computer Vision | Difficulty: Advanced
Overview of Industrial Anomaly Detection
Industrial defect detection is the application of computer vision to identify surface defects, dimensional anomalies, and quality deviations in manufactured products. The core challenge differs fundamentally from supervised classification: defective samples are extremely rare in well-controlled manufacturing processes, often representing less than 0.1% of production. This extreme rarity makes supervised learning impractical because collecting sufficient defective examples would require months of production and manual inspection.
The dominant paradigm is unsupervised anomaly detection, where models learn the distribution of "normal" products from defect-free training data and flag deviations at test time. This approach requires only normal samples for training, making it deployable immediately on new production lines. The key assumption is that defective products will exhibit features that are statistically different from the learned normal distribution, allowing detection without ever having seen a specific defect type during training.
PatchCore: Memory-Based Anomaly Detection
PatchCore represents the state-of-the-art in unsupervised anomaly detection by maintaining a memory bank of normal patch features extracted from a pretrained backbone network. During training, the model extracts feature vectors from overlapping patches of normal images and stores them in a memory bank. At test time, each test patch is compared against the memory bank using nearest-neighbor distance, and patches with large distances are flagged as anomalous.
The core insight is that a sufficiently dense sampling of normal features can represent the full distribution of normal appearance, and any deviation from this distribution indicates a potential defect. PatchCore uses aggressive subsampling (coreset) to reduce memory requirements while maintaining coverage of the feature space. The coreset subsample is selected using a greedy algorithm that maximizes the minimum distance between selected features, ensuring representative coverage.
PatchCore Anomaly Score
Where each parameter means:
- â input image patch to evaluate for anomaly
- â memory bank containing coreset subsampled normal patch features
- â global average pooled feature vector from pretrained backbone (e.g., ResNet-50 layer3)
- â L2 Euclidean distance in feature space
- Intuition: The minimum distance to the nearest memory bank entry measures how "normal" the patch is; large distances indicate features never seen in normal data
Coreset Subsampling
Where each parameter means:
- â full set of extracted features from all training images
- â target coreset size (typically 1-5% of total features)
- â optimal coreset subsample maximizing intra-core-set distance
- Intuition: Greedy farthest-point sampling approximates this NP-hard problem efficiently in time
PaDiM: Statistical Anomaly Detection
PaDiM (Patch-based Anomaly Detection using Mahalanobis distance) takes a different approach by modeling the distribution of patch features as multivariate Gaussians. For each patch location, PaDiM fits a Gaussian distribution using features extracted from the training set. At test time, the Mahalanobis distance between the test feature and the local Gaussian measures how anomalous the patch is.
The advantage of PaDiM over PatchCore is computational efficiency: no memory bank lookup is needed, only a single forward pass and distance computation. However, the Gaussian assumption may not hold for complex textures, limiting performance on certain defect types. PaDiM typically uses a pretrained ResNet-18 backbone and extracts features from multiple layers to capture both local texture and global structure.
PaDiM Anomaly Score
Where each parameter means:
- â input image patch
- â spatial location in the feature map (patch index)
- â feature vector extracted at location from the backbone
- â mean of the Gaussian distribution at location estimated from training data
- â covariance matrix at location (regularized for invertibility)
- Intuition: Mahalanobis distance accounts for correlations between feature dimensions, providing a statistically principled anomaly measure
Second Architecture: Reconstruction-Based Detection
Reconstruction-based anomaly detection trains an autoencoder to reconstruct normal images from a compressed latent representation. The autoencoder learns to compress and decompress normal product appearances but cannot faithfully reconstruct defective regions it has never seen during training. The pixel-wise reconstruction error serves as an anomaly map, with high-error regions corresponding to potential defects.
The fundamental limitation of autoencoders is that they can sometimes generalize to reconstruct defects if the defect patterns are simple or the model capacity is too high. Variational autoencoders (VAE) address this by constraining the latent space to a known distribution, but this can reduce reconstruction quality. GAN-based approaches (AnoGAN, f-AnoGAN) use adversarial training to produce sharper reconstructions but introduce training instability. More recent methods like SimpleFlow and FastFlow use normalizing flows to model the exact likelihood of normal features, providing more principled anomaly scores.
Comparison of Anomaly Detection Methods
| Method | MVTec AUROC | Image AUROC | Speed | Memory | Category |
|---|---|---|---|---|---|
| Autoencoder | 83.2% | 78.1% | Fast | Low | Reconstruction |
| VAE | 85.7% | 81.3% | Fast | Low | Reconstruction |
| PaDiM | 97.9% | 95.2% | Fast | Medium | Statistics |
| PatchCore | 99.1% | 97.5% | Medium | High | Memory |
| FastFlow | 98.5% | 96.8% | Fast | Medium | Flow |
| AnomalyGPT | 99.3% | 98.1% | Slow | High | LLM |
Python Implementation: PatchCore Anomaly Detection
import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import models
class PatchCoreAnomalyDetector:
def __init__(self, backbone_name="resnet50", coreset_ratio=0.1):
self.backbone = self._build_backbone(backbone_name)
self.memory_bank = None
self.coreset_ratio = coreset_ratio
def _build_backbone(self, name):
if name == "resnet50":
backbone = models.resnet50(pretrained=True)
backbone = nn.Sequential(*list(backbone.children())[:-2])
backbone.eval()
return backbone
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)
print(f"Memory bank: {self.memory_bank.shape[0]} features")
def extract_features(self, x):
feats = []
def hook(module, input, output):
feats.append(output.mean(dim=[2, 3]))
handle = self.backbone[-1].register_forward_hook(hook)
with torch.no_grad():
self.backbone(x.unsqueeze(0) if x.dim() == 3 else x)
handle.remove()
return feats[-1].squeeze(0)
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()
def get_anomaly_map(self, x, feature_map):
b, c, h, w = feature_map.shape
anomaly_map = torch.zeros(b, h, w)
for i in range(h):
for j in range(w):
patch_feat = feature_map[:, :, i, j]
dist = torch.cdist(
patch_feat, self.memory_bank.unsqueeze(0)
)
anomaly_map[:, i, j] = dist.min(dim=-1)[0]
return anomaly_map
Common Challenges in Industrial Defect Detection
- Extreme Class Imbalance: Defective products represent less than 0.1% of production, making supervised learning impractical and requiring unsupervised or few-shot approaches
- Texture Variability: Natural textures (wood grain, fabric weave, metal surface) have inherent variability that can be confused with defects, requiring careful threshold calibration
- Real-Time Constraints: Production lines move at 1-10 meters per minute, requiring inference times under 50ms per frame with high-resolution images (4096+ pixels)
- Domain Shift: Different production batches, lighting conditions, and material suppliers introduce variability that can cause false positives in deployed systems
- Defect Definition Ambiguity: What constitutes a "defect" varies by product grade and customer requirements, requiring flexible systems that can adapt to different quality standards
Case Study: Electronics PCB Inspection
A major electronics manufacturer deployed PatchCore-based anomaly detection for PCB quality control across 12 production lines. The system inspects high-resolution images of printed circuit boards after soldering to detect missing components, solder bridges, tombstoning, and insufficient solder. Key metrics over 12 months:
- Total PCBs inspected: 8.2 million units
- Defect detection rate: 99.4% (vs. 94.2% with previous rule-based system)
- False positive rate: 0.03% (vs. 2.1% with previous system)
- Inference time: 38ms per board at 4K resolution
- Defect types detected: 47 unique defect categories
- Training data: 500 normal PCB images (no defective samples needed)
- Annual savings: $3.8M in reduced scrap and manual inspection labor
- Customer returns: 89% reduction in defective products reaching customers
Key Takeaways
- PatchCore achieves 99.1% AUROC on MVTec AD by maintaining a coreset subsample of normal features and using nearest-neighbor distance as the anomaly score
- PaDiM offers faster inference by modeling per-patch Gaussian distributions, achieving 97.9% AUROC with lower memory requirements
- Reconstruction-based methods are intuitive but limited by the autoencoder's ability to generalize to unseen defect patterns
- Unsupervised training from normal samples only is essential for industrial deployment where defective samples are rare
- Coreset subsampling reduces memory requirements by 95% while maintaining detection performance through farthest-point sampling
- Real-time inference under 50ms is achievable with GPU acceleration, enabling inline inspection on production lines
- Threshold calibration is critical for production deployment, as the trade-off between missed defects and false rejects directly impacts manufacturing yield