共计 2145 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点
工业质检场景对 2D 目标检测提出了特殊挑战:

- 小目标问题 :芯片划痕、焊点缺陷等目标可能仅占图像的 0.1% 像素
- 复杂背景干扰 :金属反光、纹理噪声等容易产生误检
- 实时性要求 :产线通常要求 200FPS 以上的处理速度
传统方法存在明显局限:
- Faster R-CNN 的二阶段检测架构导致推理速度慢(<10FPS)
- SSD 在特征金字塔底层缺乏细节特征,小目标召回率低于 60%
- 固定阈值 NMS 在密集缺陷场景会造成目标漏检
技术方案
Backbone 优化
将原版 Focus 模块替换为 Conv+SiLU 组合:
# models/yolo.py
class ConvSiLU(nn.Module):
def __init__(self, in_ch, out_ch, k=1):
super().__init__()
self.conv = nn.Conv2d(in_ch, out_ch, k, stride=2)
self.silu = nn.SiLU()
def forward(self, x):
return self.silu(self.conv(x)) # 计算量减少 23%
特征金字塔增强
增加 P2 检测头(stride=4)捕获微小目标:
- 在 backbone 的 stage2 输出后添加 1 ×1 卷积降维
- 与 P3 层进行特征融合(concat+3×3 卷积)
- 输出通道数调整为 128 以适应高分辨率特征
动态 NMS 策略
根据目标密度自动调整 IoU 阈值:
# utils/general.py
def dynamic_nms(boxes, scores, iou_thres):
density = len(boxes) / (img_size**2) # 目标密度计算
adaptive_thres = iou_thres * (1 - 0.5*density) # 密度越大阈值越低
return torchvision.ops.nms(boxes, scores, adaptive_thres)
代码实现
数据增强组合
采用 Mosaic+MixUp 的混合增强策略:
# dataloaders/augmentations.py
def mosaic_augment(img, labels):
# 随机选取 4 张图像拼接
out_img = np.zeros((img_size*2, img_size*2, 3))
out_labels = []
# ... 拼接逻辑实现...
return out_img, out_labels
def mixup(img1, labels1, img2, labels2):
alpha = random.betavariate(1.5, 1.5) # β 分布采样
mixed_img = alpha*img1 + (1-alpha)*img2
mixed_labels = torch.cat([labels1, labels2], 0)
return mixed_img, mixed_labels
损失函数改进
加权 CIoU 损失解决类别不平衡:
# loss.py
class WeightedCIoULoss:
def __init__(self, class_weights):
self.weights = class_weights # [1.0, 2.5, 3.0] 对应不同缺陷类别
def __call__(self, pred, target):
ciou = 1 - bbox_iou(pred, target, CIoU=True)
weight = self.weights[target[:, 5].long()] # 按类别取权重
return (ciou * weight).mean()
生产部署
TensorRT 加速
FP16 与 INT8 量化对比:
-
FP16 模式 :
python export.py --weights best.pt --include engine --half速度提升 3 倍,精度损失 <0.5%
-
INT8 模式 :
# calibrator.py class DataLoaderCalibrator(trt.IInt8EntropyCalibrator2): # 实现校准数据集加载速度提升 5 倍,精度损失约 2%
显存优化
- 动态 batch:根据 GPU 剩余显存自动调整 batch 大小
- 梯度检查点 :
model.apply(checkpoint_wrapper)显存占用减少 40%,训练速度降低 15%
避坑指南
标注注意事项
- 对于部分遮挡目标,应标注可见部分并标记为 ”truncated” 属性
- 反光区域需明确标注是否为真实缺陷
蒸馏训练技巧
采用 KL 散度 + 余弦相似度多任务损失:
# 教师模型输出作为 soft label
loss = F.kl_div(student_out, teacher_out) + cosine_loss(feat_s, feat_t)
思考与讨论
如何平衡检测速度与微小缺陷的召回率?可以考虑:
- 多阶段检测:先用轻量级网络筛选可疑区域
- 动态分辨率:对检测到的 ROI 区域进行二次高分辨率检测
- 硬件加速:使用 NPU 专用指令处理小目标检测
[实验代码]:https://colab.research.google.com/drive/1xXxx…
实际部署时发现,当缺陷尺寸小于 5 ×5 像素时,即使使用 P2 检测头仍有漏检。后续计划尝试:
– 在特征融合时引入注意力机制
– 增加针对微米级缺陷的专项训练数据
工业场景的模型优化永远是在精度与效率之间寻找最佳平衡点,期待与大家交流更多实战经验。
正文完
发表至: 未分类
近三天内
