从通用到专精:基于自监督学习与领域适应的工业质检系统重构实录
前言:当“大模型”跌落神坛
在过去的两年里,我一直负责公司的工业视觉检测系统开发。起初,我们信奉“大力出奇迹”,直接在ImageNet上预训练的ResNet50后面加几个全连接层,迁移学习到我们的金属表面缺陷检测任务上。
在早期的“划痕”、“凹坑”等明显缺陷上,效果尚可。但随着客户对质量要求的提高,那些极细微的、甚至只有纹理差异的“异色”和“氧化”缺陷,模型完全视而不见。
核心痛点在于:缺乏标注数据。
工业场景极其残酷。产线跑得飞快,我们要么只能收集到海量且重复的“良品”数据,要么只能拿到极少数的“废品”样本。人工标注一张高精度的工业缺陷图,往往需要资深质检员盯着屏幕看上十几分钟,成本极高。没有标注,传统的监督学习就寸步难行。
为了打破这个“数据孤岛”,我们决定抛弃传统的预训练-微调路径,转而探索自监督学习。通过对比学习和掩码语言模型(MLM)的混合策略,在海量无标注数据中挖掘特征,最后通过领域适应技术完成最终落地。
这是一次从“授人以鱼”到“授人以渔”的技术跨越。
一、 破局者:自监督学习的引入
自监督学习的核心思想非常简单:让模型自己当老师。既然没有人工标注的Label,我们就利用数据本身的结构信息来构造伪标签。
在图像领域,这意味着我们不需要知道这张图是“划痕”还是“脏污”,我们只需要让模型学会理解图像的纹理、形状和上下文关系。
1.1 预训练策略的选择:双模并行
在调研了大量论文后,我们发现单一的预训练任务都有局限性。
- 对比学习(如SimCLR, MoCo):擅长学习全局特征,知道这是一只猫还是一只狗,但对细微的纹理差异不够敏感。
- 生成式学习(如MAE):擅长学习局部重建,但往往过于关注像素级的完美,而忽略了语义层面的判别性。
针对工业缺陷“纹理敏感”且“位置随机”的特点,我们设计了一套双流并行预训练框架:
- 流A(SimCLR变体):学习图像的整体表征,区分不同的产品和不同的表面状态。
- 流B(掩码自编码器 MAE):随机遮盖图像75%的patches,强迫模型根据周围的纹理去恢复被遮盖的区域。
这种组合让模型不仅学会了“这是什么产品”,还学会了“这里的纹理应该是连贯的”。
二、 特征提取:对比学习的工程实践
对比学习的核心在于:把拉近,把推远。
我们基于MoCo v3(Momentum Contrast)架构进行了改进。MoCo最大的优势在于它维护了一个巨大的队列来存储负样本,解决了SimCLR需要巨大Batch Size的问题(受限于显卡显存)。
2.1 动态队列与动量编码器
在工业产线上,良品和次品的比例极度不平衡(可能1000:1)。如果负样本队列里全是良品,模型学不到次品的特征。
我们引入了难例挖掘机制。
- Encoder Q:当前训练的主网络。
- Encoder K:动量更新的副本,参数缓慢跟随Q。
- Queue:存储的特征库。
在训练过程中,我们计算Q的输出与Queue中特征的相似度。如果发现某个良品样本的特征与某个特定的次品特征极度相似(容易混淆),我们会强制将该良品样本的权重提高,让它作为一个“难负样本”,逼迫模型去分辨它们之间那微小的像素级差异。
2.2 数据增强的工业定制
对比学习高度依赖数据增强。通用的裁剪、旋转在工业场景下可能引入歧义(比如旋转后的缺陷可能变成另一种形态)。我们定制了一套增强策略:
| 增强手段 | 通用场景 | 工业场景调整 | 目的 |
|---|---|---|---|
| 颜色抖动 | 随机调整亮度/对比度 | 模拟车间光照不均 | 提升对光照的鲁棒性 |
| 高斯噪声 | 低强度噪声 | 模拟传感器热噪声 | 抗干扰 |
| Cutout | 随机遮挡方块 | 缺陷式遮挡 | 模拟未知缺陷覆盖 |
| 特别是“缺陷式遮挡”,我们会用模拟的纹理去遮挡图像的一部分,强迫模型通过周围上下文去推断被遮挡的内容,这与掩码语言模型的思路不谋而合。 |
三、 全局与局部的融合:掩码自编码器
虽然对比学习很强,但它主要关注图像级别的相似度。为了捕捉像素级的细节,我们引入了掩码建模。
由于工业图像通常是灰度或高精度的彩色图,直接做像素级的MSE(均方误差)回归很难收敛。我们借鉴了NLP中的**掩码语言模型(MLM)**的思想,只不过把Word Token换成了Image Token(Patches)。
我们使用Vision Transformer (ViT) 作为Backbone。
- Masking:将输入图片切成16x16的Patch,随机掩掉75%。
- Encoding:只把可见的Patch送入ViT。
- Decoding:使用一个轻量级的Decoder,根据Encoder的特征还原被掩掉的Patch。
关键发现:在预训练过程中,我们发现模型在修复“纹理断裂”区域时,学到了极好的边缘特征。这些特征对于后续检测细微的“裂纹”至关重要。我们将Decoder丢弃,只保留Encoder作为特征提取器,这成为了我们系统的核心骨干。
四、 风险控制:预训练-微调范式的演进
预训练结束后,我们拥有了一个见多识广的Backbone,但它还没有见过具体的缺陷。接下来是经典的预训练-微调阶段。
在这个阶段,我们拿出了那仅有的几百张精心标注的缺陷数据。
4.1 冻结与解冻策略
微调最大的风险是灾难性遗忘。如果学习率太大,模型会迅速把预训练学到的通用特征(如边缘检测)忘得一干二净,转而去死记硬背那几百个缺陷样本。
我们采用了分层微调:
- Stage 1:冻结ViT的前12层,只微调最后4层和分类头。此时学习率设为,让模型快速适应数据的分布。
- Stage 2:解冻所有层,使用极小的学习率()进行全网络微调。这一步是为了精细调整特征,让模型适应具体的缺陷纹理。
4.2 Focal Loss的应用
由于缺陷样本极少,正负样本极度不平衡。我们用Focal Loss替代了Cross Entropy Loss,通过降低易分类样本(良品)的权重,让模型更关注那些难分类的缺陷样本。
五、 落地关键:领域适应
在实验室测试集上,我们的模型达到了99.5%的准确率。然而,当我们将模型部署到A客户的工厂现场时,准确率断崖式下跌至85%。
这就是传说中的Domain Shift(域偏移)。虽然都是金属表面,但A客户的材质是铝合金,B客户的是不锈钢,且现场的打光角度完全不同。重新收集数据、预训练、微调的周期太长,无法接受。
我们引入了无监督领域适应技术。
5.1 对抗训练(DANN)
我们的目标是:提取出的特征应该包含缺陷信息,但不包含“是哪个工厂”的信息。
我们在特征提取器后面加了一个域分类器。
- 任务1(缺陷分类):希望特征能准确分类缺陷。
- 任务2(域分类):希望特征能判断样本来自源域(实验室)还是目标域(工厂)。
这通过了一个梯度反转层来实现。在反向传播时,域分类器的梯度乘以-1,这意味着特征提取器在更新参数时,是在欺骗域分类器——让它无法区分源域和目标域。
效果:经过对抗训练,模型学习到了“材质无关”的缺陷特征。它不再关注是“铝合金”还是“不锈钢”,而是关注“这是不是一道划痕”。
5.2 Test-Time Adaptation
除了模型层面的适应,我们在推理阶段也加入了源数据标准化。我们在推理前,会先用一批目标域(工厂实时)的图片,计算其均值和方差,动态调整模型的归一化层参数。这种极低成本的自适应,让精度又回升了2个百分点。
六、 总结:从数据堆砌到算法智能
这次重构的成果是显著的。
| 维度 | 传统迁移学习 | 自监督 + 领域适应 |
|---|---|---|
| 标注依赖 | 高 (需数千张) | 极低 (仅需数百张) |
| 跨泛化能力 | 弱 (换产线需重训) | 强 (快速适应) |
| 微调精度 | 89.5% | 98.2% |
| 上线周期 | 4周 | 1周 |
| 通过对比学习和掩码建模,我们榨干了海量无标注数据的价值;通过领域适应,我们跨越了实验室与工厂之间的鸿沟。 | ||
| 这让我深刻认识到,在工业落地的征途中,架构创新很重要,但如何利用好手头的数据、如何解决模型落地的“最后一公里”问题,才是工程价值的核心所在。 自监督学习,正是那把打开工业数据宝库的钥匙。 |
- 点赞
- 收藏
- 关注作者
评论(0)