YOLOv3和YOLOv4长篇核心综述(下)
YOLOv3和YOLOv4长篇核心综述(下)
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操作。
在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是借鉴图像分割领域PANet的创新点,有些同学可能不是很清楚。
下面大白将这个部分拆解开来,看下Yolov4中是如何设计的。
Yolov3结构:
先来看下Yolov3中Neck的FPN结构
可以看到经过几次下采样,三个紫色箭头指向的地方,输出分别是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最后的三个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的netron网络图查看,很有意思。
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来进行改进。
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加速后速度还是挺快的。
6.相关数据集下载
项目中,目标检测算法应该的非常多非常多,比如人脸识别,比如疫情期间的口罩人脸识别,比如车流统计,人流统计等等。
因此大白也会将不错的值得一试的目标检测数据集汇总到此处,方便需要的同学进行下载。
6.1 口罩遮挡人脸数据集
数据集详情: 由武汉大学多媒体研究中心发起,目前是全球最大的口罩遮挡人脸数据集。
分为真实口罩人脸和模拟口罩人脸两部分,真实口罩人脸包含525人的5000张口罩人脸和9万张正常人脸。模拟口罩人脸包含1万个人共50万张模拟人脸数据集。
应用项目: 人脸检测、人脸识别
数据集地址:https://github.com/X-zhangyang/Real-World-Masked-Face-Dataset
6.2 Wider Face人脸数据集
数据集详情:香港中文大学发起的,包含3万张图片共40万张人脸。
应用项目:人脸检测
数据集地址:http://shuoyang1213.me/WIDERFACE/WiderFace_Results.html
6.3 Wider Person拥挤场景行人数据集
数据集详情:多种场景比较拥挤场景的行人检测数据集,包含13382张图片,共计40万个不同遮挡程度的人体。
应用项目:人体检测
数据集地址:http://www.cbsr.ia.ac.cn/users/sfzhang/WiderPerson/
因为工作原因,会搜集大量的各类公开应用场景数据集,如果有同学需要其他场景或者其他项目的,也可以留言,或者发送邮件到jiangdabai@126.com,也会将对应的数据集更新到此处。
7.不断更新ing
在深度学习的图像领域,肯定会涉及目标检测,而在目标检测中,Yolov3是非常经典,必须要学习的算法,有些同学,特别新接触的同学,刚学习时会觉得yolo算法很繁琐。
但发现,网上很多的教程其实讲的还是比较笼统,并不适合学习。
所以大白也在耗尽洪荒之力,在准备Yolov3和Yolov4及相关的基础入门视频,让大家看完就能明白整体的流程和各种算法细节,大家可以先收藏,后期制作好后会更新到此处。
YOLOv3和YOLOv4长篇核心综述(下)的更多相关文章
- YOLOv3和YOLOv4长篇核心综述(上)
YOLOv3和YOLOv4长篇核心综述(上) 对目标检测算法会经常使用和关注,比如Yolov3.Yolov4算法. 实际项目进行目标检测任务,比如人脸识别.多目标追踪.REID.客流统计等项目.因此目 ...
- Yolov4性能分析(下)
Yolov4性能分析(下) 六. 权重更新 "darknet/src/detector.c"--train_detector()函数中: ...... /* 开始训练网络 */ f ...
- CSS gradient渐变之webkit核心浏览器下的使用
一.关于渐变 渐变是一种应用于平面的视觉效果,可以从一种颜色逐渐地转变成另外一种颜色,故可以创建类似于彩虹的效果渐变可以应用在任何可以使用图片的地方.例如,您可以指定一个这么一个渐变:顶部的颜色是红色 ...
- C# 6 与 .NET Core 1.0 高级编程 - 38 章 实体框架核心(下)
译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 38 章 实体框架核心(下)),不对的地方欢迎指出与交流. 章节出自<Professional C# 6 ...
- CSS gradient渐变之webkit核心浏览器下的使用以及实例
一.关于渐变 渐变是一种应用于平面的视觉效果,可以从一种颜色逐渐地转变成另外一种颜色,故可以创建类似于彩虹的效果渐变可以应用在任何可以使用图片的地方.例如,您可以指定一个这么一个渐变:顶部的颜色是红色 ...
- yolov3源码darknet在vscode下调试
1. 安装配置: https://pjreddie.com/darknet/yolo/ darknet文件夹下make命令搞定: 2. 配置vscode 打开安装好的vscode并安装扩展C/C++( ...
- Linux red hat 核心版下安装Nginx
不要安装核心版的Linux,不要安装核心版的Linux,不要安装核心版的Linux重要的事情要说3遍.心血来潮突然想在Linux下安装Nginx,但是在安装的国程中发现了很多问题.nginx 基本安装 ...
- 【循序渐进学Python】8.面向对象的核心——类型(下)
1 构造和初始化对象 __init__方法是Python内建众多魔法方法(什么是魔法方法?)中最常见的一个,通过这个方法我们可以定义一个对象的初始操作.当构造函数被调用的时候的任何参数都会传递给__i ...
- Deep Learning综述[下]
Image understanding with deep convolutional networks 直到2012年ImageNet大赛之前,卷积神经网络一直被主流机器视觉和机器学习社区所遗弃.2 ...
随机推荐
- 【Nacos】Springboot整合Nacos配置中心(二) 多环境配置
本篇随笔接上一篇文章:Springboot整合Nacos配置中心(一),主要记录Nacos多环境的配置的方法 Nacos多环境的配置 方法一: 1.在项目中的bootstrap.yaml文件中配置激活 ...
- hdu4277 DFS+SET
题意: 给你一些木棍,问你可以组成多少个三角形.. 思路: 直接深搜,N很小深搜无压力,也可以直接算出来,但我不会算.. #include<stdio.h> #in ...
- hdu4975 行列和构造矩阵(dp判断唯一性)
题意: 和hdu4888一样,只不过是数据加强了,就是给你行列的和,让你构造一个矩阵,然后判断矩阵是否唯一. 思路: 构造矩阵很简单,跑一次最大流就行了,关键是判断矩阵的唯一性 ...
- 逆向 time.h 函数库 time、gmtime 函数
0x01 time 函数 函数原型:time_t time(time_t *t) 函数功能:返回自纪元 Epoch(1970-01-01 00:00:00 UTC)起经过的时间,以秒为单位.如果 se ...
- MySQL数据库及注入方法
目录 MySQL数据库 mysql中比较常用的一些函数: 判断MySQL数据库是否存在SQL注入 MySQL数据库文件结构 MySQL数据库密码破解 MySQL UDF提权 MySQL数据库 MySQ ...
- RabbitMQ实现延时消息的两种方法
目录 RabbitMQ实现延时消息的两种方法 1.死信队列 1.1消息什么时候变为死信(dead-letter) 1.2死信队列的原理 1.3 代码实现 1.4死信队列的一个小坑 2 .延时插件 2. ...
- UVA OJ 623 500!
500! In these days you can more and more often happen to see programs which perform some useful cal ...
- Alpha事后分析
设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件的功能主要是让一些基于表单识别的项目(如微软智能表单识别项目)减少在数据生成方面上浪费的 ...
- JAVA并发(1)-AQS(亿点细节)
AQS(AbstractQueuedSynchronizer), 可以说的夸张点,并发包中的几乎所有类都是基于AQS的. 一起揭开AQS的面纱 1. 介绍 为依赖 FIFO阻塞队列 的阻塞锁和相关同步 ...
- 把el-element的日期格式改为CRON
在日常的开发当中,经常会遇到格式的不匹配造成的困扰. 在日期管理上,el-element也是贴心的准备了相关的日期选择器,但是在取值的时候发现,el-element所给出的值格式可能并不是我们常用的. ...