共计 2382 个字符,预计需要花费 6 分钟才能阅读完成。
背景:工业异常检测的挑战与机遇
在工业质检场景中,我们常常面临两个核心问题:
- 样本极度不均衡:正常样本可能占 99% 以上,缺陷样本稀少且获取成本高
- 缺陷形态多变:同一类缺陷可能呈现完全不同的外观特征(如划痕的走向、深浅变化)
传统 OpenCV 方案依赖手工设计特征(如边缘检测、纹理分析),但在处理以下情况时表现不佳:
- 复杂背景干扰
- 微小缺陷检测(<5 像素)
- 新型缺陷类型的泛化能力
anomalib 技术选型指南
| 算法 | 训练速度 | 小样本表现 | 计算资源需求 | 适用场景 |
|---|---|---|---|---|
| Padim | ★★★★ | ★★★★ | ★★ | 快速原型开发 |
| PatchCore | ★★★ | ★★★★★ | ★★★★ | 高精度需求 |
| CFA | ★★ | ★★★ | ★★★ | 多类别异常检测 |
| STFPM | ★★ | ★★★★ | ★★★★★ | 视频时序分析 |
核心实现四步走
1. 数据准备:FolderDataset 实战
from anomalib.data import FolderDataset
data_module = FolderDataset(
root="./datasets/mvtec",
normal_dir="good",
abnormal_dir="crack",
image_size=(256, 256),
normalization=("imagenet"), # 灰度图需改为(0.5,)
train_batch_size=32,
eval_batch_size=64,
)
关键设计原则:
- 自动划分 train/val/test(默认比例 60:20:20)
- 支持
.png,.jpg,.bmp自动解码 - 内存预加载模式(设置
preload=True加速小数据集)
2. 模型构建:继承 LightningModule
from pytorch_lightning import LightningModule
from torchmetrics import AUROC, F1Score
class CustomModel(LightningModule):
def __init__(self):
super().__init__()
self.auroc = AUROC(task="binary")
self.f1 = F1Score(task="binary", threshold=0.5)
def validation_step(self, batch, _):
images, labels = batch
preds = self(images)
# 必须显式指定 device
preds = preds.to(self.device)
labels = labels.to(self.device)
self.log("val_auroc", self.auroc(preds, labels))
self.log("val_f1", self.f1(preds, labels))
3. 训练配置
# config.yaml
trainer:
max_epochs: 100
accelerator: "gpu"
devices: [0,1] # 多 GPU 时需要设置 sync_batchnorm
model:
name: "patchcore"
backbone: "wide_resnet50_2"
layers: ["layer2", "layer3"]
4. 推理部署
# TorchScript 导出前检查
torch.jit.script(model).save("model.pt")
# 量化校准示例
calibrator = torch.quantization.observer.MinMaxObserver.with_args(
dtype=torch.qint8,
qscheme=torch.per_tensor_symmetric
)
避坑实战经验
灰度图像处理
- 修改
normalization参数为单通道均值方差:normalization=(0.5,) # 替代原来的(0.485, 0.456, 0.406) - 数据加载时添加维度扩展:
image = image.unsqueeze(0) # (H,W) -> (1,H,W)
多 GPU 训练
- 必须设置
sync_batchnorm=True - 检查 DataLoader 的
num_workers不超过 CPU 核心数 - 验证分布式采样是否生效:
print(len(train_dataloader.sampler)) # 应为总样本数 /GPU 数量
生产环境优化
TorchScript 导出清单
- 检查所有 tensor 操作支持动态 shape
- 避免使用
torch.jit.ignore修饰的方法 - 测试输入输出类型一致性
INT8 量化策略
model_fp32 = ... # 加载训练好的模型
model_fp32.eval()
# 插入观测节点
model_fp32.qconfig = torch.quantization.get_default_qconfig("fbgemm")
model_fp32_prepared = torch.quantization.prepare(model_fp32)
# 用验证集校准
with torch.no_grad():
for data in calib_loader:
model_fp32_prepared(data[0].to(device))
# 生成量化模型
model_int8 = torch.quantization.convert(model_fp32_prepared)
动手实验:Colab 实战
建议尝试:
- 调整
threshold观察召回率变化 - 修改
backbone为resnet18比较效果 - 添加高斯噪声测试模型鲁棒性
写在最后
经过两周的实战验证,anomalib 在产线漏检率从 3.2% 降至 0.7%。特别提醒:处理金属反光材质时,建议在数据增强中添加随机光度畸变(photometric distortion)。下一步计划尝试将特征提取器替换为 Vision Transformer,欢迎在 GitHub 讨论区分享你的实验成果。
正文完

