Yolov5技术总结

YOLOv5代码注释版更新啦,注释的是最近的2021.07.14的版本,且注释更全
github:https://github.com/Laughing-q/yolov5_annotations

Yolov5技术总结

  • Backbone
  • Detection (YOLO) layer
  • 标签分配
  • 损失函数
  • Yolov5-1.0、2.0、3.0、4.0、5.0

Backbone

Focus:网络第一层进行 pixel un-shuffling而不是stride=2的卷积;该模块的设计主要是减少计算量加快速度;
作者原话:https://github.com/ultralytics/yolov5/issues/847
Focus() module is designed for FLOPS reduction and speed increase, not mAP increase.
Also designed for layer count reduction. 1 Focus module replaces 3 yolov3/4 layers.

SPP:分别采用5/9/13(v5.0采用3/5/7)的最大池化,再进行concat融合,提高感受野;
BottleNeckCSP/C3:Cross Stage Partial Networks,减少计算量,提高卷积神经网络学习能力;
具体网络结构可以查看:Yolov5网络结构

Detection (YOLO) layer

Anchor:根据超参数中的hyp[‘anchor_t’]来检查默认anchor与数据集标签的契合度,如果<0.98,则根据数据集标签进行聚类重新获得anchor;
默认anchor如下:

  • [10,13, 16,30, 33,23] # P3/8
  • [30,61, 62,45, 59,119] # P4/16
  • [116,90, 156,198, 373,326] # P5/3

v5.0:
anchors:

  • [ 19,27, 44,40, 38,94 ] # P3/8
  • [ 96,68, 86,152, 180,137 ] # P4/16
  • [ 140,301, 303,264, 238,542 ] # P5/32
  • [ 436,615, 739,380, 925,792 ] # P6/64

参考:https://github.com/ultralytics/yolov5/issues/471
边框回归:在进行边框回归 筛选样本对应anchor的时候,就是通过hyp[‘anchor_t’]来筛选,而不是iou;
新的边界回归方法:

Yolov5技术总结

标签分配

每个网格除了返回中心点在网格中的目标外,还返回中心点在网格附近的周围网格的目标,
grid(i, j)也会回归grid(i, j+1),grid(i, j-1),grid(i+1, j),grid(i-1, j)中的部分框,如下图中红色部分,
这也契合了上面的边框回归中心点的范围为-0.5~1.5;

笔者尝试过如果改成grid(i, j)仅回归中心点在grid(i, j)的目标(边框回归范围依旧是0.5~1.5),
召回率会下降,准确率会上升,但总体map会下降,也就是说yolov5的标签分配应该会带来一定的map提升,
毕竟一个目标采用了更多的anchor去回归,召回率提高也是有道理的;

(当然,我只是在自己的数据集上做了简单的实验)

Yolov5技术总结
代码:

        off = torch.tensor([[0, 0],
                            [1, 0], [0, 1], [-1, 0], [0, -1],  # j,k,l,m
                            # [1, 1], [1, -1], [-1, 1], [-1, -1],  # jk,jm,lk,lm
                            ], device=targets.device).float() * g  # offsets
          # Matches
         r = t[:, :, 4:6] / anchors[:, None]  # wh ratio
          j = torch.max(r, 1. / r).max(2)[0] < self.hyp['anchor_t']  # compare
          # j = wh_iou(anchors, t[:, 4:6]) > model.hyp['iou_t']  # iou(3,n)=wh_iou(anchors(3,2), gwh(n,2))
         t = t[j]  # filter
         # Offsets
          gxy = t[:, 2:4]  # grid xy
         gxi = gain[[2, 3]] - gxy  # inverse
          j, k = ((gxy % 1. < g) & (gxy > 1.)).T
          l, m = ((gxi % 1. < g) & (gxi > 1.)).T
          j = torch.stack((torch.ones_like(j), j, k, l, m))
          t = t.repeat((5, 1, 1))[j]
          offsets = (torch.zeros_like(gxy)[None] + off[:, None])[j]
          gij = (gxy - offsets).long()
          gi, gj = gij.T  # grid xy indices

损失函数

边框回归:CIOU loss
Objectness:CIOU
分类:BCE
损失平衡:ciou=0.05,objectness=1, cls=0.5;
三个输出层损失平衡:4.0, 1.0, 0.4分别对应下采样8,16,32的输出层

优化策略:
Warmup热身训练;
Cosine余弦退火;
梯度累积;
EMA;
数据增强:
Mosaic;
仿射变换、随机旋转、平移、缩放、裁剪、上下翻转;
随机hsv;
进行数据增强操作还有一个bbox筛选的过程:
去除被裁剪过小的框(面积小于裁剪前的20%) ,并且还有长和宽必须大于2个像素,且长宽比范围在(1/20, 20)之间的限制;

Yolov5-1.0、2.0、3.0、4.0、5.0

1.0->2.0:
yolov5x mAP有提升,但yolov5s mAP却下降了,
训练策略的改变,包括余弦退火的公式更新了,以及类别损失cls_loss的系数gain,对数据进行仿射变换(dataset.py数据增强部分)的超参数进行调整,三个output的损失比重balance的调整。
2.0->3.0:
V3.0据作者所说,大约10%的推理速度为代价提高了所有模型的mAP。尽管CUDA内存需求增加了约10%,但训练速度并未受到明显影响,具体未测试;
最小的模型从Hardswish()激活中受益最大,YOLOv5s / m / l / x的增加幅度为+0.9/+0.8/+0.7/+0.2mAP@0.5:0.95。

主要做出的变化是,采用了hardswish激活函数替换CONV模块的LeakyReLu,但是注意:BottleneckCSP模块中的LeakyReLu未被替换,采用了CIOU作为损失函数(但这个更新好像是还在v2.0版本过度的时候已经更新),还更改了一个默认超参数:translate=0.5 → 0.1(数据增强的仿射系数)。

3.0->4.0:
更改网络结构:C3模块代替BottleNeckCSP模块,使用SiLU激活函数代替hardswish和leakyrelu;

4.0->5.0:
yolov5s/m/l/x6系列,输入分辨率640 -> 1280,增加一次下采样,增加一层特征金字塔网络(PANet),在coco数据及上map达到55;
spp的最大池化改为3/5/7;

由于没有发paper,只有自己看代码学习,有不正确欢迎指正,谢谢!

附上yolov5代码注释解析

版权声明:本文为博主Laughing-q原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/Q1u1NG/article/details/108799609

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2022年2月15日
下一篇 2022年2月15日

相关推荐