简话O B D(持续更新)

本文详细介绍了目标检测的发展历程,从传统的HOG、SIFT特征提取到深度学习方法,如R-CNN系列(R-CNN、Fast R-CNN、Faster R-CNN、Cascade R-CNN)、YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv5)以及其他的检测框架如SSD、RetinaNet、Focal Loss等。文章探讨了这些方法的原理、优缺点,并对比了它们在性能和效率上的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


:以下主要介绍了各种目标检测的方法概要, 而非详细解说,若要查看详细解读,可点击各方法中的 链接进行查阅。

一、BACKGROUND

在过去的十多年时间里,传统的机器视觉领域,通常采用特征描述子来应对目标识别任务,这些特征描述子最常见的就是 SIFT 和 HOG.而 OpenCV 有现成的 API 可供大家实现相关的操作
计算机视觉五大技术:图像分类、对象检测、目标跟踪、语义分割和实例分割
目前学术和工业界出现的目标检测算法分成3类:
1、传统的目标检测算法:Cascade + HOG/DPM + Haar/SVM以及上述方法的诸多改进、优化;
2、双阶段方法:候选区域/框 + 深度学习分类:通过提取候选区域,并对相应区域进行以深度学习方法为主的分类的方案, 如:R-CNN(Selective Search + CNN + SVM)SPP-net(ROI Pooling)Fast R-CNN(Selective Search + CNN + ROI)Faster R-CNN(RPN + CNN + ROI)R-FCN等系列方法;
3、单阶段方法: 基于深度学习的回归方法:YOLO/SSD/DenseBox 等方法, 及anchor based 和anchor free的方法。

二、传统目标检测方法(后面更新)

HOG(方向梯度直方图Histogram of Oriented Gradient)

HOG特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子,是与SIFT、SURF、ORB属于同一类型的描述符。HOG不是基于颜色值而是基于梯度来计算直方图的,它通过计算和统计图像局部区域的梯度方向直方图来构建特征。HOG特征结合SVM分类器已经被广泛应用到图像识别中,尤其在行人检测中获得了极大的成功。
此方法的基本观点是:局部目标的外表和形状可以被局部梯度或边缘方向的分布很好的描述,即使我们不知道对应的梯度和边缘的位置。(本质:梯度的统计信息,梯度主要存在于边缘的地方)
在这里插入图片描述

SIFT 特征提取

  1. sift = cv2.xfeatures2d.SIFT_create() 实例化

参数说明:sift为实例化的sift函数

  1. kp = sift.detect(gray, None) 找出图像中的关键点

参数说明: kp表示生成的关键点,gray表示输入的灰度图,

  1. ret = cv2.drawKeypoints(gray, kp, img) 在图中画出关键点

参数说明:gray表示输入图片, kp表示关键点,img表示输出的图片

  1. kp, dst = sift.compute(kp) 计算关键点对应的sift特征向量

参数说明:kp表示输入的关键点,dst表示输出的sift特征向量,通常是128维的

BOW

BoW模型最初是为解决文档建模问题而提出的,因为文本本身就是由单词组成的。它忽略文本的词序,语法,句法,仅仅将文本当作一个个词的集合,并且假设每个词彼此都是独立的。这样就可以使用文本中词出现的频率来对文档进行描述,将一个文档表示成一个一维的向量。
将BoW引入到计算机视觉中,就是将一幅图像看着文本对象,图像中的不同特征可以看着构成图像的不同词汇。和文本的BoW类似,这样就可以使用图像特征在图像中出现的频率,使用一个一维的向量来描述图像。
BOW一般过程:

  1. 取一个样本数据集
  2. 对样本集中的每幅图像提取描述符(采用SIFT,SURF等方法)
  3. 将每一个描述符都加入到BOW训练器中
  4. 将描述符聚类到K簇中(聚类的中心就是视觉单词)
    在这里插入图片描述
  5. 利用词汇字典中的词汇表示图像, 利用SIFT算法,可以从每幅图像中提取很多个特征点,这些特征点都可以用词汇字典中的词汇近似代替,通过统计词汇字典中每个词汇在图像中出现的次数,可以将图像表示成为一个k维数值向量, 即基于这些特征到最近簇心的距离来实现向量化,已形成直方图。
    在这里插入图片描述
简略过程:
feature_detector = cv2.xfeatures2d.SIFT_create()
bow_kmeans_trainer = cv2.BOWKMeansTrainer(k)
voc = bow_kmeans_trainer.cluster()
bow_img_descriptor_extractor = cv2.BOWImgDescriptorExtractor(self.descriptor_extractor, flann)
bow_img_descriptor_extractor.setVocabulary(voc)
bow_img_descriptor_extractor.compute(im, feature_detector.detect(im))

三、深度学习方法

在这里插入图片描述

R-CNN

结构:selective search →ROI →CNN→max score
也可参考:这篇文章

对一张图片,用各种大小的框(大牛们发明好多选定候选框的方法,比如EdgeBoxes和Selective Search。)将图片截取出来,输入到CNN,然后CNN会输出这个框的得分(classification)以及这个框图片对应的x,y,h,w(regression)候选区域方法(region proposal method)创建目标检测的感兴趣区域(ROI)。在选择性搜索(selective search,SS)中,我们首先将每个像素作为一组。然后,计算每一组的纹理,并将两个最接近的组结合起来。但是为了避免单个区域吞噬其他区域,我们首先对较小的组进行分组。我们继续合并区域,直到所有区域都结合在一起。能够生成候选区域的方法很多,比如: objectness、selective search、category-independen、object proposals、constrained parametric min-cuts(CPMC)、 multi-scale、 combinatorial grouping、Ciresan。 R-CNN 采用的是 Selective Search 算法。

**selective search:** 
输入: 一张图片;
输出:候选的目标位置集合L
算法:
1: 利用切分方法得到候选的区域集合R = {r1,r2,…,rn}
2: 初始化相似集合S = ϕ
3: foreach 遍历邻居区域对(ri,rj) do
4:     计算相似度s(ri,rj)
5:     S = S  ∪ s(ri,rj)
6: while S not=ϕ do
7:     从S中得到最大的相似度s(ri,rj)=max(S)
8:     合并对应的区域rt = ri ∪ rj
9:     移除ri对应的所有相似度:S = S\s(ri,r*)
10:    移除rj对应的所有相似度:S = S\s(r*,rj)
11:    计算rt对应的相似度集合St
12:    S = S ∪ St
13:    R = R ∪ rt
14: L = R中所有区域对应的边框

在这里插入图片描述在这里插入图片描述
下面展开进行介绍
1、生成候选区域
使用Selective Search(选择性搜索)方法对一张图像生成约2000-3000个候选区域,基本思路如下:
(1)使用一种过分割手段,将图像分割成小区域
(2)查看现有小区域,合并可能性最高的两个区域,重复直到整张图像合并成一个区域位置。优先合并以下区域:- 颜色(颜色直方图)相近的 -纹理(梯度直方图)相近的- 合并后总面积小的- 合并后,总面积在其BBOX中所占比例大的在合并时须保证合并操作的尺度较为均匀,避免一个大区域陆续“吃掉”其它小区域,保证合并后形状规则。
(3)输出所有曾经存在过的区域,即所谓候选区域
2、特征提取
使用深度网络提取特征之前,首先把候选区域归一化成同一尺寸227×227。
使用CNN模型进行训练,例如AlexNet,一般会略作简化,如下图:
3、类别判断
对每一类目标,使用一个线性SVM二类分类器进行判别。输入为深度网络(如上图的AlexNet)输出的4096维特征,输出是否属于此类。
4、位置精修
目标检测的衡量标准是重叠面积:许多看似准确的检测结果,往往因为候选框不够准确,重叠面积很小,故需要一个位置精修步骤,对于每一个类,训练一个线性回归模型去判定这个框是否框得完美。
R-CNN将深度学习引入检测领域后,一举将PASCAL VOC上的检测率从35.1%提升到53.7%。
位置精修方法:
G x = P x + P w ∗ t x , G y = P y + P w ∗ t y , G w = P w ∗ e t w , G h = P h ∗ e t h G_x= P_x+P_w*t_x, \\G_y= P_y+P_w*t_y, \\G_w= P_w*e^{t_w},\\G_h= P_h*e^{t_h} Gx=Px+Pwtx,Gy=Py+Pwty,Gw=Pwetw,Gh=Pheth

最大瓶颈是2k个候选区域都要经过一次CNN,速度非常慢。Kaiming He大神最先对此作出改进,提出了SPP-net,最大的改进是只需要将原图输入一次,就可以得到每个候选区域的特征。

[完结]

SPP-NET(金字塔池化)

(金字塔池化) -> ROI POOLING
在这里插入图片描述
我们使用三层的金字塔池化层pooling,分别设置图片切分成多少块,论文中设置的分别是(1,4,16),然后按照层次对这个特征图feature A进行分别处理(用代码实现就是for(1,2,3层)),也就是在第一层对这个特征图feature A整个特征图进行池化(池化又分为:最大池化,平均池化,随机池化),论文中使用的是最大池化,得到1个特征。
  第二层先将这个特征图feature A切分为4个(20,30)的小的特征图,然后使用对应的大小的池化核对其进行池化得到4个特征,
  第三层先将这个特征图feature A切分为16个(10,15)的小的特征图,然后使用对应大小的池化核对其进行池化得到16个特征.
然后将这1+4+16=21个特征输入到全连接层,进行权重计算. 当然了,这个层数是可以随意设定的,以及这个图片划分也是可以随意的,只要效果好同时最后能组合成我们需要的特征个数即可
[完结]

Fast RCNN

也可参考这篇文章
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述
一张完整图片–>CNN–>得到每张候选框的特征–>分类+回归
Fast R-CNN存在的问题:存在瓶颈:选择性搜索,找出所有的候选框,这个也非常耗时。那我们能不能找出一个更加高效的方法来求出这些候选框呢?
[完结]

RPN(region proposal network)

通过上述介绍可以知道,Faster R-CNN与Fast R-CNN最大的区别就是提出了一个叫RPN(Region Proposal Networks)的网络,专门用来推荐候选区域的,RPN可以理解为一种全卷积网络,该网络可以进行end-to-end的训练,最终目的是为了推荐候选区域,如下图所示
在这里插入图片描述Feature map->经卷积得到score[N,C,2] and loc[N,C,4] loc即dx, dy, dw, dh, 经下列与anchor变换后得到原图尺寸对应的推荐框。再经高宽大于阈值的筛选,score top6000的筛选,得到6000个符合要求的推荐框。再经NMS 得到剩下的推荐框。
在这里插入图片描述

解释一下上面这张图:

1)在原文中使用的是ZF model中,其Conv Layers中最后的conv5层num_output=256,对应生成256张特征图(feature maps),所以相当于feature map每个点都是256-dimensions
2)在conv5之后,做了rpn_conv/3x3卷积且num_output=256,相当于每个点又融合了周围3x3的空间信息),同时256-d不变
3)假设在conv5 feature map中每个点上有k个anchor(原文如上k=9),而每个anhcor要分foreground和background,所以每个点由256d feature转化为cls=2k scores;而每个anchor都有[x, y, w, h]对应4个偏移量,所以reg=4k coordinates(scores和coordinates为RPN的最终输出)
4)补充一点,全部anchors拿去训练太多了,训练程序会在合适的anchors中随机选取128个postive anchors+128个negative anchors进行训练(至于什么是合适的anchors接下来RPN的训练会讲)

RPN训练中对于正样本文章中给出两种定义。第一,与ground truth box有最大的IoU的anchors作为正样本;第二,与ground truth box的IoU大于0.7的作为正样本。文中采取的是第一种方式。文中定义的负样本为与ground truth box的IoU小于0.3的样本。
[完结]

Faster RCNN

也可参考这篇文章这篇文章
Faster R-CNN的主要贡献是设计了提取候选区域的网络RPN,代替了费时的选择性搜索,使得检测速度大幅提高。
在这里插入图片描述
在这里插入图片描述训练的算法流程:
RPN:
Feature map->经卷积得到score[N,C,2] and loc[N,C,4] loc即dx, dy, dw, dh, 经与anchor变换后得到原图尺寸对应的推荐框。经NMS得到剩余符合要求的ROI。生成ROI后,使用ROI与GT boxes做IOU, 选出IOU>thresh的推荐框anchor的top N1 为正样本, 再随机选出N2个为训练的正样本。选出IOU<thresh的推荐框anchor 为负样本, 随机选出N3个为训练的负样本。 roi score回归gt_box对应的正负样本,roi loc 回归gt_box 的位置。

RoI pooling:
将生成的ROI映射到feature map 上,然后,对应的feature map of ROI 去回归gt_box 的class and loc.

在这里插入图片描述通过上面两张图可以看出Faster R-CNN由四个部分组成:
1)卷积层(conv layers),用于提取图片的特征,输入为整张图片,输出为提取出的特征称为feature maps
2)RPN网络(Region Proposal Network),用于推荐候选区域,这个网络是用来代替之前的search selective的。输入为图片(因为这里RPN网络和Fast R-CNN共用同一个CNN,所以这里输入也可以认为是featrue maps),输出为多个候选区域,这里的细节会在后面详细介绍。
3)RoI pooling,和Fast R-CNN一样,将不同大小的输入转换为固定长度的输出,输入输出和Faste R-CNN中RoI pooling一样。
RoI pooling 详解:
1)我们有一个88大小的feature map,一个ROI,以及输出大小为22.
2)region proposal 投影之后位置(左上角,右下角坐标):(0,3),(7,8)。
3)将其划分为(22)个sections(因为输出大小为22),我们可以得到:
在这里插入图片描述
4)对每个section做max pooling,可以得到:
在这里插入图片描述

通过上述介绍可以知道,Faster R-CNN与Fast R-CNN最大的区别就是提出了一个叫RPN(Region Proposal Networks)的网络,专门用来推荐候选区域的,RPN可以理解为一种全卷积网络,该网络可以进行end-to-end的训练,最终目的是为了推荐候选区域,如下图所示。

4)分类和回归,这一层的输出是最终目的,输出候选区域所属的类,和候选区域在图像中的精确位置。
[完结]

最后总结一下各大算法的步骤
RCNN
  1. 在图像中确定约1000-2000个候选框 (使用选择性搜索)
  2. 每个候选框内图像块缩放至相同大小,并输入到CNN内进行特征提取
  3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
  4. 对于属于某一特征的候选框,用回归器进一步调整其位置
Fast RCNN
采用selective search到feature map的映射,替换rcnn中每个selective search都输入cnn导致大量的重复运算
  1. 在图像中确定约1000-2000个候选框 (使用选择性搜索)
  2. 对整张图片输进CNN,得到feature map
  3. 找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到roi pooling 层, 得到固定尺寸的feature map
  4. 对候选框中提取出的特征feature map,使用分类器判别是否属于一个特定类
  5. 对于属于某一特征的候选框,用回归器进一步调整其位置
Faster RCNN
采用RPN替换selective search映射
  1. 对整张图片输进CNN,得到feature map
  2. 卷积特征输入到RPN,得到候选框的特征信息
  3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
  4. 对于属于某一特征的候选框,用回归器进一步调整其位置
[完结]

Cascade RCNN

参考我的另一篇博客

Mask RCNN

ResNet-FPN+Fast RCNN+mask

扩展阅读:https://blog.youkuaiyun.com/wangdongwei0/article/details/83110305;
https://zhuanlan.zhihu.com/p/37998710
在这里插入图片描述
在这里插入图片描述

Mask RCNN可以看做是一个通用实例分割架构。
Mask RCNN以Faster RCNN原型,增加了一个分支用于分割任务。
Mask RCNN比Faster RCNN速度慢一些,达到了5fps。
可用于人的姿态估计等其他任务;
在这里插入图片描述

  • 实例分割不仅要正确的找到图像中的objects,还要对其精确的分割。所以Instance Segmentation可以看做object dection和semantic segmentation的结合。
  • Mask RCNN是Faster RCNN的扩展,对于Faster RCNN的每个Proposal Box都要使用FCN进行语义分割,分割任务与定位、分类任务是同时进行的。
  • 引入了RoI Align代替Faster RCNN中的RoI Pooling。因为RoI Pooling并不是按照像素一一对齐的(pixel-to-pixel alignment),也许这对bbox的影响不是很大,但对于mask的精度却有很大影响。使用RoI Align后mask的精度从10%显著提高到50%,第3节将会仔细说明。
  • 引入语义分割分支,实现了mask和class预测的关系的解耦,mask分支只做语义分割,类型预测的任务交给另一个分支。这与原本的FCN网络是不同的,原始的FCN在预测mask时还用同时预测mask所属的种类。
  • 没有使用什么花哨的方法,Mask RCNN就超过了当时所有的state-of-the-art模型。
  • 使用8-GPU的服务器训练了两天。

RoIAlign
RoIPool的目的是为了从RPN网络确定的ROI中导出较小的特征图(a small feature map,eg 7x7),ROI的大小各不相同,但是RoIPool后都变成了7x7大小。RPN网络会提出若干RoI的坐标以[x,y,w,h]表示,然后输入RoI Pooling,输出7x7大小的特征图供分类和定位使用。问题就出在RoI Pooling的输出大小是7x7上,如果RON网络输出的RoI大小是8*8的,那么无法保证输入像素和输出像素是一一对应,首先他们包含的信息量不同(有的是1对1,有的是1对2),其次他们的坐标无法和输入对应起来(1对2的那个RoI输出像素该对应哪个输入像素的坐标?)。这对分类没什么影响,但是对分割却影响很大。RoIAlign的输出坐标使用插值算法得到,不再量化;每个grid中的值也不再使用max,同样使用差值算法。

实际上,Mask RCNN中还有一个很重要的改进,就是ROIAlign。Faster R-CNN存在的问题是:特征图与原始图像是不对准的(mis-alignment),所以会影响检测精度。而Mask R-CNN提出了RoIAlign的方法来取代ROI pooling,RoIAlign可以保留大致的空间位置。

双线性插值
在这里插入图片描述
RoIAlign采用双线性插值:
下面通过一个例子来讲解ROI Align操作。如下图所示,虚线部分表示feature map,实线表示ROI,这里将ROI切分成2x2的单元格。如果采样点数是4,那我们首先将每个单元格子均分成四个小方格(如红色线所示),每个小方格中心就是采样点。这些采样点的坐标通常是浮点数,所以需要对采样点像素进行双线性插值(如四个箭头所示),就可以得到该像素点的值了。然后对每个单元格内的四个采样点进行maxpooling,就可以得到最终的ROIAlign的结果。
在这里插入图片描述
单线性插值;
在这里插入图片描述

[完结]

HTC(Hybrid Task Cascade)在这里插入图片描述

HTC的演进过程,可以概括为:
 (a)Cascade R-CNN和Mask R-CNN的简单结合;
 (b)将box分支由并联改为串联(即在每个stage里先执行box分支,将回归过的 框再交由mask分支来预测mask);
 (c)为Mask分支之间也引入信息流(类似Cascade R-CNN中Box分支间的信息 流);
 (d)通过引入语义分割分支S来提供空间上下文信息(spatial context),从而帮助 模型区分前景和背景;

SSD

  • SSD 的网络结构
    在这里插入图片描述在这里插入图片描述

  • anchor box 的构建
    在特征图的每个像素点处,生成不同宽高比的default box(anchor box),论文中设置的宽高比为{1, 2, 1/2, 3, 1/3}。假设每个像素点有k个default box,需要对每个default box进行分类和回归.
    在这里插入图片描述
    1)通过(0.2-0.9)×image_size获得每个featuremap的basesize.
    2)通过宽高比ratio获得尺度变换
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    [完结]

YOLO(V1,V2,V3)

yolo 与 SSD最大的区别:
1、SSD classes 里包含背景,yolo不包含而是做在conf里面;
2、yolo网格对应的anchors与目标的IOU比较,如果>thresh,但是目标的中心点不在该网格类,这类样本不参与训练。因此,这就是与SSD最大的不同了,在SSD里,看的是所有anchors与目标的IOU距离,如果IOU大于0.7,所在的anchors都是正例样本。而在YOLO里,只看中心点所在的网格对应的anchors,其他与之对应的anchors要么当作负样本了,要么就不参与训练了。

可以参考:https://blog.youkuaiyun.com/weixin_38570251/article/details/81853247
YOLO-V1
YOLO的核心思想就是利用整张图作为网络的输入,直接在输出层回归bounding box的位置和bounding box所属的类别。
把老狗放这比较合适。
在这里插入图片描述
faster RCNN中也直接用整张图作为输入,但是faster-RCNN整体还是采用了RCNN那种 proposal+classifier的思想,只不过是将提取proposal的步骤放在CNN中实现了,而YOLO则采用直接回归的思路,YOLO v1首先会把原始图片放缩到448×448的尺寸,然后将图片划分成SxS个单元格。如果一个对象的中心落在某个单元格上,那么这个单元格负责预测这个物体。每个单元格需要预测B个边界框(bbox)值(bbox值包括坐标和宽高),同时为每个bbox值预测一个置信度(confidence scores)。

backbone:GoogleNet with no inception modules
在这里插入图片描述将一幅图经过CNN后等到7X7X30的featuremap,30:SxSx(B∗5+C) = 7x7x(2*5 + 20)=7x7x30
2, 5,20:代表能预测2个框的5个参数(x,y,w,h,score)和20个种类。
在这里插入图片描述

损失函数
在这里插入图片描述
在这里插入图片描述[完结]
yolo-v2
backbone: darknet-19
1.添加Batch Normalization层;
2.引入anchor boxes, 在训练集(training set)Bounding Boxes上跑了一下k-means聚类,来找到几个比较好的anchor boxes。

k-means聚类的算法运行过程可以总结如下:
(1)选择k个初始聚类中心

(2)计算每个对象与这k个中心各自的距离,按照最小距离原则分配到最邻近聚类

(3)使用每个聚类中的样本均值作为新的聚类中心

(4)重复步骤(2)和(3)直到聚类中心不再变化

(5)结束,得到k个聚类
在这里插入图片描述模型中采用e指数,是为了让其值不为负。

loss function:
在这里插入图片描述

[完结]

yolo-v3
Backbone: darknet53
1.多尺度预测 (类FPN)
2.更好的基础分类网络(类似ResNet) darknet-53。
3.分类器-类别预测:
YOLOv3不使用Softmax对每个框进行分类,主要考虑因素有两个:
a.Softmax使得每个框分配一个类别(score最大的一个),而对于Open Images这种数据集,目标可能有重叠的类别标签,因此Softmax不适用于多标签分类。
b.Softmax可被独立的多个logistic分类器替代,且准确率不会下降。
分类损失采用binary cross-entropy loss.

backbone: darknet-53
结构如下图再合适不过了。
在这里插入图片描述[完结]

YOLOv3-tiny & YOLOv3-tiny-mobilenet

YOLOv3-tiny:
网络结构:
在这里插入图片描述

YOLOv3-tiny-mobilenet:采用mobilenet的主干网络

在这里插入图片描述

yolov5

在这里插入图片描述

Focus结构在这里插入图片描述
neck部分

Yolov5的Neck和Yolov4中一样,都采用FPN+PAN的结构。
FPN是自顶向下,将高层的强语义特征传递下来,对整个金字塔进行增强,不过只增强了语义信息,对定位信息没有传递。PAN就是针对这一点,在FPN的后面添加一个自底向上的金字塔,对FPN补充,将低层的强定位特征传递上去,又被称之为“双塔战术”。
在这里插入图片描述

yolvo5中的自适应anchor
 
def check_anchors(dataset, model, thr=4.0, imgsz=640):
    # Check anchor fit to data, recompute if necessary
    print('\nAnalyzing anchors... ', end='')
    m = model.module.model[-1] if hasattr(model, 'module') else model.model[-1]  # Detect()
    shapes = imgsz * dataset.shapes / dataset.shapes.max(1, keepdims=True)
    #0.1-1.1
    scale = np.random.uniform(0.9, 1.1, size=(shapes.shape[0], 1))  # augment scale
    wh = torch.tensor(np.concatenate([l[:, 3:5] * s for s, l in zip(shapes * scale, dataset.labels)])).float()  # wh
 
    def metric(k):  # compute metric
        r = wh[:, None] / k[None]
        x = torch.min(r, 1. / r).min(2)[0]  # ratio metric
        best = x.max(1)[0]  # best_x
       
        aat = (x > 1. / thr).float().sum(1).mean()  # anchors above threshold
        bpr = (best > 1. / thr).float().mean()  # best possible recall
        return bpr, aat
    
    bpr, aat = metric(m.anchor_grid.clone().cpu().view(-1, 2))
    print('anchors/target = %.2f, Best Possible Recall (BPR) = %.4f' % (aat, bpr), end='')
    #只有当由默认设定的anchor计算出来的bpr这一指标少于设定的阈值时才会通过聚类算法重新计算anchor
    if bpr < 0.98:  # threshold to recompute
        print('. Attempting to improve anchors, please wait...')
        na = m.anchor_grid.numel() // 2  # number of anchors
        new_anchors = kmean_anchors(dataset, n=na, img_size=imgsz, thr=thr, gen=1000, verbose=False)
        new_bpr = metric(new_anchors.reshape(-1, 2))[0]
        if new_bpr > bpr:  # replace anchors
            new_anchors = torch.tensor(new_anchors, device=m.anchors.device).type_as(m.anchors)
            m.anchor_grid[:] = new_anchors.clone().view_as(m.anchor_grid)  # for inference
            m.anchors[:] = new_anchors.clone().view_as(m.anchors) / m.stride.to(m.anchors.device).view(-1, 1, 1)  # loss
            check_anchor_order(m)
            print('New anchors saved to model. Update model *.yaml to use these anchors in the future.')
        else:
            print('Original anchors better than new anchors. Proceeding with original anchors.')
    print('')  # newline

metric这个函数初看一脸懵逼,再看拍案叫绝。输入参数k存储anchors,调用时被reshape后的尺寸为(9,2)。接下来要计算每个gt框的宽高和所有这9个anchor的宽高的比例值,得到的r其shape为(N,9,2)。x=torch.min(r,1./r).min(2)[0],怎么理解这句代码呢?w_gt/w_anchor或者h_gt/h_anchor这个比例值可能大于1也可能小于1,通过torch.min(r,1./r)的方式统一到<=1的情形,然后再从中选取较小的这个值。得到的x其shape为(n,9),x.max(1)[0]为每个gt框选择匹配宽高比例值最好的那一个值。这样就可以计算aat和bpr了。计算出来的bpr不小于0.98就会重新聚类,否则就返回默认的anchor设定。

PP-YOLO

参考PP-YOLO

YOLO-X

参考YOLO-x

RetinaNet(Focal Loss for Dense Object Detection)

RetinaNet是2018年Facebook AI团队在目标检测领域新的贡献。


将原先训练 回归任务 惯用的 交叉熵误差 C E ( p t ) = − y t l o g ( p t ) CE(p_t)=−y_tlog(p_t) CE(pt)=ytlog(pt)改为 FL (focal loss) 即可: F L ( p t ) = − α ∗ ( 1 − p t ) r ∗ l o g ( p t ) FL(p_t)=−\alpha*(1-p_t)^r* log(p_t) FL(pt)=α(1pt)rlog(pt)

obj_loss = alpha * pow((torch.ones_like(pre_obj) - pre_obj), 2) * self.bceloss(pre_obj * obj_mask,lab_obj * obj_mask)
noobj_loss = (1 - alpha) * pow(pre_obj, 2) * self.bceloss(pre_obj * ignore_mask, lab_obj * ignore_mask)

上面代码是我的实际应用。

Generalized Focal Loss

[完结]

RefineDet(Single-Shot Refinement Neural Network for Object Detection)

论文中心思想:作者采用了two stage的思想先用一个ARM网络结构对ancor 进行处理,ARM就像RPN网络,其作用如下:1)用于修正anchor,去掉多余的负样本,减少负本数量;2)对anchor的进行修正,使ODM网络更容易分类和回归。ODM网络是由ARM网络通过TCB网络处理得到。TCP就像FPN中的上采样那样,将高层的语义信息与低层的信息相融合。TCB网络如下图,直接对上采样的网络进行相加等到。
这样在各个feature map 上,每个anchor产生c个类别以及4个坐标。与SSD不一样的是,SSD使用的是default box去预测,而refineDet使用的是ARM网络产生的refined anchor去预测。这使RefineDet具备的one&tow stage的优点。
在这里插入图片描述可参考我的另一篇博客RefineDet
[完结]

FCOS

ATSS

参考我的博客
首先是对比了anchor_free和anchor_base在选取样本时的差异,本文以RetinaNet和FCOS作为例子进行了对比,RetinaNet是采用IOU去选取正负样本,FCOS是基于空间分布对正负样本进行score。这两种采样方式会导致最终训练的正负样本是不一致的,作者通过对ReinaNet用两种不同采样方式进行训练模型,并对比起在COCO上的AP,验证anchor_base和anchor_free本质上的区别只是在于采样的不同。

FSAF(Feature Selective Anchor-Free Module for Single-Shot Object Detection)

作者提出anchor-free的在线式的选择特征层的方法,尤其是对FPN的多个特征层选择,并且在这个训练的同时也可以采用anchor-based的方法并行训练。大致可描述为下图:
在这里插入图片描述
可参考我的另一篇博客FSAF
[完结]

M2Det(A Single-Shot Object Detector based on Multi-Level Feature Pyramid Network)

论文中心思想:更改了以目标分类的backbone,得到目标检测的backbone:M2Det.
在这里插入图片描述
请参考我的另一篇博客M2Det
[完结]

EfficientDet: Scalable and Efficient Object Detection

Motivation:
作者认为检测效果好的网络,模型都比较大,而且速度大都比较慢。检测速度快的网络,大都检测效果差,因此,提出EfficientDet,在兼容效果的同时保证了速度。
在这里插入图片描述

Related Works:

BiFPN:
BiFPN是作者构建的创新网络:上一副网络演变对比图
在这里插入图片描述
Weighted Feature Fusion:
以P6为例说明了计算过程
在这里插入图片描述
其中 ω \omega ω是融合系数。并用softmax使所有 ω \omega ω相加为1.为使稳定加入了一个很小的系数: ϵ = 0.0001 \epsilon= 0.0001 ϵ=0.0001

Networks:
于是构建出整个网络模型:
在这里插入图片描述
Compound Scaling:
作者参考了EfficientNet中的方法:
干脆直接用了EfficientNet的backboneB0-B7,这样还直接用了它的预训练权重。
在这里插入图片描述
在这里插入图片描述
形成了一系列的Scaling:
在这里插入图片描述

具体请参考我的另一篇博客Gaussian Yolov3
[完结]

others

RFB Net

详细内容请参考我的另一篇博客:RFB Net
RFB其实就是采用inception的结构+dilated convolution的方式
在这里插入图片描述在这里插入图片描述在这里插入图片描述

UnitBox(IOU loss, anchor-free)

动机:
左边的人脸框明显比右边的要准一点,但是脸太大,则导致loss最终反而比右边的大,然后我们就去惩罚这个loss,结果最后检测器对小人脸效果就不好了。
在这里插入图片描述
没啥好说的直接上原文中的图.
在这里插入图片描述在这里插入图片描述

在这里插入图片描述[完结]

Repulsion Loss:解决行人检测中密集遮挡问题

在这里插入图片描述
Repulsion Loss 的总损失函数为:
在这里插入图片描述
其中:
在这里插入图片描述
G A t t r P = a r g m a x G ∈ g I o U ( G , P ) 与 p r o p o s a l 最 大 的 那 个 g r o u n d t r u t h G^P_{Attr} = argmax_{G∈g}IoU(G,P)与proposal最大的那个groundtruth GAttrP=argmaxGgIoU(G,P)proposalgroundtruth
LAttr​ 就是一个正常的回归loss,希望候选的正样本能够靠近其对应的标注框,正样本就是和候选框有最大的 IoU 的 ground truth。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
此项的目的是使候选框与周围非其目标的ground true框排斥。给定一个候选框P∈ P+,文章把除了其目标框之外再与其具有最大IoU值的ground true框作为其排斥目标框.用来防止 proposal 靠近其周围不应该属于他的 ground-truth 目标,对于任何一个 positive proposal,其有一个和他最大 IoU 的 ground-truth 目标,除了这个目标之外和他 IoU 最大的 ground-truth 目标就是需要远离。

在这里插入图片描述
在这里插入图片描述
此项的目的是使候选框与其它目标不同的候选框排斥,这也使检测器对NMS操作更鲁棒。
[完结]

GIOU (Generalized Intersection over Union)

Motivation:
但直接用IoU作为损失函数会出现两个问题:
1,如果两个框没有相交,根据定义,IoU=0,不能反映两者的距离大小(重合度)。
2,同时因为loss=0,没有梯度回传,无法进行学习训练。

如下图: IoU无法精确的反映两者的重合度大小。如下图所示,三种情况IoU都相等,但看得出来他们的重合度是不一样的,左边的图回归的效果最好,右边的最差。
在这里插入图片描述
在这里插入图片描述GIOU方法如下:很简单
在这里插入图片描述

[完结]

Adaptive NMS

可参考我的另一篇博客 Adaptive NMS
概要:
先定义一个object density:
d i = M a x ( i o u ( b i , b j ) ) , 其 中 b i ∈ G , i ≠ j N M = M a x ( N t , d M ) , N t 为 G r e e d y N M S 中 的 阈 值 , d M 为 密 度 值 s i = { s i i o u ( M , b i ) < N M s i ∗ f ( i o u ( M , b i ) ) i o u ( M , b i ) > N M d_i = Max( iou(b_i,b_j)), 其中b_i \in G,i \ne j\\ N_M=Max(Nt, d_M), N_t为Greedy NMS中的阈值, d_M为密度值\\ s_i =\left\{ \begin{array}{rcl} s_i& & {iou(M,b_i)<N_M} \\ s_i*f(iou(M,b_i)) && {iou(M,b_i)>N_M} \end{array} \right. di=Max(iou(bi,bj)),biG,i=jNM=Max(Nt,dM),NtGreedyNMSdMsi={sisif(iou(M,bi))iou(M,bi)<NMiou(M,bi)>NM

因此,只要求到 d M d_M dM就可以了;

object density, d M d_M dM求法:

在这里插入图片描述
[完结]

PFP Net

可参考我的另一篇博客PFP Net
作者认为像金字塔形式的Feature map的网络,限制了网络的表现,尤其对于小目标的检测。对此,作者提出PFPNET。如图d所示。
在这里插入图片描述
Related Works:
先直接上PFPNET网络结构图:
在这里插入图片描述base network:预训练去掉全连接层的VGG16。
Bottleneck layer: conv1x1+batch norm +relu
FP pool: 就一般的池化
MSCA: F H 与 F L F_H与F_L FHFL的特征图组合在一起,并再将大特征图downsamping, 小特征图upsamping,到同一尺度,再concatenate.其中, F H F_H FH有D个channels, F L 有 ( N − 1 ) × D / ( N − 1 ) = D F_L有(N-1)×D/(N-1)=D FLN1×D/N1=D(作者的目的就是凑成D)个channels,各占一半。此外,作者也做过去掉 F H F_H FH,全由 F L F_L FL组成Feature map的实验,但表现与预期一样不好。

在这里插入图片描述details: 采用RfineDet的ARM方式来做Anchors.
PFPNET:
1)图像经过VGG16的base network后,产生WXHXD的Feature map
2) 再经SPP池化成N(图中为3)个high dimensional 的特征图 ( F H ) s i z e = W 2 n × H 2 n (F_H) size =\frac{W}{2^n} × \frac{H}{2^n} FH)size=2nW×2nHN:pyramid levels.
3)经过Bottleneck layer ( H L n ) (H_L^n) (HLn),得到 ( F L ) c h a n n e l = D / ( N − 1 ) (F_L)channel=D/(N-1) (FL)channel=D/(N1
4)经MSCA,得到 P L P_L PL;
5)最后采用RefineDet的方法进行训练(可以参考我的別一篇博客RefineDet)。
[完结]

RePr:一种新的训练方法

请参考我的另一篇博客RePr
在这里插入图片描述

Gaussian Yolov3

在这里插入图片描述
在这里插入图片描述
具体请参考我的另一篇博客Gaussian Yolov3

[完结]

LRF

DetectoRS

VIT 系列

相关链接

DETR
Deformable DETR
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一碗白开水一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值