深⼊浅出Yolo系列之Yolov3Yolov4Yolov5Yolox核⼼基础知识完整讲解
因为⼯作原因,项⽬中经常遇到⽬标检测的任务,因此对⽬标检测算法会经常使⽤和关注,⽐如Yolov3、Yolov4算法、Yolov5算
法、Yolox算法。
当然,实际项⽬中很多的第⼀步,也都是先进⾏⽬标检测任务,⽐如⼈脸识别、多⽬标追踪、REID、客流统计等项⽬。因此⽬标检测是计算机视觉项⽬中⾮常重要的⼀部分。
从2018年Yolov3年提出的两年后,在原作者声名放弃更新Yolo算法后,俄罗斯的Alexey⼤神扛起了Yolov4的⼤旗,然后不久⼜出现了Yolov5。
⽽到了2021年,就在⼤家质疑Yolo系列该如何改进时?旷视科技⼜发布了Yolox算法。
因为项⽬中Yolov3、Yolov4、Yolov5、Yolox使⽤很多,所以⼤⽩将项⽬中,需要了解的Yolov3、Yolov4、Yolov5、Yolox系列相关知识点以及相关代码进⾏完整的汇总,希望和⼤家共同学习探讨。
同时,⼤⽩每周会整理⼏⼗个⼈⼯智能公众号的精华⽂章,并系统的分类,让⼤家对于⼈⼯智能⾏业每周的内容动态可以⼀⽬了然,。
版权申明:本⽂包含图⽚,都为⼤⽩使⽤PPT所绘制的,如需⽹络结构⾼清图和模型权重,可。
更新提醒(2021.12.26):《AI未来星球》开放加⼊,超值福利,
其中包含⼤⽩耗尽洪荒之⼒,准备了包括Yolo⽬标检测在内的31节视频课程,
求职跳槽福利:为了便于⼤家求职、跳槽的准备,⼤⽩将45家⼤⼚的3500篇⾯经,按照,整理成700多页的《⼈⼯智能算法岗江湖武林秘籍》,限时开放下载,。
⽬录
1 论⽂汇总
2 Yolov3核⼼基础内容
2.1 ⽹络结构可视化
Yolov3是⽬标检测Yolo系列⾮常⾮常经典的算法。
不过很多同学拿到Yolov3或者Yolov4的cfg⽂件时,并不知道如何直观的可视化查看⽹络结构。如果纯粹看cfg⾥⾯的内容,肯定会⼀脸懵逼。
其实可以很⽅便的⽤netron查看Yolov3的⽹络结构图,⼀⽬了然。
这⾥不多说,如果需要安装,可以移步⼤⽩的另⼀篇⽂章:
如果不想安装,也可以直接,查看Yolov3可视化流程图。
2.2 ⽹络结构图
在这⾥插⼊图⽚描述
绘制⽹络结构图受到Yolov3的启发,包括下⾯Yolov4的结构图,从总体框架上先了解了Yolov3的流程,再针对去学习每⼀⼩块的知识点,会事半功倍。
上图三个蓝⾊⽅框内表⽰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功能⼀样。
Backbone中卷积层的数量:
每个ResX中包含1+2×X个卷积层,因此整个主⼲⽹络Backbone中⼀共包含
1+(1+2×1)+(1+2×2)+(1+2×8)+(1+2×8)+(1+2×4)=52,再加上⼀个FC全连接层,即可以组成⼀个Darknet53分类⽹络。不过在⽬标检测Yolov3中,去掉FC层,不过为了⽅便称呼,仍然把Yolov3的主⼲⽹络叫做Darknet53结构。
2.3 核⼼基础内容
Yolov3是2018年发明提出的,这成为了⽬标检测one-stage中⾮常经典的算法,包含Darknet-53⽹络结构、anchor锚框、FPN等⾮常优秀的结构。
本⽂主要⽬的在于描述Yolov4和Yolov3算法的不同及创新之处,对Yolov3的基础不过多描述。
这⾥⼤⽩也准备了Yolov3算法⾮常浅显易懂的基础视频课程,让⼩⽩也能简单清楚的了解Yolov3的整个过程及各个算法细节。
Yolov3及Yolov4深⼊浅出系列视频:
3 Yolov3相关代码
3.1 python代码
3.2 C++代码
3.3 python版本的Tensorrt代码
3.4 C++版本的Tensorrt代码
4 YoloV4核⼼基础内容
4.1 ⽹络结构可视化
Yolov4的⽹络结构也可以使⽤netron⼯具查看,⼤⽩也是对照其展⽰的可视化流程图绘制的下⽅⽹络结构图。
白崇禧简介netron可视化显⽰Yolov4⽹络结构可以参照⼤⽩的另⼀篇⽂章:《》
如果不想安装,也可以直接,查看Yolov4可视化流程图。
4.2 ⽹络结构图
在这⾥插⼊图⽚描述
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的最⼤池化的⽅式,进⾏多尺度融合。
狼来了英文版其他基础操作:
1. Concat:张量拼接,维度会扩充,和Yolov3中的解释⼀样,对应于cfg⽂件中的route操作。
2. Add:张量相加,不会扩充维度,对应于cfg⽂件中的shortcut操作。
Backbone中卷积层的数量:
和Yolov3⼀样,再来数⼀下Backbone⾥⾯的卷积层数量。
每个CSPX中包含5+2×X个卷积层,因此整个主⼲⽹络Backbone中⼀共包含
1+(5+2×1)+(5+2×2)+(5+2×8)+(5+2×8)+(5+2×4)=72。
这⾥⼤⽩有些疑惑,按照Yolov3设计的传统,72个卷积层,加上最后的⼀个全连接层,主⼲⽹络的名字不应该叫CSPDarknet73
吗
4.3 核⼼基础内容
Yolov4本质上和Yolov3相差不⼤,可能有些⼈会觉得失望。
但我觉得算法创新分为三种⽅式:
(1)第⼀种:⾯⽬⼀新的创新,⽐如Yolov1、Faster-RCNN、Centernet等,开创出新的算法领域,不过这种也是最难的。
(2)第⼆种:守正出奇的创新,⽐如将图像⾦字塔改进为特征⾦字塔。
(3)第三种:各种先进算法集成的创新,⽐如不同领域发表的最新论⽂的tricks,集成到⾃⼰的算法中,却发现有出乎意料的改进。Yolov4既有第⼆种也有第三种创新,组合尝试了⼤量深度学习领域最新论⽂的20多项研究成果,⽽且不得不佩服的是作者Alexey在Github代码库维护的频繁程度。
⽬前Yolov4代码的Star数量已经1万左右,据我所了解,⽬前超过这个数量的,⽬标检测领域只有Facebook的Detectron(v1-v2)、和Yolo(v1-v3)官⽅代码库(已停⽌更新)。
所以Yolov4中的各种创新⽅式,⼤⽩觉得还是很值得仔细研究的。
为了便于分析,将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
总体来说,Yolov4对Yolov3的各个部分都进⾏了改进优化,下⾯丢上作者的算法对⽐图。
在这⾥插⼊图⽚描述
仅对⽐Yolov3和Yolov4,在COCO数据集上,同样的FPS等于83左右时,Yolov4的AP是43,⽽Yolov3是33,直接上涨了10个百分点。
杨汉军不得不服,当然可能针对具体不同的数据集效果也不⼀样,但总体来说,改进效果是很优秀的,下⾯⼤⽩对Yolov4的各个创新点继续进⾏深挖。
4.3.1 输⼊端创新
考虑到很多同学GPU显卡数量并不是很多,Yolov4对训练时的输⼊端进⾏改进,使得训练在单张GPU上也能有不错的成绩。⽐如数据增强Mosaic、cmBN、SAT⾃对抗训练。
但感觉cmBN和SAT影响并不是很⼤,所以这⾥主要讲解Mosaic数据增强。
(1)Mosaic数据增强
Yolov4中使⽤的Mosaic是参考2019年底提出的CutMix数据增强的⽅式,但CutMix只使⽤了两张图⽚进⾏拼接,⽽Mosaic数据增强则采⽤了4张图⽚,随机缩放、随机裁剪、随机排布的⽅式进⾏拼接。
在这⾥插⼊图⽚描述
这⾥⾸先要了解为什么要进⾏Mosaic数据增强呢?
在平时项⽬训练时,⼩⽬标的AP⼀般⽐中⽬标和⼤⽬标低很多。⽽Coco数据集中也包含⼤量的⼩⽬标,但⽐较⿇烦的是⼩⽬标的分布并不均匀。
⾸先看下⼩、中、⼤⽬标的定义:
2019年发布的论⽂《》对此进⾏了区分
在这⾥插⼊图⽚描述
可以看到⼩⽬标的定义是⽬标框的长宽0×0~32×32之间的物体。
4.3.2 BackBone创新
(1)CSPDarknet53公司文化怎么写
CSPDarknet53是在Yolov3主⼲⽹络Darknet53的基础上,借鉴2019年CSPNet的经验,产⽣的Backbone结构,其中包含了5个CSP模块。
传统的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.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⼤⼩。
(2)FPN+PAN
PAN结构⽐较有意思,看了⽹上Yolov4关于这个部分的讲解,⼤多都是讲的⽐较笼统的,⽽PAN是借鉴**的创新点,有些同学可能不是很清楚。
下⾯⼤⽩将这个部分拆解开来,看下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⼤⼩,相当于下采样操作。
儿童童谣100首因此可以看到三个紫⾊箭头处的特征图是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)操作,特征图融合后的尺⼨发⽣了变化。
在这⾥插⼊图⽚描述
这⾥也可以对应Yolov4的,很有意思。
4.3.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来进⾏改进。