news 2026/9/23 2:46:41

PaddleDetection 中的 FCOS 全卷积单阶段检测器:模型配置、训练调优与源码原理解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PaddleDetection 中的 FCOS 全卷积单阶段检测器:模型配置、训练调优与源码原理解析
  • 人工智能
  • 深度学习
  • 计算机视觉

【免费下载链接】PaddleDetection

Object Detection toolkit based on PaddlePaddle. It supports object detection, instance segmentation, multiple object tracking and real-time multi-person keypoint detection.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleDetection
点击查看免费下载

FCOS(Fully Convolutional One-Stage Object Detection)是一种无锚框(anchor-free)的单阶段目标检测算法,通过逐像素(pixel-wise)预测分类与回归目标,省去了锚框设计与超参数调优的负担。本指南以 PaddleDetection 仓库中 configs/fcos/README.md 为骨架,结合 配置目录 下的全部真实配置文件与 ppdet/modeling/heads/fcos_head.py、ppdet/modeling/losses/fcos_loss.py、ppdet/data/transform/batch_operators.py 中的源码实现,系统讲解 FCOS 在 PaddleDetection 中的模型结构、COCO 模型库与精度、配置逐项拆解、训练/评估/推理全流程,以及 iou 质量分支、DCN、多尺度训练、SSLD 预训练等进阶调优方案。读完本文,你将能够独立复现官方 FCOS 基线,并在此基础上按需组合精度增强技巧。

1 FCOS 在 PaddleDetection 中的定位与整体结构

FCOS 将目标检测视为逐点(per-pixel)的稠密预测问题:对 FPN 输出的每一层特征图上的每个位置,直接回归"该点到目标框四边的距离"(l、t、r、b 四维),并预测类别与 centerness(中心度)分数,再通过后处理(阈值过滤 + NMS)得到最终检测框。

在 PaddleDetection 中,FCOS 的完整结构由 configs/fcos/base/fcos_r50_fpn.yml 定义,其组成如下:

architecture: FCOS pretrain_weights: https://paddledet.bj.bcebos.com/models/pretrained/ResNet50_cos_pretrained.pdparams FCOS: backbone: ResNet neck: FPN fcos_head: FCOSHead
  • architecture:指定整体架构为FCOS,对应 ppdet/modeling/architectures/fcos.py 中的装配逻辑;
  • backboneResNet(默认 ResNet50,variant'b');
  • neckFPN,负责将骨干网络多尺度特征融合并补充 P5 以上的高层级特征;
  • fcos_headFCOSHead,即 FCOS 特有的检测头,在 ppdet/modeling/heads/fcos_head.py 中实现。

1.1 从源码看 FCOSHead 的组成

FCOSHead__inject__ = ['fcos_feat', 'fcos_loss', 'nms']注入三个子模块(见 fcos_head.py):

  1. FCOSFeat:分类与回归两个共享 tower。默认每个 tower 由 4 个3x3卷积组成(num_convs: 4),卷积后接 ReLU 激活;norm_type: "gn"表示使用 GroupNorm,use_dcn可控制是否在 tower 中启用可变形卷积(见 fcos_head.py);
  2. 分类/回归输出层fcos_head_cls输出num_classes通道的分类 logits,其 bias 初始化为-log((1-prior_prob)/prior_prob)prior_prob: 0.01用于缓解正负样本严重不均衡导致的训练初期不稳定(见 fcos_head.py);fcos_head_reg输出 4 维回归目标,fcos_head_centerness输出 1 维 centerness(或 iou)质量分数;
  3. FCOSLoss:分类用 Focal Loss,回归用 IoU 系列损失(默认 GIoU),质量分支默认用 centerness 计算损失(见 fcos_loss.py);
  4. MultiClassNMS:NMS 后处理,配置在 fcos_r50_fpn.yml。

2 COCO 模型库与精度对照

configs/fcos/README.md 给出了 PaddleDetection 官方在 COCO train2017 上训练、COCO val2017 上评估的 FCOS 系列模型结果(推理环境:Tesla V100,每卡 2 张图):

骨架网络网络类型每张GPU图片个数学习率策略推理时间(fps)Box AP
ResNet50-FPNFCOS21x----39.6
ResNet50-FPNFCOS + iou21x----40.0
ResNet50-FPNFCOS + DCN21x----44.3
ResNet50-FPNFCOS + multiscale_train22x----41.8
ResNet50-FPNFCOS + multiscale_train + iou22x----42.6

各配置对应的完整配置文件为:

  • FCOS 基线:fcos_r50_fpn_1x_coco.yml
  • FCOS + iou:fcos_r50_fpn_iou_1x_coco.yml
  • FCOS + DCN:fcos_dcn_r50_fpn_1x_coco.yml
  • FCOS + 多尺度训练:fcos_r50_fpn_multiscale_2x_coco.yml
  • FCOS + 多尺度训练 + iou:fcos_r50_fpn_iou_multiscale_2x_coco.yml

从上表可以看出三个关键趋势:

  1. iou 质量分支替代 centerness 可带来约 0.4 AP 的提升;
  2. DCN(可变形卷积)是提升最大的单项技巧,基线 39.6 直接提升到 44.3 AP(+4.7),代价是推理速度与显存开销;
  3. **多尺度训练(2x 调度)**在 1x 基础上额外带来约 2 AP 的提升,且可与 iou 分支叠加。

需要注意,上表推理时间(fps)在原文档中未给出具体数值,说明官方未在当前模型库中公布该批模型的实测 fps;实际推理速度与硬件、输入尺寸、批大小强相关,不应引用未经验证的数值。

3 配置文件逐项拆解

FCOS 系列配置采用 PaddleDetection 的_BASE_继承机制,以 fcos_r50_fpn_1x_coco.yml 为例:

_BASE_: [ '../datasets/coco_detection.yml', '../runtime.yml', '_base_/fcos_r50_fpn.yml', '_base_/optimizer_1x.yml', '_base_/fcos_reader.yml', ] weights: output/fcos_r50_fpn_1x_coco/model_final

继承链说明:

  • configs/datasets/coco_detection.yml:COCO 数据集路径、类别数(80)与 train/val 标注;
  • configs/runtime.yml:训练轮次快照、日志、VisualDL 等运行时配置;
  • base/fcos_r50_fpn.yml:FCOS 模型结构(backbone/neck/head/损失/NMS);
  • base/optimizer_1x.yml:1x(12 epoch)学习率调度与优化器;
  • base/fcos_reader.yml:数据读取与预处理流水线。

weights指定训练完成后保存的模型路径(model_final),训练结束后在output目录下生成。

3.1 骨干网络与 FPN:模型结构基座

base/fcos_r50_fpn.yml 中 backbone 与 neck 配置如下:

ResNet: depth: 50 variant: 'b' norm_type: bn freeze_at: 0 # res2 return_idx: [1, 2, 3] num_stages: 4 FPN: out_channel: 256 spatial_scales: [0.125, 0.0625, 0.03125] extra_stage: 2 has_extra_convs: True use_c5: False

要点解析:

  • freeze_at: 0:默认不冻结任何 stage,# res2注释提示若需冻结可将值设为 1;
  • return_idx: [1, 2, 3]:返回 ResNet 第 2、3、4 个 stage 的特征图,对应下采样 8x/16x/32x,即spatial_scales: [0.125, 0.0625, 0.03125]
  • extra_stage: 2:在 P5 之上再额外生成 P6(64x stride)与 P7(128x stride)两层特征,与fpn_stride: [8, 16, 32, 64, 128]对应;
  • has_extra_convs: True:额外层级使用 1x1 卷积降维并参与上采样融合,保证特征一致性;
  • use_c5: False:不直接使用 C5 作为 P5,而是从 C4 上采样得到 P5(原版 FCOS 的做法)。

3.2 FCOSHead:检测头细节

FCOSHead: fcos_feat: name: FCOSFeat feat_in: 256 feat_out: 256 num_convs: 4 norm_type: "gn" use_dcn: False fpn_stride: [8, 16, 32, 64, 128] prior_prob: 0.01 norm_reg_targets: True centerness_on_reg: True num_shift: 0.5 fcos_loss: name: FCOSLoss loss_alpha: 0.25 loss_gamma: 2.0 iou_loss_type: "giou" reg_weights: 1.0 nms: name: MultiClassNMS nms_top_k: 1000 keep_top_k: 100 score_threshold: 0.025 nms_threshold: 0.6

各参数含义与作用:

参数默认值说明
fcos_feat.num_convs4分类/回归 tower 的卷积层数,越大感受野与容量越大、显存开销越高
fcos_feat.norm_type"gn"tower 内归一化方式,FCOS 原论文使用 GroupNorm(分组数为 32)
fcos_feat.use_dcnFalse是否在 tower 中使用可变形卷积
fpn_stride[8,16,32,64,128]五层特征对应的下采样倍数
prior_prob0.01分类层 bias 初始化依据,缓解类别不平衡
norm_reg_targetsTrue回归目标按 stride 归一化后再训练
centerness_on_regTruecenterness 分支挂在回归 tower 上(而非分类 tower)
num_shift0.5特征点相对图像左上角的偏移量(半个像素),Gt2FCOSTarget._compute_points中以shift + stride * num_shift计算采样点位置(见 batch_operators.py)
fcos_loss.loss_alpha0.25Focal Loss 的 alpha 平衡因子
fcos_loss.loss_gamma2.0Focal Loss 的 gamma 聚焦参数
fcos_loss.iou_loss_type"giou"回归损失类型,源码支持linear_iou/giou/iou(见 fcos_loss.py)
fcos_loss.reg_weights1.0回归损失的权重系数
nms.nms_top_k1000NMS 前每个类别保留的最高分框数
nms.keep_top_k100NMS 后每张图最终保留的框数上限
nms.score_threshold0.025分数阈值,低于该值的框直接丢弃
nms.nms_threshold0.6NMS 的 IoU 阈值

值得说明的是,FCOS 的回归目标在Gt2FCOSTarget中生成。该算子(见 batch_operators.py)通过object_sizes_boundary构造各层级的"感兴趣目标尺寸区间"([-1, 64][64, 128][128, 256][256, 512][512, inf)),将不同大小的目标分配给不同 stride 的特征层;center_sampling_radius: 1.5表示仅在目标中心 1.5 倍 stride 范围内采样正样本,这是 FCOS 降低低质量预测框的关键设计。

3.3 数据读取与预处理:Reader 配置

base/fcos_reader.yml 定义了训练/评估/测试三套数据流水线:

worker_num: 2 TrainReader: sample_transforms: - Decode: {} - Resize: {target_size: [800, 1333], keep_ratio: True, interp: 1} - NormalizeImage: {mean: [0.485, 0.456, 0.406], std: [0.229, 0.224, 0.225], is_scale: True} - RandomFlip: {} batch_transforms: - Permute: {} - PadBatch: {pad_to_stride: 128} - Gt2FCOSTarget: object_sizes_boundary: [64, 128, 256, 512] center_sampling_radius: 1.5 downsample_ratios: [8, 16, 32, 64, 128] norm_reg_targets: True batch_size: 2 shuffle: True drop_last: True use_shared_memory: True

关键点:

  • 训练输入尺寸Resize: {target_size: [800, 1333], keep_ratio: True}表示短边缩放到 800、长边不超过 1333,保持宽高比;
  • 归一化:使用 ImageNet 统计的 mean/std(0.485,0.456,0.406/0.229,0.224,0.225),is_scale: True表示除以 255;
  • PadBatch 对齐pad_to_stride: 128将 batch 内图像 padding 到 128 的整数倍,与五层特征最大 stride 128 对齐,保证特征图尺寸整数化;而fcos_r50_fpn_iou_1x_coco.yml中该值改为 32,可显著节省 padding 带来的显存与计算开销;
  • Gt2FCOSTarget:在 batch 维度为每个采样点生成分类标签、回归目标与中心度标签,downsample_ratios必须与fcos_feat.fpn_stride保持一致;
  • EvalReader / TestReader:均不包含RandomFlipGt2FCOSTarget,测试时fuse_normalize: True将归一化融合进模型中,便于导出推理。

3.4 优化器与学习率:1x 与 2x 调度

base/optimizer_1x.yml 定义了 1x(12 epoch)调度:

epoch: 12 LearningRate: base_lr: 0.01 schedulers: - !PiecewiseDecay gamma: 0.1 milestones: [8, 11] - !LinearWarmup start_factor: 0.3333333333333333 steps: 500 OptimizerBuilder: optimizer: momentum: 0.9 type: Momentum regularizer: factor: 0.0001 type: L2

要点:

  • base_lr: 0.01是适配8 卡训练的学习率;若改用单卡训练,应相应缩小学习率(官方建议除以 8),否则容易发散;
  • 前 500 步线性 warmup(起始系数 1/3),在第 8 与第 11 个 epoch 各衰减 0.1 倍;
  • 优化器为带 0.9 动量的 Momentum,配合 0.0001 的 L2 权重衰减。

多尺度训练配置 fcos_r50_fpn_multiscale_2x_coco.yml 将调度改为 2x(24 epoch),milestones: [16, 22],同时把训练Resize替换为多尺度随机采样:

- RandomResize: {target_size: [[640, 1333], [672, 1333], [704, 1333], [736, 1333], [768, 1333], [800, 1333]], keep_ratio: True, interp: 1}

即短边在 640~800 之间按 32 像素步长随机取值,增强模型对尺度变化的鲁棒性。注意评估/推理仍使用固定 800x1333 输入,保证与官方精度可比。

4 实战:训练、评估与推理

以下命令均基于 PaddleDetection 官方安装流程(参考 INSTALL_cn.md),在项目根目录下执行。当前仓库中该系列配置均以 COCO 数据集为前提,训练前需先按 configs/datasets/coco_detection.yml 中的路径放置好数据(可通过 dataset/coco/download_coco.py 下载)。

4.1 训练

单卡训练 FCOS 基线:

export CUDA_VISIBLE_DEVICES=0 python tools/train.py -c configs/fcos/fcos_r50_fpn_1x_coco.yml

多卡训练(8 卡,与官方学习率匹配):

export CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 python -m paddle.distributed.launch --gpus 0,1,2,3,4,5,6,7 tools/train.py -c configs/fcos/fcos_r50_fpn_1x_coco.yml

常用参数:

  • -o:命令行覆盖配置项,例如-o LearningRate.base_lr=0.00125适配单卡训练;
  • -r output/fcos_r50_fpn_1x_coco/10000:从指定 checkpoint 恢复训练;
  • --eval:边训练边评估,评估在每个 epoch 结束后进行,最优 mAP 模型保存到best_model目录;
  • --use_vdl=True --vdl_log_dir=vdl_dir/scalar:开启 VisualDL 可视化训练曲线与 mAP 趋势。

4.2 评估

使用官方预训练权重评估(也可替换为本地weights=output/fcos_r50_fpn_1x_coco/model_final):

export CUDA_VISIBLE_DEVICES=0 python tools/eval.py -c configs/fcos/fcos_r50_fpn_1x_coco.yml \ -o weights=https://paddledet.bj.bcebos.com/models/fcos_r50_fpn_1x_coco.pdparams

如需输出 COCO 格式的 json 结果文件,可追加--json_eval(结果文件须命名为bbox.jsonmask.json)。评估默认加载配置中weights指定的最后一轮模型。

4.3 推理

对单张图片推理:

python tools/infer.py -c configs/fcos/fcos_r50_fpn_1x_coco.yml \ --infer_img=demo/000000014439.jpg \ -o weights=https://paddledet.bj.bcebos.com/models/fcos_r50_fpn_1x_coco.pdparams

常用参数:

  • --infer_dir:对目录下所有图片批量推理;
  • --output_dir=infer_output/:指定结果输出目录;
  • --draw_threshold=0.5:可视化时仅绘制分数高于该阈值的框(注意与配置中 NMS 的score_threshold是两回事);
  • --use_vdl=True:推理结果可通过 VisualDL 查看。

5 进阶调优:iou 质量分支、DCN 与 SSLD 预训练

5.1 iou 质量分支(FCOS + iou)

原版 FCOS 使用 centerness(中心度)作为质量分数,训练时对质量分数计算 BCE 损失。PaddleDetection 提供的quality: "iou"变体(见 fcos_r50_fpn_iou_1x_coco.yml)改为使用预测框与真值框的 IoU作为质量分支的学习目标,使质量分数与最终框定位质量直接对齐,从而在 NMS 阶段更准确地排序候选框:

FCOSHead: fcos_loss: name: FCOSLoss loss_alpha: 0.25 loss_gamma: 2.0 iou_loss_type: "giou" reg_weights: 1.0 quality: "iou" # default 'centerness'

从源码看,FCOSLoss构造函数中quality参数默认值为'centerness',当设为'iou'时质量分支的监督信号由 centerness 切换为 IoU(见 fcos_loss.py)。官方 1x 配置下该改动带来约 0.4 AP 的提升,且几乎不增加计算量,是性价比最高的单项优化。

5.2 可变形卷积(FCOS + DCN)

fcos_dcn_r50_fpn_1x_coco.yml 仅通过两处增量开启 DCN:

ResNet: dcn_v2_stages: [1, 2, 3] FCOSHead: fcos_feat: use_dcn: True
  • dcn_v2_stages: [1, 2, 3]:在 ResNet 的第 2~4 个 stage(索引 1、2、3)的 3x3 卷积上替换为 DCNv2;
  • use_dcn: True:同时在 FCOS 分类/回归 tower 的卷积中启用 DCN。

DCN 通过可学习的偏移量让卷积核自适应目标几何形变,官方结果从 39.6 提升到 44.3 AP,但会明显增加显存占用与计算量,部署前需结合实际硬件评估。

5.3 SSLD 预训练权重(R50-vd 方案)

原 README 特别提示:PaddleDetection 默认使用R50-vb预训练(ResNet50_cos_pretrained.pdparams,见 fcos_r50_fpn.yml)。如果改用R50-vd结合 SSLD 蒸馏预训练模型,可进一步显著提升检测精度,同时需要同步修改 backbone 配置:

pretrain_weights: https://paddledet.bj.bcebos.com/models/pretrained/ResNet50_vd_ssld_v2_pretrained.pdparams ResNet: depth: 50 variant: d norm_type: bn freeze_at: 0 return_idx: [1, 2, 3] num_stages: 4 lr_mult_list: [0.05, 0.05, 0.1, 0.15]

其中variant: d将骨干切换为 ResNet-vd 结构;lr_mult_list按 stage 设置不同的学习率倍率(浅层更小、深层更大),这是迁移 SSLD 预训练权重时的推荐做法。关于 SSLD 预训练模型与精度收益的完整说明,可参考 docs/feature_models/SSLD_PRETRAINED_MODEL.md。

5.4 组合策略:multiscale_train + iou

fcos_r50_fpn_iou_multiscale_2x_coco.yml 将多尺度训练(2x)与 iou 质量分支组合,达到 42.6 AP,为当前模型库中(不含 DCN)精度最高的配置。其与 multiscale 单变体的差异仅在quality: "iou"PadBatch.pad_to_stride: 32,说明各增强技巧可自由叠加,用户可按精度/速度权衡自由组合。

6 半监督扩展与引用

6.1 基于 FCOS 的半监督检测:DenseTeacher

原 README 指出,基于 FCOS 的半监督检测方法DenseTeacher可以直接复用 configs/semi_det/denseteacher 下的配置,利用无标签数据进一步提升检测性能。该目录提供了以 FCOS 系列为检测头(基于FCOSHead_ARSL等扩展,见 ppdet/modeling/heads/fcos_head.py)的半监督训练方案,适合标注数据不足、但拥有大量无标注数据的场景。

6.2 引用

若在学术工作中使用 FCOS,请引用原论文(ICCV 2019):

@inproceedings{tian2019fcos, title = {{FCOS}: Fully Convolutional One-Stage Object Detection}, author = {Tian, Zhi and Shen, Chunhua and Chen, Hao and He, Tong}, booktitle = {Proc. Int. Conf. Computer Vision (ICCV)}, year = {2019} }

7 关键文件索引

用途路径
FCOS 模型库总览(本文主文档)configs/fcos/README.md
FCOS 模型结构基座configs/fcos/base/fcos_r50_fpn.yml
数据读取与预处理configs/fcos/base/fcos_reader.yml
1x 优化器与学习率configs/fcos/base/optimizer_1x.yml
FCOS 基线配置configs/fcos/fcos_r50_fpn_1x_coco.yml
FCOS + iou 配置configs/fcos/fcos_r50_fpn_iou_1x_coco.yml
FCOS + DCN 配置configs/fcos/fcos_dcn_r50_fpn_1x_coco.yml
FCOS 多尺度训练配置configs/fcos/fcos_r50_fpn_multiscale_2x_coco.yml
FCOS 多尺度 + iou 配置configs/fcos/fcos_r50_fpn_iou_multiscale_2x_coco.yml
检测头源码ppdet/modeling/heads/fcos_head.py
损失函数源码ppdet/modeling/losses/fcos_loss.py
标签生成算子源码ppdet/data/transform/batch_operators.py
半监督 DenseTeacher 配置configs/semi_det/denseteacher
SSLD 预训练模型说明docs/feature_models/SSLD_PRETRAINED_MODEL.md
使用入门指南(训练/评估/推理通用命令)docs/tutorials/GETTING_STARTED_cn.md
  • 人工智能
  • 深度学习
  • 计算机视觉

【免费下载链接】PaddleDetection

Object Detection toolkit based on PaddlePaddle. It supports object detection, instance segmentation, multiple object tracking and real-time multi-person keypoint detection.

项目地址:https://gitcode.com/gh_mirrors/pa/PaddleDetection
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 2:46:26

3个惨痛教训带你搞懂经验分布避坑指南

3个惨痛教训带你搞懂经验分布避坑指南 配置环境就卡半天,这种痛谁懂?很多应届生刚入行,对着文档敲命令,结果跑出来的数据全乱套,明明代码没报错,结果就是不对。我见过太多人在统计模型里栽跟头,把“经验分布”当成简单的平均值或者正态分布去套,结果上线后被数据打脸。今天这篇 避坑指南…

作者头像 李华
网站建设 2026/9/23 2:46:20

双面板价格揭秘:3个避坑点+完整示例算清成本

双面板价格揭秘:3个避坑点+完整示例算清成本 面试被问双面板PCB计价逻辑,90%的人只能背参数却算不清实际成本。很多新人拿着规格书问报价,被销售反问“板厚多少、铜厚多少、阻焊层做不做”,瞬间哑火。今天把双面板价格的底层逻辑拆透,附完整示例让你直接上手核算。…

作者头像 李华
网站建设 2026/9/23 2:46:10

面试突击:一文搞懂婚礼进行曲4底层原理与高频考点

面试突击:一文搞懂婚礼进行曲4底层原理与高频考点 面对满屏的 StackOverflowError 和 NullPointerException ,你是不是也曾在深夜对着屏幕发呆?别慌,今天这篇【婚礼进行曲4】专题,带你 一文搞懂 从报错堆栈到源码实现的完整链路。…

作者头像 李华
网站建设 2026/9/23 2:46:00

lol大脚下载图解原理与高频面试题实战拆解

lol大脚下载图解原理与高频面试题实战拆解 刚把网上扒来的 lol大脚下载 脚本丢进项目,直接 npm run dev 报错,控制台一片红,心累不累?这种“复制代码跑不通”的困境,是不少后端开发在接触非主流开源库时的常态。更尴尬的是,面试被问到文件下载流的底层机制时,答不上来,因为很多资料只教你…

作者头像 李华