2026/9/9 12:45:51

Detectron2 公共 LazyConfig 组件库完全指南:以 configs/common 复用模型、数据加载器、学习率调度器与优化器

Detectron2 公共 LazyConfig 组件库完全指南:以 configs/common 复用模型、数据加载器、学习率调度器与优化器 Detectron2 公共 LazyConfig 组件库完全指南以 configs/common 复用模型、数据加载器、学习率调度器与优化器【免费下载链接】detectron2Detectron2 is a platform for object detection, segmentation and other visual recognition tasks.项目地址: https://gitcode.com/GitHub_Trending/de/detectron2Detectron2 的configs/common/目录沉淀了一套基于 LazyConfig懒实例化体系封装的公共积木常用模型结构、COCO 数据加载器、多阶段学习率调度器与优化器以及配套的训练流程约定。本文围绕这份官方 README 展开结合底层LazyConfig.load/instantiate实现与多个真实配置文件说明这套公共组件的设计动机、每个组件的字段含义以及如何在自有训练配置中 import 后按需覆盖快速拼出 Mask R-CNN、Cascade R-CNN、RetinaNet、FCOS、Keypoint R-CNN 等训练任务。一、目录定位给可编辑后再构造的对象提供一个仓库级公共命名空间configs/common/README.md用三句话阐明了该目录的核心价值它集中定义了训练中经常被复用的模型models、数据加载器dataloaders、调度器scheduler与优化器optimizers这些对象全部以lazy instantiation懒实例化的形式描述——即用户可以在真正构造对象之前先用 Python 语句自由修改其参数它们既可以被其他配置文件通过**相对导入import**引用也可以通过model_zoo.get_configAPI加载。换句话说configs/common/不是一个独立可运行的任务配置而是一套官方预置的部件仓库真正的任务配置文件如configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.py、configs/new_baselines/*_LSJ.py都从这里取料并做增量覆盖。整个目录由四类文件组成类别文件相对仓库根目录对外导出的对象数据data/coco.pydataloader含dataloader.train/dataloader.test/dataloader.evaluator数据常量data/constants.pyconstantsImageNet 像素均值/标准差模型models/mask_rcnn_fpn.py、models/retinanet.pymodel调度器coco_schedule.pylr_multiplier_1x / _2x / _3x / _6x / _9x优化器optim.pySGD、AdamW训练约定train.pytrain纯字典非懒调用复合模型models/cascade_rcnn.py、models/fcos.py、models/keypoint_rcnn_fpn.py、models/mask_rcnn_c4.py、models/mask_rcnn_vitdet.py、models/panoptic_fpn.py基于基底模型二次改造得到的model二、底层机制LazyCall 与递归实例化instantiate要理解configs/common/必须先理解它所谓的lazy instantiation具体指什么。官方教程 lazyconfigs.md 给出了完整背景。2.1 字典描述一次调用懒实例化的核心思想是用一个字典来描述调用某个类/函数并传入若干参数这件事而不立即执行调用。字典包含两类键_target_可调用对象的路径字符串例如detectron2.modeling.meta_arch.GeneralizedRCNN其余键要传给该可调用对象的参数参数本身也可以递归地用同构字典描述。辅助函数LazyCall定义于 detectron2/config/lazy.pyLazyCall.__call__会把_target_注入并返回一个带allow_objectsTrue标志的omegaconf.DictConfig可以帮我们生成这类字典。例如 optim.py 中from detectron2.config import LazyCall as L SGD L(torch.optim.SGD)( paramsL(get_default_optimizer_params)(weight_decay_norm0.0), lr0.02, momentum0.9, weight_decay1e-4, )L(torch.optim.SGD)(...)并不真正创建优化器而是生成一个形如{_target_: torch.optim.SGD, lr: 0.02, ...}的配置字典。这些字典被写入模块全局变量后LazyConfig.load会收集模块顶层所有字典值并把它们统一转成omegaconf.DictConfig参见 lazy.py 中LazyConfig.load对返回值的过滤逻辑从而获得 omegaconf 的属性访问语法与变量插值interpolation能力。2.2 instantiate递归地把配置变回对象真正执行构造的是 detectron2/config/instantiate.py 中的instantiate(cfg)它递归遍历配置树遇到含_target_的节点就先实例化所有子参数、再locate出目标类并执行cls(**cfg)。因此optim instantiate(cfg.optimizer) # 真正创建 torch.optim.SGD model instantiate(cfg.model) # 真正创建 GeneralizedRCNN train_loader instantiate(cfg.dataloader.train)这套机制的价值在于配置在加载——覆盖——实例化三个阶段彻底解耦用户可以先 import 公共组件、用普通 Python 代码任意改字段再一次性实例化这正是 lazyconfigs.md 中强调的dict 可编辑性优于传统 YAML 的地方。三、公共数据配置configs/common/data/3.1 coco.pytrain / test 加载器与评估器的三件套data/coco.py 是最常用的公共组件它在顶层导出一个用OmegaConf.create()创建的空配置dataloader随后挂上三个子键训练加载器dataloader.train由build_detection_train_loader描述包含datasetget_detection_dataset_dicts(namescoco_2017_train)mapperDatasetMapperis_trainTrue其augmentations列表使用了经典的多尺度短边抖动ResizeShortestEdge(short_edge_length(640, 672, 704, 736, 768, 800), sample_stylechoice, max_size1333)配合RandomFlip(horizontalTrue)image_formatBGR、use_instance_maskTruetotal_batch_size16、num_workers4。注意这里的 16 是整个训练的全局 batch size与后方调度器以 batch 16 为基准计算迭代数呼应。测试加载器dataloader.testbuild_detection_test_loaderDatasetMapper(is_trainFalse)测试仅做单尺度ResizeShortestEdge(short_edge_length800, max_size1333)且图像格式通过 omegaconf 插值引用训练 mapperimage_format${...train.mapper.image_format}——即父配置的 train 分支下的 mapper 的 image_format避免重复定义。评估器dataloader.evaluatorCOCOEvaluator其数据集名同样用插值${..test.dataset.names}从测试加载器同步保证评估数据与测试数据一致。这种插值引用而非复制值的写法是公共组件的关键设计让后续覆盖test.dataset.names时评估器自动跟随。3.2 constants.py像素归一化常量data/constants.py 导出constants字典集中存放 ImageNet 预训练权重所需的像素统计量共四组imagenet_rgb256_mean/imagenet_rgb256_std标准 RGB 顺序std 为真实 ImageNet 标准差[58.395, 57.12, 57.375]imagenet_bgr256_mean/imagenet_bgr256_stdBGR 顺序供input_formatBGR的骨干使用。注释特别说明使用 Detectron1 或 MSRA 系列预训练模型时std 已被吸收进 conv1 权重必须置为[1.0, 1.0, 1.0]因此这里的 BGR std 默认取 1若自训练从头开始可换回真实 ImageNet 标准差[57.375, 57.120, 58.395]。这些常量随后被 models/mask_rcnn_fpn.py 与 models/retinanet.py 通过from ..data.constants import constants引用并填充模型的pixel_mean/pixel_std/input_format字段。四、公共模型定义configs/common/models/4.1 基石mask_rcnn_fpn.py 组装了一条完整的 Mask R-CNN 流水线models/mask_rcnn_fpn.py 是整套模型的地基用不到 100 行字典嵌套完整描述了 Detectron2 标准 Mask R-CNN FPNR-50结构顶层model为L(GeneralizedRCNN)内部自底向上分层backboneFPN其bottom_up是ResNet——stem 用BasicStem(in_channels3, out_channels64, normFrozenBN)主干阶段由ResNet.make_default_stages(depth50, stride_in_1x1True, normFrozenBN)生成out_features[res2,res3,res4,res5]FPN 的in_features用插值${.bottom_up.out_features}复用同一列表top_blockLastLevelMaxPool负责在 P5 之上追加 P6proposal_generatorRPNStandardRPNHead(in_channels256, num_anchors3)DefaultAnchorGenerator5 个金字塔层anchor sizes[32,64,128,256,512]纵横比[0.5,1.0,2.0]strides[4,8,16,32,64]Matcher(thresholds[0.3, 0.7], labels[0, -1, 1], allow_low_quality_matchesTrue)区分背景/忽略/前景每图 256 个 proposal 样本pre_nms_topk(2000, 1000)、post_nms_topk(1000, 1000)、nms_thresh0.7roi_headsStandardROIHeads(num_classes80, ...)内部box_in_features[p2,p3,p4,p5]ROIPooler(output_size7, ..., pooler_typeROIAlignV2)FastRCNNConvFCHead无卷积、两层 1024 维 FCFastRCNNOutputLayers(test_score_thresh0.05, box2box_transformBox2BoxTransform(weights(10,10,5,5)))分割分支mask_in_features同四层、mask_pooler输出 14×14、mask_headMaskRCNNConvUpsampleHead5 层 256 通道卷积。两个 head 的num_classes均通过${..num_classes}插值跟随 ROIHeads 顶层设置输入归一化pixel_mean/pixel_std取自constants.imagenet_bgr256_mean / _stdinput_formatBGR。注意RPN、StandardROIHeads的batch_size_per_image、positive_fraction等采样超参全部显式列出便于后续配置直接点改。这份完整定义也被官方教程 lazyconfigs.md 以 A Full Mask R-CNN described in recursive instantiation 的折叠块直接引用作为递归实例化的教学样例。4.2 派生模型在基底上做增删改公共目录真正的威力在于派生其他模型文件以mask_rcnn_fpn.model为基底用纯 Python 对配置树做操作即可变换模型族。Cascade R-CNNmodels/cascade_rcnn.py先[model.roi_heads.pop(k) for k in [box_head, box_predictor, proposal_matcher]]移除单级 box 部件再用model.roi_heads.update(_target_CascadeROIHeads, ...)替换目标类并分别用列表推导构造 3 个级联的FastRCNNConvFCHead、3 个FastRCNNOutputLayers回归权重依次(10,5)/(20,10)/(30,15)与 3 个MatcherIoU 阈值 0.5/0.6/0.7。Keypoint R-CNNmodels/keypoint_rcnn_fpn.pypop 掉 mask 分支三个键后update为 keypoint 分支KRCNNConvDeconvUpsampleHead17 个关键点、8 层 512 通道卷积、loss_normalizervisible并把 RPN 的post_nms_topk提到(1500, 1000)——注释解释 Detectron2 中该参数按图计算1000 会损伤 box AP同时smooth_l1_beta0.5改善关键点 AP。RetinaNetmodels/retinanet.py独立从零定义L(RetinaNet)ResNet 只保留res3..res5FPN top 换成LastLevelP6P75 层特征图上接RetinaNetHead每个空间位置 9 个 anchorprior_prob0.01初始化前景概率focal lossalpha0.25、gamma2.0。FCOSmodels/fcos.py直接 import RetinaNet 的model后做减法和替换——model._target_ FCOSdel掉 anchor 相关键top_block 改从 P5 上采样出 P6/P7对应论文 Sec 2.2阈值换为基于sqrt(cls_score * centerness)的 0.2/0.6head 换成FCOSHead(normGN)。每一层改造都在 import 处即时生效且不需要理解 YAML 继承的覆盖规则这正是公共组件选择 Python 配置的根本原因。五、调度器与优化器5.1 coco_schedule.py1x/3x 等论文调度的工厂函数coco_schedule.py 把论文中常见的 1x / 3x 等训练协议实现为一个带参函数default_X_scheduler(num_X)并在模块末尾一次性导出lr_multiplier_1x / _2x / _3x / _6x / _9x五个成品。核心逻辑1x 以 batch size 16 下的90,000 次迭代对应约 1,440,000 张训练图像、约 12 个 COCO epoch为基准故总迭代数total_steps_16bs num_X * 90000LR 按三段阶梯衰减MultiStepParamScheduler(values[1.0, 0.1, 0.01])。当num_X 2时直接用固定里程碑[60000, 80000, 90000]注释指出该调度对迭代数具有尺度不变性等价于 YAML 配置里的milestones[6, 8, 9]epochnum_X 2时则改为[total_steps_16bs - 60000, total_steps_16bs - 20000, total_steps_16bs]——即把最后两次衰减固定在距训练结束 60k/20k 迭代处保证尾段衰减节奏不随总长度漂移这也是 Rethinking ImageNet Pre-trainingSec 4所提倡的策略最外层套WarmupParamScheduler线性 warmup长度1000 / total_steps_16bs恒为 1000 次迭代的相对比例warmup_factor0.001。也就是说1x本身包含 1000 步线性预热与两次阶梯式降 LR任务配置只需from ..common.coco_schedule import lr_multiplier_1x即可复用完整协议。5.2 optim.py内置 SGD 与 AdamW 两套出厂优化器optim.py 提供SGD与AdamW两个成品SGDlr0.02、momentum0.9、weight_decay1e-4ResNet 系标准的 1x 学习率与正则AdamWlr1e-4、betas(0.9, 0.999)、weight_decay0.1适合 ViT / MViT 系主干。两者的params都由L(get_default_optimizer_params)(weight_decay_norm0.0)描述。注释点明关键约定params.model留待真正实例化优化器前由训练脚本把已构造的 model 对象填进去。该脚本即 tools/lazyconfig_train_net.py其do_train中顺序执行model instantiate(cfg.model) # 1. 先构造模型 cfg.optimizer.params.model model # 2. 把模型塞进优化器配置 optim instantiate(cfg.optimizer) # 3. 再构造优化器以获取参数分组get_default_optimizer_params定义于 detectron2/solver/build.py负责按模块名把参数分成含 norm 的weight_decay_norm0.0即 norm 层不做权重衰减等若干组从而保证weight_decay_norm这类参数能在公共文件里被预置、而在实例化时针对真实模型结构生效。六、train.py训练入口约定的最小公共契约train.py 导出的train是一个普通 Python 字典刻意不用 LazyCall因为它不是某个类的参数而是训练脚本直接读取的字段集。文件头部注释声明它是为tools/lazyconfig_train_net.py设计的通用约定使用者完全可以定义自己的结构并配套自己的 train_net.py。字段含字段默认值说明output_dir./output输出目录init_checkpoint初始权重可指向 detectron2:// 托管的 ImageNet 预训练max_iter90000训练总迭代数amp.enabledFalse是否启用自动混合精度决定用AMPTrainer还是SimpleTrainerddp见源码传给create_ddp_model的参数broadcast_buffers、find_unused_parameters、fp16_compressioncheckpointerperiod5000, max_to_keep100PeriodicCheckpointer参数eval_period/log_period5000/20评估与日志周期迭代devicecuda训练设备对照 tools/lazyconfig_train_net.py 的 docstring 与do_train实现可见该脚本对配置对象的期望恰好是cfg.model、cfg.dataloader.{train,test,evaluator}、cfg.optimizer、cfg.lr_multiplier与cfg.train与configs/common/各文件导出的对象一一对应——common目录其实是该训练脚本的官方配套零件包。七、实战三种使用姿势与完整命令7.1 姿势一import 少量覆盖官方任务配置的标准写法configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.py全文件仅 5 行业务代码其余全是 importfrom ..common.optim import SGD as optimizer from ..common.coco_schedule import lr_multiplier_1x as lr_multiplier from ..common.data.coco import dataloader from ..common.models.mask_rcnn_fpn import model from ..common.train import train model.backbone.bottom_up.freeze_at 2 # 冻结 res2 之前的层 train.init_checkpoint detectron2://ImageNetPretrained/MSRA/R-50.pkl # 使用 ImageNet 预训练同目录下mask_rcnn_R_50_C4_1x.py、mask_rcnn_R_50_FPN_3x.py以及configs/COCO-Detection/fcos_R_50_FPN_1x.py、configs/COCO-Keypoints/keypoint_rcnn_R_50_FPN_1x.py、configs/COCO-PanopticSegmentation/panoptic_fpn_R_50_1x.py、configs/Misc/cascade_mask_rcnn_R_50_FPN_3x.yaml对应的cascade_mask_rcnn_R_50_FPN_1x/3x系列均遵循此模式。要点公共配置通过相对导入路径..common.xxx获取Detectron2 的LazyConfig在加载时会重写导入逻辑见 lazy.py 的_patch_import相对导入只允许加载同仓库的其他配置 .py 文件不要求目录有__init__.py保证任何位置的配置都能按相对位置解析文件。7.2 姿势二深度改造以 new_baselines 的 LSJ 大尺度抖动方案为例configs/new_baselines/mask_rcnn_R_50_FPN_100ep_LSJ.py 展示了在同一套公共组件上做换骨干训练范式级别的改造重写数据增强为 LSJdataloader.train.mapper.augmentations [ResizeScale(min_scale0.1, max_scale2.0, ...), FixedSizeCrop(crop_size(1024, 1024)), RandomFlip]并recompute_boxesTrue裁剪需重算框全程 SyncBN一次性把 stem、stages、FPN 的 norm 全部置SyncBNbox/mask head 换NaiveSyncBatchNorm换 4conv1fc box headconv_dims[256,256,256,256]fc_dims[1024]、2conv RPN head、从头训练freeze_at0放大 batchdataloader.train.total_batch_size 64train.max_iter 184375100 epochtrain.amp.enabledTrue、train.ddp.fp16_compressionTrue重写调度器lr_multiplier与优化器超参optimizer.lr0.1、weight_decay4e-5。这些改动全程使用点路径赋值与 Python 推导式任何一处都能精准落到公共组件定义的具体字段上——这正是懒配置相比传统 YAML 无法做到、却是公共组件被大量项目采用的原因。7.3 姿势三通过 model_zoo.get_config 以编程方式加载官方教程 lazyconfigs.md 明确说明这些 lazy 配置在安装后被视作模型库的一部分可由 model_zoo.get_config 加载其get_config对.py配置会走LazyConfig.load分支若传入trainedTrue还会把官方权重地址写入cfg.train.init_checkpoint前提是配置中含train字段——这正说明为什么 common 的train.py是模型库 lazy 配置的共同基础。典型用法from detectron2 import model_zoo cfg model_zoo.get_config( COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.py, trainedTrue ) cfg.train.output_dir ./my_output cfg.train.max_iter 90000之后即可用instantiate(cfg.model)等构建对象或直接python tools/lazyconfig_train_net.py --config-file 路径启动训练。7.4 运行训练 / 评估 / 命令行覆盖针对任意基于 common 组件的 lazy 配置训练入口统一为 tools/lazyconfig_train_net.py# 单机多卡训练使用公共组件组合出的 Mask R-CNN 1x 配置 python tools/lazyconfig_train_net.py \ --config-file configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.py \ --num-gpus 8 # 仅评估加载配置中 train.init_checkpoint 指定的权重 python tools/lazyconfig_train_net.py \ --config-file configs/new_baselines/mask_rcnn_R_50_FPN_100ep_LSJ.py \ --eval-only \ --num-gpus 8 # 用 --opts 做命令行覆盖等价于 Python 内调用 LazyConfig.apply_overrides python tools/lazyconfig_train_net.py \ --config-file configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.py \ --num-gpus 1 \ train.max_iter1000 dataloader.train.total_batch_size8 \ train.eval_period500其中--opts的a.bc语法由 lazy.py 的LazyConfig.apply_overrides支持优先借助 Hydra 的覆盖语法解析缺失时回退到ast.literal_eval简单解析脚本在main中会依次执行LazyConfig.load、apply_overrides并在评估模式下直接instantiate(cfg.model)后调用do_test。八、最佳实践与注意事项公共组件是基底而非成品像mask_rcnn_fpn.model这样的基底对象被多个配置文件 import 后各自独立覆盖互不影响因为每个配置 .py 在被LazyConfig.load时都会在新命名空间重新执行见 lazy.py 中_patch_import的不缓存模块、全局修改无副作用设计。优先用插值而非复制data/coco.py中${...train.mapper.image_format}、${..test.dataset.names}等 omegaconf 插值保证了派生配置改一处、相关字段同步应沿用此习惯。增加新组件只需遵守契约若给common/增加新的公共模型或数据配置保证导出model/dataloader/train等约定键名即可无缝接入lazyconfig_train_net.py与model_zoo.get_config。阅读延伸完整设计理念见 lazyconfigs.mdconfigs/common/README.md同时被官方教程引用为 common baselines 的示例入口new_baselines/目录下的全部*_LSJ.py与各任务目录下的.py配置都是common 组件 × 任务差异的现成范本可对照 configs 逐一阅读。【免费下载链接】detectron2Detectron2 is a platform for object detection, segmentation and other visual recognition tasks.项目地址: https://gitcode.com/GitHub_Trending/de/detectron2创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考