yolov1 - yolov4 深度理解

持续更新中。。。。

一、yolov1

1. YOLOv1的核心思想

  • YOLOv1的核心思想就是利用整张图作为网络的输入,直接在输出层回归bounding box的位置和bounding box所属的类别(x,y,w,h,class)。那其他的wanglu哦输出是什么

2. YOLO1的实现方法

  • 将一幅图像分成SxS个网格(grid cell),之后的输出是以单元格为单位进行的,如果某个object的中心落在这个小网格中,则这个小网格就负责预测这个object,也就是在训练中,这个小网格的损失计算是以有物体进行计算的(yolov1中S * S 取值为7 * 7)实际训练中,中心点落在哪个小网格中,是怎么计算的?

  • 每个网格要预测B个bounding box,每个bounding box除了要回归自身的位置之外,还要附带预测一个confidence值。 (yolov1中B 取值为2)
    这个confidence代表了所预测的box中含有object的置信度和这个box预测的有多准(score)两重信息,其值是这样计算的:
    在这里插入图片描述

  • 其中如果有object落在一个grid cell里,Pr(Object)第一项取1,否则取0。(无目标时取0,那此处confidence的取值为0,如果整张图片都没有目标,那还可以训练?loss中xywh没有是否有目标这一项要求,是不是只计算xywh即可,不用进行confidence的loss计算)。 第二项是预测的bounding box和实际的groundtruth之间的IoU值。

  • 每个bounding box要预测(x, y, w, h, confidence)共5个值,每个网格还要预测一个类别信息,记为C类。则SxS个网格,每个网格要预测B个bounding box还要预测C个categories。输出就是S x S x (5*B+C)的一个tensor。
    注意:class信息是针对每个网格的,confidence信息是针对每个bounding box的。也就是每个网格grid,只能预测1个类别,每个类别预测2个box。
    此处暴露出了yolov1的问题,如果一个grid中包含了多种类别的物体,那么yolov1是无法进行处理的,只能选择1个类别进行处理。

3. 目标函数(x,y,w,h,confidence,classes)详解

首先看一下每个单元格预测的B个( x , y , w , h , c o n f i d e n c e ) 的向量和C的条件概率中,每个参数的含义(假设图片宽为{wi}高为{hi},将图片分为S×S):
在这里插入图片描述
1.(x,y)是bbox的中心相对于单元格的offset
对于下图中蓝色框的那个单元格(坐标为(Xcol=1,Yrow=4)),假设它预测的输出是红色框的bbox,设bbox的中心坐标为(Xc,Yc),那么最终预测出来的(x,y)是经过归一化(大于0 小于1)处理的 表示的是中心相对于网格的offset,计算公式如下:

在这里插入图片描述
举例:
S=7, wi = 700 ,hi = 700,xc = 110, yc = 420, xcol = 1, ycol = 4
则: x = 110/700 * 7 - 1 = 0.1 y = 420/700 * 7 -4 = 0.2

2.(w,h)是bbox相对于整个图片的比例
预测的bbox的宽高为wb,hb,(w,h)表示的是bbox的是相对于整张图片的占比,计算公式如下:
在这里插入图片描述

3.confidence

这个置信度是由两部分组成,一是格子内是否有目标,二是bbox的准确度。定义置信度为
在这里插入图片描述

其中若bounding box包含物体,则在这里插入图片描述


否则在这里插入图片描述


IOU(intersection over union)为预测bounding box与物体真实区域的交集面积(以像素为单位,用真实区域的像素面积归一化到[0,1]区间)。

4.C类的条件概率
条件概率定义为在这里插入图片描述
,表示该单元格存在物体且属于第i类的概率。

测试的时候每个单元格预测最终输出的概率定义为,如下两图所示(两幅图不一样,代表一个框会输出B列概率值)
在这里插入图片描述
预测时,IOU中的truth是如何取值的????,没有真实框,只有预测框
在这里插入图片描述
在这里插入图片描述
最后将(S×S)×B×20 列的结果送入NMS,最后即可得到最终的输出框结果。

4. yolov1损失函数

​ YOLO全部使用了均方和误差作为loss函数.由三部分组成:坐标误差、IOU误差和分类误差。损失函数的设计目标就是让坐标$(x,y,w,h),confidence,classification $这个三个方面达到很好的平衡。

yolo的损失函数并不是简单的进行均方差求和,而是对需要求误差的某些值进行了相应的变换,下面详细介绍,公式如下:
在这里插入图片描述

  1. 位置相关误差(坐标)与分类误差对网络loss的贡献值是不同的,这里更重视8维的坐标预测,给这些损失前面赋予更大的loss weight,因此YOLO在计算loss时,使用在这里插入图片描述
    修正coordError。

  2. 在计算IOU误差时,包含物体的grid与不包含物体的grid,二者的IOU误差对网络loss的贡献值是不同的。(注此处的‘包含’是指存在一个物体,它的中心坐标落入到格子内)。

    • 若有物体落入边界框中,则计算预测边界框含有物体的置信度Ci和真实物体与边界框IoUCi_hat的损失,我们希望两差值越小损失越低。
    • 若没有任何物体中心落入边界框中,则Ci_object为0,此时我们希望预测含有物体的置信度Ci越小越好。然而,大部分边界框都没有物体,积少成多,造成loss的第3部分与第4部分的不平衡,为解决这个问题,在loss的三部分使用在这里插入图片描述
      修正iouError。
  3. 对于相等的误差值,大物体误差对检测的影响应小于小物体误差对检测的影响。这是因为,相同的位置偏差占大物体的比例远小于同等偏差占小物体的比例。YOLO将物体大小的信息项(w和h)进行求平方根来改进这个问题。(注:这个方法并不能完全解决这个问题)

    • 对不同大小的bbox预测中,相比于大bbox预测偏一点,小box预测偏相同的尺寸对IOU的影响更大。而sum-square error loss中对同样的偏移loss是一样。
    • 为了缓和这个问题,作者用了一个巧妙的办法,就是将box的width和height取平方根代替原本的height和width。 如下图:small bbox的横轴值较小,发生偏移时,反应到y轴上的loss(下图绿色)比big box(下图红色)要大。

在这里插入图片描述
例如,一个同样将一个100x100的目标与一个10x10的目标都预测大了10个像素,预测框为110 x 110与20 x 20。显然第一种情况我们还可以接受,但第二种情况相当于把边界框预测大了一倍,但如果不使用根号函数,那么损失相同,都为200。但把宽高都增加根号时:
在这里插入图片描述
在这里插入图片描述
显然,对小框预测偏差10个像素带来了更高的损失。通过增加根号,使得预测相同偏差与更小的框产生更大的损失。但根据YOLOv2的实验证明,还有更好的方法解决这个问题。

5. yolov1 总结

  1. 训练过程:
    (1)通过模型的参数进行前向传播(计算),得到7 × 7 × 2 = 98 个框
    (2)计算这98个框的loss,也就是代上图中的公式,把有无物体等条件代入公式中,进行loss计算
    (3)反向传播,调节模型参数
    (4)周而复始

  2. 预测过程:
    (1)模型计算,得到98个框,然后在传入到NMS,然后输出。

  3. 每个grid有30维,这30维中,8维是回归box的坐标,2维是box的confidence,还有20维是类别。其中坐标的x,y用对应网格的offset归一化到0-1之间,w,h用图像的width和height归一化到0-1之间。

  4. 输入尺寸固定:由于输出层为全连接层,因此在检测时,YOLO训练模型只支持与训练图像相同的输入分辨率。其它分辨率需要缩放成改分辨率,实际使用时,也得进行resize,耗时。

  5. 占比较小的目标检测效果不好.虽然每个格子可以预测B个bounding box,但是最终只选择只选择IOU最高的bounding box作为物体检测输出,即每个格子最多只预测出一个物体。当物体占画面比例较小,如图像中包含畜群或鸟群时,每个格子包含多个物体,但却只能检测出其中一个。

二、yolov2

1. YOLOv2的核心思想

待定

三、yolov3

1. Yolov3论文

Yolov3论文名:《Yolov3: An Incremental Improvement》
Yolov3论文地址:https://arxiv.org/pdf/1804.02767.pdf

2. Yolov3基础内容

2.1 网络结构可视化

使用 netron 查看, 在线查看网址https://netron.app/
具体安装步骤见此博文:https://blog.csdn.net/nan355655600/article/details/106245563

2.2 网络结构图

在这里插入图片描述
上图三个蓝色方框内表示Yolov3的三个基本组件:
(1)CBL:Yolov3网络结构中的最小组件,由Conv+Bn+Leaky_relu激活函数三者组成。
(2)Res unit:借鉴Resnet网络中的残差结构,让网络可以构建的更深。
(3)ResX:由一个CBL和X个残差组件构成,是Yolov3中的大组件。每个Res模块前面的CBL都起到下采样的作用,因此经过5次Res模块后,得到的特征图是608->304->152->76->38->19大小。

其他基础操作:
(1)Concat:张量拼接,会扩充两个张量的维度,例如26×26×256和26×26×512两个张量拼接,结果是26×26×768。Concat和cfg文件中的route功能一样。
(2)Add:张量相加,张量直接相加,不会扩充维度,例如104×104×128和104×104×128相加,结果还是104×104×128。add和cfg文件中的shortcut功能一样。
concat 同 add的区别

3. Yolov3相关代码

3.1 python代码

代码地址:https://github.com/ultralytics/Yolov3

3.2 C++代码

这里推荐Yolov4作者的darknetAB代码,代码和原始作者代码相比,进行了很多的优化,如需要运行Yolov3网络,加载cfg时,使用Yolov3.cfg即可
代码地址:https://github.com/AlexeyAB/darknet

3.3 python版本的Tensorrt代码

除了算法研究外,实际项目中还需要将算法落地部署到工程上使用,比如GPU服务器使用时还需要对模型进行tensorrt加速。
(1)Tensort中的加速案例
强烈推荐tensort软件中,自带的Yolov3加速案例,路径位于tensorrt解压文件夹的TensortX/samples/python/Yolov3_onnx中
针对案例中的代码,如果有不明白的,也可参照下方文章上的详细说明:
代码讲解文章:https://www.cnblogs.com/shouhuxianjian/p/10550262.html
(2)Github上的tensorrt加速
除了Tensorrt软件中的代码, Github上也有其他作者的开源代码
代码地址:https://github.com/lewes6369/TensorRT-Yolov3

3.4 C++版本的Tensorrt代码

项目的工程部署上,如果使用C++版本进行Tensorrt加速,一方面可以参照Alexey的Github代码,另一方面也可以参照下面其他作者的开源代码
代码地址:https://github.com/wang-xinyu/tensorrtx/tree/master/Yolov3

四、yolov4

1. Yolov4论文

Yolov4论文名:《Yolov4: Optimal Speed and Accuracy of Object Detection》
Yolov4论文地址:https://arxiv.org/pdf/2004.10934.pdf

2. 网络结构可视化

netron

3. 网络结构图

在这里插入图片描述

Yolov4的结构图和Yolov3相比,因为多了CSP结构,PAN结构,如果单纯看可视化流程图,会觉得很绕,但是在绘制出上面的图形后,会觉得豁然开朗,其实整体架构和Yolov3是相同的,不过使用各种新的算法思想对各个子结构都进行了改进。
先整理下Yolov4的五个基本组件:

  1. CBM:Yolov4网络结构中的最小组件,由Conv+Bn+Mish激活函数三者组成。
  2. CBL:由Conv+Bn+Leaky_relu激活函数三者组成。
  3. Res unit:借鉴Resnet网络中的残差结构,让网络可以构建的更深。
  4. CSPX:借鉴CSPNet网络结构,由卷积层和X个Res unint模块Concat组成。
  5. SPP:采用1×1,5×5,9×9,13×13的最大池化的方式,进行多尺度融合。

其他基础操作:
6. Concat:张量拼接,维度会扩充,和Yolov3中的解释一样,对应于cfg文件中的route操作。
7. Add:张量相加,不会扩充维度,对应于cfg文件中的shortcut操作。

为了便于分析,将Yolov4的整体结构拆分成四大板块:
在这里插入图片描述

主要从以上4个部分对YoloV4的创新之处进行讲解,让大家一目了然。

(1)输入端:这里指的创新主要是训练时对输入端的改进,主要包括Mosaic数据增强、cmBN、SAT自对抗训练。
(2)BackBone主干网络:将各种新的方式结合起来,包括:CSPDarknet53、Mish激活函数、Dropblock
(3)Neck:目标检测网络在BackBone和最后的输出层之间往往会插入一些层,比如Yolov4中的SPP模块、FPN+PAN结构
(4)Prediction:输出层的锚框机制和Yolov3相同,主要改进的是训练时的损失函数CIOU_Loss,以及预测框筛选的nms变为DIOU_nms

4. 创新

4. 1输入端创新

考虑到很多同学GPU显卡数量并不是很多,Yolov4对训练时的输入端进行改进,使得训练在单张GPU上也能有不错的成绩。比如数据增强Mosaic、cmBN、SAT自对抗训练。
但感觉cmBN和SAT影响并不是很大,所以这里主要讲解Mosaic数据增强。

(1)Mosaic数据增强
Yolov4中使用的Mosaic是参考2019年底提出的CutMix数据增强的方式,但CutMix只使用了两张图片进行拼接,而Mosaic数据增强则采用了4张图片,随机缩放、随机裁剪、随机排布的方式进行拼接。

在这里插入图片描述

这里首先要了解为什么要进行Mosaic数据增强呢?
在平时项目训练时,小目标的AP一般比中目标和大目标低很多。而Coco数据集中也包含大量的小目标,但比较麻烦的是小目标的分布并不均匀。
首先看下小、中、大目标的定义:
2019年发布的论文《Augmentation for small object detection》对此进行了区分

在这里插入图片描述

可以看到小目标的定义是目标框的长宽0×0~32×32之间的物体。

在这里插入图片描述

但在整体的数据集中,小、中、大目标的占比并不均衡。
如上表所示,Coco数据集中小目标占比达到41.4%,数量比中目标和大目标都要多。
但在所有的训练集图片中,只有52.3%的图片有小目标,而中目标和大目标的分布相对来说更加均匀一些。
针对这种状况,Yolov4的作者采用了Mosaic数据增强的方式。
主要有几个优点:
a. 丰富数据集:随机使用4张图片,随机缩放,再随机分布进行拼接,大大丰富了检测数据集,特别是随机缩放增加了很多小目标,让网络的鲁棒性更好。
b. 减少GPU:可能会有人说,随机缩放,普通的数据增强也可以做,但作者考虑到很多人可能只有一个GPU。
因此Mosaic增强训练时,可以直接计算4张图片的数据,使得Mini-batch大小并不需要很大,一个GPU就可以达到比较好的效果。
此外,发现另一研究者的训练方式也值得借鉴,采用的数据增强和Mosaic比较类似,也是使用4张图片(不是随机分布),但训练计算loss时,采用“缺啥补啥”的思路:
如果上一个iteration中,小物体产生的loss不足(比如小于某一个阈值),则下一个iteration就用拼接图;否则就用正常图片训练,也很有意思。
参考链接:https://www.zhihu.com/question/390191723?rf=390194081

4.2 BackBone创新

(1)CSPDarknet53
CSPDarknet53是在Yolov3主干网络Darknet53的基础上,借鉴2019年CSPNet的经验,产生的Backbone结构,其中包含了5个CSP模块。

在这里插入图片描述

这里因为CSP模块比较长,不放到本处.
每个CSP模块前面的卷积核的大小都是3×3,步长为2,因此可以起到下采样的作用。
因为Backbone有5个CSP模块,输入图像是608608,所以特征图变化的规律是:608->304->152->76->38->19
经过5次CSP模块后得到19
19大小的特征图。
而且作者只在Backbone中采用了Mish激活函数,网络后面仍然采用Leaky_relu激活函数。
我们再看看下作者为啥要参考2019年的CSPNet,采用CSP模块?
CSPNet论文地址:https://arxiv.org/pdf/1911.11929.pdf
CSPNet全称是Cross Stage Paritial Network,主要从网络结构设计的角度解决推理中从计算量很大的问题。
CSPNet的作者认为推理计算过高的问题是由于网络优化中的梯度信息重复导致的。
因此采用CSP模块先将基础层的特征映射划分为两部分,然后通过跨阶段层次结构将它们合并,在减少了计算量的同时可以保证准确率。
因此Yolov4在主干网络Backbone采用CSPDarknet53网络结构,主要有三个方面的优点:
优点一:增强CNN的学习能力,使得在轻量化的同时保持准确性。
优点二:降低计算瓶颈
优点三:降低内存成本

(2)Mish激活函数
Mish激活函数是2019年下半年提出的激活函数
论文地址:https://arxiv.org/abs/1908.08681
和leaky_relu激活函数的图形对比如下:

在这里插入图片描述
Yolov4的Backbone中都使用了Mish激活函数,而后面的网络则还是使用Leaky_relu函数。
在这里插入图片描述
Yolov4作者实验测试时,使用CSPDarknet53网络在ImageNet数据集上做图像分类任务,发现使用了Mish激活函数的TOP-1和TOP-5的精度比没有使用时都略高一些。
因此在设计Yolov4目标检测任务时,主干网络Backbone还是使用Mish激活函数。

(3)Dropblock
Yolov4中使用的Dropblock,其实和常见网络中的Dropout功能类似,也是缓解过拟合的一种正则化方式。
Dropblock在2018年提出,论文地址:https://arxiv.org/pdf/1810.12890.pdf

传统的Dropout很简单,一句话就可以说的清:随机删除减少神经元的数量,使网络变得更简单。

在这里插入图片描述

而Dropblock和Dropout相似,比如下图:

在这里插入图片描述

中间Dropout的方式会随机的删减丢弃一些信息,但Dropblock的研究者认为,卷积层对于这种随机丢弃并不敏感.
因为卷积层通常是三层连用:卷积+激活+池化层,池化层本身就是对相邻单元起作用。
而且即使随机丢弃,卷积层仍然可以从相邻的激活单元学习到相同的信息。因此,在全连接层上效果很好的Dropout在卷积层上效果并不好。
所以右图Dropblock的研究者则干脆整个局部区域进行删减丢弃。
这种方式其实是借鉴2017年的Cutout数据增强的方式,cutout是将输入图像的部分区域清零,而Dropblock则是将Cutout应用到每一个特征图。而且并不是用固定的归零比率,而是在训练时以一个小的比率开始,随着训练过程线性的增加这个比率。

在这里插入图片描述
Dropblock的研究者与Cutout数据增强对训练效果进行对比验证时,发现有几个优点:
优点一:Dropblock的效果优于Cutout
优点二:cutout只能作用于输入层,而Dropblock则是将Cutout应用到网络中的每一个特征图上
优点三:Dropblock可以定制各种组合,在训练的不同阶段可以修改删减的概率,从空间层面和时间层面,和cutout相比都有更精细的改进。
Yolov4中直接采用了更优的Dropblock,对网络的正则化过程进行了全面的升级改进。

4.3 Neck创新

在目标检测领域,为了更好的提取融合特征,通常在Backbone和输出层,会插入一些层,这个部分称为Neck。相当于目标检测网络的颈部,也是非常关键的。
Yolov4的Neck结构主要采用了SPP模块、FPN+PAN的方式。

(1)SPP模块
SPP模块,其实在Yolov3中已经存在了,在Yolov4的C++代码文件夹中有一个Yolov3_spp版本,但有的同学估计从来没有使用过,在Yolov4中,SPP模块仍然是在Backbone主干网络之后:

在这里插入图片描述

作者在SPP模块中,使用k={1×1,5×5,9×9,13×13}的最大池化的方式,再将不同尺度的特征图进行Concat操作。
注意:这里最大池化采用padding操作,移动的步长为1,比如13×13的输入特征图,使用5×5大小的池化核池化,padding=2,因此池化后的特征图仍然是13×13大小。

在这里插入图片描述
在2019年的《DC-SPP-Yolo》文章:https://arxiv.org/ftp/arxiv/papers/1903/1903.08589.pdf
也对Yolo目标检测的SPP模块进行了对比测试。
和Yolov4作者的研究相同,采用SPP模块的方式,比单纯的使用k×k最大池化的方式,更有效的增加主干特征的接收范围,显著的分离了最重要的上下文特征。
Yolov4的作者在使用608×608大小的图像进行测试时发现,在COCO目标检测任务中,以0.5%的额外计算代价将AP50增加了2.7%,因此Yolov4中也采用了SPP模块。

(2)FPN+PAN
PAN结构比较有意思,看了网上Yolov4关于这个部分的讲解,大多都是讲的比较笼统的,而PAN是借鉴2018年图像分割领域PANet的创新点,有些同学可能不是很清楚。
下面大白将这个部分拆解开来,看下Yolov3和Yolov4
中是如何设计的。

Yolov3各个网络结构
在这里插入图片描述
可以看到经过几次下采样,三个紫色箭头指向的地方,输出分别是76×76、38×38、19×19。
以及最后的Prediction中用于预测的三个特征图①19×19×255、②38×38×255、③76×76×255 [注:255表示80类别 (1+4+80)×3=255]。
我们将Neck部分用立体图画出来,更直观的看下两部分之间是如何通过FPN结构融合的。

在这里插入图片描述
如图所示,FPN是自顶向下的,将高层的特征信息通过上采样的方式进行传递融合,得到进行预测的特征图。

Yolov4各个网络结构
而Yolov4中Neck这部分除了使用FPN外,还在此基础上使用了PAN结构。
在这里插入图片描述
前面CSPDarknet53中讲到,每个CSP模块前面的卷积核都是3×3大小,相当于下采样操作。
因此可以看到三个紫色箭头处的特征图是76×76、38×38、19×19。
以及最后Prediction中用于预测的三个特征图:①76×76×255,②38×38×255,③19×19×255。
我们也看下Neck部分的立体图像,看下两部分是如何通过FPN+PAN结构进行融合的。

在这里插入图片描述

和Yolov3的FPN层不同,Yolov4在FPN层的后面还添加了一个自底向上的特征金字塔。
其中包含两个PAN结构。
这样结合操作,FPN层自顶向下传达强语义特征,而特征金字塔则自底向上传达强定位特征,两两联手,从不同的主干层对不同的检测层进行特征聚合,这样的操作确实很皮。
FPN+PAN借鉴的是18年CVPR的PANet,当时主要应用于图像分割领域,但Alexey将其拆分应用到Yolov4中,进一步提高特征提取的能力。

不过这里需要注意几点:
注意一:
Yolov3的FPN层输出的三个大小不一的特征图①②③直接进行预测
但Yolov4的FPN层,只使用最后的一个76×76特征图①,而经过两次PAN结构,输出预测的特征图②和③。
这里的不同也体现在cfg文件中,这一点有很多同学之前不太明白。
比如Yolov3.cfg中输入时608×608,最后的三个Yolo层中,
第一个Yolo层是最小的特征图19×19,mask=6,7,8,对应最大的anchor box。
第二个Yolo层是中等的特征图38×38,mask=3,4,5,对应中等的anchor box。
第三个Yolo层是最大的特征图76×76,mask=0,1,2,对应最小的anchor box。
而Yolov4.cfg则恰恰相反
第一个Yolo层是最大的特征图76×76,mask=0,1,2,对应最小的anchor box。
第二个Yolo层是中等的特征图38×38,mask=3,4,5,对应中等的anchor box。
第三个Yolo层是最小的特征图19×19,mask=6,7,8,对应最大的anchor box。
注意二:
原本的PANet网络的PAN结构中,两个特征图结合是采用shortcut操作,而Yolov4中则采用concat(route)操作,特征图融合后的尺寸发生了变化。

在这里插入图片描述

4.4 Prediction创新

(1)CIOU_loss
目标检测任务的损失函数一般由Classificition Loss(分类损失函数)和Bounding Box Regeression Loss(回归损失函数)两部分构成。
Bounding Box Regeression的Loss近些年的发展过程是:Smooth L1 Loss-> IoU Loss(2016)-> GIoU Loss(2019)-> DIoU Loss(2020)->CIoU Loss(2020)
我们从最常用的IOU_Loss开始,进行对比拆解分析,看下Yolov4为啥要选择CIOU_Loss。

a. IOU_loss

在这里插入图片描述

可以看到IOU的loss其实很简单,主要是交集/并集,但其实也存在两个问题。

在这里插入图片描述

问题1:即状态1的情况,当预测框和目标框不相交时,IOU=0,无法反应两个框距离的远近,此时损失函数不可导,IOU_Loss无法优化两个框不相交的情况。
问题2:即状态2和状态3的情况,当两个预测框大小相同,两个IOU也相同,IOU_Loss无法区分两者相交情况的不同。
因此2019年出现了GIOU_Loss来进行改进。

b. GIOU_loss
在这里插入图片描述

可以看到右图GIOU_Loss中,增加了相交尺度的衡量方式,缓解了单纯IOU_Loss时的尴尬。
但为什么仅仅说缓解呢?因为还存在一种不足:

在这里插入图片描述

问题:状态1、2、3都是预测框在目标框内部且预测框大小一致的情况,这时预测框和目标框的差集都是相同的,因此这三种状态的GIOU值也都是相同的,这时GIOU退化成了IOU,无法区分相对位置关系。
基于这个问题,2020年的AAAI又提出了DIOU_Loss。

c. DIOU_loss

好的目标框回归函数应该考虑三个重要几何因素:重叠面积、中心点距离,长宽比。
针对IOU和GIOU存在的问题,作者从两个方面进行考虑
一:如何最小化预测框和目标框之间的归一化距离?
二:如何在预测框和目标框重叠时,回归的更准确?
针对第一个问题,提出了DIOU_Loss(Distance_IOU_Loss)

在这里插入图片描述

DIOU_Loss考虑了重叠面积和中心点距离,当目标框包裹预测框的时候,直接度量2个框的距离,因此DIOU_Loss收敛的更快。
但就像前面好的目标框回归函数所说的,这时并没有考虑到长宽比。
在这里插入图片描述

问题:比如上面三种状态,目标框包裹预测框,本来DIOU_Loss可以起作用。
但预测框的中心点的位置都是一样的,因此按照DIOU_Loss的计算公式,三者的值都是相同的。
针对这个问题,又提出了CIOU_Loss,不对不说,科学总是在解决问题中,不断进步!!

d. CIOU_loss

CIOU_Loss和DIOU_Loss前面的公式都是一样的,不过在此基础上还增加了一个影响因子,将预测框和目标框的长宽比都考虑了进去。

在这里插入图片描述
其中v是衡量长宽比一致性的参数,我们也可以定义为:

在这里插入图片描述

这样CIOU_Loss就将目标框回归函数应该考虑三个重要几何因素:重叠面积、中心点距离,长宽比全都考虑进去了。

再来综合的看下各个Loss函数的不同点:
IOU_Loss:主要考虑检测框和目标框重叠面积。
GIOU_Loss:在IOU的基础上,解决边界框不重合时的问题。
DIOU_Loss:在IOU和GIOU的基础上,考虑边界框中心点距离的信息。
CIOU_Loss:在DIOU的基础上,考虑边界框宽高比的尺度信息。
Yolov4中采用了CIOU_Loss的回归方式,使得预测框回归的速度和精度更高一些。

(2)DIOU_nms

nms主要用于预测框的筛选,常用的目标检测算法中,一般采用普通的nms的方式,Yolov4则借鉴上面D/CIOU loss的论文:https://arxiv.org/pdf/1911.08287.pdf
将其中计算IOU的部分替换成DIOU的方式:
再来看下实际的案例:

在这里插入图片描述
在上图重叠的摩托车检测中,中间的摩托车因为考虑边界框中心点的位置信息,也可以回归出来。
因此在重叠目标的检测中,DIOU_nms的效果优于传统的nms。

注意:
有读者会有疑问,这里为什么不用CIOU_nms,而用DIOU_nms?
答:因为前面讲到的CIOU_loss,实在DIOU_loss的基础上,添加的影响因子,包含groundtruth标注框的信息,在训练时用于回归。
但在测试过程中,并没有groundtruth的信息,不用考虑影响因子,因此直接用DIOU_nms即可。

总体来说,YOLOv4的论文称的上良心之作,将近几年关于深度学习领域最新研究的tricks移植到Yolov4中做验证测试,将Yolov3的精度提高了不少。
虽然没有全新的创新,但很多改进之处都值得借鉴,借用Yolov4作者的总结。

Yolov4 主要带来了 3 点新贡献:
(1)提出了一种高效而强大的目标检测模型,使用 1080Ti 或 2080Ti 就能训练出超快、准确的目标检测器。
(2)在检测器训练过程中,验证了最先进的一些研究成果对目标检测器的影响。
(3)改进了 SOTA 方法,使其更有效、更适合单 GPU 训练。

5. YoloV4相关代码

5.1 python代码

代码地址:https://github.com/Tianxiaomo/pytorch-Yolov4
作者的训练和测试推理代码都已经完成

5.2 C++代码

Yolov4作者Alexey的代码,俄罗斯的大神,应该是个独立研究员,更新算法的频繁程度令人佩服。
在Yolov3作者Joseph Redmon宣布停止更新Yolo算法之后,Alexey凭借对于Yolov3算法的不断探索研究,赢得了Yolov3作者的认可,发布了Yolov4。
代码地址:https://github.com/AlexeyAB/darknet

5.3 python版本的Tensorrt代码

目前测试有效的有tensorflow版本:weights->pb->trt
代码地址:https://github.com/hunglc007/tensorflow-Yolov4-tflite

5.4 C++版本的Tensorrtrt代码

代码地址:https://github.com/wang-xinyu/tensorrtx/tree/master/Yolov4
作者自定义了Mish激活函数的Plugin层,Tensorrt加速后速度还是挺快的。

yolov5 待更新

目标检测的各个组成部分

		1. Input
		2. Backbone
		3. Neek
		4. Head
		共包含上面4个部分,其中可以替换的结构如下图所示:
		说明:Dense Prediction:标注出图像中每个像素点的对象类别
				    	Sparse Prediction:稀疏预测

在这里插入图片描述

七、问题:

  1. 什么情况下需要使用nms?
    答:图片中有多个同类目标时。
    同类:最大抑制只能是抑制同一类的框
    多个:当图片中只有1个目标时,直接输出score最高的即可,不需要nms。

  2. yolov1,在构建目标函数时,是如何解决一个图片中有多个目标的问题(也就是有多个cxywh)的?
    答:yolo head的结构。
    进行7 * 7 13 * 13 26 * 26 52 * 52等划分,构建出多个区域,然后进行检测。将整张图片划分为7 × 7 的小方格,也就是一张图片上可以有49个目标。为了防止划分出来的小方格中有多个目标,可以进行52*52的细致划分,以将目标划分到不同的小方格中。形式如下图:
    在这里插入图片描述

  3. yolov1 目标函数是如何解决多类问题的?
    答:yolo head的构建 7730(以voc数据集的种类进行举例),
    77:将图片划分为49个小方格
    30:[c1,x1,y1,w1,h1,c2,x2,y2,w2,h2,onehot],其中onehot是20个类,也就是每个划分的小方格可以有两个框,但因为后面跟着一个onehot,所以这两个框画的都是1个种类的目标。后面再通过NMS去掉重复的框,留下最好的。也就是7
    7的头,共输出 7 × 7 × 2 = 98个框。

  4. yolo系列预测是否需要滑动窗口?
    答:yolov系列,直接拟合,不进行窗口滑动

  5. yolo是否可以预测旋转有角度的物体?
    答:yolo 可以进行检测旋转的物体,但是需要改head和loss,在目标函数中加上角度即可,当然损失loss中也需要添加相应的计算。

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Python图像识别

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值