单阶段目标检测重要论文总结


单阶段目标检测重要论文总结

目标检测的常见结构:

image-20220415103203365

Backbone:从图像中提取必要的特征,然后利用这些特征去实现分类和定位。常使用ImageNet Pretrained model,以减少训练时间。常见的有VGG-16,ResNet-50,ResNet-101,ResNeXT,ResNet+DCN,DarkNet,CSPResNet,Mobile-Net,ShuffleNet。

Neck:将backbone提取出的信息整合。常见的有FPN,SPP,RFB,ASPP,SAM,PAN。

Detection Head:输出分类与定位结果。这一模块通常就是普通的卷积。

目录

一、Yolov1

1、论文简介

论文名称:You Only Look Once: Unified, Real-Time Object Detection

论文链接:yolov1

论文源码:yolov1的简单复现

自己注释了一部分并实现了demo

加强版yolov1

yolo的官方实现网站

摘要:我们提出了一种新的目标检测方法YOLO。以前目标检测的工作是重新利用分类器来执行检测,而我们将目标检测视为一个空间上分离的BBox和有联系的类概率的回归问题。YOLO 从输入图像仅仅经过一个 神经网络就能直接得到 bounding boxes 以及每个 bounding box 所属类别的概率。由于整个检测管道是一个单一的网络,因此可以直接对检测性能进行端到端优化。正因为整个的检测过程仅仅有一个网络,所以它可以直接在检测性能上进行端到端优化。
​ 我们的统一架构非常快。基本YOLO模型能以每秒45帧的速度实时处理图像。该网络的一个较小版本Fast YOLO处理图像速度能达到每秒155帧,同时还较其他实施检测器的mAP提升了两倍。但是较之前目标检测的SOTA相比,YOLO在物体定位时更容易出错,但是在背景上预测出假阳性(不存在的物体)的情况会少一些。最后要说的是YOLO比DPM、R-CNN等物体检测系统能够学到更加抽象的物体的特征,这使得YOLO可以从真实图像领域迁移到其他领域,如艺术。

提出的问题:DPM,RCNN等目标检测器太慢又不好优化,RCNN太慢是因为要经过生成RP和分类RP这两个阶段,又要经过NMS后处理,难以优化是因为两阶段所用模型要分开训练。那么怎么解决这种太慢有不好优化的问题?

解决方案:将目标检测重建为一个单回归问题,直接从图像像素输出BBox坐标和分类概率。提出YOLO框架。

image-20220415111904390

YOLO检测系统运作流程:
①将输入图resize到448×448;
②将resize后的图像喂到单个CNN中运作;
③根据模型的置信度对得到的检测结果进行阈值化。

YOLO优点:

①单个网络可以同时预测多个BBox和这些BBox的分类概率;
②在整张图片上训练且可以直接优化检测性能;
③速度快,可以做到实时检测。
④mAP较其他实时检测器提升了两倍之多。
⑤在做预测时YOLO 使用的是全局图像。YOLO在训练和测试时都是“看”的整张图,所以它可以将各类别的整体信息和外观信息进行编码。(Fast R-CNN较容易误将图像中的背景的一个小块看成是物体,因为它“看”的范围比较小,而YOLO犯的背景错误比 Fast R-CNN 少一半多)
⑥能够学到物体更泛化的特征表示。(当在自然场景图像上训练 YOLO,再在艺术图像上去测试 YOLO 时,YOLO 的表现要优于 DPM、R-CNN)
⑦仅使用一个卷积神经网络就可以端到端地实现检测物体的目的

YOLO缺点:较目标检测的SOTA系统定位精度欠缺,尤其对于小物体

2、检测原理

YOLO工作原理:将图片分成S×S的网格,如果物体中心落在一个网格上,那么这个网格就要被拿来检测这个物体(即只有GT处的网格才会被训练)。每个网格预测B个BBox和这些BBox的置信分数。每个BBox包含5个预测值,即置信分数和矩形框参数(x,y,w,h),单阶段目标检测重要论文总结坐标代表BBox的中心与网格边界的相对值,单阶段目标检测重要论文总结代表相对于整张图像来说BBox的宽高。注意:实际训练过程中,单阶段目标检测重要论文总结的值使用图像的宽度和高度进行归一化到[0,1]区间内;单阶段目标检测重要论文总结是BBox中心位置相对于当前网格位置的偏移值,并且被归一化到[0,1]。置信分数代表BBox和GT之间的IOU,这个IOU可看做是是正样本的标签。同时每个网格还要预测C个类别的概率,即在一个网格包含一个物体的前提下它属于某个类的概率,只为每个网格预测一组(C个)类的概率,不考虑BBox B的数量。因此特征图的通道数为:单阶段目标检测重要论文总结。其中单阶段目标检测重要论文总结

image-20220415155207128

本文使用S=7, B=2, VOC数据集的类别数C=20的配置,因此预测数有7 × 7 × 30。

本文的置信分数计算公式:

image-20220415151537562

若BBox包含物体,则P(object) = 1;否则P(object) = 0。IOU(intersection over union)为预测BBox与GT之间的交集面积。object是一个二分类,即有物体还是无物体,也就是“边框的置信度”,没物体的标签显然就是0,而有物体的标签可以直接给1,也可以计算当前预测的bbox与GT之间的IoU作为有物体的标签,注意:这个IoU是object预测学习的标签

测试时的置信分数计算公式:

image-20220415152736749

这对每个BBox来说是一个特定类别的置信分数,这些分数对该类出现在框中的概率以及预测框与目标物体的匹配程度进行编码。

问题:对于这个公式最大的问题就在于IOU,因为测试阶段根本就没有真实框能够让我们去计算IoU。但是YOLO的objectness的学习标签就是预测框和GT之间的IoU,所以在测试阶段,这个IOU其实就是指YOLO预测的object-ness,它的物理意义就是:这个网格是否有物体。所以可以认为objectness隐含了IoU的概念,但本质就是有无物体的预测。基于这种问题,上面的置信分数公式可以写作:

image-20220415154316928

这个IoU就是objectness预测,因为objectness在训练过程中的正样本标签就是IoU。

总的来说,yolov1一共有三部分输出,分别是object、class以及BBox:

  • object就是框的置信度,用于表征该网格是否有物体;
  • class就是类别预测;
  • BBox就是Bounding Box

3、结构设计

image-20220415161534080

YOLO的backbone:仿照GoogLeNet,但是没有Inception模块,而是替换成1×1和3×3卷积。24层卷积层+2个FC层,网络在最后的卷积层中将输出特征图做flatten操作,得到一个一维向量然后再接2个全连接层做预测。

以下就是YOLOv1的整体工作流程:

image-20220424152824344

4、疑难问题

①训练阶段和测试阶段各做了些什么?

训练阶段:标签GT框中心点落在哪个网格,就由哪个网格预测这个物体,每个网格预测B个BBox,与GT的IOU最大的BBox负责预测这个物体,每个网格只能检测一个物体,包含/不包含GT的网格/BBox依损失函数分别处理。

测试阶段:直接获得单阶段目标检测重要论文总结向量进行NMS后处理,得到目标检测结果。

②BBox怎么产生的?

答:是通过GT标签中的[xmin,xmax,ymin,ymax]计算得到GT的中心点坐标单阶段目标检测重要论文总结和宽高,现通过这四个参数回归学习得到BBox的中心点坐标以及宽高。

③如何通过卷积操作将置信度+类别概率+位置偏移映射到卷积输出通道上?

答:因为CNN前向传播的同时要进行loss的反向传播,然后根据loss更新前向传播的这些预测值,因为这些预测值和反向传播的loss通道是一一对应的,所以是将预测值一一映射到卷积输出通道上了。至于为什么更新loss会对预测值产生影响:因为loss的计算离不开ground truth里的值和预测值,通用优化器如SGD根据loss对预测值进行更新,直到设置的epoch结束就可以输出预测值了。

5、论文总结

本文贡献:

①实现了使用单个卷积神经网络就可以端到端地实现检测物体的目的;
②提出的YOLO能够在整张图片上训练且可以直接优化检测性能;
③YOLO可以做到实时检测,mAP较其他实时检测器提升巨大;
④在做预测时YOLO 使用的是全局图像,使得检测器犯背景错误概率降低;
⑤能够学到物体更泛化的特征表示。

YOLOv1缺点:

①较目标检测的SOTA系统定位精度欠缺,召回率较低,尤其对于小物体;
②使用flatten操作破坏特征的空间结构信息;
③没有使用BN层(因为当时BN还不火)。

二、Yolov2

1、论文简介

论文名称:《YOLO9000: Better, Faster, Stronger》

论文链接:yolov2

论文源码:yolov2的简单复现

yolov2实现+自己理解

摘要:我们引进了YOLO9000,这是一个SOTA实时目标检测系统,可以检测9000多个目标类别。首先对YOLO检测方法提出了各种改进,在以前的工作上用了些创新点。yoov2模型在VOC和COCO数据集上已经达到SOTA。其次使用了一种新的多尺度训练方法,同样的一个YOLOv2模型可以在不同尺寸图片下运行,权衡了速度及精度。最后提出了一种联合训练目标检测和分类任务的方法,利用这种方法我们在COCO检测数据集和ImageNet分类数据集上同时对YOLO9000进行训练。联合训练允许YOLO9000预测那些没有检测数据标签的目标类别的检测。YOLO只能检测200多个类别,而YOLO9-000可以预测9000多个类别且可以实时运行。

本文提出的问题:检测数据集不会像分类数据集一样拥有很多类别,因此要怎么使得检测任务能够在有限类别的检测数据集上训练出能够检测更多类别的检测器呢?

解决方案:利用分类数据集且提出联合训练方案。(在YOLO中,边界框的预测其实并不依赖于物体的标签,所以YOLO可以实现在分类和检测数据集上的联合训练) 对于检测数据集,可以用来学习预测物体的边界框、置信度以及为物体分类;而对于分类数据集可以仅用来学习分类,但是其可以极大扩充模型所能检测的物体种类。

2、更好、更快、更强

1)为什么更好?

答:在提升召回率和定位精度做了提升,不改变分类精度。

①添加BN层

image-20220424095617498

②高分辨率分类器

YOLOv2做法:将已在224×224的低分辨率图像上训练好的分类网络在448×448的高分辨率图像上进行微调10个epoch。微调完之后再去掉最后的GAP层和softmax层作为最后的检测backbone网络。

YOLOv1做法:backbone网络先在ImageNet上进行预训练,预训练时所输入的图像尺寸是224×224,而做检测任务时,YOLOv1所接收的输入图像尺寸是448×448,不难想到,训练过程中,网络必须要先克服由分辨率尺寸的剧变所带来的问题。

③anchor box机制

从YOLOv1中移除FC层并用anchor框去预测BBox。移除一个池化层使得网络卷积层(32倍下采样)后的输出具有更高分辨率(13×13),再将输入图像缩小到416使得特征图有奇数个位置且仅有一个中心点。为每个anchor分别预测类别和置信分数(objec-tness),这两种预测遵从YOLOv1。

缺点:mAP下降且生成BBox数量过多。
优点:recall提升(意味着有更多提升的空间)

Faster RCNN中RPN的原理:RPN网络在这些预先放置好的锚框上去为后续的预测提供ROI区域。每个网格处设定了k个不同尺寸、不同宽高比的anchor box,RPN网络会为每一个anchor box学习若干偏移量:中心点的偏移量和宽高的偏移量。用这些偏移量去调整每一个anchor box,得到最终的边界框。anchor box的本质是提供边界框的尺寸先验,网络使用偏移量在这些先验值上进行调整,从而得到最终的尺寸,对于边界框的学习,不再是之前的“无中生有”了。

anchor box与BBox区别:

anchor box是预设的,用来作为参照框,得到与GT框的IOU,然后让CNN输出物体相对于anchor box的中心点偏移以及长宽比例,用来做位置形状预测。

BBox是根据CNN输出的相对于anchor box中心点偏移以及长宽比例计算出的框,是后面产生的框,用来做分类预测。

训练标注阶段:把anchor box作为训练样本,为了训练样本我们需要为每个锚框标注两类标签:一是锚框所含目标的类别,简称类别;二是真实边界框相对锚框的偏移量,简称偏移量(offset)。找出与每个anchor box交并比最大的GT框,然后GT框的标签作为anchor box的标签,然后计算anchor box相对于GT框的偏移量。在目标检测时,我们首先生成多个锚框,然后为每个锚框预测类别以及偏移量,接着根据预测的偏移量调整锚框位置从而得到预测边界框,最后筛选需要输出的预测边界框。

训练阶段触发anchor box:在经过一系列卷积和池化之后,在feature map层使用anchor box,如下图所示,经过一系列的特征提取,最后针对3×3的网格会得到一个3×3×2×8的特征层,其中2是anchor box的个数,8代表每个anchor box包含的变量数,分别是4个位置偏移量、3个类别(one-hot标注方式)、1个anchor box标注(如果anchor box与真实边框的交并比最大则为1,否则为0)。到了特征层之后对每个cell映射到原图中,找到预先标注的anchor box,然后计算这个anchor box与ground truth之间的损失,训练的主要目的就是训练出用anchor box去拟合GT框的模型参数。

image-20220507171616229

预测阶段:首先在图像中生成多个anchor box,然后根据训练好的模型参数去预测这些anchor box的类别和偏移量,进而得到预测的边界框。由于阈值和anchor box数量选择的问题,同一个目标可能会输出多个相似的预测边界框,这样不仅不简洁,而且会增加计算量,为了解决这个问题,常用的措施是使用NMS。

④维度聚类

不需要人工设计先验框的参数(先验框的数量和大小),在训练集上的BBox做K-means聚类得到好的先验框。聚类的目标是数据集中所有检测框的宽和高,与类别无关。使用IoU作为聚类的衡量指标,如下公式所示:

image-20220424110621116

优点:得到的结果要比手动设置先验框参数好。
缺点:聚类效果依赖于数据集。倘若数据集规模过小、样本不够丰富,那么由聚类得到的先验框也未必会提供足够好的尺寸先验信息。

⑤定位预测

换上新先验框之后,又对BBox的预测方法做了一些调整:首先对每一个BBox,YO LO仍旧去学习中心点偏移量单阶段目标检测重要论文总结单阶段目标检测重要论文总结,YOLOv1中是直接用线性函数输出的,而现在改用sigmoid函数使得网络对偏移量的预测是处在0~1范围内的;其次对每个BBox ,由于有了BBox的尺寸先验信息,因此网络不用再去学习整个BBox的宽高,但是仍要学习BBox宽高偏移量。假设某个先验框的宽高分别为:单阶段目标检测重要论文总结单阶段目标检测重要论文总结,网络输出宽高的偏移量为单阶段目标检测重要论文总结单阶段目标检测重要论文总结,则使用下面公式可以算出BBox的宽和高。

image-20220424111903238

image-20220424113555743

⑥使用更高分辨率的特征

在前面的改进中,YOLOv1都是在最后一张大小为13×13×1024的特征图上进行检测,为了引入更多的细节信息,作者将backbone的第17层卷积输出的26×26×512特征图拿出来,做一次特殊的降采样操作,得到一个13×13×2048特征图,然后将二者在通道的维度上进行拼接,最后在这张融合了更多信息的特征图上去做检测。

特殊下采样操作:类似pixelshuffle的逆操作:passthrough。这种特殊降采样操作的好处就在于降低分辨率的同时,没丢掉任何细节信息,信息总量保持不变

image-20220424114553524

⑦多尺度训练

使用图像金字塔。通过使用图像金字塔的操作,网络能够在不同尺寸下去感知同一目标,从而增强了其本身对目标尺寸变化的鲁棒性,提升了YOLO对物体的尺度变化的适应能力。

2)为什么更快?

①全卷积网络结构

网络的输入图像尺寸从448改为416,去掉了YOLOv1网络中的最后一个池化层和所有的全连接层,修改后的网络的最大降采样倍数为32,最终得到的也就是13×13的网格,不再是7×7。每个网格处都预设了k个anchor box。

image-20220424152402609

原先的YOLOv1中,每个网格处的B个边界框都有一个置信度,但是类别是共享的,因此每个网格处最终只会有一个输出,而不是B个输出(YOLOv1只输出置信度最高的那一个),倘若一个网格包含了两个以上的物体,那必然会出现漏检问题。加入anchor box后,YOLOv1改为每一个anchor box都预测一个类别和置信度,即每个网格处会有多个边界框的预测输出。YOLOv2的输出张量大小是S×S×k×(1+4+C),每个边界框的预测都包含1个置信度、4个边界框的位置参数和C个类别预测。

②Darknet-19

网络结构:

image-20220424144952801

卷积层有19层:包括线性卷积、BN层以及LeakyReLU激活函数。

做法:首先将DarkNet19在ImageNet上进行预训练,预训练完毕后,去掉最后一层卷积层(与此同时添加3个大小为3×3卷积核数量为1024的卷积层,其中每个3×3卷积层之后都跟一个大小为1×1且数量同检测的输出数量的卷积核的卷积层,还从最后一个卷积层中添加了从最后一个3×3×512的层到第二个3×3×512的层的passthro-ugh层)、GAP层以及softmax层,然后换掉原先的backbone网络。

3)为什么更强? 此为YOLO9000内容

①在分类、检测数据集上联合训练

原理:使用专门为检测贴标签的图像去学习特定的检测信息(BBox坐标预测和object-ness置信分数),使用专门为分类贴标签的图像去扩展可检测的目标类别。

做法:混合检测、分类数据集,当网络看到检测标签图时,网络反向传播YOLOv2的全部loss;当网络看到分类标签图时,网络仅反向传播特定的分类loss。

问题:检测数据集仅有常见标签,而ImageNet类别太细化,怎么去融合标签?

解决方案:使用多标签模型组合标签不互斥的数据集。

②建立分类层级树:WordTree

结合分类数据集和检测数据集标签。计算类别概率就可以用条件概率/全概率来计算,如:单阶段目标检测重要论文总结

image-20220424154931983

3、Darknet-19代码实现

class Conv_BN_LeakyReLU(nn.Module):
    def __init__(self, in_channels, out_channels, ksize, padding=0, dilation=1):
        super(Conv_BN_LeakyReLU, self).__init__()
        self.convs = nn.Sequential(
            nn.Conv2d(in_channels, out_channels, ksize, padding=padding, dilation=dilation),
            nn.BatchNorm2d(out_channels),
            nn.LeakyReLU(0.1, inplace=True)
        )

    def forward(self, x):
        return self.convs(x)

class DarkNet_19(nn.Module):
    def __init__(self, num_classes=1000):
        print("Initializing the darknet19 network ......")
        
        super(DarkNet_19, self).__init__()
        # backbone network : DarkNet-19
        # output : stride = 2, c = 32
        self.conv_1 = nn.Sequential(
            Conv_BN_LeakyReLU(3, 32, 3, 1),
            nn.MaxPool2d((2,2), 2),
        )

        # output : stride = 4, c = 64
        self.conv_2 = nn.Sequential(
            Conv_BN_LeakyReLU(32, 64, 3, 1),
            nn.MaxPool2d((2,2), 2)
        )

        # output : stride = 8, c = 128
        self.conv_3 = nn.Sequential(
            Conv_BN_LeakyReLU(64, 128, 3, 1),
            Conv_BN_LeakyReLU(128, 64, 1),
            Conv_BN_LeakyReLU(64, 128, 3, 1),
            nn.MaxPool2d((2,2), 2)
        )

        # output : stride = 16, c = 256
        self.conv_4 = nn.Sequential(
            Conv_BN_LeakyReLU(128, 256, 3, 1),
            Conv_BN_LeakyReLU(256, 128, 1),
            Conv_BN_LeakyReLU(128, 256, 3, 1),
            nn.MaxPool2d((2,2), 2)
        )

        # output : stride = 32, c = 512
        self.conv_5 = nn.Sequential(
            Conv_BN_LeakyReLU(256, 512, 3, 1),
            Conv_BN_LeakyReLU(512, 256, 1),
            Conv_BN_LeakyReLU(256, 512, 3, 1),
            Conv_BN_LeakyReLU(512, 256, 1),
            Conv_BN_LeakyReLU(256, 512, 3, 1),
            nn.MaxPool2d((2,2), 2)
        )

        # output : stride = 32, c = 1024
        self.conv_6 = nn.Sequential(
            Conv_BN_LeakyReLU(512, 1024, 3, 1),
            Conv_BN_LeakyReLU(1024, 512, 1),
            Conv_BN_LeakyReLU(512, 1024, 3, 1),
            Conv_BN_LeakyReLU(1024, 512, 1),
            Conv_BN_LeakyReLU(512, 1024, 3, 1)
        )

        self.conv_7 = nn.Conv2d(1024, 1000, 1)
        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))

    def forward(self, x):
        x = self.conv_1(x)
        x = self.conv_2(x)
        x = self.conv_3(x)
        x = self.conv_4(x)
        x = self.conv_5(x)
        x = self.conv_6(x)

        x = self.conv_7(x)
        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        return x

4、论文总结

本文较YOLOv1改进点:只说YOLOv2

①移除了FC层,在卷积层上添加了BN层。
②在低分辨率图像上训练好的网络再放到高分辨率图像中微调,使得检测网络能够对高分辨率图像做出较快适应。
③用anchor box机制生成BBox,对BBox预测方法做了改进。
④使用多尺度训练,具体表现在使用图金字塔。
⑤将类似GoogLeNet的网络替换为Darknet-19网络。
⑤一个网格可以预测多个类别,漏检情况减少。

本文贡献:

①提出了YOLOv2和YOLO9000
②用维度聚类方法产生更好的先验框(anchor boxes)
③使用passthrough层从而可以使用更高分辨率的特征
④提出Darknet-19网络

本文缺点:

①YOLOv2输出量太大,使得运算时间加长了。
②anchor box机制会出现聚类所获得的先验框严重依赖于数据集本身的问题。
③YOLOv1只使用了最后一个经过32倍降采样的特征图即C5特征图,而尽管YOLOv2使用了passthrough技术将16倍降采样的特征图即C4特征图融合到了C5特征图中,但最终的检测仍是在C5尺度的特征图上进行的,最终结果便是导致了模型的小目标的检测性能较差(YOLOv1与YOLOv2的共同缺点)

三、Yolov3

1、论文简介

论文名称:《YOLOv3: An Incremental Improvement》

论文链接:yolov3

论文源码:yolov3实现

yolov3实现+自己理解

摘要:我们对YOLO进行了更新,做了一系列小的设计修改,使之更好,除此之外还训练了一个新网络DarkNet-53,虽然比YOLOv2使用的网络要大但是运行速度很快。在320×320图像中YOLOv3以28.2 mAP的速度在22毫秒内运行,与SSD一样精确,但速度快了三倍。相比之下RetinaNet与YOLOv3性能相似,但速度快3.8倍。

BBox预测:用均方差损失函数,每个BBox置信分数用罗杰思特回归计算得到。

类别预测:用单独的罗杰思特分类器,不用softmax,训练时用BCEloss。是多标签分类预测(即每个框不一定只有一类,而有多类)

2、结构设计

Darknet-53

特征提取器backbone——Darknet-53(融合了darknet-19和ResNet的方法)

image-20220502105443059

注意:Darknet-53降采样使用的是步长为2的卷积,而没用maxpooling。卷积层仍是线性卷机+BN层+LeakyReLU激活函数。

特点:比Darknet-19更强,比ResNet-101和ResNet-152更快。

整体结构

image-20220502144532847

每个特征图上,YOLOv3在每个网格处放置3个先验框。由于YOLOv3一共使用3个尺度,因此,YOLOv3一共设定了9个先验框,这9个先验框仍旧是使用kmeans聚类的方法获得的。注意:YOLOv3的先验框尺寸不同于YOLOv2,后者是除以了32,而前者是在原图尺寸上获得的,没有除以32。

每个先验框预测依然是置信度+位置偏移+类别,因此每个尺度预测的张量通道数为3×(1+4+C)。如果输入图像尺寸为416×416,那么yolov3在一种尺度上最终会输出52×52×3×(1+4+C)、26×26×3×(1+4+C)、13×13×3×(1+4+C)三个预测张量,然后将这些预测结果汇总到一起,进行后处理并得到最终的检测结果。

3、Darknet-53代码实现

import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import os
import sys

__all__ = ['darknet53']

class Conv_BN_LeakyReLU(nn.Module):
    def __init__(self, c1, c2, k=1, p=0, s=1, d=1):
        super(Conv_BN_LeakyReLU, self).__init__()
        self.convs = nn.Sequential(
            nn.Conv2d(c1, c2, k, padding=p, stride=s, dilation=d),
            nn.BatchNorm2d(c2),
            nn.LeakyReLU(0.1, inplace=True)
        )

    def forward(self, x):
        return self.convs(x)

class resblock(nn.Module):
    def __init__(self, ch, nblocks=1):
        super().__init__()
        self.module_list = nn.ModuleList()
        for _ in range(nblocks):
            resblock_one = nn.Sequential(
                Conv_BN_LeakyReLU(ch, ch//2, k=1),
                Conv_BN_LeakyReLU(ch//2, ch, k=3, p=1)
            )
            self.module_list.append(resblock_one)

    def forward(self, x):
        for module in self.module_list:
            x = module(x) + x
        return x


class DarkNet_53(nn.Module):
    """
    DarkNet-53.
    """
    def __init__(self, num_classes=1000):
        super(DarkNet_53, self).__init__()
        # stride = 2
        self.layer_1 = nn.Sequential(
            Conv_BN_LeakyReLU(3, 32, k=3, p=1),
            Conv_BN_LeakyReLU(32, 64, k=3, p=1, s=2),
            resblock(64, nblocks=1)
        )
        # stride = 4
        self.layer_2 = nn.Sequential(
            Conv_BN_LeakyReLU(64, 128, k=3, p=1, s=2),
            resblock(128, nblocks=2)
        )
        # stride = 8
        self.layer_3 = nn.Sequential(
            Conv_BN_LeakyReLU(128, 256, k=3, p=1, s=2),
            resblock(256, nblocks=8)
        )
        # stride = 16
        self.layer_4 = nn.Sequential(
            Conv_BN_LeakyReLU(256, 512, k=3, p=1, s=2),
            resblock(512, nblocks=8)
        )
        # stride = 32
        self.layer_5 = nn.Sequential(
            Conv_BN_LeakyReLU(512, 1024, k=3, p=1, s=2),
            resblock(1024, nblocks=4)
        )

        # self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        # self.fc = nn.Linear(1024, num_classes)

    def forward(self, x, targets=None):
        c1 = self.layer_1(x)
        c2 = self.layer_2(c1)
        c3 = self.layer_3(c2)
        c4 = self.layer_4(c3)
        c5 = self.layer_5(c4)

        # x = self.avgpool(x)
        # x = x.view(x.size(0), -1)
        # x = self.fc(x)

        return c3, c4, c5

4、论文总结

本文较yolov2改进点:

①从单级检测(只在C5特征图做检测)改变为使用FPN结构与多级检测方法(分别在C3\C4\C5特征图上针对目标大小有选择地做检测);
②特征提取backbone由不带残差结构的Darknet-19替换为带有残差结构的Darknet-53;

image-20220503115202161

缺点:精度仍然落后于RetinaNet检测器

四、Yolov4

1、论文简介

论文名称:《YOLOv4: Optimal Speed and Accuracy of Object Detection》

论文链接:yolov4

论文源码:yolov4实现一

yolov4实现二

摘要:有大量的trick可以提高CNN的准确性。需要在大型数据集上对这些trick的组合进行实际测试,并对结果进行理论证明。某些trick只在某些模型上奏效,或者说只在某些问题上运行,或者只在小规模数据集上运行;而一些trick,如BN和残差连接适用于大多数模型、任务和数据集。我们假设这些通用trick包括加权残差连接(WRC)、跨阶段部分连接(CSP)、跨小批量标准化(CmBN)、自我对抗训练(SAT)和Mish激活。我们使用了新方法:WRC、CSP、CmBN、SAT、Mish激活、Masaic数据增强、CmBN、DropBlock正则化和CIoU loss,并结合这些trick中的一些以达到SOTA。

本文意图:欲解决目标检测系统速度和精度之间的平衡,并用1片GPU训练。设计一个更快速的目标检测器并优化并行计算。

image-20220503102628127

作者总结目标检测器通常包含的元素有:输入、骨干网络、脖颈、头部。

输入包括:Image, Patches, Image Pyramid
Backbone包括:VGG-16、ResNet、ResNeXt、DenseNet、SpineNet、EfficientNet-B0/B7、CSPResNeXt50、CSPDarknet53
Neck包括:
①添加额外块:SPP、ASPP、RFB、SAM
②通路聚合块:FPN、PAN、NAS-FPN、FC-FPN、BiFPN、ASFF、SFAM
Head包括:
①密集预测(单阶段基于anchor):RPN、SSD、YOLO、RetinaNet
②密集预测(单阶段anchor-free):CornerNet、CenterNet、MatrixNet,、FCOS
③稀疏预测(两阶段基于anchor):Faster R-CNN、R-FCN、Mask RCNN
④稀疏预测(两阶段anchor-free):RepPoints

2、结构简介

Yolov4组成部分:
Backbone: CSPDarkNet53,Neck: SPP、PAN,Head: YOLOV3

Yolov4用到的BoF:
①对backbone使用的:CutMixMosaic数据增强DropBlock正则化类标签平滑(Class Label Smoothing)
②对检测器使用的:CIoU lossCmBN(交叉小批量标准化)DropBlock正则化Mosaic数据增强SAT自对抗训练消除网格敏感性为单个GT box使用多个anchor余弦退火调度器最优超参数随机训练形状

Yolov4用到的BoS:
①对backbone使用的:Mish激活函数CSP:Cross-stage partial connectionsMiWRC:Multi-input weighted residual connections
②对检测器使用的:Mish激活函数SPPSAM(将空间上注意力改为点注意力)PAN(将shrot-connect从相加修改为拼接)DIoU NMS

Bag of Freebies:指的是那些不增加模型复杂度,也不增加推理的计算量的训练方法技巧,来提高模型的准确度。

主要代指:
1)数据增强:图像几何变换(随机缩放,裁剪,旋转),Cutmix,CutMix, Mosaic、SAT等
2)网络正则化:Dropout, Dropblock等
3)损失函数的设计:边界框回归的损失函数的改进如CIOU、GIOU等
4)数据不平衡问题:HEM、OHEM、focal loss、label smoothing

Bag-of-Specials:指的是那些增加少许模型复杂度或计算量的训练技巧,但可以显著提高模型的准确度。

主要代指:
1)增大模型感受野:SPP、ASPP等
2)引入注意力机制:SE、SAM
3)特征集成:PAN,BiFPN、FPN、ASFF、SFAM
4)激活函数改进:Swish、Mish、ReLU、Leaky-ReLU、ReLU6
5)后处理方法改进:soft NMS、DIoU NMS、NMS

YOLOv4结构图:

image-20220503114938843

YOLOv4的五个基本组件:
CBM:由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的最大池化的方式,进行多尺度融合

a、Mosaic数据增强

Why?:在平时项目训练时,小目标的AP一般比中目标和大目标低很多。而COCO数据集中也包含大量的小目标,但比较麻烦的是小目标的分布并不均匀。在所有的训练集图片中,只有52.3%的图片有小目标,而中目标和大目标的分布相对来说更加均匀一些。

How?:采用了4张图片,用随机缩放、随机裁剪、随机排布的方式进行拼接。

效果:image-20220503114515971 image-20220503114533195

优点:

  • 丰富数据集:随机使用4张图片,随机缩放,再随机分布进行拼接,大大丰富了检测数据集,特别是随机缩放增加了很多小目标,让网络的鲁棒性更好。
  • 减少GPU:Mosaic增强训练时,可以直接计算4张图片的数据,使得Mini-batch大小并不需要很大,一个GPU就可以达到比较好的效果。

b、CSPDarknet53

why CSP?:推理计算过高的问题是由于网络优化中的梯度信息重复导致的,主要从网络结构设计的角度解决推理中从计算量很大的问题。

how?:采用CSP模块先将基础层的特征映射划分为两部分,然后通过跨阶段层次结构将它们合并,在减少了计算量的同时可以保证准确率。

优点:

  • 增强CNN的学习能力,使得在轻量化的同时保持准确性。
  • 降低计算瓶颈,降低内存成本

c、Dropblock正则化

why?:卷积层对于这种随机丢弃并不敏感。因为卷积层通常是三层连用:卷积+激活+池化层,池化层本身就是对相邻单元起作用。而且即使随机丢弃,卷积层仍然可以从相邻的激活单元学习到相同的信息。因此在全连接层上效果很好的Dropout在卷积层上效果并不好。

how?:将整个局部区域进行删减丢弃,借鉴了cutout数据增强,cutout是将输入图像的部分区域清零,而Dropblock是将Cutout应用到每一个特征图。而且并不是用固定的归零比率,而是在训练时以一个小的比率开始,随着训练过程线性的增加这个比率

效果:image-20220503120450900

优点:

  • cutout只能作用于输入层,而Dropblock则是将Cutout应用到网络中的每一个特征图上
  • Dropblock可以定制各种组合,在训练的不同阶段可以修改删减的概率,从空间层面和时间层面,和cutout相比都有更精细的改进,效果也更好。

d、SPP模块

image-20220503121124739

用在backbone之后。本文在SPP模块中,使用k={1×1,5×5,9×9,13×13}的最大池化的方式,再将不同尺度的特征图进行Concat操作。

注意:这里最大池化采用padding操作,stride为1,比如13×13的输入特征图,使用池化核大小为5×5做池化,padding=2,因此池化后的特征图仍然是13×13大小。

e、FPN+PAN

yolov4输入为608×608×3图片时结构图:

image-20220503121824214

最后Prediction中用于预测的三个特征图:①76×76×255,②38×38×255,③19×19×255。FPN+PAN工作结构如下:

image-20220503122859594

这样结合操作,FPN层自顶向下传达强语义特征,而特征金字塔则自底向上传达强定位特征,两两联手,从不同的主干层对不同的检测层进行特征聚合。

f、CIOU loss

①IOU loss

image-20220503123231975

出现的问题:

image-20220503123259522

问题1:即状态1的情况,当预测框和目标框不相交时,IOU=0,无法反应两个框距离的远近,此时损失函数不可导,IOU_Loss无法优化两个框不相交的情况。
问题2:即状态2和状态3的情况,当两个预测框大小相同,两个IOU也相同,IOU_Loss无法区分两者相交情况的不同。
②GIOU_loss

image-20220503123346575

GIOU_Loss中,增加了相交尺度的衡量方式,缓解了IOU_Loss的一些问题

出现的问题:

image-20220503123438741

问题:状态1、2、3都是预测框在目标框内部且预测框大小一致的情况,这时预测框和目标框的差集都是相同的,因此这三种状态的GIOU值也都是相同的,这时GIOU退化成了IOU,无法区分相对位置关系。基于这个问题,又提出DIOU_Loss

③DIOU_loss

好的目标框回归函数应该考虑三个重要几何因素:重叠面积、中心点距离,长宽比。
针对IOU和GIOU存在的问题,作者从两个方面进行考虑
一:如何最小化预测框和目标框之间的归一化距离?
二:如何在预测框和目标框重叠时,回归的更准确?

针对第一个问题提出了DIOU_loss,DIOU_Loss考虑了重叠面积和中心点距离,当目标框包裹预测框的时候,直接度量2个框的距离,因此DIOU_Loss收敛的更快。但就像前面好的目标框回归函数所说的,这时并没有考虑到长宽比。

image-20220503123630510

出现的问题:

image-20220503123811598

问题:比如上面三种状态,目标框包裹预测框,本来DIOU_Loss可以起作用。但预测框的中心点的位置都是一样的,因此按照DIOU_Loss的计算公式,三者的值都是相同的。针对这个问题,又提出了CIOU_Loss。

④CIOU_loss

CIOU_Loss和DIOU_Loss前面的公式都是一样的,不过在此基础上还增加了一个影响因子,将预测框和目标框的长宽比都考虑了进去。

image-20220503124045382

其中v是衡量长宽比一致性的参数,我们也可以定义为:

image-20220503124103621

这样CIOU_Loss就将目标框回归函数应该考虑三个重要几何因素:重叠面积、中心点距离,长宽比全都考虑进去了。

总结IOU loss:

IOU_Loss:主要考虑检测框和目标框重叠面积。
GIOU_Loss:在IOU的基础上,解决边界框不重合时的问题。
DIOU_Loss:在IOU和GIOU的基础上,考虑边界框中心点距离的信息。
CIOU_Loss:在DIOU的基础上,考虑边界框宽高比的尺度信息。

g、DIOU-NMS

为什么不用CIOU_nms,而用DIOU_nms?

答:因为CIOU_loss是在DIOU_loss的基础上添加了影响因子,包含groundtruth标注框的信息,在训练时用于回归。
但在测试过程中,并没有groundtruth的信息,不用考虑影响因子,因此直接用DIOU_nms即可。

效果:

image-20220503124512648

3、论文总结

本文贡献:

①开发了一个集快速、精准度为一体的目标检测模型,使得任何人都可以用一片1080Ti或2080Ti去训练。
②检测器训练过程中验证了SOTA所使用的Bag-of-Freebies 和 Bag-of-Specials。
③修改了已有的SOTA并使之更高效、更适合于单个GPU训练,包括CBNPANSAM

本文较yolov3改进点:

①将backbone改进为CSPDarkNet53
②用BoF和BoS中的部分有效方法,具体表现如下:

  • 输入端:Mosaic数据增强、cmBN、SAT自对抗训练
  • BackBone主干网络:CSPDarknet53、Mish激活函数(后面的网络仍然使用Leaky-ReLU)、Dropblock
  • Neck:SPP、FPN+PAN结构
  • Head:输出层的锚框机制和Yolov3相同,主要改进的是训练时的损失函数CIOU loss,以及预测框筛选的nms变为DIOU_nms

五、SSD

1、论文简介

论文名称:《SSD: Single Shot MultiBox Detector》

论文链接:SSD

源码:SSD实现

摘要:我们提出了一种使用单个CNN检测图像中目标的方法,该方法称为SSD。将BBox的输出空间离散化为一组默认的Box,该Box在每个特征图位置上有不同的纵横比和尺寸。在预测时,网络为每个默认框的每个存在的目标类别生成分数,并对框进行调整,以更好地匹配目标的形状。此外该网络将多个具有不同分辨率的特征图的预测结合起来,以自适应地处理各种大小的目标。SSD模型相对于region proposal方法要简单,因为它完全消除了proposal生成和后续像素或特征重采样阶段,并将所有计算封装在单个网络中。这使得SSD易于训练,并且可以直接集成到需要检测组件的系统中。在PASCAL VOC、COCO和ILSVRC数据集上SSD与使用region proposal的方法相比具有相似准确性并且速度更快,同时SSD为训练和推理提供了统一的框架。与其他单阶段方法相比,SSD具有更好的精度。

提出问题:怎么做到精度和速度的平衡

解决方案:
①使用基于CNN的不对像素或特征进行重采样的检测器。
用小卷积核预测类别和BBox位置偏移
③使用不同纵横比的分离的预测器(卷积核)并应用到后面的多个特征图中以实现多尺度检测。

优点:输入低分辨率图像也可以输出高进度检测结果,提高检测速度。

2、结构设计

SSD检测框架

image-20220427112111823

图a:SSD训练期间仅需输入图像和每个目标的BBox

图b\图c:1)卷积时在具有不同尺度的若干特征图的每个位置处评估不同纵横比的一小组默认Box,对每个默认Box都预测所有目标类别的置信分数单阶段目标检测重要论文总结和形状偏移;

​ 2)训练时让默认Box对GT进行匹配;

​ 3)loss为定位损失(SmoothL1 loss)与分类损失(softmax loss)的加权求和。

SSD方法概述

基于前馈CNN产生固定大小的BBox集合和框中目标类别的置信分数,然后用NMS方法得到最终检测结果。本文使用VGG-16模型,再在此基础上添加了辅助结构。SSD的关键点如下所述:

①多尺度特征图检测:将卷积特征层添加到截断基础网络的末尾,实现了多尺度检测。对于每个特征层,预测检测的卷积模型不同。(这与Overfeat和YOLOv1只在单个尺度特征图上检测,仅有一个检测卷积模型不同)

②检测的卷积预测器:每个添加的特征层可以使用一组卷积核产生固定的预测集。对于具有p个通道的大小为m×n的特征层,使用3×3×p的小卷积核做卷积操作,产生类别的分数或相对于默认框的相对形状偏移。在每个应用卷积核运算的m×n大小位置处,产生一个输出值。这个BBox偏移输出值是相对于默认框测量的,默认框位置则是相对于每个特征图的。

image-20220427183643604

③默认框和纵横比:将一组默认的BBox与顶层网络的每个特征图单元关联。每个特征图单元预测在单元中相对于默认框的偏移,同时预测各类别的分数。具体来说,对于在给定位置的k个框中每个框计算c类分数和相对于原始默认框的4个形状偏移量,这使得在特征图中的每个位置需要总共(c+4)k个卷积核,对于m×n特征图产生(c+4)kmn个输出。默认框这种方法与Faster RCNN中的anchor相似,但是本文是将默认框应用于不同分辨率的特征图中。在多个特征图中使用不同的默认框形状,可以有效地将可能的输出框形状空间离散化。

3、论文总结

SSD是在多尺度特征图上提取得到特征,然后评估在该尺度下的目标类别概率及BBox位置偏置。训练中应用到匹配策略(筛选默认框)、默认框比例计算法、数据增强和难例挖掘策略。

本文贡献:

①提出SSD这个单阶段检测器——可用于多类别检测,较YOLOv1更快,准度更高;
SSD方法的核心是使用小卷积核来预测特征图上固定的一组默认BBox的类别分数和位置偏移
③为了实现高检测精度,从不同尺度的特征图上进行不同尺度的预测,并且通过纵横比来明确地分离预测;
④可以实现端到端训练和高精度,在低分辨率输入上也能够获得精度与准度的平衡。

训练整体流程:

①图像经过卷积网络,得到图像的base特征A;
②在对这个特征进行多层级的提取特征图 B ;
③在每个特征图中各个位置都对应多个默认框;
④计算每个默认框的位置偏移 以及 类别得分;
⑤根据默认框以及位置偏移计算区域位置P,再根据类别得分,计算每个默认框的损失函数,累加得到最终的损失函数。

论文缺点:在各个位置中用到的特征仅是该尺度下的特征,没有结合其它层, 没有权衡语义信息和分辨率信息。

六、RetinaNet

1、论文简介

论文名称:《Focal Loss for Dense Object Detection》

论文链接:RetinaNet

源码:RetinaNet实现

摘要:迄今为止精度最高的目标检测器都是基于R-CNN推广的两阶段检测器,即对稀疏的候选目标位置集合应用分类器。相比之下,对可能的目标位置进行常规、密集采样的单阶段目标检测器可能更快、更简单,但迄今为止,其精度落后于两阶段目标检测器。在本文中我们将探讨为什么会出现这种情况,**我们发现,在密集检测器的训练过程中遇到的极端前景-背景类别不平衡是主要原因。我们通过重塑标准交叉熵损失来解决这一不平衡性,从而降低分类良好的示例损失的权重。Focal loss将训练集中在一组稀疏的难分示例上,并防止大量易分负样本在训练期间中占据主导。**为了评估损失的有效性,设计并训练了一种简单的密集检测器RetinaNet。我们的研究结果表明,当使用Focal loss进行训练时,RetinaNet能够与以前的单阶段检测器的速度相抗衡,同时精度超过现有的SOTA两阶段目标检测器。

提出问题:为什么单阶段目标检测器精度落后于两阶段?
主要原因:单阶段检测器训练中会遇到极端前景-背景不平衡问题。
前人解决类别不平衡问题的方法:固定前景-背景比例、OHEM、bootstrapping、HEM。
本文解决方案:提出Focal loss降低分类较好例子的损失权重。

Focal loss:动态变化比例的交叉熵损失,当正确类别置信度增加时,比例因子会衰减到0。比例因子在训练中可自动降低简单样本对权重的贡献并快速使模型关注困难样本。用Focal loss损失训练模型使得训练较用抽样启发和难例挖掘的方法效果更佳。Focal loss没有确切的格式,可以随着任务不同自己调整格式。

单阶段检测器RetinaNet:需要在输入图片中对目标位置做密集采样。特点是在一个有效的网络内使用特征金字塔和anchor框。本文实验得出最好的RetinaNet模型是基于ResNet-101-FPN的,超过了之前所有单模型的单阶段、两阶段目标检测器

2、结构设计

Focal Loss

Cross Entropy Loss(CE)→Balanced Cross Entropy Loss(BCE)→Focal Loss(FL)

①二分类交叉熵损失定义为:

image-20220429154908551

上述 单阶段目标检测重要论文总结 代表前景和背景,单阶段目标检测重要论文总结是模型预测属于前景单阶段目标检测重要论文总结的概率。为了标记方便,定义单阶段目标检测重要论文总结为:

image-20220429155547125

因此简化公式为:单阶段目标检测重要论文总结

②BCEloss:在CE上添加一个权重因子单阶段目标检测重要论文总结给类别1和单阶段目标检测重要论文总结给类别-1,这种单阶段目标检测重要论文总结平衡的交叉熵损失记如下,这种损失是对交叉熵损失的简单扩展。

image-20220429160015619

权重因子单阶段目标检测重要论文总结时效果最好。

③Focal Loss:虽然BCEloss平衡了正负样本,但是没有区分易分、难分样本,基于此引入了调节因子单阶段目标检测重要论文总结使得训练聚焦到难分负样本上。其中单阶段目标检测重要论文总结是可变聚焦参数,因此定义Focal loss为:

image-20220429160601005

Focal loss性质:
a) 当一个样本被误分类并单阶段目标检测重要论文总结时,调节因子单阶段目标检测重要论文总结且损失没有改变。当单阶段目标检测重要论文总结时,单阶段目标检测重要论文总结即分类较好的样本权重较低。
b) 易分样本权重较低时,聚焦参数单阶段目标检测重要论文总结平滑地调整比率。当单阶段目标检测重要论文总结时,Focal loss等于交叉熵损失,当单阶段目标检测重要论文总结增长时,调节因子的影响也在增长。

image-20220429151719334

上图表明了不同单阶段目标检测重要论文总结对loss效果的影响,当单阶段目标检测重要论文总结越大即易分样本,其对应的loss越小。

④本文最终使用的是带有BCEloss权重因子单阶段目标检测重要论文总结的Focal loss:

image-20220429161732404

优点:通过单阶段目标检测重要论文总结可以抑制正负样本的数量失衡,通过单阶段目标检测重要论文总结可以控制易分\难分样本的数量失衡。

注意:Focal loss的精确形式不是很重要,可以有很多变体。

⑤本文中其他形式的Focal loss

image-20220429164335768

效果如下:

image-20220429164420701

image-20220429164444614

Focal loss使用场景:目标检测训练中正负样本极不平衡时。

RetinaNet

由一个主干网络和两个特定任务子网组成。主干网络提取整张输入图像的特征图,主要包括前馈ResNet+FPN,加入FPN目的是为了获得丰富的多尺度特征;第一个子网对主干网络的输出做目标分类,有anchor;第二个子网做预测框回归,从先验框到GT框。

image-20220430102705365

①ResNet+FPN:使用金字塔层的单阶段目标检测重要论文总结单阶段目标检测重要论文总结,结构如下:

层数获得源头源头处操作
单阶段目标检测重要论文总结ResNet(单阶段目标检测重要论文总结)直接从输出计算
单阶段目标检测重要论文总结ResNet(单阶段目标检测重要论文总结)直接从输出计算
单阶段目标检测重要论文总结ResNet(单阶段目标检测重要论文总结)直接从输出计算
单阶段目标检测重要论文总结ResNet(单阶段目标检测重要论文总结)单阶段目标检测重要论文总结上做3×3步长为2的卷积运算
单阶段目标检测重要论文总结单阶段目标检测重要论文总结单阶段目标检测重要论文总结上做3×3步长为2的卷积运算

与FPN不同之处:
1)没有用高分辨率的单阶段目标检测重要论文总结金字塔层,因为计算太复杂;
2)单阶段目标检测重要论文总结是通过有步长的卷积运算得到,而没用FPN中的下采样;
3)在FPN基础上添加了单阶段目标检测重要论文总结层,提升大型目标的检测性能。

②分类子网:在每个空间位置上对于每个A个anchor和K个目标类别预测当前目标出现的概率,这个子网是一个连接每个FPN层的小型FCN;子网参数可以共享到金字塔的各个层,只用到3×3卷积,但不与回归子网共享参数。

层数卷积核尺寸卷积核数量步长/填充输入尺寸输出尺寸
conv1+ReLU3×32561/1W×H×256W×H×256
conv2+ReLU3×32561/1W×H×256W×H×256
conv3+ReLU3×32561/1W×H×256W×H×256
conv4+ReLU3×32561/1W×H×256W×H×256
conv53×3K×A1/1W×H×256W×H×K×A
sigmoid///W×H×K×AK×A

③回归子网:与分类子网并行,此子网也是一个连接到每个FPN层的小型FCN,最后输出得到anchor框相对于邻近GT框的偏移量。设计同分类子网,但是每个空间位置的输出为4A个(即输出A个anchaor框的相对偏移量x,y,w,h)。因此与之前不同的是本文使用是这种参数更少、类不可知且同样高效的BBox回归,即虽然分类子网和回归子网共享同一个FPN,但是使用不同参数。

层数卷积核尺寸卷积核数量步长/填充输入尺寸输出尺寸
conv1+ReLU3×32561/1W×H×256W×H×256
conv2+ReLU3×32561/1W×H×256W×H×256
conv3+ReLU3×32561/1W×H×256W×H×256
conv4+ReLU3×32561/1W×H×256W×H×256
conv53×3K×A1/1W×H×256W×H×K×A
sigmoid///W×H×K×A4×A

3、Focal loss pytorch实现

from torch import nn
import torch
from torch.nn import functional as F


class focal_loss(nn.Module):
    def __init__(self, alpha=0.25, gamma=2, num_classes=5, size_average=True):
        """
        focal_loss损失函数, -α(1-yi)**γ *ce_loss(xi,yi)
        步骤详细的实现了 focal_loss损失函数.
        :param alpha:   阿尔法α,类别权重. 当α是列表时,为各类别权重,当α为常数时,类别权重为[α, 1-α, 1-α, ....],常用于 目标检测算法中抑制背景类 , retainnet中设置为0.25
        :param gamma:   伽马γ,难易样本调节参数. retainnet中设置为2
        :param num_classes:     类别数量
        :param size_average:    损失计算方式,默认取均值
        """
        super(focal_loss, self).__init__()
        self.size_average = size_average
        if isinstance(alpha, list):
            assert len(alpha) == num_classes  # α可以以list方式输入,size:[num_classes] 用于对不同类别精细地赋予权重
            print(" --- Focal_loss alpha = {}, 将对每一类权重进行精细化赋值 --- ".format(alpha))
            self.alpha = torch.Tensor(alpha)
        else:
            assert alpha < 1  # 如果α为一个常数,则降低第一类的影响,在目标检测中为第一类
            print(" --- Focal_loss alpha = {} ,将对背景类进行衰减,请在目标检测任务中使用 --- ".format(alpha))
            self.alpha = torch.zeros(num_classes)
            self.alpha[0] += alpha
            self.alpha[1:] += (1 - alpha)  # α 最终为 [ α, 1-α, 1-α, 1-α, 1-α, ...] size:[num_classes]

        self.gamma = gamma

    def forward(self, preds, labels):
        """
        focal_loss损失计算
        :param preds:   预测类别. size:[B,N,C] or [B,C]    分别对应与检测与分类任务, B批次, N检测框数, C类别数
        :param labels:  实际类别. size:[B,N] or [B]        [B*N个标签(假设框中有目标)],[B个标签]
        :return:
        """
        # 固定类别维度,其余合并(总检测框数或总批次数),preds.size(-1)是最后一个维度
        preds = preds.view(-1, preds.size(-1))
        self.alpha = self.alpha.to(preds.device)

        # 使用log_softmax解决溢出问题,方便交叉熵计算而不用考虑值域
        preds_logsoft = F.log_softmax(preds, dim=1)

        # log_softmax是softmax+log运算,那再exp就算回去了变成softmax
        preds_softmax = torch.exp(preds_logsoft)

        # 这部分实现nll_loss ( crossentropy = log_softmax + nll)
        preds_softmax = preds_softmax.gather(1, labels.view(-1, 1))
        preds_logsoft = preds_logsoft.gather(1, labels.view(-1, 1))

        self.alpha = self.alpha.gather(0, labels.view(-1))

        # torch.mul 矩阵对应位置相乘,大小一致
        # 这里对应于公式的loss = -(1-p_t)^y*log(p_t)
        loss = -torch.mul(torch.pow((1 - preds_softmax), self.gamma), preds_logsoft)

        # torch.t()求转置
        loss = torch.mul(self.alpha, loss.t())
        if self.size_average:
            loss = loss.mean()
        else:
            loss = loss.sum()
        return loss

4、论文总结

本文贡献:

①提出了一种基于交叉熵损失的新loss:Focal loss,通过控制正负样本权重和易分/难分样本权重得到好的结果(因为类别不平衡是一阶段检测器的通病,所以这点改进效果提升明显),使得目标检测器准确率提升,同时实现了单阶段目标检测的密集检测。

②提出全卷积的单阶段检测器RetinaNet,backbone使用ResNet+FPN,使用了多尺度特征的方法,并在FPN的基础上做了一些改进,使得保证检测精度的同时提升检测速度。

缺点:速度太慢

七、YOLOF

1、论文简介

论文名称:《You Only Look One-level Feature》

论文链接:YOLOF

实现源码:YOLOF实现

摘要:本文回顾了用于单阶段检测器的FPN,指出FPN的之所以是由于它对目标检测中的优化问题的分而治之的解决方案,而不是多尺度特征融合。从优化的角度来看,我们引入了一种替代方法来解决这个问题,而不是采用复杂的FPN——只使用一层特征进行检测。基于简单而高效的解决方案,我们提出了YOLOF,在该方法中,提出了两个关键组件:膨胀编码器和均衡匹配,并带来了相当大的改进。在COCO benchmark上的大量实验证明了该模型的有效性,YOLOF在速度为RetinaNet的2.5倍的情况下,实现了与带有特征金字塔的RetinaNet相当的结果。在没有transformer层的情况下,YOLOF可以利用单层特征与DETR的性能相抗衡,并且训练次数可以减少7倍。

提出问题:能否不用FPN就达到分而治之的目的?(因为多层分治会使检测器结构复杂从而降低检测速度)

分析问题:FPN中有两种策略:①多尺度融合策略;②分治策略(即针对不同目标尺度选择在不同的层检测目标)。

实验实施:解耦两种策略,在RetinaNet上分别用这两种策略中的一种。将FPN看做是多入多出编码器,并对比多入多出,单入多出,多入单出,单入单出策略,对比发现多入多出,单入(C5特征图)多出得到的mAP指标相距甚微。

实验结论:C5特征图已经携带了足够多的不同尺度上的检测上下文信息,多尺度特征融合策略没有分治策略对FPN那么重要。

解决方法:用一层C5特征图解决优化策略问题,提出YOLOF。为弥补单入单出和多入多出编码器的性能差距,提出了膨胀编码器(解决多层特征信息缺乏问题)和均衡匹配组件(解决单一特征中稀疏anchor引起的真样本anchor的不平衡问题)。

2、结构设计

SiSo结构取代MiMo结构造成性能大幅下降原因:①与C5特征图感受野匹配的目标尺度范围是有限的,阻碍了不同尺度目标的检测性能;②单层特征图上由稀疏anchor生成策略引起的正样本anchor的不均衡问题。

膨胀编码器

受限尺度范围问题

SISO结构只会输出固定感受野的单层特征图。如图(a)所示,当一层特征图只能覆盖一个受限的感受野,且目标的尺度和感受野不匹配时检测效果就会很差。

通过堆叠标准卷积和膨胀卷积增大感受野,使得覆盖尺度范围得到一定程度的扩大,但仍不能覆盖所有的目标尺度,因为扩大过程相当于将一个大于1的因子乘以原来覆盖的所有尺度。如图(b)所示,表明了扩大了的尺度范围虽然可以使得特征能够覆盖大目标,但是仍然会错失小目标的检测。

如果将原始特征图(C5)和扩大感受野的特征图相加,就能覆盖所有目标尺度的特征图。如图©所示,具有多个感受野的特征覆盖了所有目标尺度。

image-20220505173924653

通过在中间的3×3卷积层上构造带有膨胀的残差块实现,将之称为膨胀编码器

image-20220505193248859

膨胀编码器有两个模块:投影模块+残差模块。该编码器使得我们可以再单层特征图中做各种尺度的目标检测,不需要再使用多层特征图了。残差模块的第一个1×1卷积用于减少通道维数,3×3卷积用于增大感受野,第二个1×1卷积用于恢复通道维数。

模块类型元素说明
投影模块1个1×1卷积层+1个3×3卷积层1×1卷积用于减少通道维数,3×3卷积用于提炼语义上下文信息,与FPN相同。
残差模块4×(1×1卷积层+3×3卷积层+1×1卷积层)每个膨胀残差块的膨胀率不同,以此产生多感受野的输出特征图,包含所有目标尺度。

注:每个膨胀残差快没有共享权重,投影模块每个卷积层是CB(Conv+BN)范式,残差模块每个卷积层都是CBR(Conv+BN+ReLU)范式。

均衡匹配策略

正样本anchor不均衡问题

正样本定义是基于anchor和GT框之间的IOU进行的,若一个anchor和GT之间的最大IOU大于一个给定的阈值叫这个anchor为正样本的话,则称此策略为Max-IOU匹配。

MiMo结构中,anchor以一个密集平铺的方式在多层特征图上预定义,GT框根据尺度在不同层的特征图上产生正样本,Max-IOU匹配使得GT框在各个尺度可以产生足够数量的正样本。但在SiSo结构中,正样本数量急剧减少,导致anchor非常稀疏,对稀疏anchor采用Max-IOU引起的问题如下:

image-20220505201243079

大GT框回避小GT框产生更多的正anchor,从而造成了正anchor的不平衡问题,导致检测器只关注大目标而忽视小目标。

均衡匹配策略:对每个GT框而言,将K个最近的anchor和K个最近的预测框的索引标记为标记为正样本,使得GT框无论尺度大小(也可以说目标无论大小)都有相同数目的正样本与之匹配。

YOLOF

image-20220505203718400

backbone:ResNet和ResNeXt系列,输出特征图是C5,通道数2048,下采样率32。

neck(encoder):对backbone输出使用两个投影模块,再用残差模块,结构上面已说。

head(decoder):两个并行分支,用于目标分类和边框回归。在DETR的FFN基础上修改两处:①两个head卷积层数目不同,回归分支中,是四个卷积层+BN层+ReLU层,分类分支是只有两个卷积层;②依据Autoassign,为回归分支的每个anchor增加一个隐式的置信分数objectness(没有直接监督),最终分类的置信度是由分类分支的输出和objectness得分相乘得到(与Yolov1类似)。

4、论文总结

本文贡献:

①发现FPN最重要的好处是对密集目标检测器的优化问题上有分治策略,多尺度特征融合只是其次的。
②提出YOLOF,不用FPN达分治目的。提出YOLOF关键组件:扩展编码器和均衡匹配,弥补SiSo与MiMo编码器的性能差距。使用单层特征图就可以达到多尺度目标检测的目的。
③在COCO基准上做了各组件重要性测试,并与RetinaNet和DETR做了对比,在精度几乎一致的前提下速度提高了。

八、CornerNet

1、论文简介

论文名称:《CornerNet: Detecting Objects as Paired Keypoints》

论文链接:CornerNet

实现源码:CornerNet实现

摘要: CornerNet——一种新的目标检测方法即使用单个CNN将目标BBox看作成对的关键点的检测,这个关键点是左上角以及右下角(通过检测目标框的左上角和右下角两个关键点得到预测框)。 通过将目标检测为成对的关键点,这就不需要再用anchor框了。 除了新构思之外,我们还引入了边角池化,这是一种新型的池化层,可以帮助网络更好地定位角点。 实验表明,CornerNet 在 MS COCO 上实现了 42.2% 的 AP,优于所有现有的一级检测器。

本文动机:可以不用anchor做目标检测吗?

分析基于锚框检测器的缺点:

①产生锚框的数量太大,造成正样本锚框样本及其不均衡,训练速度也慢。

正样本不均衡原因:anchor框数量巨大,能与GT框的IOU超过设定阈值的anchor框并不多,如果想解决此问题需要设定IOU阈值上下限、设定正负样本比例以及难负例挖掘。

②使用锚框引入了许多超参数如锚框数量、尺寸、长宽比,当与多尺度模型架构结合时会使问题变得更加复杂

复杂原因:单个网络在多个分辨率图像上是进行单独预测的,每个分辨率对应不同尺度大小,不同尺度大小又会使用不同的特征和独有的一组锚框。(锚框的尺寸是根据图像以及目标尺度来的,不是随便设的,因此各个尺度的锚框是独有的,可以自己根据经验设定锚框超参数,也可以根据Kmeans聚类确定)

解决办法:提出anchor-free的CenterNet。

具体做法①:将目标检测为一对关键点,这个关键点是BBox的左上角和右下角。使用单个CNN来预测同一目标类别的所有实例的左上角的热图、右下角热图以及每个检测角的嵌入向量,embedding用于对属于同一对象的一对角进行分组,具体是计算两种角点embedding的距离,若距离最小则说明两个角点是同一类目标。训练网络也就是要让网络能够预测它们的相似embedding。

优点:简化了网络输出并除去了anchor框。

image-20220507194058783

具体做法②:提出角池化层,该层以两个特征图作为输入,在每个像素位置,从其中一个特征图上最大池化位于这个位置右边的所有位置的特征向量,从另外一个特征图上最大池化位于这个位置下边的所有位置的特征向量,然后将两个向量相加得到此位置的最终向量(长度为1)。每个类别独立进行该操作,因此有多少个类别,这个向量长度就是num_classes,所有位置的向量就构成了一张热图。

优点:帮助CNN更好地定位BBox的角点。

检测角点为什么比检测中心点或region proposal方法更好?

答:①框的中心点很难去定位因为它依赖于目标的四条边,而定位角点方法只需要两条边就够了,再加上角池化运用了角的先验知识(即左上角是由最上边界和最左边界确定这样的),因此更加简单。②比起region proposal方法,角在离散化BBox空间上更加高效。比如一张单阶段目标检测重要论文总结大小的特征图,检测角点方法一共只有单阶段目标检测重要论文总结种可能,而带有anchor框的region proposal方法则有单阶段目标检测重要论文总结种可能,设每个位置有A个anchor。

2、结构设计

CornerNet总体框架

网络预测两组热图去表征不同目标类别的角点位置以及嵌入向量。

image-20220513151636076

流程:网络输入图像之后先经过1个7×7的卷积层将图像缩小为原来的1/4,然后经过backbone(沙漏网络)提取特征,之后再通过两个预测模块,分别是左上角预测分支和右下角预测分支,每个分支模块最终产生3个输出:heatmap、embeddings、offsets。

heatmap是角点信息,用维度为CHW的特征图表示,其中C表示目标类别(无背景类),特征图每个通道都是一个mask,mask的每个值表示该点是角点的得分;

embedding表示对预测的角点做分组的分组信息,也就是说找到属于同一目标的左上角和右下角;通道为1因为embedding只需要在一张图中反映各类别目标信息。

offsets表示预测框的微调,这是因为从输入图像中的点映射到特征图时有量化误差,offsets就用来输出这些误差信息。通道为2是因为要分别调整x,y轴方向的。

沙漏网络

image-20220518145705190

一个沙漏网络由若干沙漏模块组成(本文为两块),沙漏模块具体结构为:

image-20220509103119687

沙漏结构先由卷积和池化将输入下采样到一个很小的尺寸,之后再用最近邻上采样方法进行上采样,将特征图恢复到最开始的尺度,每个上采样层都有一个跳跃连接,跳跃连接是一个残差模块。沙漏结构可以获取不同尺度下图片的信息,有局部信息和全局信息。

预测模块

image-20220516140524673

角池化

角池化层原理:当BBox的角不包含目标时,不能根据局部特征对角进行定位。一般确定像素位置是否是左上角,需要从这个位置水平向右看,知道是不是目标的最上边界,同时也需要垂直向下看,才能知道是不是目标的最左边界。

image-20220507194348371

角池化概念:

image-20220507200705914

image-20220509110000728

式子中单阶段目标检测重要论文总结单阶段目标检测重要论文总结分别代表输入到左上角池化层的特征图,单阶段目标检测重要论文总结单阶段目标检测重要论文总结分别代表在特征图单阶段目标检测重要论文总结单阶段目标检测重要论文总结位置(i,j)处的向量,如果特征图大小为H×W,那么首先池化层需要最大池化在特征图单阶段目标检测重要论文总结的(i,j)和(i,H)之间的所有向量化为单阶段目标检测重要论文总结,然后再最大池化在特征图单阶段目标检测重要论文总结的(i,j)和(i,W)之间的所有向量化为单阶段目标检测重要论文总结,最后将单阶段目标检测重要论文总结单阶段目标检测重要论文总结相加。右下角层化层工作原理与左上角相似。

image-20220509112048190

loss函数

对每个角都有一个相对于GT的正位置,所有其他位置都是负的。训练期间减少正位置半径内负位置的惩罚,确保半径内的一对点将生成一个与GT的IOU至少为t的BBox以此来确定半径。给定半径,则惩罚量的减少由未归一化的2D高斯函数给出,这里中心点单阶段目标检测重要论文总结为正样本角点位置,单阶段目标检测重要论文总结为半径的1/3。

image-20220518150240496

那么这个半径怎么确定呢?

答:依赖于目标BBox的宽高,以IOU=0.7作为临界值,分别计算出下面三种临界情况的半径,取最小值作为高斯核的半径。情况一为两个角点均出现圆外切情况,如果使得BBox与GT的IOU大于0.7即交集要增大,那么要将绿色框缩小,此时圆半径变小;情况二为两个角点均出现圆内切情况,如果使得BBox与GT的IOU大于0.7,那么要将绿色框增大,此时圆半径变小;情况三为一个角点出现圆内切情况且另一个角点出现圆外切情况,如果使得BBox与GT的IOU大于0.7,那么需要使得绿色框向红色框方向偏移,圆半径变小。若要同时满足上面三种情况,则需要取所有圆半径的交集作为高斯核半径。

image-20220510113357219

①Headmaps的loss函数:

image-20220507214800391

image-20220518150149326

单阶段目标检测重要论文总结表示预测的热图在第C个通道(类别C)的位置单阶段目标检测重要论文总结的得分;

单阶段目标检测重要论文总结表示为使用非归一化高斯函数增强的GT热图在第C个通道(类别C)的位置单阶段目标检测重要论文总结的值;

单阶段目标检测重要论文总结可以理解为从预测角点到GT角点的距离,这个距离被高斯函数非线性化了,所以离GT近的负样本惩罚就小了。

单阶段目标检测重要论文总结表示此位置就是GT角点位置;

单阶段目标检测重要论文总结为一张热图中目标数量,单阶段目标检测重要论文总结控制难分易分样本的损失权重。

②Embeddings的loss函数:

image-20220509095604379

其中单阶段目标检测重要论文总结是目标左上角的embedding得分,单阶段目标检测重要论文总结是目标右下角的embedding得分,单阶段目标检测重要论文总结代表单阶段目标检测重要论文总结单阶段目标检测重要论文总结均值,

N代表GT中目标数量,单阶段目标检测重要论文总结就是一个常数因子,论文中设置为1。

Pull loss越小表示同一目标的左上角和右下角的embedding的得分距离越小即左上角和右下角匹配同一目标的可能性越大,push loss越小表示不同的目标的左上角和右下角的embedding得分距离越大即左上角和右下角匹配同一目标的可能性越小。

③Offsets的loss函数:

一张图输入到网络中,原先位置为(x,y)的投影到热图就变为(x/n, y/n),n是下采样率,当从热图再投影回输入图像时就会出现量化误差(即有除不整的情况出现,这样会导致投影回去的坐标有差距,影响IOU的计算),为解决此问题,在投影回原输入图像之前微调角点位置。

image-20220509101024207

这里单阶段目标检测重要论文总结是GT角点的偏移量,单阶段目标检测重要论文总结单阶段目标检测重要论文总结代表角点k的x和y坐标。

image-20220509101333831

这里单阶段目标检测重要论文总结是预测角点的偏移量,N代表GT中目标数量

④总损失函数

image-20220509101734646

3、训练测试细节

训练:

  1. 随机初始化的,没有在任何外部数据集上进行预训练。
  2. 遵循Focal loss for dense object detection中的方法设置预测Heatmaps的卷积层的biases。
  3. 网络的输入分辨率是511×511, 输出分辨率为128×128。
  4. 为了减少过拟合,我们采用了标准的data augmentation,包括随机水平翻转、随机缩放、随机裁剪和随机色彩抖动,其中包括调整图像的亮度,饱和度和对比度。
  5. 使用PCA分析图像数据。
  6. 使用Adam优化训练损失

测试:

使用simple post-processing算法从Heatmaps, Embeddings, Offsets生成BBox。首先在heatmaps上使用3*3的max pooling进行非极大值抑制(NMS)。然后从Heatmaps中选择scores前100的top-left corners和前100的bottom-right corners,corner的位置由Offsets上相应的scores调整。 最后,计算top-left corners和bottom-right corners所对应的Embeddings的L1距离。距离大于0.5或包含不同类别的角点对将被剔除。配对上的top-left corners和bottom-right corners以Heatmaps的平均得分用作检测分数。

作者没有使用resize的方法保持输入图像的原始分辨率一致,而是维持原分辨率,用0填充缺失和超出的部分。 原始图像和翻转图像都参与测试,并应用soft-nms来抑制冗余检测。 仅记录前100个检测项。

4、论文总结

本文贡献:

①提出角点检测方法生成BBox,免除了anchor框。
②提出角池化概念,帮助CNN更好地定位角点。
③第一个将目标检测任务表述为使用embedding检测和角点分组任务。
④修改了沙漏架构并且对focal loss做改变去训练网络。

缺点:

①计算速度慢,因为要逐像素进行最大池化操作。
②小目标检测性能一般

九、CenterNet

1、论文简介

论文名称:《Objects as Points》

论文链接:CenterNet

实现源码:CenterNet实现

摘要:检测将目标识别为图像中的轴对齐框。 大多数成功的对象检测器都会列举详尽的潜在目标位置列表,并对每个位置进行分类。 这是浪费的、低效的,并且需要额外的后处理。 在本文中我们采用了不同的方法。我们将一个目标建模为一个点——BBox的中心点。 我们的检测器使用关键点估计来找到中心点并回归到所有其他目标属性,如大小、3D 位置、方向,甚至姿势。CenterNet具有端到端的可微分性且比相应的基于BBox的检测器更简单、更快且更准确。

问题:①anchor的定义在一定程度上限制了算法的性能。②后处理操作会降低整个检测的速度,大多数检测器都不是端到端可训练的。

解决措施:通过BBox的中心点来表示目标,然后直接从中心位置的图像特征回归得到其他属性,因此就将目标检测问题化成了关键点检测问题,只需要将图像输入到生成热图的FCN中,此热图的峰值就是目标中心。每个热图的峰值预测目标的BBox高宽,训练用标准密集监督学习,测试用单网络前向传递,没有NMS。

优点:①输出分辨率大,下采样率为4,对小目标召回率高。②不需要NMS

缺点:同一类别的两个物体中心点相同,模型只能给出一个物体检测框,因为输出特征图同一位置只设置一个样本。

2、结构设计

CenterNet总体框架

网络预测关键点值单阶段目标检测重要论文总结,偏移单阶段目标检测重要论文总结,大小单阶段目标检测重要论文总结,网络在每个位置总共预测C+4个输出,所有输出共享一个共同的FCN网络。

image-20220510095623995

image-20220513151749500

backbone

分别使用三种backbone对比实验

image-20220510114350690

(a)为使用沙漏网络,(b)为使用转置卷积的ResNet网络,©为使用最初语义分割的DLA-34网络,(d)为使用修改的DLA-34网络

若用ResNet50提取图片特征,首先使用反卷积改变通道维度,然后再用转置卷积对特征图进行上采样(3个转置卷积因此上采样三次),最后三个分支卷积网络用来预测heatmap, 目标的宽高和目标的中心点坐标。值得注意的是转置卷积模块,其包括三个转置卷积组,每个组都包括一个3*3的卷积和一个转置卷积,每次转置卷积都会将特征图尺寸放大一倍。

image-20220518152356293

结论:沙漏网络性能最好,但速度最慢。

损失函数

①Heatmaps的loss函数

对于类别C的每个GT关键点单阶段目标检测重要论文总结都计算一个低分辨率等价的单阶段目标检测重要论文总结,然后使用高斯核将所有的GT关键点放在一张热图单阶段目标检测重要论文总结上。如果同一类的两个高斯函数重叠,取逐元素最大值。训练置信分数是用带有focal loss的逐像素惩罚减少的逻辑回归。

单阶段目标检测重要论文总结

这里单阶段目标检测重要论文总结单阶段目标检测重要论文总结是focal loss的超参数,N是图像I的关键点数目。GT关键点信息为单阶段目标检测重要论文总结,预测关键点信息为单阶段目标检测重要论文总结

②Offsets的loss函数

为恢复输出步长引起的离散化误差,对每个中心点另外预测了一个局部偏移单阶段目标检测重要论文总结,所有类别C共享相同的偏差预测。

单阶段目标检测重要论文总结

p是GT中心点在原图中坐标,p/R是理论上该点映射到特征图的坐标,实际上映射后的坐标为单阶段目标检测重要论文总结,量化误差为单阶段目标检测重要论文总结KaTeX parse error: Got function ‘\tilde’ with no arguments as subscript at position 8: \hat{O_\̲t̲i̲l̲d̲e̲{p}}是网络的offset输出特征图,即预测中心点的偏移。

监督只在关键点位置单阶段目标检测重要论文总结起作用,其他位置都是忽略的。

③weight&height的loss函数

单阶段目标检测重要论文总结为目标k的GT坐标,单阶段目标检测重要论文总结是目标k的宽高,因为坐标已经除以下采样率了,所以计算出来的是在输出特征图上的大小。为限制计算量,对所有目标类别使用单个尺寸的预测单阶段目标检测重要论文总结,用L1loss计算中心点置信loss。不归一化尺度直接用原始像素坐标。

image-20220513142420719

训练中整体loss

image-20220510094757915

Heatmaps生成步骤

产生热图步骤:

如下图左边是缩放后送入网络的图片,尺寸为512×512,右边是生成的heatmap图,尺寸为128×128(网络最后预测的heatmap尺度为128×128。其步骤如下:

①将目标的box缩放到128×128的尺度上,然后求box的中心点坐标并取整,设为point

②根据目标box大小计算高斯圆的半径,设为R

③在heatmap图上,以point为圆心,半径为R填充高斯函数计算值。(point点处为最大值,沿着半径向外按高斯函数递减)

image-20220510112837660

由于两个目标都是猫,为同一类别,所以在同一张热图上,若输入图像上还有其他类别的目标,则该目标的关键点在另外一张热图上显示。

测试阶段细节

推理阶段,首先在热图中对每个类别独立地提取峰值,检测所有值小于或等于它的8邻域的响应,并保留前100的峰值,设单阶段目标检测重要论文总结是类别c的n个检测中心点单阶段目标检测重要论文总结的集合,通过一个整数坐标单阶段目标检测重要论文总结得到每个关键点位置,使用关键点值单阶段目标检测重要论文总结作为它的检测置信度度量,并且在关键点位置处产生一个BBox。

image-20220510100528114

这里单阶段目标检测重要论文总结是预测的偏移,单阶段目标检测重要论文总结是预测的尺寸。所有的输出直接由关键点估计产生,不需NMS等后处理,因为峰值关键点提取就已经能够看作是一个充分的NMS方案了,这个提取可以用3×3最大池化来完成。

3、论文总结

本文贡献:模型可应用于两阶段和单阶段,可推广到目标检测、3D检测和人体姿态识别领域

本文优点:没有用基于IOU的NMS方法,用到3×3最大池化对生成的热图进行抑制,筛选出最有可能出现的点。省去了NMS时间。

本文缺点:

①若两个不同物体中心点在一起,CenterNet只会检测到其中的一个。
②小目标检测性能一般

十、CenterNet++

1、论文简介

论文名称:《CenterNet: Keypoint Triplets for Object Detection》

论文链接:CenterNet

实现源码:CenterNet实现

摘要:在目标检测中,基于关键点的方法通常会遇到大量不正确的目标边界框,这可能是由于缺少对裁剪区域的检查。 本文提出了一种有效的解决方案,以最小的成本检索每个裁剪区域内的视觉模式。我们方法命名为CenterNet,是在CornerNet基础上做的。它将每个目标检测为一个三元组关键点,而不是一对关键点,提高了精度和召回率。 此外还设计了两个自定义模块,分别称为级联角池化和中心池化,它们分别起到丰富左上角和右下角收集的信息并在中心区域提供更多可识别信息的作用。 在 MS-COCO 数据集上,CenterNet 实现了 47.0% 的 AP,比所有现有的一级检测器至少高出 4.9%。 同时,凭借更快的推理速度,CenterNet 表现出与顶级两阶段检测器相当的性能。

问题:CornerNet对目标全局信息的引用能力较弱,这制约了模型性能。(每个目标由一对角构成,算法对检测目标的边界很敏感,但是不知道哪些关键点应该被归为目标)

分析原因:CornerNet无法查看边界框内的区域

image-20220513170729749

解决方案:

①提出CenterNet,使用三元组关键点。
②提出中心池化(丰富中心信息,更容易感知中心部分)和级联角池化(丰富角点信息,使原角池化模块具备了感知内部信息的能力)

原理:如果一个预测的BBox与GT有高的IOU,那么其中心区域的中心关键点被预测为同一类的概率就高。在推理过程中,在proposal作为一对角点生成后,通过检查是否有一个属于同一类的中心关键点位于其中心区域,来确定该proposal是否确实是一个目标。

优点:双向池化方法更鲁棒,有助于提高精度和recall

2、结构设计

image-20220513172406278

网络输出两个角点热图和中心点热图,一对角点和embeddings用来对两个角点做匹配生成潜在BBox,中心点用来决定是否最后输出这个BBox。

如何使用三元组关键点

使用CornerNet中提出的方法来生成top-k边界框后,为了有效地过滤不正确的包围框,我们利用检测到的中心关键点,采取以下步骤:

①根据得分选择top-k的中心关键点
②利用相应的偏移量将这些中心关键点重新映射到输入图像上
③为每个边界框定义一个中心区域,并检查中心区域是否包含中心关键点。 注意,选中的中心关键点的类标签应与BBox的类标签相同。
④如果在中心区域检测到一个中心关键点,我们将保留BBox。 BBox的得分将被左上角、右下角和中心关键点三个点的平均分所取代。 如果在它的中心区域没有检测到中心关键点,BBox将被移除。

边框中心区域大小会影响检测结果,提出尺度感知的中心区域自适应BBox大小。尺度感知的中心区域倾向于为较小的BBox生成相对较大的中心区,为一个较大的BBox生成一个相对较小的中心区。假设想确定一个BBox i是否需要保留,单阶段目标检测重要论文总结表示左上角坐标,单阶段目标检测重要论文总结表示右下角坐标;定义一个中部区域单阶段目标检测重要论文总结单阶段目标检测重要论文总结表示单阶段目标检测重要论文总结的左上角坐标,单阶段目标检测重要论文总结表示单阶段目标检测重要论文总结的右下角坐标。使得上面符号满足:

image-20220513185517867

其中n为奇数,决定中心区域j的尺度。论文中对于小于150的边界框和大于150的边界框,n分别设为3和5。

image-20220513185701890

中心池化

为什么要中心池化:物体的几何中心不一定传达可识别的视觉模式,要使用一种可以捕获更丰富和更易于识别的视觉模式的trick才行。

中心池化原理:backbone输出一个特征图,要确定特征图中的一个像素是否为中心关键点,需要在其水平和垂直方向上都找到最大值并相加。 通过这样做,中心池有助于更好地检测中心关键点。

image-20220513185845018

(a)显示中心池化是将垂直和水平方向的最大值相加

(b)显示角池化只是获得了边界方向的最大值

©显示了级联角池化将边界方向和目标内部方向的最大值相加

中心池化模块:结合不同方向角池化即可实现,若想实现水平方向池化,只需串联左池化和右池化即可。

image-20220513191752052

级联角池化

角池化使得角对边非常敏感,需要让角落看到物体的视觉模式。

原理:首先沿边界寻找边界最大值,然后沿着边界最大值的位置寻找内部最大值,然后将两个最大值相加,通过这样做,角既获得了物体的边界信息,又获得了物体的视觉模式。

寻找内部最大值的方向定义:对于最顶部、最左侧、最底部和最右侧边界,分别垂直向下看、水平向右看、垂直向上看、水平向左看。(图里方向画错了)

级联角池化模块:同样是结合不同方向的角池化。例如级联上角池化模块,在上角池化前加入一个左池化即可。

image-20220513191853771

LOSS函数

image-20220513193326077

单阶段目标检测重要论文总结单阶段目标检测重要论文总结表示Focal Loss,分别用来训练网络检测角点和中心关键点。

单阶段目标检测重要论文总结单阶段目标检测重要论文总结同CornerNet。

单阶段目标检测重要论文总结单阶段目标检测重要论文总结用来训练网络预测角点和中心关键点的偏移量,与CornerNet不同在于这里用l1 loss。

3、测试细节

单尺度:将原始和水平翻转原始分辨率图像作为输入。

多尺度:将原始和水平翻转且分辨率分别为原始图像的0.6,1,1.2,1.5,1.8的图像作为输入。

选择热图中分数最高的70个中心点、70个左上角点以及70个右下角点去检测BBox,翻转水平翻转图像中检测到的BBox,并将之混合到原始BBox中。用Soft-nms去除多余BBox,最终根据得分选前100的BBox作为最终检测结果。

4、论文总结

image-20220513201021147

本文贡献:

①对CornerNet做了改进,自定义中心池化和级联角池化模块,使得检测结果更加鲁棒。
②使用三元组角点检测,让池化模块具有感知中心信息和内部信息的能力。

论文缺点:虽然检测性能提升了但是较CornerNet更慢了。

十一、FCOS

1、论文简介

论文名称:《FCOS: Fully Convolutional One-Stage Object Detection》

论文链接:FCOS

论文实现:FCOS实现

摘要:我们提出了一种全卷积的单阶段目标检测器(FCOS),以类似于语义分割的逐像素预测方式解决目标检测问题。 几乎所有最先进的目标检测器,如 RetinaNet、SSD、YOLOv3 和 Faster R-CNN 都依赖于预定义的锚框。 相比之下,我们提出的检测器 FCOS 是anchor-free的,也无region proposal。 通过消除预定义的一组锚框,FCOS 完全避免了与锚框相关的复杂计算,例如在训练过程中计算IOU。 更重要的是,我们还避免了所有与锚框相关的超参数,这些超参数通常对最终检测性能非常敏感。凭借唯一的后处理NMS方式,FCOS with ResNeXt-64x4d-101在单模型单尺度测试的 AP 中达到 44.7%,超越了之前的单阶段检测器,且优势在于FCOS更简单。

动机:提出一种anchor-free检测器,使得检测器避免anchor、region proposal和anchor超参数。

问题1:现阶段目标检测都是需要预定义anchor的
解决方案:提出FCOS,使得它可以以类似FCN语义分割的逐像素预测方式进行目标检测。

问题2:FCOS可能会产生大量低分辨率的预测BBox
解决方案:引入新的center-ness分支来预测像素与其相应BBox中心的偏差,使得基于 FCN 的检测器可以超过基于锚框的检测器。

问题3:FCOS遇到目标重叠可能会带来recall降低,怎么解决?
解决方案:使用FPN结构,使不同尺度的目标能够在不同尺度的特征图上检测出,避免了上述问题。

实验结论:①能够以逐像素方式对目标进行预测②基于FCN的检测器比基于锚的性能更优。

FCOS优点:

①与其他使用FCN的任务(语义分割)是一样的,可以用到其他任务中的思想。
②不需要proposal和anchor,减少了参数量
③FCOS在单阶段是SOTA,也可以作为两阶段检测器的RPN网络,实现了优于基于锚框的RPN算法性能。
④FCOS可以小改后用到其他任务中:实例分割和关键点检测。

2、结构设计

网络设计

image-20220518104428930

网络直接使用了RetinaNet的backbone,只是在分类分支上多了一个center-ness用于确定当前点是否是检测目标的中心;而由于没有anchor,最后分类分支和回归分支输出的feature map depth也分别是C和4,不需要乘以anchor数(K),因此相比anchor based的输出,FCOS的骨架输出可用减少K倍;而分类分支的分类器也从多分类器换成了C个二分类器

正样本制作

特征图上的某个点只要落在GTbox区域中,这个点就是正样本;**如果这个点在多个GT box中,那么这个点就是混淆样本,当混淆情况出现时文章采用面积最小的GTBox作为这个点的回归目标。**目标框的回归从回归GT坐标单阶段目标检测重要论文总结改变到回归当前点到框的各边距离单阶段目标检测重要论文总结相比基于anchor的检测器,这种检测器能够产生更多的正样本用于训练回归,因此这也是FCOS性能超过其他基于anchor检测器的原因之一。

image-20220518144056392

loss函数

单阶段目标检测重要论文总结

单阶段目标检测重要论文总结是focal loss(单阶段目标检测重要论文总结是分类分数,单阶段目标检测重要论文总结是类别)单阶段目标检测重要论文总结是IOU loss(单阶段目标检测重要论文总结是GT的location参数,单阶段目标检测重要论文总结是回归预测的location参数),单阶段目标检测重要论文总结代表正样本数量,单阶段目标检测重要论文总结单阶段目标检测重要论文总结的权重,单阶段目标检测重要论文总结代表如果类别是前景则判断为1,否则是0。整个式子是在特征图单阶段目标检测重要论文总结中计算所有location的loss(i是特征图所在层数)。

1、focal loss

image-20220429155547125

image-20220429160601005

2、IOU loss

image-20220518153149141

基于FPN的多层预测

问题背景:对应于问题3

细节1:直接限制各层特征图上能够回归的距离范围。首先需要计算所有特征层上的每个回归位置的l,t,r,b,如果一个点的单阶段目标检测重要论文总结单阶段目标检测重要论文总结那么这个点就作为负样本,这里单阶段目标检测重要论文总结代表特征层第i层的最大距离。

细节2:预测头在各层是公用的(同FPN),降低参数量同时提高了性能,但是每一层的回归尺寸大小不同(每一层都设计不同的尺寸范围),因此回归计算的时候使用包含可训练标量单阶段目标检测重要论文总结单阶段目标检测重要论文总结来自动调整特征层单阶段目标检测重要论文总结的指数函数的基底,这会轻微提升检测性能。

Center-ness

问题背景:对应于问题2

设计初衷:因为有大量远离GTBox的低质量误检,设计Center-ness用于预测当前点是否是目标的中心。目标点的中心度评价公式为:

image-20220518155943233

根号是为了降低中心度随距离增大的衰减程度。因为中心度大小都在0~1之间,因此在训练时使用BCE loss,然后将这个loss添加到整体loss函数中;在推理的时候直接将中心度分数乘到分类分数上,将偏离很远的检测框分值进行惩罚,然后用NMS就可以很容易去除。

替代方案:仅使用GT box的中心部分作为正样本,但是会增添一个额外超参。Center-ness方法和替代方案的结合可实现更好性能。

3、实验结果

①FCOS中FPN的在降低混淆上的作用远大于其在提高召回率上的作用

②Center-ness可以显著提高精度

③Center-ness方法和仅将GT box中心作为正样本训练方法的结合可实现更好性能。

image-20220518161411065

4、论文总结

这篇论文中的框架结构是对RetinaNet的继承

论文贡献:

①用语义分割逐像素预测的方式进行目标检测
FCOS可以替代Faster RCNN中的RPN网络,性能优于RPN
③可以从本论文中拓展为其他任务

论文缺点:

①使用FPN必定会使检测器速度变慢

十二、YOLOX

1、论文简介

论文名称:《YOLOX: Exceeding YOLO Series in 2021》

论文链接:yolox

论文实现:yolox实现

摘要:我们介绍了对 YOLO 系列的一些改进,形成了一种新的高性能检测器——YOLOX。 将 YOLO 检测器切换为anchor-free的并进行其他高级检测技术,即解耦头和领先的标签分配策略 SimOTA,在大规模模型范围内都能达到SOTA:对于 YOLONano 只有 0.91M 参数和 1.08G FLOPs,我们在 COCO 上获得 25.3% AP,超过 NanoDet 1.8% AP; 对于 YOLOv3,我们在 COCO 上将其提升到 47.3% AP,比之前高出 3.0% AP; 对于与 YOLOX-L 参数量大致相同的YOLOv4-CSP、YOLOv5-L,在 COCO 上达到了 50.0% AP,超出 YOLOv5-L 1.8%的AP。

问题:YOLO系列较强的检测器都是基于anchor的,但是现在较流行的检测器都是anchor-free的

解决:yolov4和yolov5已经是在基于anchor的检测器中达到了过度优化,已经没有优化空间了,那么这篇文章就从yolov3(yolov3-SPP)作为出发点。

2、结构设计

Baseline

backbone使用yolov3的draknet-53

baseline细节:采用draknet-53和SPP层,添加EMA权重更新、COS的学习率策略、IOU loss和IOU-aware分支。其中BCE loss用来训练分类和置信度分支,IOU loss用来训练回归分支。数据增强将RandomResizedCrop替换为RandomHorizontalFlip,ColorJitter以及多尺度(因为RandomResizedCrop和mosaic增强有重复)。

解耦头

背景:分类任务与回归任务有冲突

分析:耦合检测头会对性能造成不利影响

解决:解耦这两种任务

结果:①提升了收敛速度②如果想做端到端版本YOLO,即不用NMS的话解耦头较方便

image-20220518173257413

结构设计:解耦头先通过1×1卷积将前面的特征图通道变为256,然后再经过2个3×3卷积,接着再通过一个1×1卷积,分别到分类和回归检测,同时回归的分支还增加了IOU-aware分支。

测试训练中的策略

①解耦头策略:将分类任务和回归任务分开

②数据增强策略:结合Mosaic和MixUp策略,ImageNet预训练已得不到好处,后面全部用从头训练方法。

Mosaic策略:几张图拼接为一张图。

image-20220518185339558

MixUp策略:将其他图与原图混合,标签也混合。

image-20220518185358205

③anchor-free策略:每个位置的预测量从3(长、宽、高)减少到1,并使得预测量直接预测4个值:相对于网格左上角的偏移量(2个)和预测BBox的宽高(2个)。预定义一个尺度范围(如FCOS一样在FPN的每层设计一个范围)

④多正样本策略:中心点附近的3×3区域都是正样本

⑤SimOTA策略:一种标签分配策略

SimOTA流程:

1.确定正样本候选区域(将gt里面的点或者在center_radius范围内的点作为候选正样本点)
2.计算每个样本对每个GT的 Reg+Cls loss (Loss aware)
3.使用每个GT的预测样本确定它需要分配到的正样本数(Dynamic k)
获取与当前GT的 iou前10的样本,然后将这Top10样本的 iou求和取整,就为当前GT的dynamic_k, dynamic_k最小保证为1,10这个数字并不敏感,在5-15之间几乎都没有影响
4.为每个GT取 loss最小的前dynamic k个样本作为正样本
5.人工去掉同一个样本被分配到多个GT的正样本的情况(全局信息)

SimOTA优点:①能够做到自动的分析每个gt要拥有多少个正样本;②能自动决定每个gt要从哪个特征图来检测;③相较OTA,simOTA更快且避免了额外的超参数

预测样本对每个GT的loss计算为:单阶段目标检测重要论文总结,此策略减少训练时间同时避免了额外的超参。

image-20220518200002158

3、论文总结

本文贡献:

①在YOLO系列上改为ancho-free模型并采用解耦头预测
②采用SimOTA标签分配策略提高了速度及精度
③消融实验结果表明数据增强方法的使用也需要看具体的模型大小的

image-20220518200649849

引用

[1] 1.2 YOLO入门教程:YOLOv1(2)-浅析YOLOv1

[2] SSD论文解读

[3] 【论文精读】Focal Loss for Dense Object Detection(RetinaNet)全文翻译及重点总结

[4] 2.1 YOLO入门教程:YOLOv2(1)-解读YOLOv2

[5] 3.1 YOLO入门教程:YOLOv3(1)-解读YOLOv3

[6] 深入浅出Yolo系列之Yolov3&Yolov4&Yolov5&Yolox核心基础知识完整讲解

[7] Bag of Freebies(免费包)和Bag-of-Specials(特赠包)

[8] 锚框:Anchor box综述 – 知乎 (zhihu.com)

[9] 【Anchor free】CornerNet 网络结构深度解析(全网最详细!) – 知乎 (zhihu.com)

[10] 【Anchor Free】CenterNet的详细解析 – 知乎 (zhihu.com)

[11] CenterNet: Keypoint Triplets for Object Detection_Wanderer001的博客-CSDN博客

[12] 文章解析:FCOS: Fully Convolutional One-Stage Object Detection | by zong fan | Medium

[13] YOLOX原始论文精读_钟良堂的博客-CSDN博客_yolox论文

[14] YOLOX深度解析(二)-simOTA详解 – 知乎 (zhihu.com)

总结

基于anchor的检测器:yolov2, yolov3, yolov4, yolov5, SSD, RetinaNet, YOLOF

anchor-free检测器:yolov1, YOLOX, CornerNet, CenterNet, CenterNet++, FCOS

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2022年5月20日
下一篇 2022年5月20日

相关推荐