2D目标检测实战:基于YOLOv5的工业缺陷检测解决方案

1次阅读
没有评论

共计 2145 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

背景痛点

工业质检场景对 2D 目标检测提出了特殊挑战:

2D 目标检测实战:基于 YOLOv5 的工业缺陷检测解决方案

  • 小目标问题 :芯片划痕、焊点缺陷等目标可能仅占图像的 0.1% 像素
  • 复杂背景干扰 :金属反光、纹理噪声等容易产生误检
  • 实时性要求 :产线通常要求 200FPS 以上的处理速度

传统方法存在明显局限:

  1. Faster R-CNN 的二阶段检测架构导致推理速度慢(<10FPS)
  2. SSD 在特征金字塔底层缺乏细节特征,小目标召回率低于 60%
  3. 固定阈值 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)捕获微小目标:

  1. 在 backbone 的 stage2 输出后添加 1 ×1 卷积降维
  2. 与 P3 层进行特征融合(concat+3×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 量化对比:

  1. FP16 模式

    python export.py --weights best.pt --include engine --half

    速度提升 3 倍,精度损失 <0.5%

  2. INT8 模式

    # calibrator.py
    class DataLoaderCalibrator(trt.IInt8EntropyCalibrator2):
        # 实现校准数据集加载 

    速度提升 5 倍,精度损失约 2%

显存优化

  1. 动态 batch:根据 GPU 剩余显存自动调整 batch 大小
  2. 梯度检查点
    model.apply(checkpoint_wrapper)

    显存占用减少 40%,训练速度降低 15%

避坑指南

标注注意事项

  • 对于部分遮挡目标,应标注可见部分并标记为 ”truncated” 属性
  • 反光区域需明确标注是否为真实缺陷

蒸馏训练技巧

采用 KL 散度 + 余弦相似度多任务损失:

# 教师模型输出作为 soft label
loss = F.kl_div(student_out, teacher_out) + cosine_loss(feat_s, feat_t)

思考与讨论

如何平衡检测速度与微小缺陷的召回率?可以考虑:

  1. 多阶段检测:先用轻量级网络筛选可疑区域
  2. 动态分辨率:对检测到的 ROI 区域进行二次高分辨率检测
  3. 硬件加速:使用 NPU 专用指令处理小目标检测

[实验代码]:https://colab.research.google.com/drive/1xXxx…

实际部署时发现,当缺陷尺寸小于 5 ×5 像素时,即使使用 P2 检测头仍有漏检。后续计划尝试:
– 在特征融合时引入注意力机制
– 增加针对微米级缺陷的专项训练数据

工业场景的模型优化永远是在精度与效率之间寻找最佳平衡点,期待与大家交流更多实战经验。

正文完
 0
评论(没有评论)