FasterRCNN目标检测

R-CNN

在这里插入图片描述

四个步骤:

  1. 对输入图片提取候选区(region proposal),每张大约2000个。论文中采用selective search的方法。
  2. 对每个候选区采用CNN网络提取特征。此处需要将proposal的尺寸缩放成统一的227x227,以匹配CNN网络。最终提取到的特征展平处理,长度为4096。
  3. 类别判断。将所提特征送入每一类的SVM分类器,判断是否属于该类。
  4. 候选框位置回归。

Fast RCNN

在这里插入图片描述

Fast RCNN相比于RCNN改进了3点:

  1. 共享卷积:将整幅图输出卷积神经网络,得到特征图,而不是像RCNN那样一个一个的候选区域输入卷积神经网络。
  2. ROI Pooling:将最后一个卷积层的SSP Layer改为RoI Pooling Layer,利用特征池化的方法,进行特征尺度变换,这样可以有任意大小的图片输入。
  3. 多任务损失函数:将边框回归直接加入到CNN网络中训练,同时包含了候选区域分类损失和位置回归损失。

Faster RCNN

在这里插入图片描述

  1. Conv layers。作为一种CNN网络目标检测方法,Faster RCNN首先使用一组基础的conv+relu+pooling层提取image的feature maps。该feature maps被共享用于后续RPN层和全连接层。
  2. Region Proposal Networks。RPN网络用于生成region proposals。该层通过softmax判断anchors属于positive或者negative,再利用bounding box regression修正anchors获得精确的proposals。
  3. Roi Pooling。该层收集输入的feature maps和proposals,综合这些信息后提取proposal feature maps,送入后续全连接层判定目标类别。
  4. Classification。利用proposal feature maps计算proposal的类别,同时再次bounding box regression获得检测框最终的精确位置。
    在这里插入图片描述

在这里插入图片描述

作为 torchvision 中目标检测基类,GeneralizedRCNN 继承了 torch.nn.Module,后续 FasterRCNN 、MaskRCNN 都继承 GeneralizedRCNN。

4个步骤:

  1. 将 transform 后的图像输入到 backbone 模块提取特征图

    #GeneralizedRCNN.forward(…)
    features = self.backbone(images.tensors)
    backbone 一般为 VGG、ResNet、MobileNet 等网络。

  2. 然后经过 rpn 模块生成 proposals 和 proposal_losses

    #GeneralizedRCNN.forward(…)
    proposals, proposal_losses = self.rpn(images, features, targets)

  3. 接着进入 roi_heads 模块(即 roi_pooling + 分类)

    #GeneralizedRCNN.forward(…)
    detections, detector_losses = self.roi_heads(features, proposals, images.image_sizes, targets)

  4. 最后经 postprocess 模块(进行 NMS,同时将 box 通过 original_images_size映射回原图)
    #GeneralizedRCNN.forward(…)
    detections = self.transform.postprocess(detections, images.image_sizes, original_image_sizes)

在这里插入图片描述

对于普通的 FasterRCNN 只需要将 feature_map 输入到 rpn 网络生成 proposals 即可。但是由于加入 FPN,需要将多个 feature_map 逐个输入到 rpn 网络。

在这里插入图片描述

class AnchorGenerator(nn.Module):
    def generate_anchors(self, scales, aspect_ratios, dtype=torch.float32, device="cpu"):
    def set_cell_anchors(self, dtype, device):

首先,每个位置有 5 种 anchor_size 和 3 种 aspect_ratios,所以每个位置生成 15 个 base_anchors:

[ -23., -11., 23., 11.] # w = h = 32, ratio = 2
[ -16., -16., 16., 16.] # w = h = 32, ratio = 1
[ -11., -23., 11., 23.] # w = h = 32, ratio = 0.5
[ -45., -23., 45., 23.] # w = h = 64, ratio = 2
[ -32., -32., 32., 32.] # w = h = 64, ratio = 1
[ -23., -45., 23., 45.] # w = h = 64, ratio = 0.5
[ -91., -45., 91., 45.] # w = h = 128, ratio = 2
[ -64., -64., 64., 64.] # w = h = 128, ratio = 1
[ -45., -91., 45., 91.] # w = h = 128, ratio = 0.5
[-181., -91., 181., 91.] # w = h = 256, ratio = 2
[-128., -128., 128., 128.] # w = h = 256, ratio = 1
[ -91., -181., 91., 181.] # w = h = 256, ratio = 0.5
[-362., -181., 362., 181.] # w = h = 512, ratio = 2
[-256., -256., 256., 256.] # w = h = 512, ratio = 1
[-181., -362., 181., 362.] # w = h = 512, ratio = 0.5

由于有 FPN 网络,所以输入 rpn 的是多个特征。为了方便介绍,以下都是以某一个特征进行描述,其他特征类似。

假设有h * w的特征,首先会计算这个特征相对于输入图像的下采样倍数 stride:
比如原图800*800大小的图片,输出特征图50*50,stride则为800/50=16
在这里插入图片描述
然后生成一个h*w大小的网格,每个格子长度为 stride,如下图:
在这里插入图片描述

#AnchorGenerator.grid_anchors(...)
shifts_x = torch.arange(0, grid_width, dtype=torch.float32, device=device) * stride_width
shifts_y = torch.arange(0, grid_height, dtype=torch.float32, device=device) * stride_height
shift_y, shift_x = torch.meshgrid(shifts_y, shifts_x)

然后将 base_anchors 的中心从(0,0)移动到网格的点,且在网格的每个点都放置一组 base_anchors。这样就在当前 feature_map 上有了很多的 anchors。
stride 代表网络的感受野,网络不可能检测到比 feature_map 更密集的框了!所以才只会在网格中每个点设置 anchors(反过来说,如果在网格的两个点之间设置 anchors,那么就对应 feature_map 中半个点,显然不合理)。
在这里插入图片描述

#AnchorGenerator.grid_anchors(...)
anchors.append((shifts.view(-1, 1, 4) + base_anchors.view(1, -1, 4)).reshape(-1, 4))

#RPN

  1. 如果输入3*600*800的图像,经过Backbone网络,降采样率为16,输出512*37*50(600/16=37.5,800/16=50)的特征图feature map.

  2. 经过RPNhead的3*3卷积神经网络维度还是512*37*50,对于分类网络分支,1x1卷积输出18*37*50的特征,对于回归网络分支,1x1卷积输出36*37*50的数据。
    18是因为在RPN中的分类网络部分只是判断有无物体,即正负样本,不进行物体类别分类,所以分类结果只有两种(0和1),若每个特征点生成9个锚框Anchor,2*9=18.
    回归网络中每个anchor对应四个数据,tx、ty、tw、th,因此9x4=36。

  3. RPN中的AnchorGenerator 生成37*50*9=16650个锚框Anchors,有一些锚框超出了边界,因此保留边框内部部分。

  4. RPN中分类网络部分:通过计算Anchor与标签的IOU来判断是正样本还是负样本,具体实现时,需要计算每一个Anchor与每一个标签的IOU,因此会得到一个IOU矩阵。判断标准如下:

     (1) 对于任何一个Anchor,与所有标签的最大IOU小于0.3,则视为负样本。
     (2) 对于任何一个标签,与其有最大IOU的Anchor视为正样本。
     (3) 对于任何一个Anchor,与所有标签的最大IOU大于0.7,则视为正样本。
    

    由于Anchor的数量接近2万,并且大部分时背景,因此需要筛选一部分,默认选择256个Anchor。

  5. RPN的回归偏移真值:得到anchor相对于target框的偏移量后,保存在bbox_tarets中,损失函数通常使用smooth函数,smooth函数结合了1阶与2阶损失函数,原因在于,当预测偏移量与真值差距较大时,使用2阶函数时导数太大,模型容易发散而不容易收敛,因此大于1时采用导数较小的1阶段损失函数。

  6. RPN的非极大值抑制(NMS)将重叠的框去掉,最后再次根据RPN的预测得分选择前2000个,作为最终的Proposal,输出到下一阶段。这里得到2000个候选框还是太多,继续Select Sample,筛选出的正负样本总数为256,筛选标准如下:

     (1)对于任何一个proposal,其与所有标签的最大IOU如果大于等于0.5,则视为正样本。
     (2)对于任何一个proposal,其与所有标签的最大IOU如果大于等于0且小于0.5,则视为负样本。
    

    为了控制正负样本比例基本满足1:3,在此正样本数量不超过64,超过了则随机选取64个。

ROI Pooling

  1. 从RPN得到了256个ROI,以及每一个ROI对应的类别与偏移量真值,为了计算损失,还需要计算每一个ROI的预测量。由于ROI是由各种大小高宽不同的Anchor经过偏移修正、筛选得到的,但后续的RCNN全连接网络部分要求输入特征大小维度固定。Pooling的过程就是获得7*7大小区域的特征。
  2. 如输入原图像600*800,ROI为332*332,对应原图的一块子区域,经过下采样率为16的Backbone,特征图上ROI对应区域为20*20大小(332/16=20.75),然后为了获得7x7的特征,20/7=2.857,对ROI对应的20*20区域进行步长为2的最大池化。

全连接RCNN模块

  1. 在经过ROIPooling层之后,特征被池化到了固定的维度,因此接下来可以利用全连接网络进行分类与回归预测量的计算。经过池化后的256个ROI维度为256*512*7*7,作展平处理为256*25088,两个全连接网络输出256*4096,再分别进入分类网络分支和回归网络分支,得到256*21的分类输出和256*84的回归网络输出
  2. RCNn部分的损失函数计算方法与RPN相似,只不过分类类别有2变为21,回归则是至多有64个正样本参与回归计算,负样本不参与回归计算。

代码

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

网络输出
2. RCNn部分的损失函数计算方法与RPN相似,只不过分类类别有2变为21,回归则是至多有64个正样本参与回归计算,负样本不参与回归计算。

代码

[外链图片转存中…(img-ujOc2x2C-1699491243408)]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

<think>嗯,用户想了解Faster R-CNN的评估指标。首先,我得回忆一下Faster R-CNN的基本结构和它在目标检测中的应用。Faster R-CNN是一个两阶段的检测器,首先由区域提议网络(RPN)生成候选区域,然后对这些区域进行分类和边界框回归。评估这样的模型通常会用一些通用的目标检测指标。 首先想到的是常用的指标比如准确率、召回率,但目标检测更常用的是mAP(mean Average Precision)。mAP是通过计算不同IoU(交并比)阈值下的平均精度得来的。每个类别的AP是精度-召回率曲线下的面积,然后对所有类别取平均得到mAP。不过用户可能想知道具体的计算细节,比如IoU的阈值设定,比如COCO数据集用的0.5到0.95的不同阈值,而PASCAL VOC用的是0.5的固定阈值。 另外,还有其他的指标比如FPS(每秒帧数)来衡量检测速度,这对于实时应用很重要。还有每个类别的AP,或者检测的召回率在不同IoU下的表现。可能还要提到误检率、漏检率这些辅助指标,但在实际论文中主要还是以mAP为主。 用户提到的问题中还引用了关于NULL的讨论,不过这部分可能与评估指标无关,可能是用户误贴了内容,需要忽略。要确保回答集中在Faster R-CNN的评估指标上,比如COCO和PASCAL VOC数据集的评估标准差异,以及指标的具体计算方法。比如,COCO的mAP是多个IoU阈值的平均值,而VOC是单一阈值。此外,可能需要解释AP的计算步骤,比如如何生成PR曲线,如何积分等。 可能还需要提到其他变种指标,如AP50、AP75,分别对应IoU为0.5和0.75的情况。另外,小目标、中目标、大目标的AP细分,这在COCO评估中常见。最后,还要说明这些指标如何反映模型性能的不同方面,比如mAP综合反映精度和召回率,而FPS反映速度,帮助用户全面评估模型。</think>### Faster R-CNN的评估指标 Faster R-CNN作为经典的目标检测模型,其评估主要依赖以下核心指标: 1. **mAP(mean Average Precision)** 目标检测的核心指标,反映模型在定位和分类上的综合性能。 - **计算步骤**: - 对每个类别计算精度-召回率曲线 - 计算曲线下面积得到AP(Average Precision) - 对所有类别的AP取平均得到mAP - **阈值差异**: - COCO数据集使用IoU阈值$0.5:0.05:0.95$的多尺度计算[^1] - PASCAL VOC采用固定阈值$IoU=0.5$ 2. **IoU(交并比)** 定义检测框与真实框的重合度: $$ IoU = \frac{Area_{overlap}}{Area_{union}} $$ 通常以$IoU \geq 0.5$作为正确检测的标准[^2]。 3. **FPS(Frames Per Second)** 衡量模型推理速度,计算方式: $$ FPS = \frac{Total\_Frames}{Inference\_Time} $$ 工业级应用通常要求$FPS \geq 30$。 4. **AP细分指标** - **AP50/AP75**:IoU阈值为0.5/0.75时的AP - **AP\_S/AP\_M/AP\_L**:针对小/中/大目标的AP(按像素面积划分) ```python # AP计算伪代码示例(基于COCO评估协议) def calculate_ap(recall, precision): mrec = np.concatenate(([0.], recall, [1.])) mpre = np.concatenate(([0.], precision, [0.])) for i in range(mpre.size-1, 0, -1): mpre[i-1] = max(mpre[i-1], mpre[i]) i = np.where(mrec[1:] != mrec[:-1])[0] return np.sum((mrec[i+1] - mrec[i]) * mpre[i+1]) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值