YOLO系列-YOLOv1

重新学习YOLOv1论文,以及复现YOLOv1工程。

前言

YOLOv1是2015年发布的目标检测相关论文,从AI发展的角度来看已经是非常久远的年代了。只不过YOLO系列一直在不断的进化,从原作者的YOLOv1/v2/v3,到后来的YOLOv4/v5/v6,再到2023年的YOLOv7/v8,YOLO系列算法一直是实时目标检测领域最受欢迎的实现。作为计算机视觉研发工程师,如何在具体场景下落地图像算法,平衡好算法精度和软硬件的局限性,一直是我追逐的方向。YOLO系列作为目标检测任务最重要的解决方案,对其进行深入的研究和实践,一定能够帮助到现实场景优化。

YOLOv1论文已经看过好多遍了,之前也发布了一篇论文解读:You Only Look Once: Unified, Real-Time Object Detection,只不过从知道到做到还是需要花非常多的功夫。最新的实现zjykzj/YOLOv1能够完整的复现YOLOv1模型定义,并且在数据预处理以及算法训练上进行了优化,最终在Pascal VOC数据集评估上能够达到更好的效果。

工程架构

训练优化

相比于原始论文实现,我在数据预处理以及YOLOv1损失函数上进行了着重优化,

  • 数据预处理:结合ultralytics/yolov5的预处理实现,增加了马赛克以及随机视角等预处理算法;
  • YOLOv1Loss:对于分类损失,使用交叉熵损失(CrossEntropyLoss)替代均值平方差损失(MSELoss);
  • 其他:
    • 关于优化器和学习率调度器的实现,采用了我之前常用的训练配置:SGD + Warmup + MultiStepLR;
    • 通过调整模型结构,取消最后一个下采样操作来增加空间感受野大小,可以帮助模型采集细粒度特征,从训练结果来看有效提高精度。

损失函数

YOLOv1官方损失函数定义如下:

共计算了三个损失:预测框损失、置信度损失和分类损失。

  1. 对于预测框,仅计算每个网格中存在真值标签的预测框损失;
    1. 如何判断该网格是否存在真值标签:计算真值框的中心点位于哪个网格内;
    2. 如何判断该网格那个预测框对应真值标签:计算预测框与真值框的IoU,最大的那个参与损失计算;
  2. 对于置信度损失,所有的预测框置信度均参与计算;
    1. 为了平衡正样本损失和负样本损失,设置超参数\(\lambda_{coord}\)\(\lambda_{noobj}\)
  3. 对于预测框分类概率,仅计算每个网格中存在真值标签的预测框分类损失;
  4. 在YOLOv1论文中,均使用均值平方差(Mean Square Error/MSE)来计算损失;
  5. 为了平衡不同损失对于YOLOv1的训练,
    1. 对于预测框的w/h开根号后参与计算;
    2. 设置超参数\(\lambda_{coord}=5\)\(\lambda_{noobj}=0.5\)

实际使用如下:

\[ Loss=\lambda_{coord}\sum_{i=0}^{S^{2}}\sum_{j=0}^{B}1_{ij}^{obj}[(x_{i}-\hat{x}_{i})^{2}+(y_{i}-\hat{y}_{i})^{2}]\\ \] \[ +\lambda_{coord}\sum_{i=0}^{S^{2}}\sum_{j=0}^{B}1_{ij}^{obj}[(\sqrt{w_{i}}-\sqrt{\hat{w}_{i}})^{2}+(\sqrt{h_{i}} - \sqrt{\hat{h}_{i}})^{2}] \] \[ +\sum_{i=0}^{S^{2}}\sum_{j=0}^{B}1_{ij}^{obj}(C_{i} - \hat{C}_{i})^{2} \\ \] \[ +\lambda_{noobj}\sum_{i=0}^{S^{2}}\sum_{j=0}^{B}1_{ij}^{noobj}(C_{i} - \hat{C}_{i})^{2}\\ \] \[ -\sum_{i=0}^{S^{2}}1_{ij}^{obj}y_{c}\log(p_{c}) \]

差别在于调整了分类损失的计算,使用交叉熵损失替代均方差损失。实际训练体验上来看,这两个损失的训练差别不大。

训练结果

和原来论文一样,使用VOC2007和VOC2012的trainval数据集进行训练,使用VOC2007的test数据集进行评估,训练结果如下:

Original (darknet) Original (darknet) abeardear/pytorch-YOLO-v1 zjykzj/YOLOv1(This) zjykzj/YOLOv1(This) zjykzj/YOLOv1(This) zjykzj/YOLOv1(This)
ARCH YOLOv1 FastYOLOv1 ResNet_YOLOv1 YOLOv1(S=14) FastYOLOv1(S=14) YOLOv1 FastYOLOv1
VOC AP[IoU=0.50] 63.4 52.7 66.5 71.71 60.38 66.85 52.89

小结

从论文可知,作者在实验中也发现了YOLOv1对于密集目标的检测效果(受限于网格约束)以及小目标的检测效果(YOLOv1Loss对于大目标和小目标的预测误差并没有区分,相同大小的预测误差对于小目标影响更大)不佳。这也是后续YOLOv2优化的方向。