你一定从未看过如此通俗易懂的YOLO系列(从v1到v5)模型解读 (下)
文章系列:
你一定从未看过如此通俗易懂的YOLO系列(从v1到v5)模型解读 (上)
你一定从未看过如此通俗易懂的YOLO系列(从v1到v5)模型解读 (中)
你一定从未看过如此通俗易懂的YOLO系列(从v1到v5)模型解读 (下)
上篇文章我们介绍了YOLO v2 v3 v4 v5对于检测头head和损失函数loss的优化,如果你忘了,可以看上面的链接回顾。本文是YOLO系列的最后一篇文章了,会介绍YOLO这个系列对于backbone方面的优化和对输入端的改进。
为了使本文尽量生动有趣,我仍然和以前一样使用葫芦娃作为例子展示YOLO的过程(真的是尽力了。。。)。
下面进入正题,目标检测器模型的结构如下图1所示,之前看过了YOLO v2 v3 v4 v5对于检测头和loss函数的改进,如下图2所示,下面着重介绍backbone的改进:
我们发现YOLO v1只是把最后的特征分成了
backbone的改进:
YOLO v1
我们先看看YOLO v1的backbone长什么样子:
最后2层是全连接层,其他使用了大量的卷积层,网络逐渐变宽,是非常标准化的操作。注意这里面试官可能会问你一个问题:为什么都是卷积,图上要分开画出来,不写在一起?答案是:按照feature map的分辨率画出来。分辨率A变化到分辨率B的所有卷积画在了一起。因为写代码时经常会这么做,所以问这个问题的意图是看看你是否经常写代码。
然后我们看下检测类网络的结构,如下图3所示,这个图是YOLO v4中总结的:
YOLO v1没有Neck,Backbone是GoogLeNet,属于Dense Prediction。1阶段的检测器属于Dense Prediction,而2阶段的检测器既有Dense Prediction,又有Sparse Prediction。
YOLO v2
为了进一步提升性能,YOLO v2重新训练了一个darknet-19,如下图4所示:
仔细观察上面的backbone的结构(双横线上方),提出3个问题:
为什么没有
卷积了?只剩下了 卷积和 卷积了?
答:vgg net论文得到一个结论,
网络可以做得更深,更好地提取到特征。为什么?因为每做一次卷积,后面都会接一个非线性的激活函数,更深意味着非线性的能力更强了。所以,你可能以后再也见不到
另外还用了bottleneck结构(红色框):
为什么没有FC层了?
答:使用了GAP(Global Average Pooling)层,把
这对提高检测器的性能有什么作用呢?
对于小目标的检测,之前输入图片是固定的大小的,小目标很难被检测准确;现在允许多尺度输入图片了,只要把图片放大,小目标就变成了大目标,提高检测的精度。
为什么最后一层是softmax?
答:因为backbone网络darknet-19是单独train的,是按照分类网络去train的,用的数据集是imagenet,是1000个classes,所以最后加了一个softmax层,使用cross entropy loss。
接下来总结下YOLO v2的网络结构:
图4中的双横线的上半部分(第0-22层)为backbone,train的方法如上文。
后面的结构如下图5所示:
从第23层开始为检测头,其实是3个 3 * 3 * 1024 的卷积层。
同时增加了一个 passthrough 层(27层),最后使用 1 * 1 卷积层输出预测结果,输出结果的size为
。 route层的作用是进行层的合并(concat),后面的数字指的是合并谁和谁。
passthrough 层可以把
。
YOLO2 的训练主要包括三个阶段:
先在 ImageNet 分类数据集上预训练 Darknet-19,此时模型输入为 224 * 224 ,共训练 160 个 epochs。(为什么可以这样训练?因为有GAP)
将网络的输入调整为 448 * 448(注意在测试的时候使用 416 * 416 大小) ,继续在 ImageNet 数据集上 finetune 分类模型,训练 10 个 epochs。
修改 Darknet-19 分类模型为检测模型为图5形态,即:移除最后一个卷积层、global avgpooling 层以及 softmax 层,并且新增了3个 3 * 3 * 1024 卷积层,同时增加了一个 passthrough 层,最后使用 1 * 1 卷积层输出预测结果,并在检测数据集上继续finetune 网络。
注意这里图5有个地方得解释一下:第25层把第16层进行reorg,即passthrough操作,得到的结果为27层,再与第24层进行route,即concat操作,得到第28层。
可视化的图为:
YOLO v3
先看下YOLO v3的backbone,如下图6所示:
先声明下darknet 53指的是convolution层有52层+1个conv层把1024个channel调整为1000个,你会发现YOLO v2中使用的GAP层在YOLO v3中还在用,他还是在ImageNet上先train的backbone,
观察发现依然是有bottleneck的结构和残差网络。
为什么YOLO v3敢用3个检测头?因为他的backbone更强大了。
为什么更强大了?因为当时已经出现了ResNet结构。
所以YOLO v3的提高,有一部分功劳应该给ResNet。
再观察发现YOLO v3没有Pooling layer了,用的是conv(stride = 2)进行下采样,为什么?
因为Pooling layer,不管是MaxPooling还是Average Pooling,本质上都是下采样减少计算量,本质上就是不更新参数的conv,但是他们会损失信息,所以用的是conv(stride = 2)进行下采样。
下图7是YOLO v3的网络结构:
特征融合的方式更加直接,没有YOLO v2的passthrough操作,直接上采样之后concat在一起。
YOLO v4
图9,10展示了YOLO v4的结构:
Yolov4的结构图和Yolov3相比,因为多了CSP结构,PAN结构,如果单纯看可视化流程图,会觉得很绕,不过在绘制出上面的图形后,会觉得豁然开朗,其实整体架构和Yolov3是相同的,不过使用各种新的算法思想对各个子结构都进行了改进。
Yolov4的五个基本组件:
CBM:Yolov4网络结构中的最小组件,由Conv+Bn+Mish激活函数三者组成。
CBL:由Conv+Bn+Leaky_relu激活函数三者组成。
Res unit:借鉴Resnet网络中的残差结构,让网络可以构建的更深。
CSPX:借鉴CSPNet网络结构,由三个卷积层和X个Res unint模块Concate组成。
SPP:采用1×1,5×5,9×9,13×13的最大池化的方式,进行多尺度融合。
其他基础操作:
Concat:张量拼接,维度会扩充,和Yolov3中的解释一样,对应于cfg文件中的route操作。
add:张量相加,不会扩充维度,对应于cfg文件中的shortcut操作。
Backbone中卷积层的数量:
和Yolov3一样,再来数一下Backbone里面的卷积层数量。
每个CSPX中包含3+2*X个卷积层,因此整个主干网络Backbone中一共包含2+(3+2*1)+2+(3+2*2)+2+(3+2*8)+2+(3+2*8)+2+(3+2*4)+1=72。
输入端的改进:
YOLO v4对输入端进行了改进,主要包括数据增强Mosaic、cmBN、SAT自对抗训练,使得在卡不是很多时也能取得不错的结果。
这里介绍下数据增强Mosaic:
CutMix只使用了两张图片进行拼接,而Mosaic数据增强则采用了4张图片,随机缩放、随机裁剪、随机排布的方式进行拼接。
Yolov4的作者采用了Mosaic数据增强的方式。
主要有几个优点:
丰富数据集:随机使用4张图片,随机缩放,再随机分布进行拼接,大大丰富了检测数据集,特别是随机缩放增加了很多小目标,让网络的鲁棒性更好。
减少GPU:可能会有人说,随机缩放,普通的数据增强也可以做,但作者考虑到很多人可能只有一个GPU,因此Mosaic增强训练时,可以直接计算4张图片的数据,使得Mini-batch大小并不需要很大,一个GPU就可以达到比较好的效果。
cmBN的方法如下图:
YOLO v5
图11,12展示了YOLO v5的结构:
检测头的结构基本上是一样的,融合方法也是一样。
Yolov5的基本组件:
Focus:基本上就是YOLO v2的passthrough。
CBL:由Conv+Bn+Leaky_relu激活函数三者组成。
CSP1_X:借鉴CSPNet网络结构,由三个卷积层和X个Res unint模块Concate组成。
CSP2_X:不再用Res unint模块,而是改为CBL。
SPP:采用1×1,5×5,9×9,13×13的最大池化的方式,进行多尺度融合,如图13所示。
提特征的网络变短了,速度更快。YOLO v5的结构没有定下来,作者的代码还在持续更新。
Focus的slice操作如下图所示:
这里解释以下PAN结构是什么意思,PAN结构来自论文Path Aggregation Network,可视化结果如图15所示:
可以看到包含了自底向上和自顶向下的连接,值得注意的是这里的红色虚线和绿色虚线:
FPN的结构把浅层特征传递给顶层要经历几十甚至上百层,显然经过这么多层的传递,浅层信息(小目标)丢失比较厉害。这里的红色虚线就象征着ResNet的几十甚至上百层。
自下而上的路径由不到10层组成,浅层特征经过FPN的laterial connection连接到
输入端的改进:
1.Mosaic数据增强,和YOLO v4一样。
2.自适应锚框计算:
在Yolo算法中,针对不同的数据集,都会有初始设定长宽的锚框。
在网络训练中,网络在初始锚框的基础上输出预测框,进而和真实框groundtruth进行比对,计算两者差距,再反向更新,迭代网络参数。
因此初始锚框也是比较重要的一部分,比如Yolov5在Coco数据集上初始设定的锚框:
Yolov5在Coco数据集上初始设定的锚框
在Yolov3、Yolov4中,训练不同的数据集时,计算初始锚框的值是通过单独的程序运行的。
但Yolov5中将此功能嵌入到代码中,每次训练时,自适应的计算不同训练集中的最佳锚框值。
当然,如果觉得计算的锚框效果不是很好,也可以在代码中将自动计算锚框功能关闭。
parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')
设置成False,每次训练时,不会自动计算。
3.自适应图片缩放
在常用的目标检测算法中,不同的图片长宽都不相同,因此常用的方式是将原始图片统一缩放到一个标准尺寸,再送入检测网络中。
比如Yolo算法中常用416*416,608*608等尺寸,比如对下面800*600的图像进行缩放:,如图15所示:
但Yolov5代码中对此进行了改进,也是Yolov5推理速度能够很快的一个不错的trick。
作者认为,在项目实际使用时,很多图片的长宽比不同,因此缩放填充后,两端的黑边大小都不同,而如果填充的比较多,则存在信息冗余,影响推理速度。
因此在Yolov5的代码中datasets.py的letterbox函数中进行了修改,对原始图像自适应的添加最少的黑边,如图16所示:
图像高度上两端的黑边变少了,在推理时,计算量也会减少,即目标检测速度会得到提升。
通过这种简单的改进,推理速度得到了37%的提升,可以说效果很明显。
Yolov5中填充的是灰色,即(114,114,114),都是一样的效果,且训练时没有采用缩减黑边的方式,还是采用传统填充的方式,即缩放到416*416大小。只是在测试,使用模型推理时,才采用缩减黑边的方式,提高目标检测,推理的速度。
最后我们对YOLO series总的做个比较,结束这个系列的解读,喜欢的同学点赞关注评论3连:
部分图源:
深入浅出Yolo系列之Yolov3&Yolov4&Yolov5核心基础知识完整讲解
https://zhuanlan.zhihu.com/p/143747206
22课时、19大主题,CS 231n进阶版课程视频上线
数据分析入门常用的23个牛逼Pandas代码如何在科研论文中画出漂亮的插图?