一文通透目标检测:R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD、DETR(首发于18年,修订于25年)

本文详细介绍了目标检测领域的经典算法,包括R-CNN系列、YOLO、SSD等,梳理了从传统方法到深度学习方法的发展脉络,对比了各算法的特点与应用场景。

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

前言

之前我所在的公司「七月在线」开设的深度学习等一系列课程经常会讲目标检测,包括R-CNN、Fast R-CNN、Faster R-CNN,但一直没有比较好的机会深入「但当你对目标检测有个基本的了解之后,再看这些课程你会收益很大

  • 但目标检测这个领域实在是太火了,经常会看到一些写的不错的通俗易懂的资料,加之之前在京东上掏了一本书看了看,就这样耳濡目染中,还是开始研究了
  • 今年(2018)五一,从保定回京,怕高速路上堵 没坐大巴,高铁又没抢上,只好选择哐当哐当好几年没坐过的绿皮车,关键还不断晚点
    在车站,用手机做个热点,修改题库,顺便终于搞清R-CNN、fast R-CNN、faster R-CNN的核心区别

    有心中热爱 何惧任何啥

为纪念这心中热爱,故成此文

再后来,25年8.7日,在解读VideoMimic的过程中,注意到了Grounded SAM2,于此,引发了要修订一系列文章的计划,包括本文

  1. 比如,计划把《SAM(分割一切)》一文完善
  2. 把《自监督ViT与目标检测:从基于ViT的DINO、DINOv2,到最新目标检测器Grounding Dino、DINO-X》一文分成两篇文章
    一篇侧重Meta发布的自监督ViT——从DINO到DINOv2
    一篇侧重IDEA-Research推出的一系列检测、分割模型

    在解读后者的过程中发现,值得把本文涉及的Faster R-CNN/RPN等模型的介绍 精进完善下
    如此,便将本文的前三部分做了重要修订,且部分不够高清的配图 全部换成了超高清配图
  3. 再之后,考虑到此文中《图像生成发展起源:从VAE、扩散模型DDPM、DDIM到DETR、ViT、Swin transformer》的DETR与该文前半部分的内容DDPM并无很大的联系
    DETR与本文目标检测的定位 完全一致,故把DETR的部分 迁移到本文的第五部分中
  4. 8.12日中午,完成本文第一轮的全面修订....

第一部分 目标检测常见算法

object detection,就是在给定的图片中精确找到物体所在位置,并标注出物体的类别。所以,object detection要解决的问题就是物体在哪里以及是什么的整个流程问题

然而,这个问题可不是那么容易解决的,物体的尺寸变化范围很大,摆放物体的角度,姿态不定,而且可以出现在图片的任何地方,更何况物体还可以是多个类别

目前学术和工业界出现的目标检测算法分成3类

1.1 传统的目标检测算法

传统目标检测主要是Cascade + HOG/DPM + Haar/SVM以及上述方法的诸多改进、优化,其核心流程为:

  1. 区域选择(穷举策略:采用滑动窗口,且设置不同的大小,不同的长宽比对图像进行遍历,时间复杂度高)
  2. 特征提取(SIFT、HOG等;形态多样性、光照变化多样性、背景多样性使得特征鲁棒性差)
  3. 分类器分类(主要有SVM、Adaboost等)

具体而言,如下表格所示

方法及其流程简介

(区域选择-特征提取-分类器分类)

技术亮点

对后续检测框架的影响

Viola-Jones(2001)

滑动窗口 + Haar 特征 + 级联 AdaBoost 强分类器

1) 积分图快速计算 Haar 特征

2) 级联结构实现毫秒级人脸检测

启发了「级联网络」思想(如 Cascade CNN、MTCNN)

HOG + SVM(2005)
多尺度滑动窗口 + HOG 特征 + 线性 SVM

1) HOG 特征成为通用视觉基元

2) 首次系统提出「特征+分类器」两阶段检测范式

特征金字塔、多尺度检测、SVM→Softmax 过渡

DPM(2008)
根滤波器 + 部件滤波器 + 隐变量 SVM(允许形变)

1) 部件弹性模型 → 解决姿态/形变

2) 难例挖掘、bounding-box 回归、混合模型(mixture model)

后续演变为 Faster R-CNN 的 anchor 与 RoI 思想

总之

  • Viola-Jones 把「实时」带进检测
  • HOG+SVM 把「手工特征 + 分类器」范式标准化
  • DPM 在传统框架内把「形变建模」做到极致

三者共同为 2012 以后「端到端 CNN 检测器」奠定了问题定义、评价指标、后处理(NMS、回归)等全部基础设施

1.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

等系列方法;

1.3 基于深度学习的回归方法

YOLO/SSD/DenseBox 等方法;以及最近出现的结合RNN算法的RRC detection;结合DPM的Deformable CNN等

第二部分 传统的目标检测(2001-2010):滑动窗口 + 特征提取 + SVM分类

    2.1 图像识别的任务:一是图像识别,二是定位

    这里有一个图像任务:既要把图中的物体识别出来,又要用方框框出它的位置

    这个任务本质上就是这两个问题:一:图像识别,二:定位

    1. 图像识别(classification)
      输入:图片
      输出:物体的类别
      评估方法:准确率

    2. 定位(localization)
      输入:图片
      输出:方框在图片中的位置(x,y,w,h)
      评估方法:检测评价函数 intersection-over-union,比如IOU

    卷积神经网络CNN已经帮我们完成了图像识别(判定是猫还是狗)的任务了,我们只需要添加一些额外的功能来完成定位任务即可

    关于什么是IOU,请参看七月在线APP题库大题查看深度学习分类下第55题:https://www.julyedu.com/question/big/kp_id/26/ques_id/2138


    在目标检测的评价体系中,有一个参数叫做 IoU ,简单来讲就是模型产生的目标窗口和原来标记窗口的交叠率。具体我们可以简单的理解为: 即检测结果(DetectionResult)与 Ground Truth 的交集比上它们的并集,即为检测的准确率 IoU:

    \text { IOU }=\frac{\text { DetectionResult } \bigcap \text { GroundTruth }}{\text { DetectionResult } \bigcup \text { GroundTruth }}

    如下图所示:GT = GroundTruth; DR = DetectionResult; 

    • 黄色边框框起来的是:
      GTDR
    • 绿色框框起来的是:
      GTDR

    当然最理想的情况就是 DR 与 GT 完全重合,即IoU=1

    原图则如下

    定位的问题的解决思路有哪些?

    思路一:看做回归问题

    看做回归问题,我们需要预测出(x,y,w,h)四个参数的值,从而得出方框的位置

    1. 步骤1
      先解决简单问题, 搭一个识别图像的神经网络
      在AlexNet VGG GoogleLenet上fine-tuning一下关于什么是微调fine-tuning,请参看:https://www.julyedu.com/question/big/kp_id/26/ques_id/2137

    2. 步骤2:分成两个头,分别处理识别问题(分类)、定位问题(回归)
      在上述神经网络的尾部展开(也就说CNN前面保持不变,我们对CNN的结尾处作出改进:加了两个头:“分类头”和“回归头”
      成为classification + regression模式

    3. 步骤3:
      定位目标下的Regression那个部分用欧氏距离损失
      使用SGD训练
    4. 步骤4:
      预测阶段把2个头部拼上
      完成不同的功能

    这里需要进行两次fine-tuning
    第一次在ALexNet上做,第二次将头部改成regression head,前面不变,做一次fine-tuning

    Regression的部分加在哪?

    有两种处理方法:

    1. 加在最后一个卷积层后面(如VGG)
    2. 加在最后一个全连接层后面(如R-CNN)

    由于regression不好做,故一般想方设法转换为classification问题


    regression的训练参数收敛的时间要长得多,所以上面的网络采取了用classification的网络来计算出网络共同部分的连接权值

    2.1.2 解决定位问题的思路二:取图像窗口——弄个框框 框住

    思路二:取图像窗口

    还是刚才的classification + regression思路,咱们取不同的大小的“框”,让框出现在不同的位置,得出这个框的判定得分,最终取得分最高的那个框

    • 左上角的黑框:得分0.5

    • 右上角的黑框:得分0.75

    • 左下角的黑框:得分0.6

    • 右下角的黑框:得分0.8

    根据得分的高低,我们选择了右下角的黑框作为目标位置的预测。
    注:有的时候也会选择得分最高的两个框,然后取两框的交集作为最终的位置预测

    疑惑:框要取多大?
    取不同的框,依次从左上角扫到右下角。非常粗暴啊

    总结一下思路:
    对一张图片,用各种大小的框(遍历整张图片)将图片截取出来,输入到CNN,然后CNN会输出这个框的得分(classification)以及这个框图片对应的x,y,h,w(regression)


    但这方法实在太耗时间了,故可以做个优化。

    1. 原来网络是这样的:

    2. 故可以优化成这样:把全连接层改为卷积层,这样可以提提速

    2.2 物体检测(Object Detection)

    当图像有很多物体怎么办的?难度可是一下暴增啊,那任务就变成了:多物体识别+定位多个物体

    那把这个任务看做分类问题?

    看成分类问题有何不妥?

    • 你需要找很多位置, 给很多个不同大小的框
    • 你还需要对框内的图像分类
    • 当然, 如果你的GPU很强大, 恩, 那加油做吧…

    所以,传统目标检测的主要问题是:

    1. 基于滑动窗口的区域选择策略没有针对性,时间复杂度高,窗口冗余
    2. 手工设计的特征对于多样性的变化没有很好的鲁棒性

    看做classification, 有没有办法优化下?我可不想试那么多框那么多位置啊!

    第三部分 迈入DL时代:候选区域/窗 + 深度学习分类(2013-2015)

    3.1 2013年11月,R-CNN横空出世

    3.1.1 提取候选框(Region Proposal):选择性搜索

    有人想到一个好方法:预先找出图中目标可能出现的位置,即候选区域(Region Proposal)。利用图像中的纹理、边缘、颜色等信息,可以保证在选取较少窗口(几千甚至几百)的情况下保持较高的召回率(Recall)

    所以,问题就转变成找出可能含有物体的区域/框(也就是候选区域/框,比如选2000个候选框),这些框之间是可以互相重叠互相包含的,这样我们就可以避免暴力枚举的所有框了

    1. 大牛们发明好多选定候选框Region Proposal的方法,比如Selective Search和EdgeBoxes,下图是各种选定候选框的方法的性能对比

    2. R-CNN最终采用的selective search
      那提取候选框用到的算法“选择性搜索”到底怎么选出这些候选框的呢?具体可以看一下PAMI2015的:What makes for effective detection proposals

    有了候选区域,剩下的工作实际就是对候选区域进行图像分类的工作(特征提取+分类)

    对于图像分类,不得不提的是2012年ImageNet大规模视觉识别挑战赛(ILSVRC)上,机器学习泰斗Geoffrey Hinton教授带领学生Krizhevsky,使用卷积神经网络将ILSVRC分类任务的Top-5 error降低到了15.3%,而使用传统方法的第二名top-5 error高达 26.2%


    ​​​​​此后,卷积神经网络CNN占据了图像分类任务的绝对统治地位

    3.1.2 R-CNN:Region Proposal + CNN提取特征 + SVM分类

    2013年11月,UC伯克利的Ross Girshick、Jeff Donahue、Trevor Darrell、Jitendra MalikUC Berkeley等人使用Region Proposal + CNN代替传统目标检测使用的滑动窗口+手工设计特征,设计了R-CNN框架,使得目标检测取得巨大突破,并开启了基于深度学习目标检测的热潮

    R-CNN的简要步骤如下

    1. 输入测试图像
    2. 利用选择性搜索Selective Search算法在图像中从下到上提取2000个左右的可能包含物体的候选区域(Region Proposal)
    3. 因为取出的区域大小各自不同,所以需要
      \rightarrow  先将每个Region Proposal缩放(warp)成统一的227x227的大小
      PS,至于为何需要这么做,简言之,是为了和下面的CNN兼容——其结构要求输入为固定的227 × 227 像素大小,更具体的下文马上会解释
      \rightarrow  然后再输入到CNN
      作者用 Caffe [24] 实现的 Krizhevsky等人提出的卷积神经网络CNN[25-ImageNet clas-sification with deep convolutional neural networks],从每个区域建议中提取一个 4096 维的特征向量。特征的计算方式是将一个均值已减的 227×227 RGB 图像,通过五个卷积层和两个全连接层进行前向传播
      \rightarrow  最终将CNN的fc7层的输出作为特征
    4. 将每个Region Proposal提取到的CNN特征输入到SVM进行分类

    再进一步解释一下在计算候选区域的特征时,为何必须首先将该区域内的图像数据转换为与CNN 兼容的形式

    1. 众所周知,CNN一般都含有卷积部分和全连接部分,其中,卷积层不需要固定尺寸的图像,而全连接层是需要固定大小的输入

    2. 所以当全连接层面对各种尺寸的输入数据时,就需要对输入数据进行

      \rightarrow  cropcrop就是从一个大图扣出网络输入大小的patch,比如227×227

      \rightarrow  warp把一个边界框bounding box的内容resize成227×227
      等一系列操作以统一图片的尺寸大小,比如224*224(ImageNet)、32*32(LenNet)、96*96等

    具体步骤则如下

    1. 步骤一:训练(或者下载)一个分类模型(比如AlexNet)

    2. 步骤二:对该模型做fine-tuning
      将分类数从1000改为20,比如20个物体类别 + 1个背景
      去掉最后一个全连接层

    3. 步骤三:特征提取
      提取图像的所有候选框(选择性搜索Selective Search)
      对于每一个区域:修正区域大小以适合CNN的输入,做一次前向运算,将第五个池化层的输出(就是对候选框提取到的特征)存到硬盘

    4. 步骤四:训练一个SVM分类器(二分类)来判断这个候选框里物体的类别
      每个类别对应一个SVM,判断是不是属于这个类别,是就是positive,反之nagative

      比如下图,就是狗分类的SVM

    5. 步骤五:使用回归器精细修正候选框位置:对于每一个类,训练一个线性回归模型去判定这个框是否框得完美

      比如上面的左图把猫完全框出来了,很完美,中图 框的偏左了,右图 框画的太大了 空白太多

    3.1.3 2000个候选框都要进行CNN提特征 + SVM分类,如何提速

    细心的同学可能看出来了问题

    1. R-CNN虽然不再像传统方法那样穷举,但R-CNN流程的第一步中对原始图片通过Selective Search提取的候选框region proposal多达2000个左右

      这2000个候选框每个框都需要进行CNN提特征+SVM分类,计算量很大,导致R-CNN检测速度很慢,一张图都需要47s
    2. 有没有方法提速呢?
      答案是有的,这2000个region proposal不都是图像的一部分吗,那么我们完全可以对图像提一次卷积层特征,然后只需要将region proposal在原图的位置映射到卷积层特征图上
      这样对于一张图像只需要提一次卷积层特征,然后将每个region proposal的卷积层特征输入到全连接层做后续操作
    3. 但现在的问题是每个region proposal的尺度不一样,而全连接层输入必须是固定的长度,所以直接这样输入全连接层肯定是不行的
      巧的是,SPP Net恰好可以解决这个问题

    3.2 SPP Net(2014/6):Spatial Pyramid Pooling(空间金字塔池化)

    3.2.1 卷积层最后加入SSP Net,使得后面全连接层得到的输入变成固定

    2014年6月,一堆CV牛人们Kaiming He, Xiangyu Zhang, Shaoqing Ren, and Jian Sun通过发表在IEEE上的论文《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》提出了SPP-Net

    1. 如你在上文中看到的,在R-CNN中,“因为取出的区域大小各自不同,所以需要将每个Region Proposal缩放(warp)成统一的227x227的大小并输入到CNN”

    2. warp/crop这种预处理,导致的问题要么被拉伸变形、要么物体不全,限制了识别精确度。没太明白?
      说句人话就是,一张16:9比例的图片你硬是要Resize成1:1的图片,你说图片失真不?

      SPP Net的作者Kaiming He等人逆向思考
      i)  既然由于全连接FC层的存在,普通的CNN需要通过固定输入图片的大小来使得全连接层的输入固定
      ii) 那借鉴卷积层可以适应任何尺寸,为何不能在卷积层的最后加入某种结构,使得后面全连接层得到的输入变成固定的呢
      这个“化腐朽为神奇”的结构就是spatial pyramid pooling layer

    3.2.2 和R-CNN检测流程的比较:SPPNet实现CNN多尺度输入且只需要计算一次卷积

    具体而言,SPP Net的特点有两个:

    1. 结合空间金字塔方法实现CNNs的多尺度输入
      从上已知,在普通的CNN结构中,输入图像的尺寸往往是固定的(比如224*224像素),输出则是一个固定维数的向量

      为使得深度网络能够适应任意尺寸的图像,SPP Net的第一个贡献就是在最后一个卷积层后,作者将最后一个池化层(ROI Pooling,例如,在最后一个卷积层之后的 pool5)替换为空间金字塔池化层(spatial pyramid pooling layer)
      从而
      保证传到下一层全连接层的输入固定(即SSP是一个固定维数的向量,然后给到全连接FC层)

      如此,CNN原本只能固定输入、固定输出,CNN加上SSP之后,便能任意输入、固定输出。神奇吧?
      下图便是R-CNN和SPP Net检测流程的比较


      下图图3则是包含空间金字塔池化层的网络结构。这里256表示conv5层的滤波器数量,conv5是最后一个卷积层

    2. 只对原图提取一次卷积特征
      在R-CNN中,每个候选框先resize到统一大小,然后分别作为CNN的输入,这样是很低效的
      而SPP Net根据这个缺点做了优化:只对原图进行一次卷积计算,便得到整张图的卷积特征feature map,然后找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层,完成特征提取工作

      如此这般,R-CNN要对每个区域计算卷积,而SPPNet只需要计算一次卷积,从而节省了大量的计算时间,比R-CNN有一百倍左右的提速

      如下图图5所示,在特征图的任意窗口中进行特征池化。特征图是从整个图像计算得到的,池化操作则在候选窗口中进行

    3.3 2015年4月:Fast R-CNN推出

    3.3.1 Fast R-CNN:R-CNN的基础上采纳SPP Net方法

    SPP Net真是个好方法,R-CNN的进阶版Fast R-CNN就是在R-CNN的基础上采纳了SPP Net方法,对R-CNN作了改进,使得性能进一步提高

    下图便是Fast R-CNN架构『输入图像及多个感兴趣区域(RoI)被输入到一个CNN中。每个RoI被池化为固定大小的特征图,然后通过全连接层(FCs)映射为特征向量。网络针对每个RoI输出两个向量:softmax概率和每类的边界框回归偏移量。该架构通过多任务损失进行端到端训练 』

    R-CNN与Fast R-CNN的区别有哪些呢?

    • 先说R-CNN的缺点:即使使用了Selective Search等预处理步骤来提取潜在的bounding box作为输入,但是R-CNN仍会有严重的速度瓶颈,原因也很明显,就是计算机对所有region进行特征提取时会有重复计算,Fast-RCNN正是为了解决这个问题诞生的

    • 与R-CNN框架图对比,可以发现主要有两处不同:

      一是最后一个卷积层后加了一个ROI pooling layer
      二是损失函数使用了多任务损失函数(multi-task loss),将边框回归Bounding Box Regression直接加入到CNN网络中训练
      关于什么是边框回归,请参看七月在线APP题库大题查看深度学习分类下第56题:https://www.julyedu.com/question/big/kp_id/26/ques_id/2139

    具体而言

    1. ROI pooling layer实际上是SPP-NET的一个精简版
      \rightarrow  SPP-NET对每个proposal使用了不同大小的金字塔映射
      \rightarrow  而ROI pooling layer只需要下采样到一个7x7的特征图
      对于VGG16网络conv5_3有512个特征图,这样所有region proposal对应了一个7*7*512维度的特征向量作为全连接层的输入

      换言之,这个网络层可以把不同大小的输入映射到一个固定尺度的特征向量
      虽然conv、pooling、relu等操作都不需要固定size的输入,因此,在原始图片上执行这些操作后,虽然输入图片size不同导致得到的feature map尺寸也不同,不能直接接到一个全连接层进行分类
      但是,可以加入这个神奇的ROI Pooling层,对每个region都提取一个固定维度的特征表示,再通过正常的softmax进行类型识别
    2. R-CNN训练过程分为了三个阶段,而Fast R-CNN直接使用softmax替代SVM分类,同时利用多任务损失函数边框回归也加入到了网络中,这样整个的训练过程是端到端的(除去Region Proposal提取阶段)

      也就是说,之前R-CNN的处理流程是先提proposal,然后CNN提取特征,之后用SVM分类器,最后再做bbox regression
      而在Fast R-CNN中,作者巧妙的把bbox regression放进了神经网络内部,与region分类和并成为了一个multi-task模型,实际实验也证明,这两个任务能够共享卷积特征,并相互促进

      所以,Fast-RCNN很重要的一个贡献是成功的让人们看到了Region Proposal + CNN这一框架实时检测的希望,原来多类检测真的可以在保证准确率的同时提升处理速度,也为后来的Faster R-CNN做下了铺垫

    3.3.2 Fast R-CNN相比R-CNN在性能上的提升

    画一画重点:

    1. R-CNN有一些相当大的缺点(把这些缺点都改掉了,就成了Fast R-CNN)
      大缺点:由于每一个候选框都要独自经过CNN,这使得花费的时间非常多
      解决:共享卷积层,现在不是每一个候选框都当做输入进入CNN了,而是输入一张完整的图片,在第五个卷积层再得到每个候选框的特征
    2. 原来的方法:许多候选框(比如两千个)→ CNN → 得到每个候选框的特征 → 分类+回归
      现在的方法:一张完整图片 → CNN → 得到每张候选框的特征 → 分类+回归

    所以容易看见,Fast R-CNN相对于R-CNN的提速原因就在于:不像R-CNN把每个候选区域给深度网络提特征,而是整张图提一次特征,再把候选框映射到conv5上,而SPP只需要计算一次特征,剩下的只需要在conv5层上操作就可以了

    在性能上提升也是相当明显的:

    3.4 Faster R-CNN(2015/6)

    3.4.1 Faster R-CNN:把Fast R-CNN中的Selective Search换成RPN

    Fast R-CNN存在的问题:存在瓶颈:选择性搜索,找出所有的候选框,这个也非常耗时。那我们能不能找出一个更加高效的方法来求出这些候选框呢?

    解决:加入一个提取边缘的神经网络,也就说找到候选框的工作也交给神经网络来做了

    所以,还是咱们熟悉的CV牛人们Shaoqing Ren, Kaiming He, Ross Girshick, and Jian Sun等人

    • 在Fast R-CNN中引入Region Proposal Network(RPN)替代Selective Search,相当于RPN模块指示后续的「CNN + ROI池化」模块应该关注的位置

      同时引入anchor box应对目标形状的变化问题(anchor就是位置和大小固定的box,可以理解成事先设置好的固定的proposal)

    • 具体做法分两步:1 将RPN放在最后一个卷积层的后面,2 RPN直接训练得到候选区域
      如此得到了Faster R-CNN,其对应的论文为《Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks

    至于什么是RPN呢?简言之:

      • 在feature map上滑动窗口
      • 建一个神经网络用于物体分类 + 框位置的回归——即在规则网格的每个位置同时计算目标性得分回归区域边界cls 层输出 2k 个分数,用于估计每个候选框为目标或非目标的概率而reg 层有 4k 个输出,用于编码 k 个框的坐标
      • 滑动窗口的位置提供了物体的大体位置信息
      • 框的回归提供了框更精确的位置

    如此,一种网络,四个损失函数

    1. RPN calssification(anchor good.bad)
    2. RPN regression(anchor->propoasal)
    3. Fast R-CNN classification(over classes)
    4. Fast R-CNN regression(proposal ->box)

    在速度对比上

    Faster R-CNN的主要贡献就是设计了提取候选区域的网络RPN,代替了费时的选择性搜索selective search,使得检测速度大幅提高

    3.4.2 三大算法的对比:R-CNN、Fast R-CNN、Faster R-CNN

    最后总结一下各大算法的步骤:

    R-CNNFast R-CNNFaster R-CNN
    1.在图像中确定约1000-2000个候选框 (使用选择性搜索Selective Search)1.在图像中确定约1000-2000个候选框 (使用选择性搜索Selective Search)1.对整张图片输进CNN,得到feature map
    2.每个候选框内图像块缩放至相同大小,并输入到CNN内进行特征提取 

    2.对整张图片输进CNN,得到feature map

    3.找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层

    2.卷积特征输入到RPN,得到候选框的特征信息
    3.对候选框中提取出的特征,使用分类器判别是否属于一个特定类 

    4.对候选框中提取出的特征,使用分类器判别是否属于一个特定类 

    3.对候选框中提取出的特征,使用分类器判别是否属于一个特定类 
    4.对于属于某一类别的候选框,用回归器进一步调整其位置5.对于属于某一类别的候选框,用回归器进一步调整其位置4.对于属于某一类别的候选框,用回归器进一步调整其位置

    也如下图所示

    简言之,即如本文开头所列

    • R-CNN(Selective Search + CNN + SVM)
    • SPP-net(ROI Pooling)
    • Fast R-CNN(Selective Search + CNN + ROI)
    • Faster R-CNN(RPN + CNN + ROI)

    总的来说,从R-CNN, SPP-NET, Fast R-CNN, Faster R-CNN一路走来,基于深度学习目标检测的流程变得越来越精简,精度越来越高,速度也越来越快

    可以说基于Region Proposal的R-CNN系列目标检测方法是当前目标检测技术领域最主要的一个分支

    第四部分 基于深度学习的回归方法(2015-2020)

    4.1 YOLO (2015/6)

    4.1.1 统一检测流程

    Faster R-CNN的方法目前是主流的目标检测方法,但是速度上并不能满足实时的要求

    YOLO『其对应的论文为:You Only Look Once: Unified, Real-Time Object Detection,中稿CVPR2016, oral』一类的方法慢慢显现出其重要性,这类方法使用了回归的思想,利用整张图作为网络的输入,直接在图像的多个位置上回归出这个位置的目标边框,以及目标所属的类别

    我们直接看上面YOLO的目标检测的流程图,如下图所示「系统将检测建模为回归问题。它将图像划分为一个S×S的网格,并且对于每个网格单元预测B个边界框、这些边界框的置信度以及C个类别的概率。这些预测被编码为一个S×S×(B∗5+C)的张量

    1. 给个一个输入图像,首先将图像划分成S×S——比如7*7的网格
      如果某个物体的中心落在某个网格单元内,则该网格单元负责检测该物体
    2. 对于每个网格,我们都预测B 个(比如2个)边框:包括每个边框是目标的置信度
      相当于边框是否框对了对应物体,而置信度分数反映了模型对该边界框包含物体的信心,以及模型认为该边界框预测的准确程度These confidence scores reflect how confident the model is that the box contains an object andalso how accurate it thinks the box is that it predicts

      形式上,将置信度定义为
      \operatorname{Pr}(\text { Object }) * \operatorname{IOU}_{\text {pred }}^{\text {truth }}

      如果该单元格中不存在目标,则置信度分数应为零。否则,我们希望置信度分数等于预测框与真实框之间的交并比(IOU)
      每个边界框由5个预测值组成:x、y、w、h和置信度。其中,(x, y)坐标表示边界框中心相对于网格单元边界的位置。宽度和高度是相对于整个图像进行预测的。最后,置信度预测表示预测框与任意真实框之间的IOU(交并比
      毕竟在训练时,一般只希望每个目标由一个边界框预测器负责。可根据当前与真实值的IOU(交并比)最高的预测,将其中一个预测器分配为负责预测该目标的预测器


      以及每个边框区域在多个类别上的概率
      即每个网格单元还预测C 个条件类别概率,\operatorname{Pr}\left(\text { Class }_{i} \mid \text { Object }\right)。这些概率以网格单元包含一个物体为条件。无论框的数量 B有多少,我们每个网格单元仅预测一组类别概率

      在测试时,将条件类别概率与各个框的置信度预测相乘

      这为我们每个框提供了类别特定的置信度分数。这些分数同时编码了该类别出现在该框中的概率,以及预测框与目标物体的匹配程度
    3. 根据上一步可以预测出7*7*2个目标窗口,然后根据阈值去除可能性比较低的目标窗口,最后通过可消除重复检测的NMS去除冗余窗口即可「关于什么是非极大值抑制NMS,请参看七月在线APP题库大题查看深度学习分类下第58题:https://www.julyedu.com/question/big/kp_id/26/ques_id/2141

    可以看到整个过程非常简单,不再需要中间的Region Proposal找目标,直接回归便完成了位置和类别的判定

    4.1.2 网络设计:基于CNN

    作者将该模型实现为一个卷积神经网络,并在PASCAL VOC 检测数据集 [9] 上进行评估。网络的初始卷积层用于从图像中提取特征,而全连接层则用于预测输出的概率和坐标

    1. 具体而言,网络架构受到了用于图像分类的GoogLeNet 模型[34] 的启发。且网络包含24 个卷积层,后接2个全连接层

      与GoogLeNet 中使用的inception 模块不同,作者仅仅采用1 × 1 降维层,后接3 × 3 卷积层,这与Lin 等人[22] 的方法类似
    2. 此外,作者还训练了一个快速版的YOLO,旨在突破快速目标检测的极限。Fast YOLO采用了更少的卷积层(9层而非24层)以及每层更少的滤波器
      除了网络规模不同外,YOLO和FastYOLO在训练和测试参数上完全一致

    小结:YOLO将目标检测任务转换成一个回归问题,大大加快了检测的速度,使得YOLO可以每秒处理45张图像。而且由于每个网络预测目标窗口时使用的是全图信息,使得false positive比例大幅降低(充分的上下文信息)

    但是YOLO也存在问题:没有了Region Proposal机制,只使用7*7的网格回归会使得目标不能非常精准的定位,这也导致了YOLO的检测精度并不是很高

    4.2 SSD(2015/12)

    上面分析了YOLO存在的问题,使用整图特征在7*7的粗糙网格内回归对目标的定位并不是很精准。那是不是可以结合Region Proposal的思想实现精准一些的定位?

    SSD『其对应的论文为:SSD: Single Shot MultiBox Detector』结合:YOLO的回归思想以及Faster R-CNN的anchor机制做到了这点

    下图便是SSD的框架图

    在训练过程中,SSD 只需输入一张图像及每个目标的真实边界框

    1. 通过卷积方式,在多个不同尺度的特征图「如(b)和(c)中的8×8和4×4」上的每个位置评估一组(例如4个)具有不同纵横比的默认框
      对于每个默认框,会预测所有目标类别(如(c1, c2, · · ·,cp))的形状偏移量和置信度
    2. 在训练时,首先将这些默认框与真实边界框进行匹配。例如,将两个默认框与猫匹配,一个与狗匹配,这些被视为正样本,其余则为负样本。模型损失为定位损失(如SmoothL1[6])与置信度损失(如Softmax)的加权和

    总之,SSD获取目标位置和类别的方法跟YOLO一样,都是使用回归,但是YOLO预测某个位置使用的是全图的特征,SSD预测某个位置使用的是这个位置周围的特征

    1. 那么如何建立某个位置和其特征的对应关系呢?
      可能你已经想到了,使用Faster R-CNN的anchor机制。如SSD的框架图所示,假如某一层特征图(图b)大小是8*8,那么就使用3*3的滑窗提取每个位置的特征,然后这个特征回归得到目标的坐标信息和类别信息(图c)
    2. 不同于Faster R-CNN,这个anchor是在多个feature map上,这样可以利用多层的特征并且自然的达到多尺度(不同层的feature map 3*3滑窗感受野不同)

    小结:SSD结合了YOLO中的回归思想和Faster R-CNN中的anchor机制,使用全图各个位置的多尺度区域特征进行回归,既保持了YOLO速度快的特性,也保证了窗口预测的跟Faster R-CNN一样比较精准。SSD在VOC2007上mAP可以达到72.1%,速度在GPU上达到58帧每秒

    第五部分 CNN+Transformer端对端解决方案的新时代(2020及以后)

    5.1 DETR整体结构:backbone,encoder,decoder和FFN

    注,本小节的内容主要参考科技猛兽此文的相关部分

    一般目标检测的任务是预测一系列的Bounding Box的坐标以及Label,而大多数检测器的具体做法是

    • 要么基于proposal,比如R-CNN系列的工作,类似Faster R-CNN、Mask R-CNN
    • 要么基于anchor,比如YOLO
    1. 把问题构建成为一个分类和回归问题来间接地完成这个任务,但最后都会生成很多个预测框(确定框的坐标及框内是什么物体),从而不可避免的出现很多冗余的框
    2. 而要去除这些冗余的框,则都需要做一个NMS(non-maximum suppersion,非极大值抑制)的后处理(使得最后调参不易、部署不易)
      所以如果要是有一个端对端的模型,不需要做NMS之类的后处理 也不需要太多先验知识则该有多好

    而通过发布于2020年5月这篇论文《End-to-End Object Detection with Transformers》提出的DETR则满足了大家这个期待:首次通过结合CNN+Transformer端对端解决object detection,其取代了现在的模型需要手工设计的工作,效果不错且可扩展性强——在DETR上加个专用的分割头便可以做全景分割

    其解决的方法是把检测问题看做是一个集合预测的问题(即set prediction problem,说白了,各种预测框本质就是一个集合),其基本流程如下图所示

    1. CNN抽特征且拉直
    2. 全局建模,给到transformer-encoder去进一步学习全局信息
      通过借助Transformer中的的self-attention机制,可以显式地对一个序列中的所有elements两两之间的interactions进行建模或交互,如此就知道了图片中哪块是哪个物体,从而对于同一个物体只需出一个预测框即可
    3. 接着通过不带掩码机制的transformer-decoder生成很多预测框
      注意是并行预测(即并行出框,而不是像原始transformer预测下一个token时一个一个往外蹦)
      相当于一次性生成 N 个box prediction,其中 N是一个事先设定的远远大于image中object个数的一个整数(比如100)
    4. 预测框和真实框做二分图匹配
      最后通过bipartite matching loss的方法,基于预测的100个boxex和ground truth boxes的二分图做匹配,计算loss的大小,从而使得预测的box的位置和类别更接近于ground truth
      当然,这第4步更多是做模型训练的时候用,如果模型训练好了去做推理时,该第4步就不需要了,可以直接在预测的100个框中设定个阈值,比如置信度大于0.7的预测框保留下来,其他视为背景物体而 舍弃

    5.1.1 DETR结构之前两部分:backbone与encoder

    更细致的讲,DETR整体结构可以分为四个部分:backbone,encoder,decoder和FFN,如下图所示

    对于前两部分——backbone和encoder而言

    由于一开始的backbone面对的是 x_{img} \in B \times 3 \times H_0 \times W_0维的图像

    首先把它转换为f \in R^{B \times C \times H \times W}维的feature map,一般来说,通道数C = 2048或256,H = \frac{H_0}{32}W = \frac{W_0}{32}

    然后,由于encoder的输入是f \in R^{B \times C \times H \times W}维的feature map,故正式输入encoder之前还需要依次进行以下过程(图源:科技猛兽):

    1. 通道数压缩(其实就是降维操作)
      用 1×1 convolution处理将通道数channels数量从 C 压缩到d,即得到z_0 \in R^{B \times d \times H \times W}维的新feature map
    2. 转化为序列化数据
      将空间的维度(高H和宽W)压缩为一个维度HW,即把上一步得到的z_0 \in R^{B \times d \times H \times W}(d = 256)维的feature map通过reshape成(HW,B,256)维的feature map
      这步相当于把编码矩阵的维度是 (B,256,H,W) ,序列化成维度为 (HW,B,256)维的张量
    3. 位置编码
      在上一步得到了z_0 \in R^{B \times d \times H \times W}维的feature map之后,再对 z_0 \in R^{B \times d \times H \times W}维的feature map做positional encoding
      最后也做下reshape:高H和宽W压缩为一个维度HW,使得其与上面input embedding维度是一致的

    对于上面第3步的位置编码,再好好解释说明下

    首先,通过此文《一文通透位置编码:从标准位置编码、旋转位置编码RoPE到ALiBi、LLaMA 2 Long(含NTK-aware简介)》可知,原始transformer中的Positional Encoding的表达式为:

    PE_{(pos,2i+1)} = cos\left ( \frac{pos}{10000^{\frac{2i}{d_{model}}}} \right )

    PE_{(pos,2i)} = sin\left ( \frac{pos}{10000^{\frac{2i}{d_{model}}}} \right )

    其中

    • d 就是这个 d \times HW维的feature map的第一维
      pos \in [1,HW]表示token在sequence中的位置,sequence的长度是HW,例如第一个token 的 pos = 0,第二个token的pos = 1
    • i,或者准确意义上是2i2i+1表示了Positional Encoding的维度,i 的取值范围是:[0,...,d_{model}/2]
      所以当 pos 为1时,对应的Positional Encoding可以写成(注意到d = 256):

      PE_1 = [sin(\frac{1}{10000^{\frac{0}{256}}}),cos(\frac{1}{10000^{\frac{0}{256}}}), sin(\frac{1}{10000^{\frac{2}{256}}}),cos(\frac{1}{10000^{\frac{2}{256}}}), sin(\frac{1}{10000^{\frac{4}{256}}}), cos(\frac{1}{10000^{\frac{4}{256}}}),..., sin(\frac{1}{10000^{\frac{255}{256}}}),cos(\frac{1}{10000^{\frac{255}{256}}})]


    其次,DETR与原版transformer中的位置编码有两点不同

    1. 第一点不同的是,原版Transformer只考虑 x 方向的位置编码,但是DETR考虑了 xy 方向的位置编码,因为图像特征是2-D特征:即虽然采用的依然是 sin cos 模式,但是需要考虑 xy 两个方向
      换言之,DETR不是类似vision transoformer的做法——简单的将其拉伸为 d \times HW,然后从 [1,HW]进行长度为256的位置编码,而是考虑了 xy 方向同时编码,每个方向各编码128维向量,这种编码方式更符合图像特点

      Positional Encoding的输出张量是:(B,d,H,W),d = 256 ,其中 d 代表位置编码的长度, H,W代表张量的位置
      意思是说,这个特征图上的任意一个点 (H_1,W_1)有个位置编码,这个编码的长度是256,其中,前128维代表 H_1 的位置编码,后128维代表W_1 的位置编码

      a) P E_{\left(p_{x}, 2 i\right)}=\sin \left(\operatorname{pos}_{x} / 10000^{2 i / 128}\right) \\\ b) P E_{\left(p_{0}, 2 i+1\right)}=\cos \left(\operatorname{pos}_{x} / 10000^{2 i / 128}\right) \\c) P E_{\left(p o s_{y}, 2 i\right)}=\sin \left(\operatorname{pos}_{y} / 10000^{2 i / 128}\right) \\ d) P E_{\left(p o s_{y}, 2 i+1\right)}=\cos \left(\operatorname{pos}_{y} / 10000^{2 i / 128}\right)


      假设你想计算任意一个位置(pos_x,pos_y) ,pos_x \in[1,HW]pos_y \in[1,HW]的Positional Encoding
      \rightarrow 先把pos_x代入上面4个公式中的a 式和 b 式可以计算得到128维的向量,它代表 pos_x 的位置编码
      \rightarrow 再把 pos_y 代入上面4个公式中的 c 式和d 式可以计算得到128维的向量,它代表 pos_y 的位置编码
      \rightarrow 把这2个128维的向量拼接起来,就得到了一个256维的向量,它代表(pos_x,pos_y)的位置编码
      从而计算所有位置的编码,就得到了(256,H,W)的张量,代表这个batch的位置编码
    2. 第二点不同的是,原版Transformer只在Encoder之前使用了Positional Encoding,而且是在输入上进行Positional Encoding,再把输入经过transformation matrix变为Query,Key和Value这几个张量
      但是DETR在Encoder的每一个Multi-head Self-attention之前都使用了Positional Encoding,且只对Query和Key使用了Positional Encoding——即只把维度为(HW,B,256)维的位置编码与维度为(HW,B,256)维的Query和Key相加,而不与Value相加

      上图为DETR的Transformer的详细结构,读者可以对比下原版Transformer的结构 可以发现,除了Positional Encoding设置的不一样外,Encoder其他的结构是一致的。每个Encoder Layer包含一个multi-head self-attention 的module和一个前馈网络Feed Forward Network

     所以,了解了DETR的位置编码之后,你应该明白了其实input embedding和位置编码维度其实是一样的,从而也就可以直接相加,使得Encoder最终输出的是(HW,b,256)维的编码矩阵Embedding,按照原版Transformer的做法,把这个东西给Decoder

    5.1.2 DETR结构的后两部分:decoder和FFN

    通过上面或下面的对比图,可知DETR的Decoder和原版Transformer的decoder也是不太一样的

      

    • 对于原版Transformer,其decoder的最后一个框(上面左图右上角所示):output probability,代表我们一次只产生一个单词的softmax,根据这个softmax得到这个单词的预测结果,即:predicts the output sequence one element at a time
    • 不同的是,DETR的Transformer Decoder是一次性处理全部的object queries(上面右图右上角所示),即一次性输出全部的predictions(而不像原始的Transformer是auto-regressive的,从左到右一个词一个词地输出),即:decodes the N objects in parallel at each decoder layer

    至于DETR的Decoder主要有两个输入:

    1. 第一个输入是Transformer Encoder输出的Embeddingposition encoding(在上图右侧第二个multi-head self-attention处)相 + 之后 给到K
      其中的Embedding就是上文提到的(HW,B,256)的编码矩阵
    2. 第二个输入是Object queries
      所谓Object queries是一个维度为(100,b,256)维的张量,数值类型是nn.Embedding(意味着是可以学习的)
      Object queries矩阵内部通过学习建模了100个物体之间的全局关系,例如房间里面的桌子旁边(A类)一般是放椅子(B类),而不会是放一头大象(C类),那么在推理时候就可以利用该全局注意力更好的进行解码预测输出

      关于上图右侧第1个multi-head self-attention的Q K V
      如上图所示,它的Q K是这么来的:Decoder原本的输入一开始初始化成维度为(100,b,256)维的全部元素都为0的张量,然后和Object queries加在一起之后充当第1个multi-head self-attention的QueryKey,至于Value则是Decoder原本的输入,也就是全0的张量

      关于上图右侧第2个multi-head self-attention的Q K V
      它的KeyValue来自Encoder的输出张量,维度为(hw,b,256),其中Key值还进行位置编码(正如上面第一个输入所述)
      至于其Query值的一部分来自第1个Add and Norm的输出,维度为(100,b,256)的张量,另一部分来自Object queries,充当可学习的位置编码
      所以,第2个multi-head self-attention的Key和Value的维度为(hw,b,256),而Query的维度为(100,b,256)

    每个Decoder的输出维度为(1,b,100,256),送入后面的前馈网络

    到这里你会发现:Object queries充当的其实是位置编码的作用,只不过它是可以学习的位置编码,所以,我们对Encoder和Decoder的每个self-attention的Query和Key的位置编码做个归纳,如下图所示,Value没有位置编码

    5.1.3 损失函数部分解读

    得到了Decoder的输出以后,如前文所述,应该是输出维度为(b,100,256)的张量

    接下来要送入2个前馈网络FFN得到class和Bounding Box(如再度引用的下图所示),它们会得到 N=100 个预测目标 包含类别和Bounding Box(当然这个100肯定是大于图中的目标总数的,如果不够100,则采用背景填充)

    所以,DETR输出张量的维度为(b,100,class+1),和(b,100,4)对应COCO数据集来说:class+1=92 , 4 指的是每个预测目标归一化的(c_x,c_y,w,h),归一化就是除以图片宽高进行归一化

    对于这两个维度

    • 前者代表分类分支,指100个预测框的类型
    • 后者代表回归分支,指100个预测框的Bounding Box(仅仅计算有物体位置,背景集合忽略)

    但是读者可能会有疑问:预测框和真值是怎么一一对应的?换句话说:你怎么知道第47个预测框对应图片里的狗,第88个预测框对应图片里的车?..

    1. 这就需要用到经典的双边匹配算法了,也就是常说的匈牙利算法,该算法广泛应用于最优分配问题
      一幅图片,我们把第 i 个物体的真值表达为 y_i = (c_i,b_i)——其中,c_i表示它的 class ,b_i 表示它的 Bounding Box
      然后定义\hat{y}=\left\{\hat{y}_{i}\right\}_{i=1}^{N}为网络输出的N 个预测值

      对于第i 个真值GT ,\sigma (i)为匈牙利算法得到的与真值GT_i 对应的预测值prediction的索引,举个例子,比如 i = 3\sigma (i) = 18 ,意思就是:与第3个真值对应的预测值是第18个
    2. 那如何根据匈牙利算法找到与每个真值对应的预测值到底是哪个呢?

      \hat{\sigma}=\arg \min _{\sigma \in \Sigma_{N}} \sum_{i}^{N} L_{\text {match }}\left(y_{i}, \hat{y}_{\sigma(i)}\right)

      对于某一个真值y_i ,假设已经找到这个真值对应的预测值\hat{y}_{\sigma (i)},这里的\Sigma _N是所有可能的排列(代表从真值索引到预测值索引的所有的映射),然后用L_{match}最小化y_i\hat{y}_{\sigma (i)}的距离
    3. 这个L_{match}具体是:

      -1_{\left\{c_{i} \neq \varnothing\right\}} \hat{p}_{\sigma(i)}\left(c_{i}\right)+1_{\left\{c_{i} \neq \varnothing\right\}} L_{b o x}\left(b_{i}, \hat{b}_{\sigma(i)}\right)

      意思是:假设当前从真值索引到预测值索引的所有映射为\sigma,对于图片中的每个真值 i
      \rightarrow  先找到对应的预测值\sigma (i),再看看分类网络的结果\hat{p}_{\sigma(i)}\left(c_{i}\right),取反作为 L_{match}的第1部分
      \rightarrow  再计算回归网络的结果\hat{b}_{\sigma(i)}与真值的 Bounding Box 的差异,即 L_{b o x}\left(b_{i}, \hat{b}_{\sigma(i)}\right),作为L_{match}的第2部分

      所以,可以使得L_{match}最小的排列 \hat{\sigma } 就是我们要找的排列,即:对于图片中的每个真值i来讲,\hat{\sigma}(i)就是这个真值所对应的预测值的索引
      上述这个匈牙利算法的过程与Anchor或Proposal有异曲同工的地方,只是此时我们找的是一对一匹配
    4. 接下来就是使用上一步得到的排列\hat{\sigma },计算匈牙利损失
      L_{\text {Hungarian }}(y, \hat{y})=\sum_{i=1}^{N}\left[-\log \hat{p}_{\hat{\sigma}(i)}\left(c_{i}\right)+1_{\left\{c_{i} \neq \varnothing\right\}} L_{b o x}\left(b_{i}, \hat{b}_{\hat{\sigma}(i)}\right)\right]
      式中的L_{box}具体为:

      最常用的L_1 loss对于大小 Bounding Box 会有不同的标度,即使它们的相对误差是相似的。为了缓解这个问题,作者使用了L_1 loss和广义IoU损耗L_{iou}的线性组合,它是比例不变的

      Hungarian意思就是匈牙利,也就是前面的L_{match},上述意思是需要计算M个 GTBounding Box 和N个输预测出集合两两之间的广义距离,距离越近表示越可能是最优匹配关系,也就是两者最密切,广义距离的计算考虑了分类分支和回归分支

    主要参考及扩展阅读

    1. 斯坦福Fei-Fei Li & Andrej Karpathy & Justin Johnson,1 Feb 2016
      Lecture 8: Spatial Localization and Detection
    2. https://www.cnblogs.com/skyfsm/p/6806246.html,by @Madcola
    3. https://mp.weixin.qq.com/s?__biz=MzI1NTE4NTUwOQ==&mid=502841131&idx=1&sn=bb3e8e6aeee2ee1f4d3f22459062b814#rd
    4. https://zhuanlan.zhihu.com/p/27546796
    5. https://blog.youkuaiyun.com/v1_vivian/article/details/73275259
    6. https://blog.youkuaiyun.com/tinyzhao/article/details/53717136
    7. Spatial Pyramid Pooling in Deep Convolutional
    8. Networks for Visual Recognition,by Kaiming He等人
    9. https://zhuanlan.zhihu.com/p/24774302
    10. 知乎专栏作者何之源新书《21个项目玩转深度学习——基于TensorFlow的实践详解
    11. YOLO:https://blog.youkuaiyun.com/tangwei2014/article/details/50915317,https://zhuanlan.zhihu.com/p/24916786
    ### Faster R-CNN 的评估指标 对于目标检测模型而言,评价其性能的关键在于多个方面,包括但不限于位置准确性以及类别预测能力。针对Faster R-CNN这类的目标检测算法,常用的评估指标有mAP(mean Average Precision)、精度(Precision)和召回率(Recall)[^1]。 #### 平均精度均值 (mAP) 平均精度均值(mAP)是衡量目标检测器整体表现的重要标准之一。它综合考虑了不同类别的检测效果,并通过计算各个类别下的AP(Average Precision),最后取所有类别的平均值得到最终的mAP得分。具体来说,在每个IoU交并比阈值下都会有一个对应的AP值;而mAP则是这些AP值在整个数据集上的算术平均数[^2]。 为了更精确地反映模型的表现,通常会采用多种不同的IoU阈值来分别计算各自的mAP,比如0.5, 0.75等常见设定。这有助于全面了解模型在各种条件下的泛化能力和鲁棒性[^3]。 #### 精度 (Precision) 精度是指被正确识别为目标对象的比例,即真正例(True Positive)占所有正向预测数量的比例: \[ \text{Precision} = \frac{\text{TP}}{\text{TP + FP}} \] 其中TP表示真实存在且成功检出的对象数目,FP则代表错误标记为前景的情况。高精度意味着较少误报的发生概率[^4]。 #### 召回率 (Recall) 召回率反映了实际存在的目标中有多少比例能够被有效发现,定义如下: \[ \text{Recall} = \frac{\text{TP}}{\text{TP + FN}} \] 这里FN指的是未能成功捕捉的真实实例。良好的召回率表明模型具有较高的敏感度,可以广泛覆盖感兴趣区域内的潜在目标。 ```python def calculate_precision_recall(tp, fp, fn): precision = tp / (tp + fp) if (tp + fp) != 0 else 0 recall = tp / (tp + fn) if (tp + fn) != 0 else 0 return precision, recall ```
    评论 36
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    打赏作者

    v_JULY_v

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

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

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

    打赏作者

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

    抵扣说明:

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

    余额充值