目标检测算法(R-CNN,fast R-CNN,faster R-CNN,yolo,SSD,yoloV2,yoloV3,yoloV4,yoloV5,yoloV6,yoloV7)
1.引言
深度学习目前已经应用到了各个领域,应用场景大体分为三类:物体识别,目标检测,自然语言处理。 目标检测可以理解为是物体识别和物体定位的综合,不仅仅要识别出物体属于哪个分类,更重要的是得到物体在图片中的具体位置。
为了完成这两个任务,目标检测模型分为两类。一类是two-stage,将物体识别和物体定位分为两个步骤,分别完成,这一类的典型代表是R-CNN, fast R-CNN, faster-RCNN家族。他们识别错误率低,漏识别率也较低,但速度较慢,不能满足实时检测场景。为了解决这一问题,另一类方式出现了,称为one-stage, 典型代表是Yolo, SSD, YoloV2等。他们识别速度很快,可以达到实时性要求,而且准确率也基本能达到faster R-CNN的水平。下面针对这几种模型进行详细的分析。
2 R-CNN
2014年R-CNN算法被提出,基本奠定了two-stage方式在目标检测领域的应用。它的算法结构如下图:
算法步骤如下:
1,获取输入的原始图片。
2,使用选择性搜索算法(selective search)评估相邻图像之间的相似度,把相似度高的进行合并,并对合并后的区块打分,选出感兴趣区域的候选框,也就是子图。这一步大约需要选出2000个子图。
3,分别对子图使用卷积神经网络,进行卷积-relu-池化以及全连接等步骤,提取特征。这一步基本就是物体识别的范畴了。
4,对提取的特征进行物体分类,保留分类准确率高的区块,以作为最终的物体定位区块。
R-CNN较传统的目标检测算法获得了50%的性能提升,在使用VGG-16模型作为物体识别模型情况下,在voc2007数据集上可以取得66%的准确率,已经算还不错的一个成绩了。其最大的问题是速度很慢,内存占用量很大,主要原因有两个
1,候选框由传统的selective search算法完成,速度比较慢,。
2,对2000个候选框,均需要做物体识别,也就是需要做2000次卷积网络计算。这个运算量是十分巨大的
3 Fast R-CNN
针对R-CNN的部分问题,2015年微软提出了Fast R-CNN算法,它主要优化了两个问题。
1,提出ROI pooling池化层结构,解决了候选框子图必须将图像裁剪缩放到相同尺寸大小的问题。 由于CNN网络的输入图像尺寸必须是固定的某一个大小(否则全连接时没法计算),故R-CNN中对大小形状不同的候选框,进行了裁剪和缩放,使得他们达到相同的尺寸。这个操作既浪费时间,又容易导致图像信息丢失和形变。fast R-CNN在全连接层之前插入了ROI pooling层,从而不需要对图像进行裁剪,很好的解决了这个问题。 ROI pooling的思路是,如果最终我们要生成MxN的图片,那么先将特征图水平和竖直分为M和N份,然后每一份取最大值,输出MxN的特征图。这样就实现了固定尺寸的图片输出了。ROI pooling层位于卷积后,全连接前。
2,提出多任务损失函数思想,将分类损失和边框定位回归损失结合在一起统一训练,最终输出对应分类和边框坐标。
4.Faster R-CNN
R-CNN和fast R-CNN均存在一个问题,那就是由选择性搜索来生成候选框,这个算法很慢。而且R-CNN中生成的2000个左右的候选框全部需要经过一次卷积神经网络,也就是需要经过2000次左右的CNN网络,这个是十分耗时的(fast R-CNN已经做了改进,只需要对整图经过一次CNN网络)。这也是导致这两个算法检测速度较慢的最主要原因。
faster R-CNN 针对这个问题,提出了RPN网络来进行候选框的获取,从而摆脱了选择性搜索算法,也只需要一次卷积层操作,从而大大提高了识别速度。这个算法十分复杂,我们会详细分析。它的基本结构如下图
主要分为四个步骤:
卷积层。原始图片先经过conv-relu-pooling的多层卷积神经网络,提取出特征图。供后续的RPN网络和全连接层使用。faster
R-CNN不像R-CNN需要对每个子图进行卷积层特征提取,它只需要对全图进行一次提取就可以了,从而大大减小了计算时间。RPN层,region proposal networks。RPN层用于生成候选框,并利用softmax判断候选框是前景还是背景,从中选取前景候选框(因为物体一般在前景中),并利用bounding box regression调整候选框的位置,从而得到特征子图,称为proposals。
ROI层,fast R-CNN中已经讲过了ROI层了,它将大小尺寸不同的proposal池化成相同的大小,然后送入后续的全连接层进行物体分类和位置调整回归
分类层。利用ROI层输出的特征图proposal,判断proposal的类别,同时再次对bounding box进行regression从而得到精确的形状和位置。
使用VGG-16卷积模型的网络结构:
4.1卷积层
卷积层采用的VGG-16模型,先将PxQ的原始图片,缩放裁剪为MxN的图片,然后经过13个conv-relu层,其中会穿插4个max-pooling层。所有的卷积的kernel都是3x3
的,padding为1,stride为1。pooling层kernel为2x2, padding为0,stride为2。
MxN的图片,经过卷积层后,变为了(M/16) x (N/16)
的feature map了。
4.2 RPN层
faster R-CNN抛弃了R-CNN中的选择性搜索(selective search)方法,使用RPN层来生成候选框,能极大的提升候选框的生成速度。RPN层先经过3x3的卷积运算,然后分为两路。一路用来判断候选框是前景还是背景,它先reshape成一维向量,然后softmax来判断是前景还是背景,然后reshape恢复为二维feature map。另一路用来确定候选框的位置,通过bounding box regression实现,后面再详细讲。两路计算结束后,挑选出前景候选框(因为物体在前景中),并利用计算得到的候选框位置,得到我们感兴趣的特征子图proposal。
4.2.1 候选框的生成 anchors
卷积层提取原始图像信息,得到了256个feature map,经过RPN层的3x3卷积后,仍然为256个feature map。但是每个点融合了周围3x3的空间信息。对每个feature map上的一个点,生成k个anchor(k默认为9)。anchor分为前景和背景两类(我们先不去管它具体是飞机还是汽车,只用区分它是前景还是背景即可)。anchor有[x,y,w,h]四个坐标偏移量,x,y表示中心点坐标,w和h表示宽度和高度。这样,对于feature map上的每个点,就得到了k个大小形状各不相同的选区region。
4.2.2 softmax判断选区是前景还是背景
对于生成的anchors,我们首先要判断它是前景还是背景。由于感兴趣的物体位于前景中,故经过这一步之后,我们就可以舍弃背景anchors了。大部分的anchors都是属于背景,故这一步可以筛选掉很多无用的anchor,从而减少全连接层的计算量。
对于经过了3x3的卷积后得到的256个feature map,先经过1x1的卷积,变换为18个feature map。然后reshape为一维向量,经过softmax判断是前景还是背景。此处reshape的唯一作用就是让数据可以进行softmax计算。然后输出识别得到的前景anchors。
4.2.3 确定候选框位置
另一路用来确定候选框的位置,也就是anchors的[x,y,w,h]坐标值。如下图所示,红色代表我们当前的选区,绿色代表真实的选区。虽然我们当前的选取能够大概框选出飞机,但离绿色的真实位置和形状还是有很大差别,故需要对生成的anchors进行调整。这个过程我们称为bounding box regression。
假设红色框的坐标为[x,y,w,h], 绿色框,也就是目标框的坐标为[Gx, Gy,Gw,Gh], 我们要建立一个变换,使得[x,y,w,h]能够变为[Gx, Gy,Gw,Gh]。最简单的思路是,先做平移,使得中心点接近,然后进行缩放,使得w和h接近。如下:
我们要学习的就是dx dy dw dh这四个变换。由于是线性变换,我们可以用线性回归来建模。设定loss和优化方法后,就可以利用深度学习进行训练,并得到模型了。对于空间位置loss,我们一般采用均方差算法,而不是交叉熵(交叉熵使用在分类预测中)。优化方法可以采用自适应梯度下降算法Adam。
4.2.4 输出特征子图proposal
得到了前景anchors,并确定了他们的位置和形状后,我们就可以输出前景的特征子图proposal了。步骤如下:
1,得到前景anchors和他们的[x y w h]坐标。
2,按照anchors为前景的不同概率,从大到小排序,选取前pre_nms_topN个anchors,比如前6000个
3,剔除非常小的anchors。
4,通过NMS非极大值抑制,从anchors中找出置信度较高的。这个主要是为了解决选取交叠问题。首先计算每一个选区面积,然后根据他们在softmax中的score(也就是是否为前景的概率)进行排序,将score最大的选区放入队列中。接下来,计算其余选区与当前最大score选区的IOU(IOU为两box交集面积除以两box并集面积,它衡量了两个box之间重叠程度)。去除IOU大于设定阈值的选区。这样就解决了选区重叠问题。
5,选取前post_nms_topN个结果作为最终选区proposal进行输出,比如300个。
经过这一步之后,物体定位应该就基本结束了,剩下的就是物体识别了。
4.3 ROI Pooling层
和fast R-CNN中类似,这一层主要解决之前得到的proposal大小形状各不相同,导致没法做全连接。全连接计算只能对确定的shape进行运算,故必须使proposal大小形状变为相同。通过裁剪和缩放的手段,可以解决这个问题,但会带来信息丢失和图片形变问题。我们使用ROI pooling可以有效的解决这个问题。
ROI pooling中,如果目标输出为MxN,则在水平和竖直方向上,将输入proposal划分为MxN份,每一份取最大值,从而得到MxN的输出特征图。
4.4 分类层
ROI Pooling层后的特征图,通过全连接层与softmax,就可以计算属于哪个具体类别,比如人,狗,飞机,并可以得到cls_prob概率向量。同时再次利用bounding box regression精细调整proposal位置,得到bbox_pred,用于回归更加精确的目标检测框。
这样就完成了faster R-CNN的整个过程了。算法还是相当复杂的,对于每个细节需要反复理解。faster R-CNN使用resNet101模型作为卷积层,在voc2012数据集上可以达到83.8%的准确率,超过yolo ssd和yoloV2。其最大的问题是速度偏慢,每秒只能处理5帧,达不到实时性要求。
5 Yolo:you only look once
主要分为三个部分:卷积层,目标检测层,NMS筛选层。
5.1 卷积层
采用Google inceptionV1网络,对应到上图中的第一个阶段,共20层。这一层主要是进行特征提取,从而提高模型泛化能力。但作者对inceptionV1进行了改造,他没有使用inception module结构,而是用一个1x1的卷积,并联一个3x3的卷积来替代。(可以认为只使用了inception module中的一个分支,应该是为了简化网络结构)
5.2 目标检测层
先经过4个卷积层和2个全连接层,最后生成7x7x30的输出。先经过4个卷积层的目的是为了提高模型泛化能力。yolo将一副448x448的原图分割成了7x7个网格,每个网格要预测两个bounding box的坐标(x,y,w,h)和box内包含物体的置信度confidence,以及物体属于20类别中每一类的概率(yolo的训练数据为voc2012,它是一个20分类的数据集)。所以一个网格对应的参数为(4x2+2+20) = 30。如下图
1,bounding box坐标: 如上图,7x7网格内的每个grid(红色框),对应两个大小形状不同的bounding box(黄色框)。每个box的位置坐标为(x,y,w,h),x和y表示box中心点坐标,w和h表示box宽度和高度。通过与训练数据集上标定的物体真实坐标(Gx,Gy,Gw,Gh)进行对比训练,可以计算出初始boundingbox平移和伸缩得到最终位置的模型。
2,bounding box置信度confidence:这个置信度只是为了表达box内有无物体的概率,并不表达box内物体是什么。
其中前一项表示有无人工标记的物体落入了网格内,如果有则为1,否则为0。第二项代表bounding box和真实标记的box之间的重合度。它等于两个box面积交集,除以面积并集。值越大则box越接近真实位置。
分类信息:yolo的目标训练集为voc2012,它是一个20分类的目标检测数据集。常用目标检测数据集如下表:
| Name | # Images (trainval) | # Classes | Last updated |
| --------------- | ------------------- | --------- | ------------ |
| ImageNet | 450k | 200 | 2015 |
| COCO | 120K | 90 | 2014 |
| Pascal VOC | 12k | 20 | 2012 |
| Oxford-IIIT Pet | 7K | 37 | 2012 |
| KITTI Vision | 7K | 3 | |
每个网格还需要预测它属于20分类中每一个类别的概率。分类信息是针对每个网格的,而不是bounding box。故只需要20个,而不是40个。而confidence则是针对bounding box的,它只表示box内是否有物体,而不需要预测物体是20分类中的哪一个,故只需要2个参数。虽然分类信息和confidence都是概率,但表达含义完全不同。
5.3 NMS筛选层
筛选层是为了在多个结果中(多个bounding box)筛选出最合适的几个,这个方法和faster R-CNN 中基本相同。都是先过滤掉score低于阈值的box,对剩下的box进行NMS非极大值抑制,去除掉重叠度比较高的box(NMS具体算法可以回顾上面faster R-CNN小节)。这样就得到了最终的最合适的几个box和他们的类别。
5.4 yolo损失函数
yolo的损失函数包含三部分,位置误差,confidence误差,分类误差。具体公式如下
误差均采用了均方差算法,其实我认为,位置误差应该采用均方差算法,而分类误差应该采用交叉熵。由于物体位置只有4个参数,而类别有20个参数,他们的累加和不同。如果赋予相同的权重,显然不合理。故yolo中位置误差权重为5,类别误差权重为1。由于我们不是特别关心不包含物体的bounding box,故赋予不包含物体的box的置信度confidence误差的权重为0.5,包含物体的权重则为1。
yolo算法开创了one-stage检测的先河,它将物体分类和物体检测网络合二为一,都在全连接层完成。故它大大降低了目标检测的耗时,提高了实时性。但它的缺点也十分明显:
1,每个网格只对应两个bounding box,当物体的长宽比不常见(也就是训练数据集覆盖不到时),效果很差。
2,原始图片只划分为7x7的网格,当两个物体靠的很近时,效果很差。
3,最终每个网格只对应一个类别,容易出现漏检(物体没有被识别到)。
4,对于图片中比较小的物体,效果很差。这其实是所有目标检测算法的通病,SSD对它有些优化,我们后面再看。
6 SSD: Single Shot MultiBox Detector
Faster R-CNN准确率mAP较高,漏检率recall较低,但速度较慢。而yolo则相反,速度快,但准确率和漏检率不尽人意。SSD综合了他们的优缺点,对输入300x300的图像,在voc2007数据集上test,能够达到58 帧每秒( Titan X 的 GPU ),72.1%的mAP。
SSD网络结构如下图:
和yolo一样,也分为三部分:卷积层,目标检测层和NMS筛选层
6.1 卷积层
SSD论文采用了VGG16的基础网络,其实这也是几乎所有目标检测神经网络的惯用方法。先用一个CNN网络来提取特征,然后再进行后续的目标定位和目标分类识别。
6.2 目标检测层
这一层由5个卷积层和一个平均池化层组成。去掉了最后的全连接层。SSD认为目标检测中的物体,只与周围信息相关,它的感受野不是全局的,故没必要也不应该做全连接。SSD的特点如下。
6.2.1 多尺寸feature map上进行目标检测
每一个卷积层,都会输出不同大小感受野的feature map。在这些不同尺度的feature map上,进行目标位置和类别的训练和预测,从而达到多尺度检测的目的,可以克服yolo对于宽高比不常见的物体,识别准确率较低的问题。而yolo中,只在最后一个卷积层上做目标位置和类别的训练和预测。这是SSD相对于yolo能提高准确率的一个关键所在。
如上所示,在每个卷积层上都会进行目标检测和分类,最后由NMS进行筛选,输出最终的结果。多尺度feature map上做目标检测,就相当于多了很多宽高比例的bounding box,可以大大提高泛化能力。
6.2.2 多个anchors,每个anchor对应4个位置参数和21个类别参数
和faster R-CNN相似,SSD也提出了anchor的概念。卷积输出的feature map,每个点对应为原图的一个区域的中心点。以这个点为中心,构造出6个宽高比例不同,大小不同的anchor(SSD中称为default box)。每个anchor对应4个位置参数(x,y,w,h)和21个类别概率(voc训练集为20分类问题,在加上anchor是否为背景,共21分类)。如下图所示:
另外,在训练阶段,SSD将正负样本比例定位1:3。训练集给定了输入图像以及每个物体的真实区域(ground true box),将default box和真实box最接近的选为正样本。然后在剩下的default box中选择任意一个与真实box IOU大于0.5的,作为正样本。而其他的则作为负样本。由于绝大部分的box为负样本,会导致正负失衡,故根据每个box类别概率排序,使正负比例保持在1:3。SSD认为这个策略提高了4%的准确率
另外,SSD采用了数据增强。生成与目标物体真实box间IOU为0.1 0.3 0.5 0.7 0.9的patch,随机选取这些patch参与训练,并对他们进行随机水平翻转等操作。SSD认为这个策略提高了8.8%的准确率。
6.3 筛选层
和yolo的筛选层基本一致,同样先过滤掉类别概率低于阈值的default box,再采用NMS非极大值抑制,筛掉重叠度较高的。只不过SSD综合了各个不同feature map上的目标检测输出的default box。
SSD基本已经可以满足我们手机端上实时物体检测需求了,TensorFlow在Android上的目标检测官方模型ssd_mobilenet_v1_android_export.pb,就是通过SSD算法实现的。它的基础卷积网络采用的是mobileNet,适合在终端上部署和运行。
7 YoloV2, Yolo9000
针对yolo准确率不高,容易漏检,对长宽比不常见物体效果差等问题,结合SSD的特点,提出了yoloV2。它主要还是采用了yolo的网络结构,在其基础上做了一些优化和改进,如下
网络采用DarkNet-19:19层,里面包含了大量3x3卷积,同时借鉴inceptionV1,加入1x1卷积核全局平均池化层。结构如下
1,去掉全连接层:和SSD一样,模型中只包含卷积和平均池化层(平均池化是为了变为一维向量,做softmax分类)。这样做一方面是由于物体检测中的目标,只是图片中的一个区块,它是局部感受野,没必要做全连接。而是为了输入不同尺寸的图片,如果采用全连接,则只能输入固定大小图片了。
2,batch normalization:卷积层后加入BN,对下一次卷积输入的数据做归一化。可以在增大学习率的前提下,同样可以稳定落入局部最优解。从而加速训练收敛,在相同耗时下,增大了有效迭代次数。
3,使用anchors:借鉴faster R-CNN和SSD,对于一个中心点,使用多个anchor,得到多个bounding box,每个bounding box包含4个位置坐标参数(x y w h)和21个类别概率信息。而在yolo中,每个grid(对应anchor),仅预测一次类别,而且只有两个bounding box来进行坐标预测。
4,pass through ayer:yolo原本最终特征图为13x13x256。yoloV2还利用了之前的26x26的特征图进行目标检测。26x26x256的feature map分别按行和列隔点采样,得到4幅13x13x256的feature map,将他们组织成一幅13x13x2048的feature map。这样做的目的是提高小物体的识别率。因为越靠前的卷积,其感受野越小,越有利于小物体的识别。
5,高分辨率输入Training:yolo采用224x224图片进行预训练,而yoloV2则采用448x448
6,Multi-Scale Training:输入不同尺寸的图片,迭代10次,就改变输入图片尺寸。由于模型中去掉了全连接层,故可以输入不同尺寸的图片了。从320x320,到608x608
yolo和yoloV2只能识别20类物体,为了优化这个问题,提出了yolo9000,可以识别9000类物体。它在yoloV2基础上,进行了imageNet和coco的联合训练。这种方式充分利用imageNet可以识别1000类物体和coco可以进行目标位置检测的优点。当使用imageNet训练时,只更新物体分类相关的参数。而使用coco时,则更新全部所有参数。
8.YOLOv3
YOLOv3可以说出来直接吊打一切图像检测算法。比同期的DSSD(反卷积SSD), FPN(feature pyramid networks)准确率更高或相仿,速度是其1/3.。
YOLOv3的改动主要有如下几点:
1、增加了top down的多级预测,直接解决了YOLO对小目标很难识别的顽疾。 v2 只有一个 detection,v3 增加到了3个detection,分别是一个下采样的,feature map 为 1313,还有2 个上采样的 eltwise sum,feature map 为 2626,52*52,也就是说 v3 的 416 版本已经用到了 52 的 feature map,而 v2 把多尺度考虑到训练的 data 采样上,最后也只是用到了 13 的 feature map,这可以说在对小目标的识别上,是一个突破。论文中,一共是9个聚类中心,按照大小分给三个detection,单层只预测三种boundingbox。
2、loss不同。 v3 替换了 v2 的 softmax loss 变成 logistic loss,由于每个点所对应的 bounding
box 少并且差异大,每个 bounding 与 ground truth 的 matching 策略变成了 1 对 当目标类别很复杂的时候,通常logistic loss更有效,也方便使用多标签分类(比如一个人有Woman 和 Person两个标签)。3、加深了网络。使用简化的残差网络代替了11,33的卷积层(加了短路),基础模型也从Darknet-19变成了Darknet-53,在网络中也有一连串的11(用来压缩特征表示),33(用于增加信道)卷积。YOLOv3也不是毫无缺点,由于最根本原理的原因(每个网格固定目标数量),召回率并不很高。对于位置并没有很好优化,精准度比较差。而且模型泛化能力太强,有时候容易跑偏。当然优点更明显,简单,速度快,精度高,可以识别小物体,泛化能力强(语义识别能力)YOLO3借鉴了残差网络结构,形成更深的网络层次,以及多尺度检测,提升了mAP及小物体检测效果。如果采用COCO mAP50做评估指标(不是太介意预测框的准确性的话),YOLO3的表现相当惊人,如下图所示,在精确度相当的情况下,YOLOv3的速度是其它模型的3、4倍。
不过如果要求更精准的预测边框,采用COCO AP做评估标准的话,YOLO3在精确率上的表现就弱了一些。如下图所示。
9 YOLOV4
- 输入端:这里指的创新主要是训练时对输入端的改进,主要包括Mosaic数据增强、cmBN、SAT自对抗训练
- BackBone主干网络:将各种新的方式结合起来,包括:CSPDarknet53、Mish激活函数、Dropblock
- Neck:目标检测网络在BackBone和最后的输出层之间往往会插入一些层,比如Yolov4中的SPP模块、FPN+PAN结构
- Prediction:输出层的锚框机制和Yolov3相同,主要改进的是训练时的损失函数CIOU_Loss,以及预测框筛选的nms变为DIOU_nms
9.1 输入端改进
9.1.1 mosaic数据增强
Yolov4中使用的Mosaic是参考2019年底提出的CutMix数据增强的方式,但CutMix只使用了两张图片进行拼接,而Mosaic数据增强则采用了4张图片,随机缩放、随机裁剪、随机排布的方式进行拼接。
- 丰富数据集:随机使用4张图片,随机缩放,再随机分布进行拼接,大大丰富了检测数据集,特别是随机缩放增加了很多小目标,让网络的鲁棒性更好。
- 减少GPU:可能会有人说,随机缩放,普通的数据增强也可以做,但作者考虑到很多人可能只有一个GPU,因此Mosaic增强训练时,可以直接计算4张图片的数据,使得Mini-batch大小并不需要很大,一个GPU就可以达到比较好的效果。
9.1.2 cmBN
BN就是仅仅利用当前迭代时刻信息进行norm,而CBN在计算当前时刻统计量时候会考虑前k个时刻统计量,从而实现扩大batch size操作。同时作者指出CBN操作不会引入比较大的内存开销,训练速度不会影响很多,但是训练时候会慢一些,比GN还慢。
CmBN是CBN的改进版本,其把大batch内部的4个mini batch当做一个整体,对外隔离。CBN在第t时刻,也会考虑前3个时刻的统计量进行汇合,而CmBN操作不会,不再滑动cross,其仅仅在mini batch内部进行汇合操作,保持BN一个batch更新一次可训练参数。
9.1.2自对抗训练(SAT)
SAT为一种新型数据增强方式。在第一阶段,神经网络改变原始图像而不是网络权值。通过这种方式,神经网络对其自身进行一种对抗式的攻击,改变原始图像,制造图像上没有目标的假象。在第二阶段,训练神经网络对修改后的图像进行正常的目标检测。
**Self-Adversarial Training是在一定程度上抵抗对抗攻击的数据增强技术。**CNN计算出Loss, 然后通过反向传播改变图片信息,形成图片上没有目标的假象,然后对修改后的图像进行正常的目标检测。需要注意的是在SAT的反向传播的过程中,是不需要改变网络权值的。 使用对抗生成可以改善学习的决策边界中的薄弱环节,提高模型的鲁棒性。因此这种数据增强方式被越来越多的对象检测框架运用。
9.2 BackBone主干网络
9.2.1 CSPDarknet53
每个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网络结构,主要有三个方面的优点:
- 增强CNN的学习能力,使得在轻量化的同时保持准确性。
- 降低计算瓶颈
- 降低内存成本
9.2.2 Mish 激活函数
- Mish是一个平滑的曲线,平滑的激活函数允许更好的信息深入神经网络,从而得到更好的准确性和泛化;
- 在负值的时候并不是完全截断,允许比较小的负梯度流入。
9.2.3 DropBlock正则化
- 原始输入图像。
- 绿色部分表示激活的特征单元,b图表示了随机dropout激活单元,但是这样dropout后,网络还会从drouout掉的激活单元附近学习到同样的信息。
- 绿色部分表示激活的特征单元,c图表示本文的DropBlock,通过dropout掉一部分相邻的整片的区域(比如头和脚),网络就会去注重学习狗的别的部位的特征,来实现正确分类,从而表现出更好的泛化。
9.2.4 label smoothing标签平滑
通常YOLO模型中,80个分类标签都是使用0或1进行描述,在训练过程中,如果认为属于第n个分类,则该位置输出1(这种分类标签编码形式也称为one hot编码,即一位(独热)编码)。在数据集为无穷的情况下,可以对所有分类进行训练和标记,但是数据集不可能是无穷,尤其是当数据集量并不太大的时候,训练次数过多,很容易造成过拟合。采用Label Smoothing的技巧可以将标签的确定性减弱,从而降低过拟合的可能性。
9.3Neck部分
目标检测网络在BackBone和最后的输出层之间往往会插入一些层,比如SPP模块、FPN+PAN模块,用来融合不同尺寸特征图的特征信息。
5.3.1空间金字塔池化SPP模块
V3中为了更好的满足不同输入的大小,训练时要改变输入数据的大小。SPP其实就是对任意尺寸的特征图通过最大池化来满足最终输入特征一致。
常见的池化核有(1,1)(5,5)(9,9)(13,13)
如上图,以3个尺寸的池化为例,对特征图进行一个最大值池化,即一张特征图得取其最大值,得到1*d(d是特征图的维度)
个特征;对特征图进行网格划分为2x2
的网格,然后对每个网格进行最大值池化,那么得到4*d
个特征;同样,对特征图进行网格划分为4x4
个网格,对每个网格进行最大值池化,得到16*d
个特征。 接着将每个池化得到的特征合起来即得到固定长度的特征个数(特征图的维度是固定的),接着就可以输入到全连接层中进行训练网络了。用到这里是为了增加感受野。
9.3.2 FPN+PAN结构
YOLOv4的第二处改进便是采用了PAN(Path Aggregation Network)结构。原先的YOLOv3仅使用了top-down(上采样)结构的FPN,而PAN是在此基础上加了bottom-up(下采样)的结构。
由下图可以看到,主要用到两次PAN,第一次是在76*76
那层,有一个指向下面的箭头,该箭头为一次下采样,同样的在38*38
那一层也进行了一次PAN。
FPN和PAN都是通过融合不同尺度的特征,提高模型对不同尺寸目标的检测能力。
9.4检测头部分
9.4.1 C-IOU损失函数
考虑到了detect与gt之间的重叠面积、中心点距离和长宽比
L=1-重叠面积+中心点距离+长宽比
9.4.2 非极大值抑制DIOU-NMS
DIoU(前面讨论过的) 被用作非最大值抑制(NMS)的一个因素。该方法在抑制冗余框的同时,采用IoU和两个边界盒中心点之间的距离。这使得它在有遮挡的情况下更加健壮。
10 YOLOV5
Yolov5s网络是Yolov5系列中深度最小,特征图的宽度最小的网络。后面的3种都是在此基础上不断加深,不断加宽。模型文件只有24M
10.1 概述
YOLOv5版本 UltralyticsLLC 公司推出的,是在YOLOv4的基础上做了少许的修补,由于改进比较小,仅做简单介绍。
改进譬如:
-
将v4版本骨干网络中的csp结构拓展到了NECK结构中。
-
增加了FOCUS操作,但是后续6.1版本中又剔除掉了该操作,使用一个6x6的卷积进行了替代。
-
使用SPPF结构代替了SPP。
10.2 思路
YOLOv5检测算法的思路与v4基本一致,此处不再赘述。
10.3 网络结构
骨干网络: CSPDarknet53(含SPPF)
Neck: FPN+PAN
检测头:同v3版本
tricks1:SPPF
主要区别就是MaxPool由原来的并行调整为了串行,值得注意的是:串行两个 5 x 5
大小的 MaxPool 和一个 9 x 9
大小的 MaxPool 是等价的,串行三个 5 x 5
大小的 MaxPool 层和一个 13 x 13
大小的 MaxPool 是等价的。虽然并行和串行的效果一样,但是串行的效率更高,降低了耗时。
tricks2:自适应锚框计算
比较简单,就是把锚框的聚类改为了使用程序进行自适应计算,此处就不再赘述了。
tricks3:Focus操作 后续版本剔除了该操作,此处就展开介绍了。
10.4优势
站在巨人的肩膀上,效果当然也不差啦。
11 YOLOV6
11.1概述
YOLOv6是由美团推出的,所做的主要工作是为了更加适应GPU设备,将2021年的RepVGG结构引入到了YOLO。思路比较简单,仅做少许介绍。
11.2思路
YOLOv6检测算法的思路类似YOLOv5(backbone+neck)+YOLOX(head),此处不再赘述。
主要改动:
1.骨干网络由CSPDarknet换为了EfficientRep
2.Neck是基于Rep和PAN构建了Rep-PAN
3.检测头部分模仿YOLOX,进行了解耦操作,并进行了少许优化。
11.3网络结构
骨干网络: EfficientRep
Neck: FPN+RepPAN
检测头:类似YOLOX
tricks1:引入RepVGG
按照RepVGG的思路,为每一个3x3的卷积添加平行了一个1x1的卷积分支和恒等映射分支,然后在推理时融合为3x3的结构,这种方式对计算密集型的硬件设备会比较友好。
**tricks2:**骨干网络EfficientRep
把backbone中stride=2的卷积层换成了stride=2的RepConv层,并且也将CSP-Block修改为了RepBlock。
tricks3:Neck中引入Rep
tricks4:对检测头解耦并重新设计了高效的解耦头为了加快收敛速度和降低检测头复杂度,YOLOv6模仿YOLOX对检测头进行了解耦,分开了目标检测中的边框回归过程和类别分类过程。 由于YOLOX的解耦头中,新增了两个额外的3x3卷积,会在一定程度增加运算的复杂度。鉴于此,YOLOv6基于Hybrid Channels的策略重新设计出了一个更高效的解耦头结构。在不怎么改变精度的情况下降低延时,从而达到了速度与精度的权衡。
11.4优势
对耗时做了进一步的优化,进一步提升YOLO检测算法性能。
12 YOLOv7
12.1 概述
YOLOv7是YOLOv4团队的续作,主要是针对模型结构重参化和动态标签分配问题进行了优化。
12.2思路
YOLOv7检测算法的思路是与YOLOv4、v5类似。
主要改动:
1.提出了计划的模型结构重参化。
2.借鉴了YOLOv5、Scale YOLOv4、YOLOX,“拓展”和“复合缩放”方法,以便高效的利用参数和计算量。
3.提出了一种新的标签分配方法。
12.3 网络结构
在YOLOv4、YOLOv5、YOLOv6基础上通过添加了以下tricks进行了进一步的升级改造。
tricks1:高效的聚合网络
E-ELAN采用expand、shuffle、merge cardinality结构,实现在不破坏原始梯度路径的情况下,提高网络的学习能力。在体系结构方面,E-ELAN只改变了计算模块中的结构,而过渡层的结构则完全不变。作者的策略是利用分组卷积来扩展计算模块的通道和基数,将相同的group parameter和channel multiplier用于计算每一层中的所有模块。然后,将每个模块计算出的特征图根据设置的分组数打乱成G组,最后将它们连接在一起。此时,每一组特征图中的通道数将与原始体系结构中的通道数相同。最后,作者添加了G组特征来merge cardinality。
tricks2:模型缩放
类似于YOLOv5、Scale YOLOv4、YOLOX,一般是对depth、width或者module scale进行缩放,实现扩大或缩小baseline的目的。
tricks3:引入了卷积重参化并进行了改进采用梯度传播路径来分析不同的重参化模块应该和哪些网络搭配使用。同时分析出RepConv中的identity破坏了ResNet中的残差结构和DenseNet中的跨层连接,因此作者做了改进,采用没有Identity连接的RepConv结构进行卷积重参数化。下图是设计的用于PlainNet和ResNet的计划重参数卷积。
tricks4:引入了辅助训练模块-coarse-to-fine(由粗到细)引导标签分配策略
常用的方式是图(c)所示,即辅助头和引导头各自独立,分别利用ground truth和它们(辅助头、引导头)各自的预测结果实现标签分配。YOLOV7算法中提出了利用引导头的预测结果作为指导,生成从粗到细的层次标签,将这些层次标签分别用于辅助头和引导头的学习,如下图(d)和(e)所示。
12.4 优势
参数量和计算量大幅度减少,但性能仍能保持少量的提升。
名词解释
1、批量归一化Batch Normalization
内部协变量偏移问题(Internal Covariate Shift,ICS)
随着训练的进行,网络中的参数也随着梯度下降在不停更新。一方面,当底层网络中参数发生微弱变化时,由于每一层中的线性变换(网络训练)与非线性激活映射(激活函数),这些微弱变化随着网络层数的加深而被放大(类似蝴蝶效应);另一方面,参数的变化导致每一层的输入分布会发生改变,进而上层的网络需要不停地去适应这些分布变化,使得我们的模型训练变得困难。
Batch Normalization的原论文作者给了Internal Covariate Shift一个较规范的定义:在深层网络训练的过程中,由于网络中参数变化而引起内部结点数据分布发生变化的这一过程被称作Internal Covariate Shift。
Batch Normalization原理
通常,一次训练会输入一批样本(batch)进入神经网络。批规一化在神经网络的每一层,在网络(线性变换)输出后和激活函数(非线性变换)之前增加一个批归一化层(BN),BN层进行如下变换:
①对该批样本的各特征量(对于中间层来说,就是每一个神经元)分别进行归一化处理,分别使每个特征的数据分布变换为均值0,方差1。从而使得每一批训练样本在每一层都有类似的分布。这一变换不需要引入额外的参数。
②对上一步的输出再做一次线性变换,假设上一步的输出为Z,则 Z1=γZ + β。这里γ、β是可以训练的参数。增加这一变换是因为上一步骤中强制改变了特征数据的分布,可能影响了原有数据的信息表达能力。增加的线性变换使其有机会恢复其原本的信息。
总结:
- batch normalization的提出是为了解决ICS问题,即在深层网络训练过程中,由于网络参数的变化引起内部节点数据分布发生变化,导致梯度下降变慢和网络收敛速度变慢;
- 在神经网络中引入BN,对分布差异较大的数据进行归一化,让数据特征具有相同的分布,而且保留了输入数据的表达能力。
- 在神经网络中引入BN,使得在训练时网络模型对学习率、初始化方法等参数的敏感度降低。例如,当学习率设置太高时,会使得参数更新步伐过大,容易出现震荡和不收敛,当对权重进行缩放时,经过BN后缩放因子会被消去;而且在求偏导时,缩放因子越大,梯度变化就越小,避免了学习率的大小变化带来的影响。
- BN允许网络使用饱和性激活函数(例如sigmoid,tanh等),缓解梯度消失问题。在不使用BN层的时候,由于网络的深度与复杂性,很容易使得底层网络变化累积到上层网络中,导致模型的训练很容易进入到激活函数的梯度饱和区;通过normalize操作可以让激活函数的输入数据落在梯度非饱和区,缓解梯度消失的问题;另外通过自适应学习λ与β又让数据保留更多的原始信息。
- 正则化效果: 在Batch Normalization中,由于我们使用mini-batch的均值与方差作为对整体训练样本均值与方差的估计,尽管每一个batch中的数据都是从总体样本中抽样得到,但不同mini-batch的均值与方差会有所不同,这就为网络的学习过程中增加了随机噪音,与Dropout通过关闭神经元给网络训练带来噪音类似,在一定程度上对模型起到了正则化的效果。
- 另外,原作者通过也证明了网络加入BN后,可以丢弃Dropout,模型也同样具有很好的泛化效果。
2、梯度消失和梯度爆炸
深度学习网络在训练时,最终是求得让损失函数达到收敛的一组权重参数,这就需要进行迭代。假设这个网络共有三层,在计算得到一次训练的误差之后,为了更新网络第一层参数,需要使用这个误差对第一层权重求偏导,根据链式法则,误差需要先对第三层求偏导然后对第二层求偏导然后对第一层求偏导
(1) 梯度消失(gradient vanishing problem)
我们知道神经网络在进行反向传播(BP)的时候会对参数W进行更新,梯度消失就是靠后面网络层(如layer3)能够正常的得到一个合理的偏导数,但是靠近输入层的网络层,计算的到的偏导数近乎零,W几乎无法得到更新。
(2)梯度爆炸(gradient exploding problem)
梯度爆炸的意思是,靠近输入层的网络层,计算的到的偏导数极其大,更新后W变成一个很大的数(爆炸)。
3、特征金字塔FPN
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的尺寸便可以达到与之相当的性能
9.总结
当前目标检测模型算法也是层出不穷。在two-stage领域,2017年Facebook提出了mask R-CNN。CMU也提出了A-Fast-RCNN 算法,将对抗学习引入到目标检测领域。Face++也提出了Light-Head R-CNN,主要探讨了 R-CNN 如何在物体检测中平衡精确度和速度。
one-stage领域也是百花齐放,2017年首尔大学提出 R-SSD 算法,主要解决小尺寸物体检测效果差的问题。清华大学提出了 RON 算法,结合 two stage 名的方法和 one stage 方法的优势,更加关注多尺度对象定位和负空间样本挖掘问题。
目标检测领域的深度学习算法,需要进行目标定位和物体识别,算法相对来说还是很复杂的。当前各种新算法也是层不出穷,但模型之间有很强的延续性,大部分模型算法都是借鉴了前人的思想,站在巨人的肩膀上。我们需要知道经典模型的特点,这些tricks是为了解决什么问题,以及为什么解决了这些问题。这样才能举一反三,万变不离其宗。综合下来,目标检测领域主要的难点如下:
1,检测速度:实时性要求高,故网络结构不能太复杂,参数不能太多,卷积层次也不能太多。
2,位置准确率:(x y w h)参数必须准确,也就是检测框大小尺寸要匹配,且重合度IOU要高。SSD和faster
RCNN通过多个bounding box来优化这个问题3,漏检率:必须尽量检测出所有目标物体,特别是靠的近的物体和尺寸小的物体。SSD和faster RCNN通过多个bounding
box来优化这个问题。4,物体宽高比例不常见:SSD通过不同尺寸feature map,yoloV2通过不同尺寸输入图片,来优化这个问题。
5,靠的近的物体准确率低。文章来源:https://www.toymoban.com/news/detail-786667.html
6,小尺寸物体准确率低:SSD取消全连接层,yoloV2增加pass through layer,采用高分辨率输入图片,来优化这个问题。文章来源地址https://www.toymoban.com/news/detail-786667.html
到了这里,关于目标检测算法(R-CNN,fast R-CNN,faster R-CNN,yolo,SSD,yoloV2,yoloV3,yoloV4,yoloV5,yoloV6,yoloV7)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!