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官方损失函数定义如下:
共计算了三个损失:预测框损失、置信度损失和分类损失。
- 对于预测框,仅计算每个网格中存在真值标签的预测框损失;
- 如何判断该网格是否存在真值标签:计算真值框的中心点位于哪个网格内;
- 如何判断该网格那个预测框对应真值标签:计算预测框与真值框的IoU,最大的那个参与损失计算;
- 对于置信度损失,所有的预测框置信度均参与计算;
- 为了平衡正样本损失和负样本损失,设置超参数\(\lambda_{coord}\)和\(\lambda_{noobj}\);
- 对于预测框分类概率,仅计算每个网格中存在真值标签的预测框分类损失;
- 在YOLOv1论文中,均使用均值平方差(Mean Square Error/MSE)来计算损失;
- 为了平衡不同损失对于YOLOv1的训练,
- 对于预测框的w/h开根号后参与计算;
- 设置超参数\(\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优化的方向。