1. 项目背景与核心挑战
在玻璃制品生产线上,瓶身缺陷检测一直是个让人头疼的问题。传统人工质检不仅效率低下(每小时最多检测200-300个瓶子),而且漏检率普遍在5%以上。我们团队去年为某大型玻璃厂部署的视觉检测系统,最初采用YOLOv5方案,但在处理以下典型缺陷时表现不佳:
- 瓶口裂纹(平均检出率仅68%)
- 瓶身气泡群(小气泡漏检率高达40%)
- 底部划痕(受反光干扰严重时检出率骤降至50%以下)
经过三个月产线实测,我们发现现有模型在三个关键指标上不达标:
- 小目标检测mAP@0.5仅0.72
- 推理速度在1080Ti上仅23FPS
- 模型大小达189MB,难以部署到边缘设备
2. 模型架构改进方案
2.1 主干网络优化:MogaBlock设计
原YOLOv13的CSPDarknet53主干在特征提取时存在两个明显缺陷:
- 浅层网络对微小缺陷特征捕获不足
- 深层网络因下采样过度丢失瓶体轮廓信息
我们引入MogaBlock模块的改进包括:
class MogaBlock(nn.Module): def __init__(self, c1, c2, expansion=0.5): super().__init__() self.channel_attention = nn.Sequential( nn.AdaptiveAvgPool2d(1), nn.Conv2d(c1, c1//8, 1), nn.ReLU(), nn.Conv2d(c1//8, c1, 1), nn.Sigmoid() ) self.depthwise = nn.Conv2d(c1, c1, 3, padding=1, groups=c1) self.pointwise = nn.Conv2d(c1, c2, 1) def forward(self, x): ca = self.channel_attention(x) x = x * ca x = self.depthwise(x) return self.pointwise(x)关键改进点:
- 通道注意力机制增强气泡等微小缺陷的特征响应
- 深度可分离卷积减少75%参数量
- 特征重校准使mAP@0.5提升0.15
2.2 Neck部分重构:C3k2模块
传统PANet存在特征融合不充分的问题,我们设计的C3k2模块结构如下:

实现代码核心:
class C3k2(nn.Module): def __init__(self, c1, c2, n=3): super().__init__() self.cv1 = Conv(c1, c2//2, 1, 1) self.cv2 = Conv(c1, c2//2, 1, 1) self.m = nn.Sequential(*[MogaBlock(c2//2, c2//2) for _ in range(n)]) def forward(self, x): y1 = self.cv1(x) y2 = self.m(self.cv2(x)) return torch.cat((y1, y2), 1)优势对比:
| 模块类型 | 参数量(M) | mAP@0.5 | 推理时延(ms) |
|---|---|---|---|
| 原PANet | 4.82 | 0.71 | 8.2 |
| C3k2 | 3.15 | 0.83 | 5.7 |
3. 关键训练技巧
3.1 数据增强策略
针对玻璃瓶检测的特殊性,我们设计了增强组合:
augmentations: - name: OpticalDistortion params: { distort_limit: 0.2, shift_limit: 0.1 } # 模拟玻璃折射 - name: RandomGamma params: { gamma_limit: (70, 130) } # 应对光照变化 - name: Cutout params: { max_h_size: 32, max_w_size: 32, fill_value: 118 } # 增强抗遮挡能力重要提示:避免使用ColorJitter,玻璃瓶颜色信息对缺陷检测无意义且会引入噪声
3.2 损失函数优化
采用Dynamic Focal Loss替代原CrossEntropy:
class DynamicFocalLoss(nn.Module): def __init__(self, alpha=0.25, gamma=2.0): super().__init__() self.alpha = alpha self.gamma = gamma def forward(self, pred, target): ce_loss = F.cross_entropy(pred, target, reduction='none') pt = torch.exp(-ce_loss) loss = self.alpha * (1-pt)**self.gamma * ce_loss return loss.mean()在10万张玻璃瓶数据集上的对比:
| 损失函数 | 裂纹检出率 | 气泡检出率 | 划痕检出率 |
|---|---|---|---|
| CrossEntropy | 82.3% | 78.5% | 75.1% |
| DynamicFocal | 89.7% | 85.2% | 83.6% |
4. 部署优化实践
4.1 模型量化方案
采用QAT(量化感知训练)的配置参数:
qconfig = torch.quantization.get_default_qat_qconfig('fbgemm') model_fp32_prepared = torch.quantization.prepare_qat( model_fp32.to('cpu').train(), qconfig, inplace=False )量化前后对比:
| 指标 | FP32模型 | INT8模型 | 变化率 |
|---|---|---|---|
| 模型大小 | 189MB | 47MB | -75% |
| 推理速度 | 23FPS | 58FPS | +152% |
| mAP@0.5 | 0.89 | 0.87 | -2.2% |
4.2 TensorRT加速
关键优化参数:
config->setMaxWorkspaceSize(1 << 30); config->setFlag(BuilderFlag::kFP16); config->setProfilingVerbosity(ProfilingVerbosity::kDETAILED);部署实测数据:
| 设备 | 原生PyTorch(FPS) | TensorRT(FPS) | 提升倍数 |
|---|---|---|---|
| Jetson Xavier | 18 | 53 | 2.94x |
| RTX 3060 | 42 | 127 | 3.02x |
5. 产线实测效果
在某日产量20万瓶的生产线上连续测试7天的数据:
| 缺陷类型 | 检出数量 | 漏检数量 | 检出率 | 误检率 |
|---|---|---|---|---|
| 瓶口裂纹 | 1,287 | 23 | 98.2% | 1.1% |
| 瓶身气泡 | 3,452 | 67 | 98.1% | 0.9% |
| 底部划痕 | 892 | 19 | 97.9% | 1.3% |
关键改进点实测对比:
- 夜间工况下的稳定性:检出率波动<2%(原系统波动达15%)
- 不同瓶型的适应能力:换型无需重新训练(原系统需30分钟微调)
- 抗干扰能力:在玻璃反光强烈区域,误检率降低83%
6. 常见问题解决方案
6.1 反光干扰处理
典型报错:
[WARNING] 检测到高反光区域,置信度波动超过阈值解决方案分三步:
- 偏振滤镜物理降噪(推荐KOWA LM-52MC)
- 在数据增强中添加SpecularHighlight:
transforms.Lambda(lambda x: x + 0.1*torch.randn_like(x)*torch.where(x>0.9, 1, 0))- 模型推理时启用反射抑制模块:
def reflect_suppress(x, threshold=0.85): return torch.where(x > threshold, x - 0.2*(x-threshold), x)6.2 小气泡漏检优化
配置参数调整:
model: anchors: - [5,6, 8,12, 11,20] # 专门针对3-8px气泡 detect: min_size: 2 # 允许检测2px以上目标训练时增加小目标权重:
loss_weights = { 'small_obj': 3.0, # 默认1.0 'medium_obj': 1.5, 'large_obj': 0.7 }7. 模型扩展应用
7.1 瓶盖检测适配
只需修改两个参数即可适配:
# 修改anchor比例 anchors = [[12,16], [19,36], [40,28]] # 调整输入尺寸 input_size = (640, 480) # 瓶盖长宽比7.2 液体杂质检测
需要新增数据预处理:
class LiquidPreprocess: def __call__(self, img): img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) img[:,:,2] = cv2.equalizeHist(img[:,:,2]) # 增强对比度 return cv2.cvtColor(img, cv2.COLOR_HSV2BGR)在产线上,这套系统目前已经稳定运行超过6个月,平均每天检测35万个玻璃瓶。最让我意外的是模型对新型瓶体的适应能力——上个月产线突然更换瓶型时,在没有重新训练的情况下,首日检出率仍保持在96.7%以上。这证明MogaBlock提取的特征确实具有出色的泛化性。