目标检测2——借Detectron2源码理解Anchors与RPN

article/2025/11/5 14:47:26

文章目录

    • 1.Regionn Proposal Network背景
    • 2.Regionn Proposal Network的结构
    • 3.Anchors
    • 4.Regionn Proposal Network的训练
    • 参考资料


欢迎访问个人网络日志🌹🌹知行空间🌹🌹


1.Regionn Proposal Network背景

RPN,Region Proposal Network是中科大与微软亚洲研究院联合培养博士,原Momenta研发总监任少卿与何凯明,Ross Girshick共同发表的论文Faster R-CNN中提出的一个网络结构,用于目标检测,RPN论文最早发表于20150604号,是在Fast RCNN上的改进,与其一起提出的Translation-Invariant Anchors极大的提高的检测的性呢和准确度。Faster R-CNN使用RPNanchors替代RCNNFast RCNN中的selective search方法,Faster R-CNN将检测问题分成了特征提取backcbone的训练和RPN候选框生成网络的训练,因此是Two Stage检测框架。RPN用于生成Proposal Boxes, 以用来输入ROI PoolingROI Align,做进一步的类别判断和检测框定位。

RPNFaster R-CNN中提出的,先来看下Faster R-CNN的整体结构:
在这里插入图片描述

上图中,可以看到,对于输入的图像,先经过Conv Layers进行特征提取得到feature map,再将feature map一支用于输入RPN结合anchors来生成Proposal Boxes,另一支feature mapRPN生成的Proposal boxes一起输入ROI Pooling,经过全连接层后做检测物体类别的回归和检测框的精细化定位。从上图中可以知道,RPN网络的作用就是输入feature map,输出Proposal Boxes,在进行检测网络整体训练之前,需基于现有的Model先训练RPN网络,使其能够用来生成Proposal Boxes,然后再训练Model,循环3次。

2.Regionn Proposal Network的结构

在这里插入图片描述

如图,这是目前R-CNN衍生出来的检测算法都会使用的RPN Head的网络结构,用来生成Proposal Boxes,并判断其中是否包含物体,输出每个Proposal Boxes的置信度。结合上图,介绍一下rpn网络的结构,RPN网络的输入是backbone提取得到的feature map(NCHW),网络结构中先有一个3x3的卷积,进一步融合特征,然后将卷积结果分别输入到两个分支上。每个分支都包含一个1x1的卷积,只改变输入特征图的通道大小,不改变feature map的宽高。其中一支负责预测anchors偏移量,输出通道数变为num_anchors*box_dims,关于anchors的介绍见下一部分。另一支负责预测每个proposal boxes的置信度,其输出通道数为num_anchors。因总的proposal boxes数里过多,得到置信度proposal boxes对应的位置后,可据此对proposal boxes进行过滤,正是图中proposals层做的事情,其介绍见图2,这里是以一个feature map进行说明的,对于FPN结构的网络,对不同层级的特征分别进行处理即可。代码实现可以参考detectron2

class StandardRPNHead(nn.Module):def forward(self, features: List[torch.Tensor]):"""Args:features (list[Tensor]): list of feature mapsReturns:list[Tensor]: A list of L elements.Element i is a tensor of shape (N, A, Hi, Wi) representingthe predicted objectness logits for all anchors. A is the number of cell anchors.list[Tensor]: A list of L elements. Element i is a tensor of shape(N, A*box_dim, Hi, Wi) representing the predicted "deltas" used to transform anchorsto proposals."""pred_objectness_logits = []pred_anchor_deltas = []for x in features:t = self.conv(x)pred_objectness_logits.append(self.objectness_logits(t))pred_anchor_deltas.append(self.anchor_deltas(t))return pred_objectness_logits, pred_anchor_deltas

3.Anchors

‵AnchorsFaster RCNN论文中提出的用来更好的回归bounding boxes`的算法。

_C.MODEL.ANCHOR_GENERATOR.SIZES = [[32, 64, 128, 256, 512]]
# Anchor aspect ratios. For each area given in `SIZES`, anchors with different aspect
# ratios are generated by an anchor generator.
# Format: list[list[float]]. ASPECT_RATIOS[i] specifies the list of aspect ratios (H/W)
# to use for IN_FEATURES[i]; len(ASPECT_RATIOS) == len(IN_FEATURES) must be true,
# or len(ASPECT_RATIOS) == 1 is true and aspect ratio list ASPECT_RATIOS[0] is used
# for all IN_FEATURES.
_C.MODEL.ANCHOR_GENERATOR.ASPECT_RATIOS = [[0.5, 1.0, 2.0]]

如上代码中,分别是5种size3种宽高比的Anchors配置,Anchors的大小是在检测输入图像的尺度上的,通过变换可知对于每个点共有15种不同宽高比和大小的anchors,

在这里插入图片描述

Anchors作用在feature map上的每个cell中心点的,再根据图像信息和特征提取网络的stride,找到原图上Anchors的对应位置。其应用可以参考faster rcnn论文的一个图,

在这里插入图片描述

使用Anchors时,bounding boxes回归的原理是anchors的中心 x , y x,y x,y和宽高 w , h w,h w,h通过平移和缩放可以得到对应的bounding box。给定 a n c h o r A ( A x , A y , A w , A h ) anchor A(A_x, A_y, A_w, A_h) anchorA(Ax,Ay,Aw,Ah) g t G ( G x , G y , G w , G h ) gt G(G_x, G_y,G_w, G_h) gtG(Gx,Gy,Gw,Gh)可以寻找一种变换F使得 F ( A x , A y , A w , A h ) = G ′ ( G x ′ , G y ′ , G w ′ , G h ′ ) F(A_x, A_y, A_w, A_h)=G'(G_x', G_y', G_w', G_h') F(Ax,Ay,Aw,Ah)=G(Gx,Gy,Gw,Gh),而 G ≈ G ′ G\approx G' GG,变换F可以表示为:

  • 先平移
    G x ′ = A w ∗ d x ( A ) + A x G y ′ = A h ∗ d x ( A ) + A y \begin{matrix} G_x'=A_w*d_x(A)+A_x \\ G_y'=A_h*d_x(A)+A_y \end{matrix} Gx=Awdx(A)+AxGy=Ahdx(A)+Ay

  • 再缩放

G w ′ = A w e x p ( d w ( A ) ) G h ′ = A h e x p ( d h ( A ) ) G_w'=A_w exp(d_w(A)) \\ G_h'=A_h exp(d_h(A)) Gw=Awexp(dw(A))Gh=Ahexp(dh(A))

其中 d x ( A ) , d y ( A ) , d w ( A ) , d h ( A ) d_x(A),d_y(A),d_w(A),d_h(A) dx(A),dy(A),dw(A),dh(A)四个变换,当anchorgt box相差很小时,可看成线性变换即Y=WX

在这里插入图片描述

上图种蓝色的网格表示feature map特征图,在其中间一个cell上生成的一个Anchor如图中黄色框所示,其中心 A x , A y A_x,A_y Ax,Aycell的中心对应的原图上的坐标,与当前这个对应IoU最大的ground truth box如图中红色的框,其中心坐标为 G x , G y G_x,G_y Gx,Gy,可以知道一般情况下Anchor只是大概定位了检测框的位置,还需对其进行少量的平移才能实现准确定位。同样Anchor也只是大概确定了检测框的宽高,还需在宽高方向上进行适量的缩放才能得到准确的检测框。

faster rcnn中的偏移量预测是tx,没有范围限制,容易导致产生超出边界的预测框,在2016年12月25号Joseph Redmon发表的Yolov2中对其进行了修改,改成了在预测相对于featue map cell左上点的偏移量,并做sigmoid,使得偏移量始终在 0 − 1 0-1 01之间。

对于检测网络训练时,传入AGround Truth Boxes之间的变换量 t x , t y , t ω , t h t_x, t_y, t_\omega,t_h tx,ty,tω,th,借此使用L1损失函数回归Y=WX函数即可完成RPN的训练。

4.Regionn Proposal Network的训练

训练RPN网络时,需先将feaure map经过RPN前向推理得到shape=(N, Hi*Wi*A)pred_objectness_logits scoresshape=(N, Hi*Wi*A, B)pred_anchor_deltas。然后将shape = [N, H*W*A]anchorsshape=[N, M, B]ground truth boxes对应起来,再计算含有物体的positive target anchorspredicted anchors之间的定位损失及positive and negative target anchors和对应predicted anchors之间的分类损失。

训练RPN网络时,比较多的工作花费在了anchor assignment,即实现anchorsground truth box之间的匹配。faster R-CNN中主要使用的anchorground truth box之间的IoU来实现。对于ManchorsNround truth boxes,两两之间分别计算IoU,可以得到MxNIoU_Match矩阵,取每个anchorNgt boxes IoU最大的box作为与anchor匹配的Ground Truth Box,如此找到了每个anchor对应的Ground Truth Box。再根据两者之间的IoU,判断其是背景bg还是前景fg即是否有物体,判断方式通常是设者IoU_Threshold_LowIoU_Threshold_HighIoU大于IoU_Threshold_High的是positive,小于IoU_Threshold_Low的是negative,介于两者之间的忽略。通过这样定义可以知道一个ground truth box可以对应多个anchor初步判断出positive/negative anchors之后,还需经过超参数每个图像中训练最多使用的anchor box数量其中positive anchors fractionanchors再次处理,限制参与训练的anchor box不多于超参数最大数量,见detectron2 rpn.py中的label_and_sample_anchors函数。

def label_and_sample_anchors(self, anchors: List[Boxes], gt_instances: List[Instances]
) -> Tuple[List[torch.Tensor], List[torch.Tensor]]:anchors = Boxes.cat(anchors)gt_boxes = [x.gt_boxes for x in gt_instances]image_sizes = [x.image_size for x in gt_instances]del gt_instancesgt_labels = []matched_gt_boxes = []for image_size_i, gt_boxes_i in zip(image_sizes, gt_boxes):"""image_size_i: (h, w) for the i-th imagegt_boxes_i: ground-truth boxes for i-th image"""match_quality_matrix = retry_if_cuda_oom(pairwise_iou)(gt_boxes_i, anchors)matched_idxs, gt_labels_i = retry_if_cuda_oom(self.anchor_matcher)(match_quality_matrix)# M个anchors与N个ground truth boxes匹配,得到M个anchors分别对应的ground truth box,找到每个anchor的标签gt_labels_i = gt_labels_i.to(device=gt_boxes_i.device)del match_quality_matrixif self.anchor_boundary_thresh >= 0:# Discard anchors that go out of the boundaries of the image# NOTE: This is legacy functionality that is turned off by default in Detectron2anchors_inside_image = anchors.inside_box(image_size_i, self.anchor_boundary_thresh)gt_labels_i[~anchors_inside_image] = -1# A vector of labels (-1, 0, 1) for each anchor# 根据超参数,限制每张图像中参与训练的anchors上限和positive anchor的比例gt_labels_i = self._subsample_labels(gt_labels_i)if len(gt_boxes_i) == 0:# These values won't be used anyway since the anchor is labeled as backgroundmatched_gt_boxes_i = torch.zeros_like(anchors.tensor)else:# TODO wasted indexing computation for ignored boxesmatched_gt_boxes_i = gt_boxes_i[matched_idxs].tensorgt_labels.append(gt_labels_i)  # N,AHWmatched_gt_boxes.append(matched_gt_boxes_i)return gt_labels, matched_gt_boxes

损失函数

  • 位置回归使用的是smooth L1 loss,通过positive mask实现只取target positive anchor和对应的predicted anchors计算regressive loss

s m o o t h L 1 ( x ) = { 0.5 x 2 i f ∣ x ∣ < 1 ∣ x ∣ − 0.5 o t h e r w i s e smooth_{L_1(x)} = \left\{\begin{matrix} 0.5x^2 & if \left | x \right | \lt 1\\ \left | x \right | - 0.5 & otherwise \end{matrix}\right. smoothL1(x)={0.5x2x0.5ifx<1otherwise

  • 分类损失使用的是binary cross entropy loss,只取positive/negative target loss计算。
    L i = y t r u e l o g y p r e d + ( 1 − y t r u e ) l o g ( 1 − y p r e d ) L_i = y_{true}log y_{pred} + (1-y_{true})log(1-y_{pred}) Li=ytruelogypred+(1ytrue)log(1ypred)
def losses(self,anchors: List[Boxes],pred_objectness_logits: List[torch.Tensor],gt_labels: List[torch.Tensor],pred_anchor_deltas: List[torch.Tensor],gt_boxes: List[torch.Tensor],
) -> Dict[str, torch.Tensor]:num_images = len(gt_labels)gt_labels = torch.stack(gt_labels)  # (N, sum(Hi*Wi*Ai))# Log the number of positive/negative anchors per-image that's used in trainingpos_mask = gt_labels == 1num_pos_anchors = pos_mask.sum().item()num_neg_anchors = (gt_labels == 0).sum().item()storage = get_event_storage()storage.put_scalar("rpn/num_pos_anchors", num_pos_anchors / num_images)storage.put_scalar("rpn/num_neg_anchors", num_neg_anchors / num_images)localization_loss = _dense_box_regression_loss(anchors,self.box2box_transform,pred_anchor_deltas,gt_boxes,pos_mask,box_reg_loss_type=self.box_reg_loss_type,smooth_l1_beta=self.smooth_l1_beta,)valid_mask = gt_labels >= 0objectness_loss = F.binary_cross_entropy_with_logits(cat(pred_objectness_logits, dim=1)[valid_mask],gt_labels[valid_mask].to(torch.float32),reduction="sum",)normalizer = self.batch_size_per_image * num_imageslosses = {"loss_rpn_cls": objectness_loss / normalizer,# The original Faster R-CNN paper uses a slightly different normalizer# for loc loss. But it doesn't matter in practice"loss_rpn_loc": localization_loss / normalizer,}losses = {k: v * self.loss_weight.get(k, 1.0) for k, v in losses.items()}return losses

Fast R-CNN论文中,bounding boxes回归使用的就是smooth L1 loss了,与 L 1 , L 2 L_1,L_2 L1,L2相比,smooth L1的导数在x较小时(0-1)时更敏感,因此可以有更好的收敛效果。

在这里插入图片描述

图片来自于
在这里插入图片描述


欢迎访问个人网络日志🌹🌹知行空间🌹🌹


参考资料

  • 1.https://zhuanlan.zhihu.com/p/31426458
  • 2.https://github.com/facebookresearch/detectron2)

http://chatgpt.dhexx.cn/article/DFoqywsE.shtml

相关文章

QML基础:锚anchors

正文 除了传统的Grid、Row和Column外,Qt Quick还提供了一种使用锚点的方法来布局。可以将每个元素视为具有7条不可见的“锚定线”的集合:left、horizontalCenter、right、top、verticalCenter、baseline和bottom。 baseline(上图未展示)对应于文本所在的虚线。对于没有文…

细说目标检测中的Anchors

本文转载自AI公园。 作者&#xff1a;Raghul Asokan 编译&#xff1a;ronghuaiyang 导读 给大家再次解释一下Anchors在物体检测中的作用。 今天&#xff0c;我将讨论在物体检测器中引入的一个优雅的概念 —— Anchors&#xff0c;它是如何帮助检测图像中的物体&#xff0c;以及…

anchors布局

anchors布局 import QtQuick 2.2 import QtQuick.Window 2.2 Window {visible: truewidth: 640height: 480title: qsTr("Hello World")Rectangle {width: 300;height: 200;color: "blue";Rectangle {id: rectl;anchors.left: parent.left;anchors.leftMar…

PDU Session Anchors

在同一时刻&#xff0c;UE可以建立多条到同一个DN或不同DN的PDU会话&#xff1b;建立到同一个DN的多个PDU会话时&#xff0c;通过不同的UPF&#xff1b;每条PDU会话对应的SMF可以不同。 为了支持到DN的可选择路由功能或支持SSC mode 3模式&#xff0c;SMF可以控制PDU session的…

kmeans++聚类生成anchors

kmeans聚类生成anchors 说明 使用yolo系列通常需要通过kmeans聚类算法生成anchors&#xff0c; 但kmeans算法本身具有一定的局限性&#xff0c;聚类结果容易受初始值选取影响。 因此通过改进原kmeans_for_anchors.py实现 kmeans聚类生成anchors。具体实现如下&#xff1a; i…

anchors如何获得_Yolov3通过k-means聚类得到自己数据的anchors

本文代码参考: https://github.com/lars76/kmeans-anchor-boxes Yolov3中默认的9个anchors是作者通过对voc数据聚类得到的。 anchors 10,14, 23,27, 37,58, 81,82, 135,169, 344,319 不过&#xff0c;当我们训练自己的数据时&#xff0c;如果也采用默认的anchors&#xff0c;可…

Unity 锚点 Anchors

锚点介绍 锚点是Rect Transform组件中的属性&#xff0c;用于描述当前物体相对于父物体的对齐方式。 选中一个UI元素&#xff0c;就会显示其父物体的矩形框以及相对于父物体的锚点。 锚点只能位于父物体的矩形框之内。 锚点表现为四个相对出现的小三角形&#xff0c; 它们时而…

QML anchors 锚布局

锚布局 锚布局有7种锚线 anchors.leftanchors.rightanchors.topanchors.bottomanchors.horizontalCenteranchors.verticalCenteranchors.baseline 5种锚边距 anchors.leftMarginanchors.rightMarginanchors.topMarginanchors.bottomMarginanchors.margins 3种锚偏移 anchor…

anchors生成

关于修改anchor anchor与图片的输入分辨率有关系。 You should use this repository to get anchors: https://github.com/AlexeyAB/darknet By using this command for Yolo v3 (or v2): ./darknet detector calc_anchors data/hand.data -num_of_clusters 9 -width 720 -he…

使用k-means聚类anchors

在之前讲yolo理论基础知识时有提到过&#xff0c;从yolov2开始使用的anchors都是通过聚类得到的。如果想了解更多yolo相关的知识可以看看我在bilibili上录得视频&#xff1a;https://www.bilibili.com/video/BV1yi4y1g7ro 今天补下之前没有细讲的聚类anchors相关知识&#xff…

细说物体检测中的Anchors

点击上方“AI公园”&#xff0c;关注公众号&#xff0c;选择加“星标“或“置顶” 作者&#xff1a;Raghul Asokan 编译&#xff1a;ronghuaiyang 导读 给大家再次解释一下Anchors在物体检测中的作用。 今天&#xff0c;我将讨论在物体检测器中引入的一个优雅的概念 —— Ancho…

带图讲解,深度学习YOLO里面的anchors的进阶理解

如果有了解过yolo网络&#xff0c;那肯定也听说过anchors&#xff0c;当然anchors这个概念布置在YOLO里面才有&#xff0c;在其他的目标检测中也存在anchors这个概念。对于anchors计算的一些公式这篇文章就不进行讲解了&#xff0c;这篇文章主要是讲在训练网络模型过程中anchor…

Linux终端的网易云音乐——musicbox

网易云音乐是听歌的不错的选择&#xff0c;如果能够在命令行听歌就更cool了。特来推荐musicbox。 网易云音乐的musicbox是网易云音乐命令行版本&#xff0c;这款命令行的客户端使用 Python 构建&#xff0c;以 mpg123 作为播放后端。提供了很多使用的功能&#xff0c;如&#x…

MusicStore-2

1.按照MusicStore-1步骤创建mvc项目&#xff0c;并初始化数据库 2.修改HomeController using Chapter8.Models; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc;namespace Chapter8.Controllers {public class…

音乐i网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字) &#xff1a;

musicbox(暂停/启动,停止,下一曲上一首)

主界面 按下开始 按下暂停 按下停止 下一首 上一首 代码 activity_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:orientation"vertical&…

node-webkit-MusicBox 基于nwjs ,html5 ,制作的音乐盒子

太长&#xff1f;单击目录直接去看最终效果&#xff0c;在最下边 文件下载地址&#xff1a;http://download.csdn.net/detail/u013934914/9180053 1.思路&#xff08;简单设想&#xff09; index.html 实现 对页面的显示&#xff0c;并调用绑定ymusic.js中的方法 需要&…

算数计算机音乐模拟器,Musicalculator

musicalculatorapp它是一个音乐旋律软件&#xff0c;在这上面你可以随时随地的记录你有灵感时创作出来的乐谱&#xff0c;还可以放好听的音色包进行自动的弹奏&#xff0c;还可以根据自己的想法设定速度音长&#xff0c;这一款非常的适合喜爱音乐的用户。该应用只是一款音乐计算…

HTML5 CSS3实战——自定义音乐播放器(一)

前几天才刚开始接触HTML5和CSS3。学习了一下里面的一些炫酷的新特性。不过&#xff0c;对于原生的HTML5的媒体播放器&#xff0c;真的不得不吐槽&#xff1a;就三个按钮 界面还那么丑。所以觉得自己整一个好看的播放器。老话说&#xff1a;说不如干&#xff0c;纸上谈兵终觉浅。…

NetEase MusicBox —— Linux系统里的网易云音乐(转载)

功能特性 320kbps的高品质音乐 歌曲&#xff0c;艺术家&#xff0c;专辑检索 网易 22 个歌曲排行榜 网易新碟推荐 网易精选歌单 网易 DJ 节目 私人歌单&#xff0c;每日推荐 随心打碟 本地收藏&#xff0c;随时加 ? 播放进度及播放模式显示 Vimer 式快捷键让操作丝般顺滑 可使…