1. 赛题背景与挑战解析去年参加华为云杯生活垃圾检测比赛时我遇到了所有目标检测选手都会头疼的经典问题模型在训练集上表现完美测试集却惨不忍睹。这个过拟合问题在生活垃圾这类特殊场景尤为明显——想象一下你要教AI识别沾着酱油的外卖盒、压扁的易拉罐、缠绕着头发丝的化妆品瓶这些物体在真实场景中的形态变化比ImageNet里的标准物体复杂得多。比赛用的数据集包含32类生活垃圾从可回收物到有害垃圾每类物体的尺度差异极大。比如废旧电池可能只占图片的5%而一张废纸板可能占据半个画面。更麻烦的是实际拍摄的垃圾图片往往存在严重遮挡比如垃圾桶里层层叠叠的垃圾袋这对YOLOv3这类单阶段检测器提出了严峻挑战。初版baseline我直接套用了经典YOLOv3配置训练集mAP轻松突破0.85但测试集始终卡在0.6左右。通过分析混淆矩阵发现两个明显问题一是小物体如瓶盖、电池的召回率不足30%二是特定类别尤其是透明塑料袋、碎玻璃的误检率极高。这引出了我们后续要解决的两个核心问题尺度敏感性和类别不平衡。2. 有效调优策略实战2.1 空间金字塔池化SPP的妙用原版YOLOv3只在三个尺度做检测这对尺寸多变的生活垃圾远远不够。我们在backbone末端加入了SPP模块就像给网络装了个多焦距镜头。具体实现时采用1×1、5×5、9×9、13×13四种最大池化并行操作将不同感受野的特征图拼接起来。这个改动让mAP提升了4.2%尤其是对中大型物体的检测改善明显。代码实现关键点class SPP(nn.Module): def __init__(self): super().__init__() self.maxpool1 nn.MaxPool2d(5, stride1, padding5//2) self.maxpool2 nn.MaxPool2d(9, stride1, padding9//2) self.maxpool3 nn.MaxPool2d(13, stride1, padding13//2) def forward(self, x): o1 self.maxpool1(x) o2 self.maxpool2(x) o3 self.maxpool3(x) return torch.cat([x, o1, o2, o3], dim1)2.2 Stitcher数据增广的黑科技传统mosaic增广对生活垃圾效果有限我们借鉴了商汤提出的Stitcher方法将4张小图拼合成大图时刻意保留部分小物体不缩放。比如保持瓶盖、打火机等小物体以原始尺寸粘贴同时缩小冰箱、家具等背景物体。这种反常识的操作让小物体mAP提升了7.3%。实际操作中有几个细节设置尺寸阈值如32×32像素小于该阈值的物体保持原样对背景物体随机缩放0.3-1.2倍拼接时采用泊松融合避免生硬边缘2.3 自适应锚框聚类用常规k-means聚类锚框时发现对小物体匹配度很差。我们改进了聚类策略对训练集所有标注框按面积分三组小、中、大每组单独做k-means聚类我们设为3:6:3比例计算聚类时使用1-IoU作为距离度量这样得到的锚框分布更符合实际数据特性特别是改善了小物体的召回率。下表对比了不同聚类策略的效果聚类方法小物体AP中物体AP大物体AP传统k-means0.4120.6530.721分组k-means0.5030.6670.735改进距离度量0.5270.6810.7423. 那些看似有效却踩坑的技巧3.1 为什么DropBlock不Work面对严重过拟合我首先尝试了DropBlock这种高级正则化方法。理论上它能比普通Dropout更好地保持空间信息但实际使用时发现两个问题在Darknet53的深层卷积层应用时导致梯度爆炸block_size参数难以调优设小了没效果设大了会破坏关键特征后来通过特征可视化发现生活垃圾的判别性特征往往集中在局部区域如瓶子的螺纹口、电池的正负极随机丢弃特征块反而破坏了这些关键信息。3.2 Focal Loss的陷阱为应对类别不平衡尝试用Focal Loss替换BCE Loss。但出现三个意外现象γ2时模型完全无法收敛γ0.5时效果不如普通BCE改变α参数对透明塑料类无效分析发现主要原因在于正负样本极端不平衡约1:1000困难样本如透明物体本身特征模糊与GIoU Loss存在优化方向冲突3.3 数据增强的边际效应尝试过以下增强方法但收效甚微CutMix垃圾图片背景简单混合后反而引入噪声GridMask规则遮挡破坏了垃圾的连续性特征色彩抖动生活垃圾本身的颜色就变化无常最终保留的有效增强只有HSV空间随机调整±30%随机旋转±15度轻度运动模糊模拟手机拍摄4. 工程实践中的关键细节4.1 训练策略优化经过多次实验最优超参组合如下优化器SGDmomentum0.937学习率余弦退火base_lr0.01final_lr0.0005batch_size16显存受限时的最佳平衡点热身训练前3个epoch逐步提升学习率关键发现过大batch_size会加剧过拟合。当batch从16增加到32时测试集mAP下降2.1%因为参数更新变得太激进。4.2 测试阶段的技巧多尺度测试时要注意尺度范围0.8-1.2倍超出范围会大幅降低小物体检测翻转增强只做水平翻转垂直翻转不符合实际场景NMS阈值设为0.5高于常规值因垃圾密集且重叠多4.3 模型部署陷阱将PyTorch模型转到华为云ModelArts时遇到两个坑ONNX导出时要指定dynamic_axestorch.onnx.export( model, dummy_input, model.onnx, input_names[images], output_names[output], dynamic_axes{ images: {0: batch}, output: {0: batch} } )华为云OBS存储的路径区分大小写提交时要注意目录结构完全匹配5. 未竟之路与进阶思考虽然最终成绩止步0.74mAP但积累了一些有价值的发现过拟合的本质可视化显示网络记住了垃圾的纹理而非形状特征小物体检测瓶颈FPN顶层特征对小物体已经严重失真类别不平衡的深层影响少数类别的梯度被淹没在反向传播中后续值得尝试的方向特征金字塔改进借鉴BiFPN的跨尺度连接解耦头设计将分类和回归任务分离动态标签分配根据预测结果动态调整正负样本这次比赛让我深刻体会到垃圾检测可能是比COCO更难的目标检测任务。它不仅考验模型能力更考验工程师对数据特性的理解。有时候看似高级的技巧反而不如针对性的小改动有效。