【2024工业图像异常检测文献】SuperSimpleNet: 统一无监督和监督式学习检测快速可靠的表面缺陷检测方法
SuperSimpleNet: Unifying Unsupervised and Supervised Learning for Fast and Reliable Surface Defect Detection
1、Background
提出的SuperSimpleNet方法,是一种从SimpleNet演变而来的创新的判别模型。
【2023工业图像异常检测文献】SimpleNet: 简单的图像异常检测和定位网络
SuperSimpleNet在SimpleNet的基础上进行了一系列的改进和创新,以下是主要的改进点和创新之处:
- 特征上采样:SuperSimpleNet引入了特征上采样步骤,通过增加特征图的分辨率来提高对小缺陷的检测能力。这是对SimpleNet的一个直接改进,有助于提升模型对细节的捕捉能力。
- 分类头部:新增了一个分类头部,用于生成图像级别的异常分数。这个分数反映了整个图像中异常的置信度,有助于减少误报并提高对小异常的检测率。
- 合成异常生成:在无监督设置中,SuperSimpleNet使用Perlin噪声和高斯噪声生成合成异常,这些异常被限制在非异常区域,而在监督设置中,合成异常与真实异常结合使用,以增强模型对异常的泛化能力。
- 损失函数和训练策略:SuperSimpleNet采用了截断的L1损失和焦点损失,以优化模型的训练过程。此外,还引入了学习率调度器和梯度调整策略,以提高训练的稳定性和模型的性能。
- 无监督和监督学习的统一:SuperSimpleNet能够灵活地在无监督和监督设置中进行训练,这使得模型能够适应不同的训练条件,并充分利用所有可用的训练数据。
2、Method
SuperSimpleNet算法流程:
1. 特征提取(Feature Extraction)
- 预训练网络:使用预训练的卷积神经网络(例如WideResNet50),从输入图像中提取特征。
- 上采样:为了提高小缺陷的检测能力,对提取的低分辨率特征图进行上采样,使其具有更高的分辨率。
- 池化:通过局部平均池化来捕捉特征图邻近区域的信息,增强特征的上下文感知能力。
2. 特征适配(Feature Adaptation)
- 线性层:通过一个线性层(特征适配器)进一步调整特征,使其更适合后续的异常检测任务。
3. 合成异常生成(Synthetic Anomaly Generation)
- Perlin噪声:使用Perlin噪声生成一个二值掩码,该掩码决定了在图像的哪些区域添加噪声。
- 高斯噪声:在无监督设置中,高斯噪声被添加到Perlin噪声掩码指定的所有区域。在监督设置中,高斯噪声被添加到非异常区域,而真实异常区域不添加噪声。
4. 分割头和分类头(Segmentation and Classification Heads)
- 分割头:负责预测输入图像的异常掩码(Mo),即识别图像中的异常区域。
- 分类头:使用分割头的输出和扰动后的特征图作为输入,产生一个异常分数(s),表示图像中异常的置信度。
5. 训练过程(Training Process)
- 损失函数:使用截断的L1损失和焦点损失来训练分割头,同时使用焦点损失来训练分类头。
- 监督信号:在监督设置中,模型的训练会受到真实异常掩码和异常标签的监督。在无监督设置中,模型仅使用合成异常进行训练。
6. 推理过程(Inference Process)
- 省略异常生成:在推理时,不生成合成异常,直接使用特征适配器的输出来预测异常掩码和异常分数。
pseudo-code
import torch
import torch.nn as nn
import torch.nn.functional as F# 定义SuperSimpleNet模型
class SuperSimpleNet(nn.Module):def __init__(self):super(SuperSimpleNet, self).__init__()# 特征提取器:预训练的卷积网络self.feature_extractor = PretrainedCNN()# 特征适配器:线性层self.feature_adaptor = nn.Linear(in_features, out_features)# 分割头:用于预测异常掩码self.segmentation_head = SegmentationHead()# 分类头:用于预测异常分数self.classification_head = ClassificationHead()def forward(self, x, is_training=False):# 特征提取features = self.feature_extractor(x)# 特征上采样和池化features = self.upsample_and_pool(features)# 特征适配adapted_features = self.feature_adaptor(features)if is_training:# 合成异常生成perturbed_features = self.generate_synthetic_anomalies(adapted_features)else:perturbed_features = adapted_features# 分割头预测异常掩码anomaly_mask = self.segmentation_head(perturbed_features)# 分类头预测异常分数anomaly_score = self.classification_head(perturbed_features)return anomaly_mask, anomaly_scoredef generate_synthetic_anomalies(self, features):# 使用Perlin噪声生成异常掩码perlin_mask = self.generate_perlin_noise_mask(features.size(0), features.size(2), features.size(3))# 添加高斯噪声生成合成异常perturbed_features = features + self.gaussian_noise(perlin_mask)return perturbed_featuresdef upsample_and_pool(self, features):# 上采样特征图upsampled_features = F.interpolate(features, scale_factor=2, mode='bilinear')# 应用池化pooled_features = F.avg_pool2d(upsampled_features, kernel_size=3, stride=1, padding=1)return pooled_features# 预训练CNN特征提取器
class PretrainedCNN(nn.Module):def __init__(self):super(PretrainedCNN, self).__init__()# 这里可以加载一个预训练的CNN模型,例如ResNetdef forward(self, x):# 提取特征return features# 分割头
class SegmentationHead(nn.Module):def __init__(self):super(SegmentationHead, self).__init__()# 定义分割头的层def forward(self, x):# 预测异常掩码return anomaly_mask# 分类头
class ClassificationHead(nn.Module):def __init__(self):super(ClassificationHead, self).__init__()# 定义分类头的层def forward(self, x):# 预测异常分数return anomaly_score# 生成Perlin噪声掩码
def generate_perlin_noise_mask(batch_size, height, width):# 生成噪声掩码return perlin_mask# 生成高斯噪声
def gaussian_noise(mask):# 生成高斯噪声return noise
3、Experiments
4、Conclusion
SuperSimpleNet还严重依赖于所使用的背景,因为需要为每个背景调整高斯噪声的大小。如果背景无法提取有意义的特征,异常检测性能也会恶化。