深入解读 MMDetection 中的 Cascade RPN级联区域提议网络与自适应卷积实战指南【免费下载链接】mmdetectionOpenMMLab Detection Toolbox and Benchmark项目地址: https://gitcode.com/gh_mirrors/mm/mmdetectionCascade RPNCascade Region Proposal Network是 MMDetection 中内置的一种高质量区域提议算法它通过单锚点 多阶段级联细化的思路替代传统 RPN 的密集多锚点设计并用自适应卷积实现特征与提议框的对齐。本文以 configs/cascade_rpn/README.md 为核心骨架结合 mmdet/models/dense_heads/cascade_rpn_head.py 的源码实现与 configs/cascade_rpn 下的三套官方配置系统讲解其算法原理、两阶段级联结构、自适应卷积的两种模式、关键配置项语义以及如何用它替换 Faster R-CNN / Fast R-CNN 的 RPN 并完成训练与推理。读完本文你将能够理解 Cascade RPN 的完整工作流并在自己的检测实验中直接复用官方配置或按需调整超参数。一、从传统 RPN 的痛点看 Cascade RPN 的设计动机传统 RPNRegion Proposal Network在特征图的每个位置上铺设多种预定义尺度和宽高比的锚点如 Faster R-CNN 默认 3 种尺度 × 3 种宽高比并通过分类分支判断前景背景、回归分支微调锚点位置。论文Cascade RPN: Delving into High-Quality Region Proposal Network with Adaptive ConvolutionVu et al., NeurIPS 2019指出这种启发式设计的两个核心局限锚点数量多但质量低为覆盖目标的尺度多样性需要大量预定义锚点但锚点与真实目标之间的对齐程度依赖人工设定的超参数特征与锚点不对齐RPN 在固定位置的网格点上采样特征而回归后的锚点提议框位置往往已偏离原始网格导致后续阶段使用的特征与实际框位置存在偏差。Cascade RPN 通过两条关键设计系统性解决上述问题单锚点 多阶段细化每个位置只使用一个锚点尺度 8、宽高比 1.0通过多个级联阶段逐步精修提议框各阶段对正样本的定义由宽松到严格第一阶段使用无锚点的区域分配策略后续阶段逐步切换到基于 IoU 的锚点策略自适应卷积Adaptive Convolution卷积的采样位置以当前锚点为引导而非固定在规则网格上从而在各阶段维持特征与提议框的对齐。论文报告在 COCO 上简单的两阶段 Cascade RPN 相比传统 RPN 将 AR 提升13.4 个点超越了当时的已有区域提议方法将其应用于 Fast R-CNN 与 Faster R-CNN检测 mAP 分别提升3.1 与 3.5 个点。MMDetection 在此基础上提供了可直接复现的官方实现。二、算法核心两阶段级联结构与自适应卷积2.1 整体工作流渐进式精修的级联流水线在 MMDetection 中级联提议网络由两个层级组成定义在 mmdet/models/dense_heads/cascade_rpn_head.pyCascadeRPNHead级联的总调度器持有若干StageCascadeRPNHead子阶段self.stages ModuleList()负责串联各阶段的输入输出、逐阶段计算损失并在阶段之间调用refine_bboxes用上一阶段的回归结果生成新的锚点StageCascadeRPNHead继承自RPNHead的单个级联阶段负责该阶段的特征提取、分类/回归预测与损失计算。CascadeRPNHead.loss与loss_and_predict中的核心循环见 cascade_rpn_head.py清晰展示了级联流程for i in range(self.num_stages): stage self.stages[i] # 依据自适应卷积类型生成偏移量offset 模式或置空dilation 模式 if stage.adapt_cfg[type] offset: offset_list stage.anchor_offset(anchor_list, stage.anchor_strides, featmap_sizes) else: offset_list None x, cls_score, bbox_pred stage(x, offset_list) # 计算本阶段损失loss 字典中以 s{i}.xxx 命名便于区分各阶段 stage_loss stage.loss_by_feat(*rpn_loss_inputs) # 除最后一个阶段外用回归结果精修锚点作为下一阶段的输入 if i self.num_stages - 1: anchor_list stage.refine_bboxes(anchor_list, bbox_pred, batch_img_metas)从源码结构可以看到两个关键机制锚点精修refine_bboxes阶段 i 的回归头输出 bbox_pred 后refine_bboxescascade_rpn_head.py使用DeltaXYWHBBoxCoder将上一阶段的锚点与回归量解码为新的绝对坐标框作为下一阶段的锚点继续细化特征桥接bridged_featureforward_singlecascade_rpn_head.py中若某阶段设置了bridged_featureTrue则该阶段卷积输出的特征会更新输入特征bridged_x x实现跨阶段的特征信息流动。2.2 自适应卷积让采样位置跟随锚点AdaptiveConv类cascade_rpn_head.py是特征对齐的关键支持两种adapt_type模式底层实现适用场景源码要点dilation普通nn.Conv2d 固定膨胀率锚点尺度均匀第一阶段paddingdilation, dilationdilation无需 offset 输入offsetDeformConv2d可变形卷积锚点任意形状第二阶段按锚点宽高与中心计算 3×3 核的 18 维偏移量在offset模式下anchor_offsetcascade_rpn_head.py为每个锚点计算可变形卷积的采样偏移偏移量由两部分叠加形状偏移shape offset由锚点的宽w、高h相对步长stride的比值决定使 3×3 卷积核的采样点沿锚点形状拉伸中心偏移center offset由锚点中心相对特征图规则网格中心的偏差决定使采样点对准锚点中心。两者相加得到最终的 18 维偏移3×3 核 × 2 坐标再通过offset.permute(0, 2, 1).reshape(N, -1, H, W)重塑后送入DeformConv2d。这一机制让每一级的卷积感受野贴在当前提议框上从实现层面印证了论文中自适应卷积以锚点为引导学习采样特征的表述。值得注意的是源码中的_shape_offset注释明确说明当前仅支持kernel_size3, dilation1的偏移模式调整adapt_cfg时需注意这一限制。2.3 两阶段训练策略从无锚点到严格 IoU与两阶段结构对应CascadeRPNHead在训练时使用两个train_cfg.rpn子配置RegionAssigner→MaxIoUAssigner正样本定义由宽松到严格阶段分配器正样本标准采样器分类分支自适应卷积特征桥接Stage 0RegionAssignercenter_ratio0.2, ignore_ratio0.5基于区域中心比的无锚点分配无samplingFalse使用PseudoSampler无with_clsFalsedilationdilation3bridged_featureTrueStage 1MaxIoUAssignerpos_iou_thr0.7, neg_iou_thr0.7, min_pos_iou0.3与 GT 的 IoU ≥ 0.7RandomSampler256 个样本正样本比例 0.5有with_clsTrueoffsetbridged_featureFalse对应源码中StageCascadeRPNHead.__init__的逻辑cascade_rpn_head.py当train_cfg中未提供sampler时自动退化为PseudoSampler这正是第一阶段samplingFalse的实现基础。这种渐进收紧的正样本定义与 Cascade R-CNN 的思想一脉相承早期阶段用宽松标准快速召回大量候选后续阶段用严格标准筛出高质量提议从而在保持召回率的同时提升提议质量。三、官方配置逐行解析configs/cascade_rpn目录下提供了三套可直接运行的官方配置cascade-rpn_r50-caffe_fpn_1x_coco.py纯 Cascade RPN 提议网络RPN-only用于评估区域提议质量ARcascade-rpn_fast-rcnn_r50-caffe_fpn_1x_coco.pyCascade RPN Fast R-CNN基于预生成的提议文件训练检测头cascade-rpn_faster-rcnn_r50-caffe_fpn_1x_coco.pyCascade RPN Faster R-CNN端到端联合训练。3.1 Cascade RPN 头配置以 RPN-only 配置为例_base_ ../rpn/rpn_r50-caffe_fpn_1x_coco.py model dict( rpn_headdict( _delete_True, # 覆盖基类配置中的标准 RPNHead typeCascadeRPNHead, # 级联提议头 num_stages2, # 级联阶段数 stages[ dict( typeStageCascadeRPNHead, in_channels256, feat_channels256, anchor_generatordict( typeAnchorGenerator, scales[8], # 每位置仅一个尺度 ratios[1.0], # 每位置仅一个宽高比正方形锚点 strides[4, 8, 16, 32, 64]), # FPN 五层特征图步长 adapt_cfgdict(typedilation, dilation3), bridged_featureTrue, # 输出特征桥接至下一阶段 samplingFalse, # 不采样使用 PseudoSampler with_clsFalse, # 第一阶段不做分类 reg_decoded_bboxTrue, # 直接对解码后的框回归配合 IoU 损失 bbox_coderdict( typeDeltaXYWHBBoxCoder, target_means(.0, .0, .0, .0), target_stds(0.1, 0.1, 0.5, 0.5)), loss_bboxdict(typeIoULoss, linearTrue, loss_weight10.0)), dict( typeStageCascadeRPNHead, in_channels256, feat_channels256, adapt_cfgdict(typeoffset), # 可变形卷积自适应采样 bridged_featureFalse, samplingTrue, with_clsTrue, # 第二阶段启用分类 reg_decoded_bboxTrue, bbox_coderdict( typeDeltaXYWHBBoxCoder, target_means(.0, .0, .0, .0), target_stds(0.05, 0.05, 0.1, 0.1)), # 更小的回归 std回归更保守 loss_clsdict( typeCrossEntropyLoss, use_sigmoidTrue, loss_weight1.0), loss_bboxdict(typeIoULoss, linearTrue, loss_weight10.0)) ]), train_cfgdict(rpn[ dict( assignerdict( typeRegionAssigner, center_ratio0.2, ignore_ratio0.5), allowed_border-1, pos_weight-1, debugFalse), dict( assignerdict( typeMaxIoUAssigner, pos_iou_thr0.7, neg_iou_thr0.7, min_pos_iou0.3, ignore_iof_thr-1, iou_calculatordict(typeBboxOverlaps2D)), samplerdict( typeRandomSampler, num256, pos_fraction0.5, neg_pos_ub-1, add_gt_as_proposalsFalse), allowed_border-1, pos_weight-1, debugFalse) ]), test_cfgdict( rpndict( nms_pre2000, max_per_img2000, nmsdict(typenms, iou_threshold0.8), min_bbox_size0))) optim_wrapper dict(clip_graddict(max_norm35, norm_type2))配置要点说明_delete_True基类 configs/rpn/rpn_r50-caffe_fpn_1x_coco.py 已定义标准RPNHead必须删除后才能替换为CascadeRPNHead单锚点scales[8]ratios[1.0]意味着每层特征图每位置仅 1 个锚点相比传统 RPN 的 9 个锚点大幅减少两个 bbox_coder 的 std 差异第一阶段的target_stds(0.1, 0.1, 0.5, 0.5)允许较大回归幅度第二阶段(0.05, 0.05, 0.1, 0.1)使回归更收敛于小范围——对应渐进精修的直觉reg_decoded_bboxTrue回归目标直接使用解码后的绝对坐标框pos_bbox_targets sampling_result.pos_gt_bboxes从而可以使用IoULoss直接在框级别监督回归梯度和IoULoss(linearTrue)两阶段均使用线性 IoU 损失且权重为 10.0配合optim_wrapper.clip_grad(max_norm35, norm_type2)的梯度裁剪保证训练稳定测试阶段 NMS 阈值 0.8较标准 RPN 默认的 0.7 更宽松因为级联提议本身质量更高允许保留更多重叠提议nms_pre2000, max_per_img2000。该配置继承的 caffe 风格基类还包含data_preprocessor的 caffe 归一化参数mean[103.530, 116.280, 123.675]bgr_to_rgbFalse以及冻结 BatchNorm 的norm_evalTrue、stylecaffe骨干设置训练时需注意数据预处理需与预训练权重匹配。3.2 与 Faster R-CNN 联合训练端到端配置cascade-rpn_faster-rcnn_r50-caffe_fpn_1x_coco.py 以 configs/faster_rcnn/faster-rcnn_r50-caffe_fpn_1x_coco.py 为基类在级联头之上调整了 R-CNN 部分rpn_weight 0.7 # 级联 RPN 损失权重缩放因子 model dict( rpn_headdict( _delete_True, typeCascadeRPNHead, num_stages2, stages[...]), # 与 3.1 相同的两阶段定义但损失权重乘 rpn_weight roi_headdict( bbox_headdict( bbox_coderdict(target_stds[0.04, 0.04, 0.08, 0.08]), loss_clsdict( typeCrossEntropyLoss, use_sigmoidFalse, loss_weight1.5), loss_bboxdict(typeSmoothL1Loss, beta1.0, loss_weight1.0))), train_cfgdict( rpn[...], # RegionAssigner → MaxIoUAssigner 两阶段分配 rpn_proposaldict(max_per_img300, nmsdict(iou_threshold0.8)), rcnndict( assignerdict( pos_iou_thr0.65, neg_iou_thr0.65, min_pos_iou0.65), samplerdict(typeRandomSampler, num256))), test_cfgdict( rpndict(max_per_img300, nmsdict(iou_threshold0.8)), rcnndict(score_thr1e-3)))与纯 RPN 配置的差异集中在rpn_weight 0.7RPN 的各损失权重乘以 0.7如loss_weight10.0 * rpn_weight、loss_cls1.0 * rpn_weight避免端到端联合训练中 RPN 损失喧宾夺主同时 R-CNN 的分类损失权重提升到 1.5rpn_proposal提议数量收紧从 2000 降至 300并设置 NMS 阈值 0.8保证送入 R-CNN 的提议数量适中R-CNN 分配器更严格pos_iou_thr0.65, neg_iou_thr0.65, min_pos_iou0.65均高于标准 Faster R-CNN 的 0.5——因为 Cascade RPN 提供的提议质量更高检测头可以放心使用更高的正样本门槛。3.3 与 Fast R-CNN 组合基于预生成提议文件cascade-rpn_fast-rcnn_r50-caffe_fpn_1x_coco.py 以 configs/fast_rcnn/fast-rcnn_r50-caffe_fpn_1x_coco.py 为基类检测头配置与 3.2 相同其特殊之处在于通过proposal_file指定预生成的提议_base_.train_dataloader.dataset.proposal_file proposals/crpn_r50_caffe_fpn_1x_train2017.pkl _base_.val_dataloader.dataset.proposal_file proposals/crpn_r50_caffe_fpn_1x_val2017.pkl test_dataloader _base_.val_dataloader这意味着使用 Fast R-CNN 时需要先用 Cascade RPN 配置在训练/验证集上离线生成提议并保存为 pkl 文件训练约 12 epoch再单独训练检测头。MMEngine 同时支持注释中展示的两种写法直接在train_dataloader dict(datasetdict(proposal_file...))中覆盖或通过_base_引用逐层修改。这种提议生成与检测训练解耦的方式更贴近论文中的实验设定也便于对比不同提议方法的公平性。四、实验结果与模型权重根据 metafile.yml 与 README官方在 COCO 上的结果汇总如下。4.1 区域提议质量AR 1000MethodBackboneStyleAR 1000ConfigDownloadCRPNR-50-FPNcaffe72.0configmodel4.2 检测性能COCO box APMethodProposalBackboneStyleSchedulebox APConfigDownloadFast R-CNNCascade RPNR-50-FPNcaffe1x39.9configmodelFaster R-CNNCascade RPNR-50-FPNcaffe1x40.4configmodel说明表中模型均为官方在 COCO 上训练所得见 metafile.ymlTraining Data: COCO训练资源 8× V10012 epochs / 1x 调度可直接下载权重用于推理或微调纯 RPN 配置的 CRPN 模型 AR 1000 达 72.0接入 Fast R-CNN / Faster R-CNN 后 box AP 分别达到 39.9 / 40.4与论文3.1 / 3.5 点提升的实验结论相互印证论文全称为Cascade RPN: Delving into High-Quality Region Proposal Network with Adaptive ConvolutionarXiv:1909.06720引用信息见 README 的 Citation 部分。五、训练与推理实战以下命令在 MMDetection 3.x 环境中运行$CONFIG指向上述任一配置文件推荐以cascade-rpn_faster-rcnn_r50-caffe_fpn_1x_coco.py起步。5.1 单机训练与测试# 单 GPU 训练 python tools/train.py $CONFIG # 多卡分布式训练8 卡 bash tools/dist_train.sh $CONFIG 8 # 测试自动加载与配置文件同目录的 checkpoint python tools/test.py $CONFIG ${CHECKPOINT_FILE}训练过程中的日志、checkpoint 默认输出到work_dirs/下与配置同名的工作目录。由于 Cascade RPN 两阶段均包含可变形卷积第二阶段与梯度裁剪训练显存占用与耗时高于标准 RPN请在资源规划时预留空间。5.2 用预训练权重做推理与可视化# 使用官方发布的权重进行测试 python tools/test.py configs/cascade_rpn/cascade-rpn_faster-rcnn_r50-caffe_fpn_1x_coco.py \ https://download.openmmlab.com/mmdetection/v2.0/cascade_rpn/crpn_faster_rcnn_r50_caffe_fpn_1x_coco/crpn_faster_rcnn_r50_caffe_fpn_1x_coco-c8283cca.pth # 单张图片推理可视化 python demo/image_demo.py demo/demo.jpg \ configs/cascade_rpn/cascade-rpn_faster-rcnn_r50-caffe_fpn_1x_coco.py \ https://download.openmmlab.com/mmdetection/v2.0/cascade_rpn/crpn_faster_rcnn_r50_caffe_fpn_1x_coco/crpn_faster_rcnn_r50_caffe_fpn_1x_coco-c8283cca.pth注意demo/image_demo.py的推理流程遵循模型配置中的test_cfg此处max_per_img300、NMS 阈值 0.8推理得到的检测框即为 Cascade RPN 提议经 R-CNN 头精修后的最终结果。5.3 Fast R-CNN 流程先出提议再训检测头若需复现 cascade-rpn_fast-rcnn_r50-caffe_fpn_1x_coco.py 的实验流程可参照以下两阶段方案用纯 RPN 配置 cascade-rpn_r50-caffe_fpn_1x_coco.py 训练 Cascade RPN并分别在train2017、val2017上推理保存提议为 pkl对应配置中的proposal_file路径以 Fast R-CNN 配置训练检测头此时数据集加载器会从proposals/crpn_r50_caffe_fpn_1x_train2017.pkl读取提议而非在线生成。这种解耦式流程适合需要在固定提议集合上快速迭代检测头或公平对比不同提议器的研究场景。六、扩展与注意事项6.1 如何调节级联强度在CascadeRPNHead中可通过num_stages与stages列表自由增减阶段数但需同时保证train_cfg.rpn列表长度一致源码断言num_stages len(stages)。经验性配置原则首阶段建议保持samplingFalse, with_clsFalse, bridged_featureTrue的粗召回设定配合RegionAssigner无锚点分配中间/末阶段逐步启用分类与随机采样将MaxIoUAssigner的pos_iou_thr从 0.7 起逐级提高实现渐进式严格化adapt_cfg的offset模式目前只支持 3×3 核与 dilation1源码断言dilation模式则支持任意膨胀率修改时注意对应限制。6.2 兼容性与限制当前实现仅支持二分类前景/背景设定源码断言num_classes 1cascade_rpn_head.py即作为提议网络使用不能直接当多类别检测头预训练权重加载CascadeRPNHead使用ModuleList组织阶段源码注释特别提示Pretrained weights cannot be loaded when use nn.ModuleList加载 caffe 风格 ResNet-50 预训练权重时以 configs/rpn/rpn_r50-caffe_fpn_1x_coco.py 的Pretrained初始化方式为准open-mmlab://detectron2/resnet50_caffe测试阶段 NMS 阈值0.8高于标准 RPN0.7若替换回标准 RPN 或与其他检测头组合需重新验证后处理参数仓库提供的RegionAssigner等任务模块实现在 mmdet/models/task_modules/assigners测试用例覆盖了 Cascade RPN 的两阶段配置与损失计算见 tests/test_models/test_dense_heads/test_cascade_rpn_head.py可作为理解各阶段行为的参考。七、总结Cascade RPN 用单锚点 多阶段级联精修 自适应卷积重新设计了区域提议网络第一阶段的dilation自适应卷积与RegionAssigner无锚点分配负责粗召回第二阶段通过offset可变形卷积对准任意形状锚点、以 IoU≥0.7 的严格标准筛选高质量提议最终以两阶段损失的渐进式监督实现提议质量的显著提升。MMDetection 提供的三套官方配置RPN-only、Fast R-CNN、Faster R-CNN覆盖了从提议质量评估到端到端检测的完整实验路径AR 1000 达到 72.0接入检测器后 box AP 达到 39.9 / 40.4。本文结合 cascade_rpn_head.py 的源码与 configs/cascade_rpn 下的配置文件完整呈现了该算法的原理、配置语义与实战用法你可以在此基础上直接复用官方配置或针对自己的数据与算力调整级联阶段数、分配阈值与损失权重。【免费下载链接】mmdetectionOpenMMLab Detection Toolbox and Benchmark项目地址: https://gitcode.com/gh_mirrors/mm/mmdetection创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考