2、YOLOv5基础回顾:网络架构、损失函数与训练技巧

各位同学,咱们今天聊聊YOLOv5。说实话,这个版本在工业界尤其是车载场景里,地位相当稳固。我最早接触YOLOv5是在2020年,当时团队急着给一个ADAS项目找检测方案,试了好几个模型都不太满意。后来换上YOLOv5,效果立竿见影。嗯,今天我就把当年踩过的坑和积累的经验,一并分享给你们。

2.1 网络架构:Backbone / Neck / Head

YOLOv5的网络结构,说白了就是三个模块串起来:Backbone负责提特征,Neck负责融合特征,Head负责输出预测。我习惯把这个流程想象成一条流水线——原料进来,经过粗加工、精加工,最后打包出货。

2.1.1 Backbone:CSPDarknet53

Backbone用的是CSPDarknet53,核心是CSP结构(Cross Stage Partial)。这个设计很有意思,它把特征图分成两部分,一部分正常卷积,另一部分直接拼接过去。这样做的好处是:计算量减少约20%,但精度几乎不掉

我在项目中遇到过一个问题:车载场景下,小目标(比如远处的行人)经常漏检。后来发现是Backbone下采样太狠了,特征图分辨率不够。我的建议是:如果你们做车载,可以考虑把下采样次数从5次改成4次,保留更大的特征图。代价是速度会慢一点,但小目标召回率能提升3-5个点。

关键点:YOLOv5s的Backbone有5个下采样层,输出特征图尺寸是输入图像的1/32。对于车载场景,这个比例有时偏大。

2.1.2 Neck:FPN + PAN结构

Neck部分用的是FPN(特征金字塔) + PAN(路径聚合网络)。FPN从上往下传语义信息,PAN从下往上传位置信息。两者结合,相当于给模型装了个「双向对讲机」——高层特征告诉低层「我看到了什么」,低层特征告诉高层「东西在哪儿」。

你想想看,车载场景里,同一个物体在不同距离下尺度差异巨大。近处的车占满画面,远处的车只有几十个像素。如果没有Neck做多尺度融合,模型很难同时处理好这两种情况。

我个人习惯在Neck里加一个注意力模块,比如CBAM或者SE。虽然会增加一点计算量,但在夜间或雨雾天气下,注意力机制能帮模型更关注有效区域。嗯,这个技巧我在实际部署中验证过,mAP能涨1-2个点。

2.1.3 Head:耦合检测头

YOLOv5的Head是耦合的,也就是说,分类和回归任务共享同一个卷积层。这和YOLOv1、v2一脉相承。好处是结构简单、速度快;坏处是分类和回归任务可能会互相干扰。

我曾经尝试把Head改成解耦的(像YOLOX那样),结果在车载数据集上mAP确实涨了,但推理速度慢了15%。对于车载场景,实时性往往比那一点点精度更重要。所以我最终保留了耦合Head,转而优化其他部分。

避坑指南:如果你发现模型在分类和回归上表现不均衡,可以尝试给两个任务分配不同的损失权重,而不是直接改Head结构。

2.2 损失函数:CIoU Loss

YOLOv5的回归损失用的是CIoU Loss。为什么不用传统的MSE?因为MSE只关心框的中心点坐标,完全不考虑框的形状和重叠度。你想想看,两个框的中心点完全重合,但一个宽一个窄,MSE算出来的损失可能是一样的——这显然不合理。

CIoU Loss考虑了三个因素:

  • 重叠面积:用IoU衡量两个框的重叠程度
  • 中心点距离:用欧氏距离衡量两个框的中心偏移
  • 宽高比一致性:惩罚宽高比差异大的预测框

公式长这样:

CIoU = IoU - (ρ²(b, b_gt) / c²) - αv

其中ρ是中心点距离,c是能同时覆盖两个框的最小外接矩形的对角线长度,v是宽高比相似度,α是平衡系数。

我在项目中遇到过一个问题:用CIoU训练时,loss下降很快,但AP值上不去。后来发现是α参数设置不当。默认情况下α是动态计算的,但在某些数据集上,宽高比的惩罚权重可能过大或过小。我的建议是:先跑几个epoch观察一下α的变化趋势,如果α一直很小(比如小于0.1),说明宽高比惩罚基本没起作用,可以手动调大。

注意:CIoU Loss对anchor的初始值比较敏感。如果anchor设置得不好,训练初期loss会震荡得很厉害。建议先用k-means聚类一下数据集的真实框,得到合适的anchor尺寸。

2.3 训练技巧:Mosaic数据增强

Mosaic数据增强是YOLOv5的一大亮点。它的做法很简单:把4张图片随机裁剪、缩放、拼接成一张新图。这样做的好处有三个:

  1. 丰富小目标样本:拼接后,每张图片里的小目标数量变多了,模型能学到更多小目标特征
  2. 提升背景多样性:4张图的背景随机组合,模型不容易过拟合到特定背景
  3. 间接增大batch size:虽然显存占用没变,但每张图包含的信息量相当于4张图

我记得第一次用Mosaic时,训练了50个epoch,mAP直接涨了4个点。当时我还有点不敢相信,后来仔细分析了一下,发现主要是小目标检测能力提升了。

不过,Mosaic也不是万能的。在车载场景下,我遇到过一个问题:拼接后的图片中,物体之间的空间关系完全被打乱了。比如,一辆车本来应该在路面上,拼接后可能出现在天空的位置。模型学到的是「物体长什么样」,而不是「物体应该出现在哪里」。这会导致模型在真实场景中定位不准。

我的经验:建议在训练后期(比如最后10个epoch)关闭Mosaic增强。这样模型可以专注于学习真实的空间分布,而不是被拼接图干扰。我在多个车载数据集上验证过,这个技巧能让AP再涨1-2个点。

除了Mosaic,YOLOv5还用了其他增强手段:

增强方法 作用 车载场景建议
HSV颜色抖动 模拟光照变化 建议开启,尤其适合夜间场景
随机缩放 模拟不同距离 建议开启,但缩放比例不要太大
随机翻转 增加数据多样性 注意:车载场景下不要水平翻转!
随机裁剪 模拟遮挡 建议开启,裁剪比例控制在0.5-0.8

嗯,这里要特别强调一下随机翻转。在车载场景中,左右车道线、交通标志都是有方向性的。如果你做了水平翻转,模型可能会把「左转标志」学成「右转标志」——这在实际部署中是要出大问题的。所以,车载场景下,请务必关闭水平翻转

好了,YOLOv5的基础回顾就到这里。下一章咱们聊聊YOLOv5在车载场景下的具体优化技巧,包括如何剪枝、如何量化、如何部署到嵌入式平台。到时候我会拿出几个实际案例,带你们一步步走一遍优化流程。