最新
yolov6和yolov7已经出来了
Yolov7:最新最快的实时检测框架,最详细分析解释(附源代码) YOLOv7上线:无需预训练,5-160 FPS内超越所有目标检测器 劲爆!YOLOv6又快又准的目标检测框架开源啦(附源代码下载)
参考资料
YOLO算法介绍
知乎 - 深入浅出Yolo系列之Yolov3&Yolov4&Yolov5&Yolox核心基础知识完整讲解(有一整个系列学习路程的推荐) B站-冒死上传!花9580买来的【目标检测YOLO算法】课程,YOLOv1/v2/v3/v4/v5全 B站 - 绝对是B站上讲的最通俗易懂的【YOLO目标检测】教程!原理+代码
YOLO算法入门
视频:吴恩达目标检测Yolo入门讲解 CSDN - YOLO系列之yolo v1 CSDN-《什么是Bounding Box、anchor box?》 CSDN-关于ancher box 和bounding box的区别 CSDN-Bounding Box与anchor box CSDN-深度特征融合—-理解add和concat之多层特征融合
① Yolov3相关资料
【视频】:深入浅出Yolov3(上)、深入浅出Yolov3(下) 【文章】:《深入浅出Yolo系列之Yolov3&4核心基础知识完整讲解》
② Yolov4相关资料
【视频】:深入浅出Yolov4(上)、深入浅出Yolov4(下)、B站-《YOLOv4网络详解》 【文章】: 《深入浅出Yolo系列之Yolov3&4核心基础知识完整讲解》 CSDN-《YOLOv4网络详解》
③ Yolov5相关资料
【文章】:《深入浅出Yolo系列之Yolov5核心基础知识完整讲解》 B站 - 目标检测+人脸识别 小白1小时入门深度学习 yolov5框架环境搭建+使用+训练+自制训练集教学(5)
④ Yolox相关资料
【文章】:《深入浅出Yolo系列之Yolox核心基础知识完整讲解》 【文章】:《深入浅出Yolox之自有数据集训练超详细讲解》
YOLO在人群计数上的使用
教室场景下-知乎-深入浅出Yolov5之自有数据集训练超详细教程 2022-01-30(源码+权重文件+数据集+讲解) 教室场景下-知乎-深入浅出Yolox之自有数据集训练超详细教程 2021-8-17(源码+权重文件+数据集+讲解) 代码安装运行介绍 - B站视频 - win10版本 yolov5 deepsort 行人 车辆 跟踪 检测 计数 2022-03-02 git源码地址 - B站视频 - win10版本 yolov5 deepsort 行人 车辆 跟踪 检测 计数 2022-03-02 路边监控模型效果展示 - B站 - 【社交距离】【行人检测跟踪计数】【轨迹】yolov5+deepsort 2020-07-25 (无源码) 楼梯电梯场景计数效果展示 - B站视频 - 基于YOLOV5的行人检测与跟踪识别计数 2021-04-17(没有源码、有视频地址) 马路场景手持设备模型结果展示 - B站视频 - 基于YOLOV5的行人检测 2021-04-06(有源码) yolov5 git源码 - B站视频 - 基于YOLOV5的行人检测 2021-04-06 训练模型讲解 git地址 - B站视频 - 基于YOLOV5的行人检测 2021-04-06 电影片段模型效果展示 - B站 - yolov5人群计数及阀值报警(有源码,但是要钱,好贵的) CSDN - yolov5 人群计数及阀值报警
YOLO算法在高密度下的目标检测人群计数任务
详细解读TPH-YOLOv5 | 让目标检测任务中的小目标无处遁形 基于改进YOLOv3算法的高密度人群目标实时检测方法研究
自动标注
目标检测
目标检测任务基本知识点
目标检测概念
图像检测和定位算法:分类定位任务,包括图像目标的分类和定位,分类辨别出物体的类别,定位识别物体在图片中的位置。 在目标检测任务中,一张图片中可以包含有多个物体时。
分类
对输入的图像进行分类,用神经网络训练,用softmax函数分类(这张图中可能有汽车、人、背景等类别)
定位
可以让神经网络多输出几个单元,输出一个边界框 具体说就是让神经网络再多输出4个数字 本图中: 输出(PC为0时候不用理睬别的属性):
!!!!(还不理解)concat
张量拼接。将darknet中间层和后面的某一层的上采样进行拼接。拼接的操作和残差层add的操作是不一样的,拼接会扩充张量的维度,而add只是直接相加不会导致张量维度的改变。
大概是把图片拼在一起吧,比如四张图片变一张
基于滑动窗口的目标检测
步骤是:
首先创建一个标签训练集 对图片剪切然后标签分类(这里写的y没写全,只写了Pc表示是否是检测目标)
滑动窗口:(给定指定大小窗口,输入网络中,从左上到右下滑动扫描)
思路是以固定步幅滑动窗口遍历图像的每个区域 把这些剪切后的小图像输入卷积网络 对每个位置按0或1进行分类
缺点:
步幅小的话窗口太多,计算成本大;步幅大的话,粗粒度影响性能。
滑动窗口的卷积实现
直接对一整张图片进行检测,不需要分小块小块分别进行卷积,一次性计算出每块预测值,减少计算量
基础知识:用卷积层代替全连接层的思路(上面全连接,下面卷积,400:400个5x5的卷积核): 改进:填充了些地方,让一次输出4个结果,减少重复的计算,减少计算量
IoU(交并比,判断定位精确度)
intersession over union:计算两个边界框的交集和并集之比,用于判断边界框是否正确(0.5是阈值)
非极大值抑制
解决问题:算法对一个目标不止检测一次,使用此方法对每个目标只检测一次
具体实现:只取预测概率最大的检测框,而其他很接近但不是最大的预测结果会被抑制
介绍:
实际检测场景: 非极大值抑制实现: 检测每次检测结果中的概率p_c(实际是p_c×c1c2c3); 找到概率最大的检测框作为检测结果; 所有和这个最大的边界框有很高交并比高度重叠的其他边界框会被抑制;
实现细节:
- pc小于阈值的边界框都去掉;
- 剩下边界框,一直选概率最高的边界框作为预测结果(预测此格有物体);
- 计算其他边界框和已被选中确认为预测结果的边界框进行IoU运算,有极高交并比的框被抑制,去掉;
- 重复进行3、4操作,直至结束
Bounding Box
YOLO v3的Bounding Box由YOLOV2又做出了更好的改进。在yolo_v2和yolo_v3中,都采用了对图像中的object采用k-means聚类。 feature map中的每一个cell都会预测3个边界框(bounding box) ,每个bounding box都会预测三个东西:(1)每个框的位置(4个值,中心坐标tx和ty,,框的高度bh和宽度bw),(2)一个objectness prediction ,(3)N个类别,coco数据集80类,voc20类。
三次检测,每次对应的感受野不同,32倍降采样的感受野最大,适合检测大的目标,所以在输入为416×416时,每个cell的三个anchor box为(116 ,90); (156 ,198); (373 ,326)。16倍适合一般大小的物体,anchor box为(30,61); (62,45); (59,119)。8倍的感受野最小,适合检测小目标,因此anchor box为(10,13); (16,30); (33,23)。所以当输入为416×416时,实际总共有(52×52+26×26+13×13)×3=10647个proposal box。
这里注意bounding box 与anchor box的区别: Bounding box它输出的是框的位置(中心坐标与宽高),confidence以及N个类别。 anchor box只是一个尺度即只有宽高。 原文链接:https://blog.csdn.net/litt1e/article/details/88907542
Anchor Boxes(和我的方向不符合,跳过)
YOLOv3 SPP
正样本匹配过程。流程大致如下图所示:比如说针对某个预测特征层采用如下三种Anchor模板AT 1、AT 2、AT 3
- 将每个GT Boxes与每个Anchor模板进行匹配(这里直接将GT和Anchor模板左上角对齐,然后计算IoU)
- 如果GT与某个Anchor模板的IoU大于给定的阈值,则将GT分配给该Anchor模板,如图中的AT 2
- 将GT投影到对应预测特征层上,根据GT的中心点定位到对应cell(图中黑色的×表示cell的左上角)
- 则该cell对应的AT2为正样本
YOLOV4/V5
但在YOLOv4以及YOLOv5中关于匹配正样本的方法又有些许不同。主要原因在于YOLOv4-优化策略-中心点预测 中提到的缩放因子,通过缩放后网络预测中心点的偏移范围已经从原来的( 0 , 1 )调整到了(− 0.5 , 1.5 ) 。所以对于同一个GT Boxes可以分配给更多的Anchor,即正样本的数量更多了。如下图所示:
- 将每个GT Boxes与每个Anchor模板进行匹配(这里直接将GT和Anchor模板左上角对齐,然后计算IoU,在YOLOv4中IoU的阈值设置的是0.213)
- 如果GT与某个Anchor模板的IoU大于给定的阈值,则将GT分配给该Anchor模板,如图中的AT 2
- 将GT投影到对应预测特征层上,根据GT的中心点定位到对应cell(注意图中有三个对应的cell,后面会解释)
- 则这三个cell对应的AT2都为正样本
YOLOV3和V4中提出的anchor模板
!!!!(再看,没太懂)ancher box、bounding box
虽然都是框框(box),但是实际上区别还是很大的,在yolo算法中,Y的输出形式为 例如: 那么,在这里,ancher box(以下称为abox)的种类为2,而bounding box(以下称为bbox)的种类为3。 abox是根据预测的形状来设计的box,而bbox是根据预测的分类来设计的,对于上面的额Y,有两个pc,三个c=(c1,c2,c3),则有2个abox,3个bbox。
YOLO会将输入的图片分成S*S个网格,每个小网格会生成n个anchor Box。图像的真实框会和图像中心点所在的小网格生成的anchor box做IOU计算。回归出来的框就是Bounding Box(也就是网络输出的框,他与真实框和anchor Box都有差距)Bounding box它输出的是框的位置(中心坐标与宽高),confidence以及N个类别。 anchor box只是一个尺度即只有宽高。
指标分析(精度、召回率、mAP)
第一张图下面的面积是mAP,越接近1越好
一步走和两步走
两步走要先选出候选区域
两步走算法-候选区域(R-CNN)
R-CNN(带区域的卷积网络) 解决问题:有些区域没有目标但是却参与了计算,此算法选择某些区域进行卷积神经网络 问题:运行速度慢 其他:有针对该算法的优化(Fast R-CNN:在此基础上使用了滑动窗口)(Faster R-CNN:使用卷积神经网络获取候选区域块)
先图像分割(分割结果如最右边显示) 找到色块,在色块上放置边界框,跑分类器看结果
YOLO算法
优缺点、使用场景
优点:速度快,适合做实时的任务
缺点:效果相比两步走的算法来的粗一些(速度越快效果越差)
评价指标:FPS(速度快慢)、mAP(效果好坏),都是越大越好
使用场景:对视频进行实时检测
YOLO-v1算法
优缺点
算法介绍
基本思想是这样:预测框的位置、大小和物体分类都通过CNN暴力predict出来。(把检测问题转化为回归问题)
算法:将图片分为网格,每个格子都能有一个y(这里是8维向量),图中的输出为3x3x8的向量 注:这里的网格不是把图片切分为一个个片段,而是为了方便中心点的确认; 优点:
- 运行速度快,可以实现实时识别
- 能输出精确的边界框(输出图像和预分配的格子大小有关,和滑动窗口的大小和步幅无关);
- 计算量减少。使用滑动窗口的卷积实现,不需要在一张图片中跑多次算法(本例指不用在3x3的图像中跑9次算法)
分配的原则:观察对象的中点,然后将其分配到中点所在的格子;所以即使一个对象横跨多个格子,也只分配到中点所在的格子; 实际:这里的示例采用的是3x3网格,实际可以更精细,比如19x19,可以减小一个格子里面多个检测对象的概率
位置定位
定位的确认是相对分配的格子来的 中心点:以在格子中的坐标表示(值在0,1之间) bh:用格子总体宽度的比例表示(如果横跨多个框,则有可能>1) bw:同理 标签的转换代码:(从具体的图片大小和标注框的坐标位置,转换成YOLO匹配的标签的box)
YOLO算法-算法结构
神经网络预测结果: 步骤:
- 每格都给两检测框
- 去掉预测结果小于阈值的
- 多目标检测的,就对每个进行多次的IoU(次数和检测目标类别一致)
- 得出结果
YOLO-v1
基本思想是这样:预测框的位置、大小和物体分类都通过CNN暴力predict出来。 YOLO系列之yolo v1 7x7是分割的网格,30是y的大小(30个参数),后面的参数是属于每个值的概率
损失函数:
YOLO-v2
优缺点
算法原理介绍
网络结构
中间使用1x1卷积(参考VGG)是为了传递并浓缩参数,结果没影响,感受野更大(这是DarkNet19,19会因为它是19层网络)
聚类提取先验框(Anchor Box)
将实际标注的数据先进行k-means聚类,聚成k类,然后从每一类中都取出一个代表作为一个先验框。 这里重新定义了k-means聚类的距离: 两个框重合度越大,IoU越大 下图左边的图横坐标是k的数,纵坐标是IoU(经实验,k=5合适) 加入先验框的结果(mAP略微下降,recall提升比较多)
坐标映射
中心思想:位置是相对网格来说的(在网格中的偏移量)
感受野
卷积核越小需要的参数越少;而且因为每个卷积后都要加BN进行调整,所以小卷积核比较好; 越大的感受野,关注的信息越多,越能考虑整体、全局,大物体也能检测完整; 对小物体来说,感受野小些比较好; 上面步骤: 1.将前一层的特征图拆分成和后面一层同样的尺寸(这里是13x13); 2.将两特征图叠加输出(这个图像就能即识别大物体也能识别小物体)
多尺度
卷积次数越多,感受野越大,能检测到的图片尺寸越大,能检测到的物体越大
YOLO-V3
算法原理介绍
网络架构
池化把特征做压缩了
多scale
- 三种scale,分别为13x13,26x26,52x52,分别检测大、中、小目标
- 每个scale都有3种规格(三个不同大小、尺寸、形状的检测框)
- 检测中目标的要融合大目标的特征;检测小目标的要融合中目标的特征;(可以比喻成老年人、中年人和年轻人的生活经历,中年人迷茫时候可以请教老年人)
FPN
- 检测中目标的要融合大目标的特征;检测小目标的要融合中目标的特征;(可以比喻成老年人、中年人和年轻人的生活经历,中年人迷茫时候可以请教老年人)
如图所示,FPN是自顶向下的,将高层的特征信息通过上采样的方式进行传递融合,得到进行预测的特征图。
ResNet 残差连接(后面看)
resnet出现的背景:
VGG中发现的,神经网络中卷积堆叠的越多,反而错误率越多;
resnet的思路:
思路:并非加入的所有层都是差的,好的留下坏的跳过 算法效果:至少不比加入前差 具体:加入resnet后有两条路可以选择,一种就是进行卷积训练,一种就是不卷积,直接进入下一层。(不好的模块直接跳过) 跳过的具体操作:在训练过程中,会把加入resnet的小模块,进行卷积前后的判断;如果加入卷积后效果更差,就会把其对应的权重调小,直至超小(也许是0),然后把卷积前的x直接映射(identity x,映射x)到卷积之后(即跳过了差的模块)
在模型中的实际应用
虚线是上下特征图不同,用1x1卷积,使特征图大小翻倍
先验框
softmax函数的改进
通过判断阈值,阈值大于某个值的就都算
YOLO-v4
创新之处
Yolov4 主要带来了 3 点新贡献: (1)提出了一种高效而强大的目标检测模型,使用 1080Ti 或 2080Ti 就能训练出超快、准确的目标检测器。 (2)在检测器训练过程中,验证了最先进的一些研究成果对目标检测器的影响。 (3)改进了 SOTA 方法,使其更有效、更适合单 GPU 训练。
YoloV4的创新之处
- 输入端:这里指的创新主要是训练时对输入端的改进,主要包括Mosaic数据增强、cmBN、SAT自对抗训练
- BackBone主干网络:将各种新的方式结合起来,包括:CSPDarknet53、Mish激活函数、Dropblock
- Neck:目标检测网络在BackBone和最后的输出层之间往往会插入一些层,比如Yolov4中的SPP模块、FPN+PAN结构
- Prediction:输出层的锚框机制和Yolov3相同,主要改进的是训练时的损失函数CIOU_Loss,以及预测框筛选的nms变为DIOU_nms
详细结构
先整理下Yolov4的五个基本组件:
- CBM:Yolov4网络结构中的最小组件,由Conv+Bn+Mish激活函数三者组成。
- CBL:由Conv+Bn+Leaky_relu激活函数三者组成。
- Res unit:借鉴Resnet网络中的残差结构,让网络可以构建的更深。
- CSPX:借鉴CSPNet网络结构,由卷积层和X个Res unint模块Concat组成。
- SPP:采用1×1,5×5,9×9,13×13的最大池化的方式,进行多尺度融合。
其他基础操作:
- Concat:张量拼接,维度会扩充,和Yolov3中的解释一样,对应于cfg文件中的route操作。
- add:张量相加,不会扩充维度,对应于cfg文件中的shortcut操作。
和其他算法的比较
仅对比Yolov3和Yolov4,在COCO数据集上,同样的FPS等于83左右时,Yolov4的AP是43,而Yolov3是33,直接上涨了10个百分点。 不得不服,当然可能针对具体不同的数据集效果也不一样,但总体来说,改进效果是很优秀的
网络结构
分析
为了便于分析,将Yolov4的整体结构拆分成四大板块: 大白主要从以上4个部分对YoloV4的创新之处进行讲解,让大家一目了然。
- 输入端:这里指的创新主要是训练时对输入端的改进,主要包括Mosaic数据增强、cmBN、SAT自对抗训练
- BackBone主干网络:将各种新的方式结合起来,包括:CSPDarknet53、Mish激活函数、Dropblock
- Neck:目标检测网络在BackBone和最后的输出层之间往往会插入一些层,比如Yolov4中的SPP模块、FPN+PAN结构
- Prediction:输出层的锚框机制和Yolov3相同,主要改进的是训练时的损失函数CIOU_Loss,以及预测框筛选的nms变为DIOU_nms
改进
相比之前的YOLOv3,改进了下Backbone,在Darknet53中引入了CSP模块(来自CSPNet)。在Neck部分,采用了SPP模块(Ultralytics版的YOLOv3 SPP就使用到了)以及PAN模块(来自PANet)。Head部分没变还是原来的检测头。
CSPDarknet53
CSPDarknet53就是将CSP结构融入了Darknet53中。
介绍:
CSPNet全称是Cross Stage Paritial Network,主要从网络结构设计的角度解决推理中从计算量很大的问题。 CSPNet的作者认为推理计算过高的问题是由于网络优化中的梯度信息重复导致的。 因此采用CSP模块先将基础层的特征映射划分为两部分,然后通过跨阶段层次结构将它们合并,在减少了计算量的同时可以保证准确率。
CSP的优点:
- 增强CNN的学习能力
- 移除计算瓶颈
- 减少显存开销
即减少网络的计算量以及对显存的占用,同时保证网络的能力不变或者略微提升。 CSP结构的思想参考原论文中绘制的CSPDenseNet,
- 进入每个stage(一般在下采样后)先将数据划分成俩部分,如下图所示的Part1和Part2。但具体怎么划分呢,在CSPNet中是直接按照通道均分,但在YOLOv4网络中是通过两个1x1的卷积层来实现的。
- 在Part2后跟一堆Blocks然后在通过1x1的卷积层(图中的Transition),
- 接着将两个分支的信息在通道方向进行Concat拼接,
- 最后再通过1x1的卷积层进一步融合(图中的Transition)。
接下来详细分析下CSPDarknet53网络的结构
每个CSP模块前面的卷积核的大小都是33,stride=2,因此可以起到下采样的作用。 因为Backbone有5个CSP模块,输入图像是**608608,所以特征图变化的规律是:608->304->152->76->38->19 经过5次CSP模块后得到19*19大小的特征图。 而且作者只在Backbone中采用了Mish激活函数,网络后面仍然采用Leaky_relu激活函数。**
下图是CSPDarknet53详细结构(以输入图片大小为416 × 416 × 3为例),图中:k 代表卷积核的大小 s 代表步距 c 代表通过该模块输出的特征层channels 注意,CSPDarknet53 Backbone中所有的激活函数都是Mish激活函数
SPP(Spatial Pyramid Pooling)
SPP(Spatial Pyramid Pooling,空间金字塔池)就是将特征层分别通过一个池化核大小为5x5、9x9、13x13的最大池化层,然后在通道方向进行concat拼接在做进一步融合,这样能够在一定程度上解决目标多尺度问题,如下图所示。
在Yolov4中,SPP模块仍然是在Backbone主干网络之后 作者在SPP模块中,使用k={11,55,99,1313}的最大池化的方式,再将不同尺度的特征图进行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模块。
PAN
PAN(Path Aggregation Network)结构其实就是在FPN(从顶到底信息融合)的基础上加上了从底到顶的信息融合,如下图(b)所示。 和Yolov3的FPN层不同,Yolov4在FPN层的后面还添加了一个自底向上的特征金字塔。其中包含两个PAN结构。 这样结合操作,FPN层自顶向下传达强语义特征,而特征金字塔则自底向上传达强定位特征,两两联手,从不同的主干层对不同的检测层进行参数聚合,这样的操作确实很皮。 FPN+PAN借鉴的是18年CVPR的PANet,当时主要应用于图像分割领域,但Alexey将其拆分应用到Yolov4中,进一步提高特征提取的能力。
不过这里需要注意几点:
注意一:
Yolov3的FPN层输出的三个大小不一的特征图①②③直接进行预测 但Yolov4的FPN层,只使用最后的一个7676特征图①,而经过两次PAN结构,输出预测的特征图②和③。 这里的不同也体现在cfg文件中,这一点有很多同学之前不太明白, 比如Yolov3.cfg最后的三个Yolo层, 第一个Yolo层是最小的特征图**1919,mask=6,7,8,对应最大的anchor box。 第二个Yolo层是中等的特征图3838,mask=3,4,5,对应中等的anchor box。 第三个Yolo层是最大的特征图7676,mask=0,1,2,对应最小的anchor box。 而Yolov4.cfg则恰恰相反 第一个Yolo层是最大的特征图7676,mask=0,1,2,对应最小的anchor box。 第二个Yolo层是中等的特征图3838,mask=3,4,5,对应中等的anchor box。 第三个Yolo层是最小的特征图1919,mask=6,7,8,对应最大的anchor box。*
注意点二:
YOLOv4的PAN结构和原始论文的融合方式又略有差异,如下图所示。图(a)是原始论文中的融合方式,即特征层之间融合时是直接通过相加的方式进行融合的,但在YOLOv4中是通过在通道方向Concat拼接的方式进行融合的。
输入端改进
考虑到很多同学GPU显卡数量并不是很多,Yolov4对训练时的输入端进行改进,使得训练在单张GPU上也能有不错的成绩。比如数据增强Mosaic、cmBN、SAT自对抗训练。 但感觉cmBN和SAT影响并不是很大,所以这里主要讲解Mosaic数据增强。
Mosaic数据增强
在数据预处理时将四张图片拼接成一张图片,增加学习样本的多样性
Yolov4中使用的Mosaic[moʊˈzeɪɪk] 是参考2019年底提出的CutMix数据增强的方式,但CutMix只使用了两张图片进行拼接,而Mosaic数据增强则采用了4张图片,随机缩放、随机裁剪、随机排布的方式进行拼接。 这里首先要了解为什么要进行Mosaic数据增强呢? 在平时项目训练时,小目标的AP(AP: 对不同召回率点上的精度进行平均(即PR曲线下的面积))一般比中目标和大目标低很多。而Coco数据集中也包含大量的小目标,但比较麻烦的是小目标的分布并不均匀。 首先看下小、中、大目标的定义:
2019年发布的论文《Augmentation for small object detection》对此进行了区分: 可以看到小目标的定义是目标框的长宽0×0~32×32之间的物体。 但在整体的数据集中,小、中、大目标的占比并不均衡。
如上表所示,Coco数据集中小目标占比达到41.4%,数量比中目标和大目标都要多。 但在所有的训练集图片中,只有52.3%的图片有小目标,而中目标和大目标的分布相对来说更加均匀一些。 针对这种状况,Yolov4的作者采用了Mosaic数据增强的方式。 主要有几个优点:
- 丰富数据集:随机使用4张图片,随机缩放,再随机分布进行拼接,大大丰富了检测数据集,特别是随机缩放增加了很多小目标,让网络的鲁棒性更好。
- 减少GPU:可能会有人说,随机缩放,普通的数据增强也可以做,但作者考虑到很多人可能只有一个GPU,因此Mosaic增强训练时,可以直接计算4张图片的数据,使得Mini-batch大小并不需要很大,一个GPU就可以达到比较好的效果。
此外,发现另一研究者的训练方式也值得借鉴,采用的数据增强和Mosaic比较类似,也是使用4张图片(不是随机分布),但训练计算loss时,采用“缺啥补啥”的思路: 如果上一个iteration中,小物体产生的loss不足(比如小于某一个阈值),则下一个iteration就用拼接图;否则就用正常图片训练,也很有意思。 参考链接:https://www.zhihu.com/question/3901
backbone改进
CSPDarknet53
见上面网络结构
Mish激活函数
Mish激活函数是2019年下半年提出的激活函数 论文地址:https://arxiv.org/abs/1908.08681 和Leaky_relu激活函数的图形对比如下:
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,对网络的正则化过程进行了全面的升级改进。
Neck改进
在目标检测领域,为了更好的提取融合特征,通常在Backbone和输出层,会插入一些层,这个部分称为Neck。相当于目标检测网络的颈部,也是非常关键的。 Yolov4的Neck结构主要采用了SPP模块、FPN+PAN的方式。
SPP(Spatial Pyramid Pooling)
见上面网络结构
FPN+PAN
见上面网络结构
anchor box改进
使用下方 中心点预测 中提到的缩放因子,通过缩放后网络预测中心点的偏移范围已经从原来的( 0 , 1 )调整到了(− 0.5 , 1.5 ) 。所以对于同一个GT Boxes可以分配给更多的Anchor,即正样本的数量更多了。如下图所示:
- 将每个GT Boxes与每个Anchor模板进行匹配(这里直接将GT和Anchor模板左上角对齐,然后计算IoU,在YOLOv4中IoU的阈值设置的是0.213)
- 如果GT与某个Anchor模板的IoU大于给定的阈值,则将GT分配给该Anchor模板,如图中的AT 2
- 将GT投影到对应预测特征层上,根据GT的中心点定位到对应cell(注意图中有三个对应的cell,后面会解释)
- 则这三个cell对应的AT2都为正样本
YOLOV3和V4中提出的anchor模板
prediction创新
中心点预测
原方法:
存在问题和解决办法:
CIoU(定位损失)
目标检测任务的损失函数一般由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的回归方式,使得预测框回归的速度和精度更高一些。
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即可。
后面细看:
BN(Batch Normalization)
神经网络中的 BN(Batch Normalization)层意义何在
leakyRelu
leakyRelu: 数学表达式:y = max(0, x) + leak*min(0,x) (leak是一个很小的常数,这样保留了一些负轴的值,使得负轴的信息不会全部丢失)
leakyRelu的图像:
ResNet
ResNet详解
residual的计算方式
residual结构使用了一种shortcut的连接方式,也可理解为捷径。让特征矩阵隔层相加,注意F(X)和X形状要相同,所谓相加是特征矩阵相同位置上的数字进行相加。
ResNet中两种不同的residual
1.左侧残差结构称为 BasicBlock
2.右侧残差结构称为 Bottleneck
(1)其中第一层的1× 1的卷积核的作用是对特征矩阵进行降维操作,将特征矩阵的深度由256降为64;
第三层的1× 1的卷积核是对特征矩阵进行升维操作,将特征矩阵的深度由64升成256。
降低特征矩阵的深度主要是为了减少参数的个数。
如果采用BasicBlock,参数的个数应该是:256×256×3×3×2=1179648
采用Bottleneck,参数的个数是:1×1×256×64+3×3×64×64+1×1×256×64=69632
(2)先降后升为了主分支上输出的特征矩阵和捷径分支上输出的特征矩阵形状相同,以便进行加法操作。 注:CNN参数个数 = 卷积核尺寸×卷积核深度 × 卷积核组数 = 卷积核尺寸 × 输入特征矩阵深度 × 输出特征矩阵深度
注意:搭建深层次网络时,采用三层的残差结构。