说明: 本文档是为了自己学习YOLO相关知识进行梳理的一份笔记,为了防止文档丢失整理成线上的方式,包括从YOLO到YOLOV5的网络结构、算法原理、版本间的改进措施等进行了整理,关于YOLOX、YOLOV7等算法因为时间关系,暂时放下。该文主要是参考了各位大佬们的技术博客,然后加以整合梳理而成,现将各位大佬们的专栏主页、文章链接一一列下放到文章最前面,表示对大佬的敬佩,如要详细学习请关注各位大佬们的相关专栏。对于文中引用的相关图片,如果侵权,请联系我删除,谢谢。
[1]YOLO系列详解:YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5
[2]深入浅出Yolo系列之Yolov3&Yolov4&Yolov5&Yolox核心基础知识完整讲解
[3]YOLO-从零开始入门目标检测
[4]目标检测之YOLO算法:YOLOv1,YOLOv2,YOLOv3,TinyYOLO,YOLOv4,YOLOv5,YOLObile,YOLOF,YOLOX详解
[5]搞懂YOLO v1看这篇就够了
[6]YOLOv1 前向推断后处理——NMS非极大值抑制
[7]一文读懂Faster R-CNN
YOLO系列是one-stage且是基于深度学习的回归方法,而R-CNN、Fast-RCNN、Faster-RCNN等是two-stage且是基于深度学习的分类方法。
YOLO官网:https://github.com/pjreddie/darknet
region proposal
的过程。Faster R-CNN中尽管RPN与fast rcnn共享卷积层,但是在模型训练过程中,需要反复训练RPN网络和fast rcnn网络。相对于R-CNN系列的"看两眼"(候选框提取与分类),YOLO只需要Look Once.论文地址:https://arxiv.org/abs/1506.02640
官方代码:https://github.com/pjreddie/darknet
YOLOv1的核心思想:
YOLOv1的核心思想就是利用整张图作为网络的输入,直接在输出层回归bounding box的位置和bounding box所属的类别。
Faster RCNN的核心思想:
Faster RCNN中也直接用整张图作为输入,但是Faster-RCNN整体还是采用了RCNN那种proposal+classifier
的思想,只不过是将提取proposal的步骤放在CNN中实现了,而YOLOv1则采用直接回归的思路。
Faster R-CNN学习参考网址:https://zhuanlan.zhihu.com/p/31426458
bounding box
,每个bounding box
除了要回归自身的位置之外,还要附带预测一个confidence值
。这个confidence代表了所预测的box中含有object的置信度和这个box预测的有多准两重信息,其值是这样计算的:448x448
像素,取S=7,B=2
,一共有20个类别(C=20)。则输出就是7x7x(2x5+20)
的一个tensor
。整个网络结构如下图所示:网络结构借鉴了GoogLeNet
。24个卷积层,2个全链接层。(用1×1 reduction layers 紧跟 3×3 convolutional layers 取代Goolenet的 inception modules )
接下来是正题——后处理——NMS非极大值抑制,把98个框变为最终的目标检测结果
每个grid有30维,这30维中,8维是回归box的坐标,2维是box confidence,还有20维是类别。其中坐标的x,y用对应网格的offset归一化到0-1之间,w,h用图像的width和height归一化到0-1之间。在实现中,最主要的就是怎么设计损失函数,让这个三个方面得到很好的平衡。作者简单粗暴的全部采用了sum-squared error loss
来做这件事。
这种做法存在以下几个问题:
解决方法:
YOLOv1在对不同大小的box预测中,相比于大box预测偏一点,小box预测偏一点肯定更不能被忍受的。而sum-square error loss
中对同样的偏移loss是一样。为了缓和这个问题,作者用了一个比较取巧的办法,就是将box的width和height取平方根代替原本的height和width。这个参考下面的图很容易理解,小box的横轴值较小,发生偏移时,反应到y轴上相比大box要大。(也是个近似逼近方式)
一个网格预测多个box,希望每个box predictor专门负责预测某个object。具体做法就是看当前预测的box与ground truth box中哪个IoU大,就负责哪个。这种做法称作box predictor的specialization。
这个损失函数中:
其他细节,例如使用激活函数使用leak RELU,模型用ImageNet预训练等等。
与ReLU函数不同的是在负值部分采用一个较小的斜率,而非直接等于0
注意:
简单的概括就是:
优缺点:
论文地址:https://arxiv.org/abs/1612.08242
官方代码:http://pjreddie.com/darknet/yolo/
YOLOv2相对v1版本,在继续保持处理速度的基础上,从预测更准确(Better),速度更快(Faster),识别对象更多(Stronger)这三个方面进行了改进。其中识别更多对象也就是扩展到能够检测9000种不同对象,称之为YOLO9000。
文章提出了一种新的训练方法–联合训练算法,这种算法可以把这两种的数据集混合到一起。使用一种分层的观点对物体进行分类,用巨量的分类数据集数据来扩充检测数据集,从而把两种不同的数据集混合起来。
联合训练算法的基本思路就是: 同时在检测数据集和分类数据集上训练物体检测器(Object Detectors ),用检测数据集的数据学习物体的准确位置,用分类数据集的数据来增加分类的类别量、提升健壮性。
YOLO9000就是使用联合训练算法训练出来的,他拥有9000类的分类信息,这些分类信息学习自ImageNet分类数据集,而物体位置检测则学习自COCO检测数据集。
YOLOv1有很多缺点,作者希望改进的方向是:改善recall,提升定位的准确度,同时保持分类的准确度。目前计算机视觉的趋势是更大更深的网络,更好的性能表现通常依赖于训练更大的网络或者把多种model综合到一起,但是YOLOv2则着力于简化网络。具体的改进见下表:
批量归一化有助于解决反向传播过程中的梯度消失和梯度爆炸问题,降低对一些超参数(比如学习率、网络参数的大小范围、激活函数的选择)的敏感性,并且每个batch分别进行归一化的时候,起到了一定的正则化效果(YOLOv2不再使用dropout),从而能够获得更好的收敛速度和收敛效果。
使用Batch Normalization对网络进行优化,让网络提高了收敛性,同时还消除了对其他形式的正则化(regularization)的依赖。通过对YOLOv2的每一个卷积层增加Batch Normalization,最终使得mAP提高了2%,同时还使model正则化。使用Batch Normalization可以从model中去掉Dropout,而不会产生过拟合。
通常,一次训练会输入一批样本(batch)进入神经网络。批规一化在神经网络的每一层,在网络(线性变换)输出后和激活函数(非线性变换)之前增加一个批归一化层(BN),BN层进行如下变换:
用于图像分类的训练样本很多,而标注了边框的用于训练目标检测的样本相比而言就少了很多,因为标注边框的人工成本比较高。所以目标检测模型通常都先用图像分类样本训练卷积层,提取图像特征,但这引出另一个问题,就是图像分类样本的分辨率不是很高。所以YOLOv1使用ImageNet的图像分类样本采用 224*224
作为输入,来训练CNN卷积层。然后在训练目标检测时,检测用的图像样本采用更高分辨率的 448*448
像素图像作为输入,但这样不一致的输入分辨率肯定会对模型性能有一定影响。
所以YOLOv2在采用 224*224
图像进行分类模型预训练后,再采用448*448
高分辨率样本对分类模型进行微调(10个epoch),使网络特征逐渐适应 448*448
的分辨率。然后再使用 448*448
的检测样本进行训练,缓解了分辨率突然切换造成的影响,最终通过使用高分辨率,mAP提升了4%。
YOLOv1包含有全连接层,从而能直接预测Bounding Boxes的坐标值。Faster R-CNN算法只用卷积层与Region Proposal Network来预测Anchor Box的偏移值与置信度,而不是直接预测坐标值,YOLOv2作者发现通过预测偏移量而不是坐标值能够简化问题,让神经网络学习起来更容易。
借鉴Faster RCNN的做法,YOLOv2也尝试采用先验框(anchor)。在每个grid预先设定一组不同大小和宽高比的边框,来覆盖整个图像的不同位置和多种尺度,这些先验框作为预定义的候选区在神经网络中将检测其中是否存在对象,以及微调边框的位置。
之前YOLOv1并没有采用先验框,并且每个grid只预测两个bounding box,也就是整个图像只有98个bounding box。YOLOv2如果每个grid采用9个先验框,总共有13*13*9=1521
个先验框。所以最终YOLOv2去掉了全连接层,使用Anchor Boxes来预测 Bounding Boxes。作者去掉了网络中一个Pooling层,这让卷积层的输出能有更高的分辨率,同时对网络结构进行收缩让其运行在416*416
而不是448*448
。
由于图片中的物体都倾向于出现在图片的中心位置,特别是那种比较大的物体,所以有一个单独位于物体中心的位置用于预测这些物体。YOLOv2的卷积层采用32这个值来下采样图片,所以通过选择416*416
用作输入尺寸最终能输出一个13*13
的Feature Map。使用Anchor Box会让精确度稍微下降,但用了它能让YOLOv2能预测出大于一千个框,同时recall达到88%,mAP达到69.2%。
召回率升高,mAP轻微下降的原因是: 因为YOLOV2不使用anchor boxes时,每个图像仅预测98个边界框。但是使用anchor boxes,YOLOV2模型预测了一千多个框,由于存在很多无用的框,这就导致了mAP值的下降。但是由于预测的框多了,所以能够预测出来的属于ground truth的框就多了,所以召回率就增加了。目标检测不是只以mAP为指标的,有些应用场景下要求召回率高。
之前Anchor Box的尺寸是手动选择的,所以尺寸还有优化的余地。YOLOv2尝试统计出更符合样本中对象尺寸的先验框,这样就可以减少网络微调先验框到实际位置的难度。YOLOv2的做法是对训练集中标注的边框进行K-means聚类分析,以寻找尽可能匹配样本的边框尺寸。如果我们用标准的欧式距离的k-means,尺寸大的框比小框产生更多的错误。因为我们的目的是提高IOU分数,这依赖于Box的大小,所以距离度量的使用:
其中,centroid是聚类时被选作中心的边框,box就是其它边框,d就是两者间的“距离”,IOU越大,“距离”越近。YOLOv2给出的聚类分析结果如下图所示,通过分析实验结果(Figure 2),在model复杂性与high recall之间权衡之后,选择聚类分类数K=5。
通过kmeans聚类的方法所获得的先验框显然会更适合于所使用的数据集,但这也会带来一个问题:
用Anchor Box的方法,会让model变得不稳定,尤其是在最开始几次迭代的时候。大多数不稳定因素产生自预测Box的(x,y)位置的时候。按照之前YOLOv1的方法,网络不会预测偏移量,而是根据YOLOv1中的网格单元的位置来直接预测坐标,这就让Ground Truth的值介于0到1之间。而为了让网络的结果能落在这一范围内,网络使用一个 Logistic Activation来对于网络预测结果进行限制,让结果介于0到1之间。 网络在每一个网格单元中预测出5个Bounding Boxes,每个Bounding Boxes有五个坐标值tx,ty,tw,th,t0,他们的关系见下图。假设一个网格单元对于图片左上角的偏移量是cx,cy,Bounding Boxes Prior的宽度和高度是pw,ph,那么预测的结果见下图右面的公式:
目标检测面临的一个问题是图像中的需要检测的目标会有大有小,输入图像经过多层网络提取特征,最后输出的特征图中(比如YOLOv2中输入416*416
经过卷积网络下采样最后输出是13*13
),较小的对象可能特征已经不明显甚至被忽略掉了。为了更好的检测出一些比较小的对象,最后输出的特征图需要保留一些更细节的信息。于是YOLOv2引入一种称为passthrough层
的方法在特征图中保留一些细节信息。具体来说,就是在最后一个pooling之前,特征图的大小是26*26*512
,将其1拆4,直接传递(passthrough)到pooling后(并且又经过一组卷积)的特征图,两者叠加到一起作为输出的特征图。
具体怎样将1个特征图拆成4个特征图,见下图,图中示例的是1个44拆成4个22,因为深度不变,所以没有画出来。
另外,根据YOLO2的代码,特征图先用11卷积从 2626512 降维到 2626*64,再做1拆4并passthrough。
作者希望YOLOv2能健壮的运行于不同尺寸的图片之上,所以把这一想法用于训练model中。
区别于之前的补全图片的尺寸的方法,YOLOv2每迭代几次都会改变网络参数。每10个Batch,网络会随机地选择一个新的图片尺寸,由于使用了下采样参数是32,所以不同的尺寸大小也选择为32的倍数{320,352…..608}
,最小320*320
,最大608*608
,网络会自动改变尺寸,并继续训练的过程。
这一政策让网络在不同的输入尺寸上都能达到一个很好的预测效果,同一网络能在不同分辨率上进行检测。当输入图片尺寸比较小的时候跑的比较快,输入图片尺寸比较大的时候精度高,所以你可以在YOLOv2的速度和精度上进行权衡。
因为YOLOV2调整网络结构后能够支持多种尺寸的输入图像。通常是使用416*416
的输入图像,如果用较高分辨率的输入图像,比如544*544
,则mAP可以达到78.6%,有1.8%的提升。
YOLOv1的backbone使用的是GoogleLeNet
,速度比VGG-16快,YOLOv1完成一次前向过程只用8.52 billion 运算,而VGG-16要30.69billion,但是YOLOv1精度稍低于VGG-16。
https://zhuanlan.zhihu.com/p/432343631
YOLOv2基于一个新的分类model,有点类似与VGG。YOLOv2使用3*3filter
,每次Pooling之后都增加一倍Channels的数量。YOLOv2使用全局平均池化(Global Average Pooling)
,使用Batch Normilazation
来让训练更稳定,加速收敛,使model规范化。最终的model–Darknet19
,有19个卷积层和5个maxpooling层,处理一张图片只需要5.58 billion次运算,在ImageNet上达到72.9%top-1精确度,91.2%top-5精确度。
网络训练在 ImageNet 1000类分类数据集上训练了160epochs,使用随机梯度下降,初始学习率为0.1, polynomial rate decay with a power of 4, weight decay of 0.0005 and momentum of 0.9 。
训练期间使用标准的数据扩大方法:随机裁剪、旋转、变换颜色(hue)、变换饱和度(saturation), 变换曝光度(exposure shifts)。
在训练时,把整个网络在更大的448*448
分辨率上Fine Turnning 10个 epoches
,初始学习率设置为0.001
,这种网络达到达到76.5%top-1精确度,93.3%top-5精确度。
网络去掉了最后一个卷积层,而加上了三个3*3卷积层,每个卷积层有1024个Filters,每个卷积层紧接着一个1*1
卷积层。
对于VOC数据,网络对每个网格单元预测五个Bounding Boxes,每个Bounding Boxes预测5个坐标和20类,所以一共125个Filters,增加了Passthough层来获取前面层的细粒度信息,网络训练了160epoches,初始学习率0.001,数据扩大方法相同,对COCO与VOC数据集的训练对策相同。
作者提出了一种在分类数据集和检测数据集上联合训练的机制。使用检测数据集的图片去学习检测相关的信息,例如bounding boxes 坐标预测,是否包含物体以及属于各个物体的概率。使用仅有类别标签的分类数据集图片去扩展可以检测的种类。
作者通过ImageNet训练分类、COCO和VOC数据集来训练检测,这是一个很有价值的思路,可以让我们达到比较优秀的效果。通过将两个数据集混合训练,如果遇到来自分类集的图片则只计算分类的Loss,遇到来自检测集的图片则计算完整的Loss。
但是ImageNet对应分类有9000种,而COCO则只提供80种目标检测,作者使用multi-label模型,即假定一张图片可以有多个label,并且不要求label间独立。通过作者Paper里的图来说明,由于ImageNet的类别是从WordNet选取的,作者采用以下策略重建了一个树形结构(称为分层树):
这个分层树我们称之为 WordTree
,作用就在于将两种数据集按照层级进行结合。比如在coco数据集有一个类别是airplane,在ImgNet数据集下有biplane、jet、airbus等多种飞机类型,这样就将airplane作为一个父节点,然后biplane这些作为airplane的子节点。在进行计算时,p(jet)=p(jet|airplane)*p(airplane)
分类时的概率计算借用了决策树思想,某个节点的概率值等于该节点到根节点的所有条件概率之积。最终结果是一颗 WordTree (视觉名词组成的层次结构模型)。用WordTree执行分类时,预测每个节点的条件概率。如果想求得特定节点的绝对概率,只需要沿着路径做连续乘积。例如,如果想知道一张图片是不是“Norfolk terrier ”需要计算:
另外,为了验证这种方法作者在WordTree(用1000类别的ImageNet创建)上训练了Darknet-19模型。为了创建WordTree1k,作者天添加了很多中间节点,把标签由1000扩展到1369。训练过程中ground truth标签要顺着向根节点的路径传播。例如,如果一张图片被标记为“Norfolk terrier”,它也被标记为“dog” 和“animal”等。为了计算条件概率,模型预测了一个包含1369个元素的向量,而且基于所有“同义词集”
计算softmax
,其中“同义词集”是同一概念的下位词。
softmax操作也同时应该采用分组操作,下图上半部分为ImageNet对应的原生Softmax,下半部分对应基于WordTree的Softmax
通过上述方案构造WordTree,得到对应9418个分类,通过重采样保证Imagenet和COCO的样本数据比例为4:1。
在上一章的最后,我们提到不论是YOLOv1,还是YOLOv2,都有一个共同的致命缺陷:只使用了最后一个经过32倍降采样的特征图(简称C5特征图)。尽管YOLOv2使用了passthrough技术将16倍降采样的特征图(即C4特征图)融合到了C5特征图中,但最终的检测仍是在C5尺度的特征图上进行的,最终结果便是导致了模型的小目标的检测性能较差。
为了解决这一问题,YOLO作者做了第三次改进,主要如下:
YOLOv3的第一处改进便是换上了更好的backbone网络:DarkNet53。相较于YOLOv2中所使用的DarkNet19,新的网络使用了更多的卷积——53层卷积
,同时,添加了残差网络中的残差连结结构,以提升网络的性能。DarkNet53的具体结构如图2所示,注意,DarkNet53网络中的降采样操作没有使用Maxpooling层,而是由stride=2的卷积来实现。卷积层仍旧是线性卷积、BN层以及LeakyReLU激活函数的串联组合。
YOLOv3的关键改进便是使用了FPN结构与多级检测方法。YOLOv3在3个尺度上去进行预测,分别是经过8倍降采样的特征图C3、经过16倍降采样的特征图C4和经过32倍降采样的特征图C5。
随着网络深度的加深,降采样操作的增多,细节信息不断被破坏,致使小物体的检测效果逐渐变差,而大目标由于像素较多,仅靠网络的前几层还不足以使得网络能够认识到大物体(感受野不充分),但随着层数变多,网络的感受野逐渐增大,网络对大目标的认识越来越充分,检测效果自然会更好。于是,一个很简单的解决方案便应运而生:**浅层网络负责检测较小的目标,深层网络负责检测较大的目标。**考虑识别物体的类别依赖于语义信息,因此将深层网络的语义信息融合到浅层网络中去是个很自然的想法。
FPN工作的出发点便是如此,提出了一个行之有效的网络结构,如图4所示。其基本思想便是对深层网络输出的特征图使用上采样操作,然后与浅层网络进行融合,使得来自于不同尺度的细节信息和语义信息得到了有效的融合。
所谓的多尺度就是来自这3条预测之路,y1,y2和y3的深度都是255,边长的规律是13:26:52
。YOLOv3设定的是每个网格单元预测3个box,所以每个box需要有(x, y, w, h, confidence)
五个基本参数,然后还要有80个类别的概率。所以3×(5 + 80) = 255
,这个255就是这么来的。
网络中作者进行了三次检测,分别是在32倍降采样,16倍降采样,8倍降采样时进行检测,这样在多尺度的feature map上检测跟SSD有点像。在网络中使用up-sample(上采样)的原因:网络越深的特征表达效果越好,比如在进行16倍降采样检测,如果直接使用第四次下采样的特征来检测,这样就使用了浅层特征,这样效果一般并不好。如果想使用32倍降采样后的特征,但深层特征的大小,因此YOLOv3使用了步长为2的up-sample(上采样),把32倍降采样得到的feature map的大小提升一倍,也就成了16倍降采样后的维度。同理8倍采样也是对16倍降采样的特征进行步长为2的上采样,这样就可以使用深层特征进行detection。
作者通过上采样将深层特征提取,其维度是与将要融合的特征层维度相同的(channel不同)。如下图所示,85层将13×13×256
的特征上采样得到26×26×256
,再将其与61层的特征拼接起来得到26×26×768
。为了得到channel255,还需要进行一系列的3×3
,1×1
卷积操作,这样既可以提高非线性程度增加泛化性能提高网络精度,又能减少参数提高实时性。52×52×255
的特征也是类似的过程。
YOLOv3的Bounding Box由YOLOv2又做出了更好的改进。在YOLOv2和YOLOv3中,都采用了对图像中的object采用k-means聚类。feature map中的每一个cell都会预测3个边界框(bounding box) ,每个bounding box都会预测三个东西:
三次检测,每次对应的感受野不同,
416×416
时,每个cell的三个anchor box为(116 ,90); (156 ,198); (373 ,326)
。(30,61); (62,45); (59,119)
。(10,13); (16,30); (33,23)
。所以当输入为416×416时,实际总共有(52×52+26×26+13×13)×3=10647
个proposal box。
YOLO v3中主要包含三种损失,即坐标的损失,置信度的损失、分类的损失。
为了实现多标签分类,模型不再使用softmax函数作为最终的分类器,而是使用logistic作为分类器,使用 binary cross-entropy作为损失函数(使用sigmoid计算的xy, 物体置信度、类别置信度中均使用了交叉熵)
YOLOv3不使用Softmax对每个框进行分类,主要考虑因素有两个:
Yolov4中使用的Mosaic是参考2019年底提出的CutMix数据增强的方式,但CutMix只使用了两张图片进行拼接,而Mosaic数据增强则采用了4张图片,随机缩放、随机裁剪、随机排布的方式进行拼接。
BN就是仅仅利用当前迭代时刻信息进行norm,而CBN在计算当前时刻统计量时候会考虑前k个时刻统计量,从而实现扩大batch size操作。同时作者指出CBN操作不会引入比较大的内存开销,训练速度不会影响很多,但是训练时候会慢一些,比GN还慢。
CmBN是CBN的改进版本,其把大batch内部的4个mini batch当做一个整体,对外隔离。CBN在第t时刻,也会考虑前3个时刻的统计量进行汇合,而CmBN操作不会,不再滑动cross,其仅仅在mini batch内部进行汇合操作,保持BN一个batch更新一次可训练参数。
SAT为一种新型数据增强方式。在第一阶段,神经网络改变原始图像而不是网络权值。通过这种方式,神经网络对其自身进行一种对抗式的攻击,改变原始图像,制造图像上没有目标的假象。在第二阶段,训练神经网络对修改后的图像进行正常的目标检测。
Self-Adversarial Training是在一定程度上抵抗对抗攻击的数据增强技术。CNN计算出Loss, 然后通过反向传播改变图片信息,形成图片上没有目标的假象,然后对修改后的图像进行正常的目标检测。需要注意的是在SAT的反向传播的过程中,是不需要改变网络权值的。 使用对抗生成可以改善学习的决策边界中的薄弱环节,提高模型的鲁棒性。因此这种数据增强方式被越来越多的对象检测框架运用。
每个CSP模块前面的卷积核的大小都是3*3
,stride=2
,因此可以起到下采样的作用。
因为Backbone有5个CSP模块,输入图像是608*608
,所以特征图变化的规律是:608->304->152->76->38->19
,经过5次CSP模块后得到19*19大小的特征图。
而且作者只在Backbone中采用了Mish激活函数,网络后面仍然采用Leaky_relu激活函数。
*我们再看看下作者为啥要参考2019年的CSPNet,采用CSP模块?
*
CSPNet全称是Cross Stage Paritial Network,主要从网络结构设计的角度解决推理中从计算量很大的问题。
CSPNet的作者认为推理计算过高的问题是由于网络优化中的梯度信息重复导致的。
因此采用CSP模块先将基础层的特征映射划分为两部分,然后通过跨阶段层次结构将它们合并,在减少了计算量的同时可以保证准确率。
因此Yolov4在主干网络Backbone采用CSPDarknet53网络结构,主要有三个方面的优点:
通常YOLO模型中,80个分类标签都是使用0或1进行描述,在训练过程中,如果认为属于第n个分类,则该位置输出1(这种分类标签编码形式也称为one hot编码,即一位(独热)编码)。在数据集为无穷的情况下,可以对所有分类进行训练和标记,但是数据集不可能是无穷,尤其是当数据集量并不太大的时候,训练次数过多,很容易造成过拟合。采用Label Smoothing的技巧可以将标签的确定性减弱,从而降低过拟合的可能性。
https://blog.csdn.net/qq_41736617/article/details/115338124
目标检测网络在BackBone和最后的输出层之间往往会插入一些层,比如SPP模块、FPN+PAN模块,用来融合不同尺寸特征图的特征信息。
V3中为了更好的满足不同输入的大小,训练时要改变输入数据的大小。SPP其实就是对任意尺寸的特征图通过最大池化来满足最终输入特征一致。
常见的池化核有(1,1)(5,5)(9,9)(13,13)
如上图,以3个尺寸的池化为例,对特征图进行一个最大值池化,即一张特征图得取其最大值,得到1*d(d是特征图的维度)
个特征;对特征图进行网格划分为2x2
的网格,然后对每个网格进行最大值池化,那么得到4*d
个特征;同样,对特征图进行网格划分为4x4
个网格,对每个网格进行最大值池化,得到16*d
个特征。 接着将每个池化得到的特征合起来即得到固定长度的特征个数(特征图的维度是固定的),接着就可以输入到全连接层中进行训练网络了。用到这里是为了增加感受野。
原文链接:https://blog.csdn.net/x454045816/article/details/109759989
YOLOv4的第二处改进便是采用了PAN(Path Aggregation Network)结构。原先的YOLOv3仅使用了top-down(上采样)结构的FPN,而PAN是在此基础上加了bottom-up(下采样)的结构。
由下图可以看到,主要用到两次PAN,第一次是在76*76
那层,有一个指向下面的箭头,该箭头为一次下采样,同样的在38*38
那一层也进行了一次PAN。
FPN和PAN都是通过融合不同尺度的特征,提高模型对不同尺寸目标的检测能力。
考虑到了detect与gt之间的重叠面积、中心点距离和长宽比
L=1-重叠面积+中心点距离+长宽比
DIoU(前面讨论过的) 被用作非最大值抑制(NMS)的一个因素。该方法在抑制冗余框的同时,采用IoU和两个边界盒中心点之间的距离。这使得它在有遮挡的情况下更加健壮。
Yolov5s网络是Yolov5系列中深度最小,特征图的宽度最小的网络。后面的3种都是在此基础上不断加深,不断加宽。模型文件只有24M
在Yolov3、Yolov4中,训练不同的数据集时,计算初始锚框的值是通过单独的程序运行的。
但Yolov5中将此功能嵌入到代码中,每次训练时,自适应的计算不同训练集中的最佳锚框值。
缩放时由原来的固定尺寸变为以添加最少黑边为原则。
定位部分的损失函数使用了GIOU函数
意思将两个任意框A,B,我们找到一个最小的封闭形状C,让C可以把A,B包含在内,接着计算C中没有覆盖A和B的面积占C总面积的比值,然后用A与B的IoU减去这个比值
内部协变量偏移问题(Internal Covariate Shift,ICS)
随着训练的进行,网络中的参数也随着梯度下降在不停更新。一方面,当底层网络中参数发生微弱变化时,由于每一层中的线性变换(网络训练)与非线性激活映射(激活函数),这些微弱变化随着网络层数的加深而被放大(类似蝴蝶效应);另一方面,参数的变化导致每一层的输入分布会发生改变,进而上层的网络需要不停地去适应这些分布变化,使得我们的模型训练变得困难。
Batch Normalization的原论文作者给了Internal Covariate Shift一个较规范的定义:在深层网络训练的过程中,由于网络中参数变化而引起内部结点数据分布发生变化的这一过程被称作Internal Covariate Shift。
https://www.zhihu.com/question/38102762/answer/607815171
Batch Normalization原理
通常,一次训练会输入一批样本(batch)进入神经网络。批规一化在神经网络的每一层,在网络(线性变换)输出后和激活函数(非线性变换)之前增加一个批归一化层(BN),BN层进行如下变换:
①对该批样本的各特征量(对于中间层来说,就是每一个神经元)分别进行归一化处理,分别使每个特征的数据分布变换为均值0,方差1。从而使得每一批训练样本在每一层都有类似的分布。这一变换不需要引入额外的参数。
②对上一步的输出再做一次线性变换,假设上一步的输出为Z,则 Z1=γZ + β
。这里γ、β
是可以训练的参数。增加这一变换是因为上一步骤中强制改变了特征数据的分布,可能影响了原有数据的信息表达能力。增加的线性变换使其有机会恢复其原本的信息。
https://zhuanlan.zhihu.com/p/362759621
总结:
深度学习网络在训练时,最终是求得让损失函数达到收敛的一组权重参数,这就需要进行迭代。假设这个网络共有三层,在计算得到一次训练的误差之后,为了更新网络第一层参数,需要使用这个误差对第一层权重求偏导,根据链式法则,误差需要先对第三层求偏导然后对第二层求偏导然后对第一层求偏导
(1) 梯度消失(gradient vanishing problem)
我们知道神经网络在进行反向传播(BP)的时候会对参数W进行更新,梯度消失就是靠后面网络层(如layer3)能够正常的得到一个合理的偏导数,但是靠近输入层的网络层,计算的到的偏导数近乎零,W几乎无法得到更新。
(2)梯度爆炸(gradient exploding problem)
梯度爆炸的意思是,靠近输入层的网络层,计算的到的偏导数极其大,更新后W变成一个很大的数(爆炸)。
https://www.jianshu.com/p/3f35e555d5ba
https://blog.csdn.net/qq_40765537/article/details/106063941
FPN的最早是在2017年的CVPR会议上提出的,其创新点在于提出了一种自底向上(bottom-up)的结构,融合多个不同尺度的特征图去进行目标预测。FPN工作认为网络浅层的特征图包含更多的细节信息,但语义信息较少,而深层的特征图则恰恰相反。原因之一便是卷积神经网络的降采样操作,降采样对小目标的损害显著大于大目标,直观的理解便是小目标的像素少于大目标,也就越难以经得住降采样操作的取舍,而大目标具有更多的像素,也就更容易引起网络的“关注”,在YOLOv1+和YOLOv2+的工作中我们也发现了,相较于小目标,大目标的检测结果要好很多。
随着网络深度的加深,降采样操作的增多,细节信息不断被破坏,致使小物体的检测效果逐渐变差,而大目标由于像素较多,仅靠网络的前几层还不足以使得网络能够认识到大物体(感受野不充分),但随着层数变多,网络的感受野逐渐增大,网络对大目标的认识越来越充分,检测效果自然会更好。于是,一个很简单的解决方案便应运而生:浅层网络负责检测较小的目标,深层网络负责检测较大的目标。考虑识别物体的类别依赖于语义信息,因此将深层网络的语义信息融合到浅层网络中去是个很自然的想法。
FPN工作的出发点便是如此,提出了一个行之有效的网络结构,如图4所示。其基本思想便是对深层网络输出的特征图使用上采样操作,然后与浅层网络进行融合,使得来自于不同尺度的细节信息和语义信息得到了有效的融合。
从网格的角度来看,越浅层的网格,划分出的网格也越精细,以416的输入尺寸为例,经过8倍降采样得到的特征图C3相当于是一个 的网格,这要比经过32倍降采样得到的特征图C5所划分的 的网格精细得多,也就更容易去检测小物体。同时,更加精细的网格,也就更能避免先前所提到的“语义歧义”的问题。
既然,FPN将不同尺度的特征图的信息进行了一次融合,那么一个很自然的方法也就应运而生:多级检测(multi-level detection)。最早,多级检测方法可以追溯到SSD网络,SSD正是使用不同大小的特征图来检测不同尺度的目标,这一方法的思想内核便是“分而治之”,即不同尺度的物体由不同尺度的特征图去做检测,而不是像YOLOv2那样,都堆在最后的C5特征图上去做检测。而FPN正是在这个基础上,让不同尺度的特征图先融合一遍,再去做检测。FPN的这一强大特性,使得它称为了“分而治之”检测方法的重要模块。也为后续许多的特征融合工作带去了启发,如PAN和BiFPN。
这里强调一下,“分而治之”方法的内核不是FPN,而是多级检测。FPN不过是锦上添花,即使我们不做特征融合,依旧可以做多级检测,如SSD。只是,使用特征融合手段,可以让检测的效果更好罢了。
多说一句,既然有“分而治之”,便也应有“合而治之”,所谓“合而治之”,是指所有物体我们都在一个特征图上去检测,换言之,就是“单级检测”(single-level detection),比如早期的YOLOv1和YOLOv2,便是最为经典的单级检测工作。只不过,主流普遍认为这种只在C5特征图上去单级检测的检测器,小目标检测效果是不行的,尽管这一点被ECCV2020的DeTR和CVPR2021的YOLOF工作否决了,却依旧难以扭转这一根深蒂固的观念,前者似乎只被关注了Transformer这一点上,而后者似乎被认为是“开历史倒车”。无数的历史已证明,根深蒂固的观念是很难被改变,而一旦被改变的那一天,便是一场旧事物的大毁灭与新事物的大喷发……
不过,还有一类单级检测工作则另辟蹊径,借鉴人体关键点检测工作的思想,使用高分辨率的特征图如只经过4倍降采样得到的特征图C2来检测物体,典型的工作包括CornerNet和脍炙人口的CenterNet。以512的输入尺寸为例,只经过4倍降采样得到的特征图C2相当于是一个128×128的网格,要比C5的16×16精细的多,然后再将所有尺度的信息都融合到这一张特征图来,使得这样一张具有精细的网格的特征图既具备足够的细节信息,又具备足够的语义信息。不难想象,这样的网络只需要一张特征图便可以去检测所有的物体。这一类工作具有典型的encoder和decoder的结构,通常encoder由常用的ResNet组成,decoder由简单的FPN结构或者反卷积组成,当然,也可以使用Hourglass网络。这一类的单级检测很轻松的得到了研究学者们的认可,毕竟,相较于在粗糙的C5上做检测,直观上便很认同分辨率高得多的C2特征图检测方式。只不过,C2特征图的尺寸太大,会带来很大的计算量,但是,这类工作不需要诸如800×1333的输入尺寸,仅仅512×512的尺寸便可以达到与之相当的性能