训练UniDetector前必看的20+个关键超参数:完整配置项逐条解读
训练UniDetector前必看的20+个关键超参数:完整配置项逐条解读
【免费下载链接】UniDetectorCode release for our CVPR 2023 paper "Detecting Everything in the Open World: Towards Universal Object Detection".项目地址: https://gitcode.com/gh_mirrors/un/UniDetector
UniDetector 是一个面向开放世界的通用目标检测框架(CVPR 2023 论文《Detecting Everything in the Open World》的代码实现),它借助 CLIP 的文本嵌入实现零样本分类,配合开放世界 RPN 就能检测训练集中没见过的物体。想训练或魔改它?本文带你逐条解读训练 UniDetector 前必须了解的 20+ 个关键超参数,覆盖模型结构、锚点、采样、数据与优化器五大模块,新手也能一次看懂。
一、配置文件在哪里?先搞清楚目录结构
所有配置集中在 configs/ 目录,按用途分为四类:
| 目录 | 用途 | 代表文件 |
|---|---|---|
| configs/singledataset/ | 单数据集(如 COCO)端到端训练 | clip_end2end_faster_rcnn_r50_c4_1x_coco.py |
| configs/multidataset/ | 多数据集(COCO+Objects365+OpenImages)训练 | clip_end2end_faster_rcnn_r50_c4_1x_oidobj365coco.py |
| configs/inference/ | LVIS 两阶段解耦式(decoupled)训练/推理 | clip_decouple_faster_rcnn_r50_c4_1x_lvis_v0.5_2ndstage.py |
| configs/base/ | 所有配置共享的运行时代基配置 | default_runtime.py |
每个训练配置都通过_base_继承 default_runtime.py,先改自己的文件、必要时再改基配置,是最稳妥的做法。
二、模型结构类超参数:决定"检测器长什么样"
以 clip_end2end_faster_rcnn_r50_c4_1x_coco.py 为主线逐条说明:
model.type = 'FasterRCNN':端到端版本用FasterRCNN(自带 RPN);LVIS 解耦式第二阶段则用FastRCNN(外接第一阶段 RPN 生成的候选框,见configs/inference/目录)。backbone.type = 'CLIPResNet',layers=[3, 4, 6, 3]:即 CLIP 版本 ResNet-50,四个 stage 的残差块数。想换更大的 CLIP backbone,改layers即可;style='pytorch'指定权重布局风格。norm_cfg = dict(type='BN', requires_grad=False):冻结 BatchNorm 的 gamma/beta,只更新其滑动统计量,是 CLIP 预训练微调的常用做法,能显著提升稳定性。rpn_head.in_channels=1024 / feat_channels=1024:CLIPResNet 无 FPN,RPN 直接吃第 4 层特征,通道数必须与 backbone 输出对齐。anchor_generator的scales=[2,4,8,16,32]、ratios=[0.5,1.0,2.0]、strides=[16]:每个像素位置 5×3=15 个锚框,步长 16。开放世界物体大小悬殊,scales跨度从 2 到 32 正是为覆盖"小虫子到摩天楼"级别的尺度范围设计的。- RPN 的
bbox_coder.target_stds=[1.0,1.0,1.0,1.0]:锚框回归的编码标准差,控制回归值缩放。 - RPN 的
loss_cls(use_sigmoid=True)与loss_bbox(L1Loss):前景/背景二分类 + 框回归损失,权重loss_weight=1.0可按任务调整。 roi_head.shared_head = CLIPResLayer(layers=[3,4,6,3]):RoI 特征再过一个 CLIP 残差层做精修,与 backbone 同款结构。RoIAlign output_size=14:把候选框特征对齐到 14×14,之后经 shared_head 与avg_pool压缩为roi_feat_size=7的 7×7 特征;in_channels=2048是共享头输出通道。bbox_coder.target_stds=[0.1, 0.1, 0.2, 0.2]:细粒度回归的编码标准差,宽高校验比位置更宽松(0.2 vs 0.1),是 Faster R-CNN 系列的经典设置。zeroshot_path⭐:零样本核心!指向 CLIP 文本嵌入的.npy文件,如 clip_embeddings/coco_clip_a+cname_rn50_manyprompt.npy(a+cname 表示 "a photo of a X" 与类名拼接的多提示词)。换数据集检测范围,主要换这个文件 +num_classes。num_classes=80:与zeroshot_path中嵌入行数一致;LVIS 配置里为 1230,多数据集版本为 500。with_cls=False:零样本模式下分类头不训练(配置中注释也写明 loss_cls 训练时不生效),只训练回归分支,类别判别完全靠 CLIP 相似度。reg_class_agnostic=True:所有类别共享同一套回归参数,减少参数、更适合零样本泛化。cat_freq_path(多数据集版专有):类别出现频率 JSON 文件,用于按类别频率加权(有效样本数均衡),缓解长尾。beta=0.3、gamma=0.6、withcalibration=True(LVIS 第二阶段推理专有):beta是融合第一阶段开放世界 RPN 开放词汇置信度的权重;gamma是推理分数校准参数(withcalibration=True时生效,见 clip_decouple_faster_rcnn_r50_c4_1x_lvis_v0.5_2ndstage_withcalibration.py)。- 第一阶段专有项(
configs/inference/..._1ststage.py):OlnRPNHead+TBLRBBoxCoder+IoULoss(loss_weight=10.0),并带 FPN(out_channels=256, num_outs=5)与frozen_stages=1(冻结 stem),用torchvision://resnet50初始化。
三、正负样本分配与采样:决定"怎么学"
这些参数都在配置的train_cfg中,是新手最容易忽略、却最影响收敛的一组:
- RPN 分配器:
pos_iou_thr=0.7 / neg_iou_thr=0.3——与 GT 重叠 ≥0.7 判正样本,<0.3 判负样本。 - RPN 采样器:
num=256, pos_fraction=0.5——每张图采 256 个样本,正负各半。 - RCNN 分配器:
pos_iou_thr=0.5 / neg_iou_thr=0.5——第二阶段阈值更宽松(0.5),且match_low_quality=False避免低质正样本。 - RCNN 采样器:
num=512, pos_fraction=0.25——512 个样本中正样本只占 25%,负样本更多,配合零样本场景压制误检。 rpn_proposal.nms_pre=12000, max_per_img=2000:训练时每图送进 RPN 的候选框上限,资源紧张可下调。nms iou_threshold=0.7:RPN 内部 NMS 阈值,越大保留的候选越多。
四、测试与后处理超参数:决定"最终输出什么"
test_cfg直接影响推理行为与 mAP:
test_cfg.rpn: nms_pre=6000, max_per_img=1000:推理时候选框比训练时更保守,换 Faster R-CNN 为 1000。score_thr=0.0001:置信度下限,几乎不过滤——开放世界检测宁可多保留、靠 NMS 去重。nms=dict(type='soft_nms', iou_threshold=0.5, method='gaussian')⭐:用软 NMS(高斯衰减)而非硬 NMS,对密集/重叠的开放世界物体更友好,是本文代码库的标志性设置。max_per_img=100:每图最终保留 100 个检测框(LVIS 配置为 300,因为类别更多)。
五、数据与预处理超参数:决定"输入质量"
Resize img_scale=[(1333,400),(1333,800)]:训练时随机在长边 400~800 间缩放(宽上限 1333),保持宽高比;测试时固定(1333, 800)。显存不足时把上界调到 600 即可。RandomFlip flip_ratio=0.5:50% 概率水平翻转;测试管线flip=False关闭增强。img_norm_cfg:ImageNet 均值/方差[122.77, 116.75, 104.09]等——CLIPResNet 微调必须沿用 CLIP 的归一化,改错会掉点。Pad size_divisor=32:尺寸补齐到 32 的倍数,保证多次下采样不丢失。samples_per_gpu=2, workers_per_gpu=2:每卡 batch 2(单图分辨率高,显存大户), DataLoader 线程数 2。注意:调大 batch 时建议同步调整学习率。- LVIS 推理专有:
LoadProposals num_max_proposals=100+proposal_file='rp_val_ow.pkl'——加载第一阶段 RPN 预生成的开放世界候选框,第二阶段只负责分类/回归精修。 - 多数据集专有:
ConcatDataset中每个子集需分配唯一dataset_id(0/1/2),与zeroshot_path列表、cat_freq_path列表一一对应。
六、优化器与训练策略:决定"学多快、稳不稳"
optimizer = SGD(lr=0.02, momentum=0.9, weight_decay=0.0001):注意 lr 是0.02 而非 0.002——配合下一条的分组学习率系数才等效常规量级。paramwise_cfg:backbone与roi_head均lr_mult=0.1⭐:CLIP 预训练部分按 1/10 学习率微调,RPN 等新增模块用全量学习率。这是"微调 + 新训练"混合场景的关键技巧。optimizer_config grad_clip max_norm=35:梯度全局范数裁剪,防止训练早期梯度爆炸。lr_config:policy='step', step=[8, 11]:第 8、11 个 epoch 衰减学习率(通常 ×0.1)。warmup='linear', warmup_iters=500, warmup_ratio=0.001:前 500 次迭代学习率从 0.1% 线性爬升,CLIP 微调的标配。runner.max_epochs=12:实际训练 12 个 epoch(注释中 "actual epoch = 3 × 3 = 9" 是 1× schedule 的折算说明,以max_epochs为准)。checkpoint_config interval=1:每个 epoch 存一次权重。log_config interval=50:每 50 次迭代打一条日志;evaluation interval=1, metric='bbox'表示每 epoch 用 bbox 指标评测一次。dist_params backend='nccl':多机多卡通信后端,配合tools/dist_train.sh启动分布式训练。
七、快速对照表:调参时优先动哪几项
| 你的需求 | 优先调整的超参数 |
|---|---|
| 检测新的类别集合 | zeroshot_path+num_classes |
| 显存不够 | img_scale、samples_per_gpu、nms_pre |
| 训练不稳 / loss 爆 | warmup_iters、lr_mult、grad_clip.max_norm |
| 漏检大/小物体 | anchor_generator.scales |
| 误检太多 | rcnn.pos_fraction、score_thr、soft_nms阈值 |
| 类别长尾严重 | cat_freq_path(多数据集)、ClassBalancedDataset |
| 开放世界推理调优 | beta、gamma、withcalibration |
💡 核心源码参考:零样本分类头实现见 bbox_head_clip.py,CLIP 骨干见 clipresnet.py,文本嵌入生成脚本见 dump_clip_features_manyprompt.py。
写在最后
UniDetector 的配置看似条目繁多,其实遵循一条清晰逻辑:CLIP 预训练部分"微调"(低学习率 + 冻结 BN),新增模块"全量训练",分类交给零样本嵌入,回归交给共享头,后处理交给软 NMS。先把configs/singledataset/下的 COCO 配置跑通,再向多数据集和 LVIS 两阶段扩展,是最平滑的上手路径。祝训练顺利,早日检测出"万物"!🚀
【免费下载链接】UniDetectorCode release for our CVPR 2023 paper "Detecting Everything in the Open World: Towards Universal Object Detection".项目地址: https://gitcode.com/gh_mirrors/un/UniDetector
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
