☰
CVPR 2021检测与分割核心方法盘点:从YOLOF到OTA
2026/10/22 8:58:14 网站建设 项目流程

每年CVPR的接收列表一出,做检测和分割的人都会面临同一个问题:一千五百多篇论文,真正值得读的其实就那么一小撮,但想从标题里把它们捞出来,往往得花整整一周。CVPR 2021刚好处于一个特殊节点——Transformer开始大举进入视觉、FPN这类多尺度特征结构的地位首次被公开挑战、标签分配从"拍脑袋规则"走向"最优传输"。如果你正打算研究目标检测、语义分割,或者想找几个能直接跑起来的开源项目练手,这篇汇总就是帮你省时间的。下面这份整理完全以"解决什么问题"为分类线索,不按作者单位排序,每类都会标注源码情况、代码可复现程度以及复现时容易踩的坑。

1. 为什么CVPR 2021的检测与分割值得单独捋一遍

1.1 这一年检测分割出现了好几条分水岭

CVPR 2021在目标检测和语义分割两个方向上,信息密度比前两年明显高。首先是架构层面的震动:Transformer不再只是NLP的工具,一批基于自注意力的backbone和检测头开始刷榜,虽然还没到全面取代CNN的程度,但"主干网络用什么"这个问题突然有了新选项。

其次是检测器内部的"基础设施"被重新审视。FPN多尺度特征金字塔已经默认了好几年,几乎没人质疑它是不是最优解,但这一年的工作开始有人从原理层面反思:多尺度特征到底解决了什么问题?能不能用更便宜的方式达到同样效果?YOLOF这样的工作就是把FPN拆掉,只保留单层特征,却用简单改动追平了RetinaNet,逼着整个领域重新想清楚尺度问题的本质。

然后是标签分配。过去anchor和GT的匹配方式基本靠IoU阈值,偶尔加个中心点距离。2021年"最优传输"这个概念被引入标签分配,OTA把每个GT当作供应方、每个候选框当作需求方,用Sinkhorn算法去求全局最优匹配关系,相比经验阈值更严谨,也因此成了后续很多"动态分配"方法的源头。

最后是预训练策略。大家发现ImageNet分类预训练对检测器来说未必是最优解,UP-DETR直接让Transformer检测器通过自监督的方式做预训练,在不用任何检测标注的前提下拿到了不错的迁移效果,这条路后来演变成了一整个分支。

1.2 我整理用的分类线索,先说清楚

看论文汇总最容易踩的坑,是照着标题扫一圈,结果脑子里只剩一堆乱七八杂的模型名。所以我这次按"动机"分类:目标检测这一大块分成"检测器结构探索、训练策略优化、标签分配方法、无监督预训练"四类;语义分割则按"全景分割统一框架、边界质量提升、实时高分辨率、多任务联合建模"四类来走。这样读起来会形成一个坐标系,你拿到任何一篇新论文时也能自己往这个坐标里放。

核心工作与源码情况对比如下:

细分方向代表性工作核心思路一句话官方源码
单阶段检测结构YOLOF单层特征+膨胀卷积替代FPN官方开源
骨干网络复合CBNet多个backbone串行融合提升精度官方开源
标签分配OTA最优传输做全局最优匹配官方开源
检测预训练UP-DETRpatch特征重建做无监督预训练官方开源
全景分割Panoptic DeepLabbottom-up与top-down融合官方开源
边界感知分割PointFlow归一化流建模边界归属官方开源
实时高分辨率分割HyperSegU型Transformer+高分辨率重建官方开源
全景+部件分割Panoptic-PartFormer语义一致性引导部件分割官方开源

2. 目标检测:四个最值得跟的子方向

2.1 YOLOF:把FPN拿掉,反而想明白了一件事

如果你要在这批记录里选一篇最"反常识"的,我会投YOLOF。它做的事情很简单:把RetinaNet引以为傲的FPN多尺度特征层删掉,只用backbone最后一层C5特征做检测,然后通过两个改动把性能拉回全尺寸FPN的水平。

这两个改动是关键。第一个是Dilated Encoder,用连续几个不同膨胀率的空洞卷积去扩大单层特征的有效感受野。FPN之所以能覆盖不同尺度目标,本质上是给了不同层不同大小的感受野,你既然只有一层,就必须让这一层的感受野本身涵盖足够多的尺度范围。第二个改动是Uniform Matching。FPN时期正样本的分配是按层来的,每层的anchor只和特定尺度范围的GT匹配。现在只有一个特征层,如果还用Max-IoU匹配,大目标或者小目标对应的正样本会过于稀疏,训练不稳定。Uniform Matching把GT和anchor的匹配从"谁最大就给谁"改成"取Top-K个候选并等权采样",保证了训练初期不会出现正样本断供。

从源码层面看,YOLOF是在mmdetection框架里实现的,配置文件组织得很规范,环境问题主要在torch版本,老版本mmdet和新版torch之间经常出现算子编译报错。我的建议是直接用作者release时对应的requirements,别一上来装最新的mmcv。跑通之后你会发现,YOLOF不只是个"缩水版RetinaNet",它提醒所有人的是:FPN的精度优势到底来自多尺度本身,还是来自它缓解了正样本稀疏和优化困难?这个问题直到今天仍然值得反复琢磨。

2.2 CBNet:用"多脑协同"的思路去堆骨干网络

CBNet走的是另一条路线。它不去动检测头的结构,而是在骨干网络上下功夫,提出了复合骨干网络的概念。直观理解就是把两个backbone串起来,前一个backbone的输出逐步引导后一个backbone的特征提取,形成一种"一个负责粗看、一个负责细看"的分工。实际结构上,它把多个backbone的stage输出按逐层递进的方式融合,后一个backbone每一层都能看到前一个backbone对应层的语义引导信息,最终输出的组合特征比单一backbone要丰富得多。

从复现体验来说,CBNet是一个纯训练侧的结构改动,推理时如果你不叠加额外的trick,它比同参数量的单backbone要稳,但显存开销很可观。我当时的测试环境是一张24G卡,跑双backbone版的Cascade R-CNN在COCO上勉强能塞下,如果换成单卡12G,就必须把输入尺度降到600左右,否则直接OOM。这类方法的实际价值在于:它证明在数据量和标注都充足的时候,算力可以换精度,而且换得非常平稳,没有太多诡异的不收敛现象。

如果你想在自己的数据集上复现,有一个容易忽略的细节:CBNet在融合多个backbone时,学习率的设置和普通单backbone有明显差异,尤其是第二个backbone如果初始学习率设太高,很容易在第一个epoch出现loss震荡。稳妥的做法是按原论文把复合backbone部分的lr设为主backbone的十分之一,或者先固定第二个backbone只训检测头,等loss掉下来再放开全部训练。

2.3 OTA:标签分配终于成了一个"可优化的问题"

检测器训练里最不起眼但最影响上限的,就是标签分配:每个GT到底把哪些anchor当作正样本。早年用IoU阈值,后来ATSS用自适应统计阈值,2020年FreeAnchor提出anchor匹配的自动化,到CTA/OTA这一代,标签分配被彻底数学化。

OTA的全称是Optimal Transport Assignment,简单来说,你把每个GT看成"需求方"、每个anchor看成"候选供应方",GT希望找到足够多的、质量足够高的候选框来覆盖自己,而anchor希望被分配到代价最小的GT上。这个"代价"通常由分类损失、回归损失、中心点距离三者加权组成。分配问题是一个不平衡的最优传输问题,它用Sinkhorn迭代来逐步逼近全局最优解,而不是给每个GT硬性划一块区域。

实际运行下来了,OTA相比FCOS和ATSS的自适应分配,在COCO上的收益主要来自"每个GT分配的正样本个数是动态决定的",而不是固定多少或者阈值多少。这一点对大目标和遮挡严重的场景特别重要,因为遮挡区域的anchor质量分布是不均匀的。

复现OTA时最麻烦的点在Sinkhorn那一段:迭代次数过多会带来明显耗时,过少又近似得不够,而且epsilon参数对数值稳定性影响大。源码里默认几个embedding维度的一致性也很容易改错,如果你是新读代码,我建议先从单卡、batch size=8开始,先确认loss曲线形状与论文一致,再考虑跑全量。

2.4 UP-DETR:检测器的"无监督预训练"并不是玄学

目标检测一直高度依赖标注数据,DETR这类Transformer检测器虽然结构优雅,却对预训练权重和训练时长要求苛刻。UP-DETR想解决的问题是:能不能先不给检测标注,就靠图片本身把Transformer检测器预训练好?

它采用的方法叫Patch-Feature Restoration,把图片切成多个patch,随机遮盖其中一部分,然后让模型通过可见patch特征和对应的query来重建被遮patch的特征,本质上是一个自监督去噪的任务。预训练完成后,再用这个权重初始化DETR,进行正常的检测微调。效果上,它在COCO上给DETR和后来的变形体带来了明显的收敛加速和mAP提升。

我理解这背后靠的是Transformer编码器-解码器结构对"场景理解"能力的预先培养。检测标注给的是"哪里有什么",而patch重建强迫模型先理解"一个完整的场景长什么样",这种像素级的空间关联建模与检测器需要的全局上下文能力是高度重合的。

它的源码也是基于PyTorch的,和DETR原版结构一致,环境相对好搭。不过要注意patch size、遮盖比例这两个超参最好别随意改动,论文里试出来的遮盖比例大约是25%上下,改动后预训练效果会明显波动,不要一上来就换自己的配置。

2.5 检测方向之外,还有几个零散线索

这一年在检测大类里还有不少偏工程或偏特殊任务的工作:旋转目标检测在遥感场景中持续升温,大量论文围绕角度回归的边界问题做文章;小目标检测陆续出现基于高分辨率特征图的注意力方案;开放词汇检测也在萌芽期,只是当时还没有形成体系。如果时间有限,我建议先用上面四个核心工作建立坐标,再按你自己的任务去查下游引用,效率会高很多。

3. 语义分割:从"像素分类"到"全景共识"

3.1 Panoptic DeepLab:把全景分割从top-down拽回bottom-up

全景分割的任务是同时给出语义类别和实例ID,经典做法是top-down:先检测实例,再在实例内部分类。Panoptic DeepLab反其道行之,采用bottom-up路线——不框物体,而是直接预测每个像素的语义类别、每个实例的中心点以及每个像素到所属实例中心点的偏移量。然后通过聚类把这些信息缝合成实例。

这个思路的高明之处在于,语义分割分支和实例分割分支可以互相增强,两个分支共享同一个backbone,不仅节省计算量,还借助中心点预测让实例分割对遮挡更鲁棒。论文里在Cityscapes和BDD上把全景分割质量拉到了当时的SOTA,而且整个网络结构是纯卷积的,没有依赖Transformer,工程上很友好。

源码是用Deeplab风格的框架写的,依赖CUDA算子比较多,编译耗时几乎不可避免。我当时跑通花了大半天,主要卡在环境上。建议先用官方给的Docker镜像或者环境配置文件,不要自己手动pip去试,不然会碰到一堆CUDA extension版本对不上的问题。

3.2 PointFlow:边界不准,那就用"流"来建模

语义分割对边界精度的要求一直很高,尤其是医学影像、自动驾驶这类下游任务,区域内部的整体精度再高,边界如果锯齿状明显,实用价值也会打折扣。PointFlow的思路是把"边界"这个几何属性交给归一化流来处理。

我把它理解为:网络先预选出靠近物体边界的像素,再对这些像素的归属关系进行建模,用流模型把"边界相邻区域的概率分布"映射到"类别归属分布",从而恢复出一个更锐利的边界。对比一般用CRF做后处理或者用多尺度特征强行融合的方法,PointFlow是在模型内部把边界当成一个生成问题来完成,训练和推理是一体的。

复现PointFlow的难度中等,主要问题在归一化流的训练需要更精细的learning rate schedule,直接套用普通分割的优化器配置,loss会下降得很慢。如果你习惯用poly学习率策略,这里建议把power调小一些,并在前几个epoch观察边界loss曲线的下降趋势。

3.3 HyperSeg:高分辨率输入也能做到接近实时

实时语义分割通常意味着低分辨率输入,而低分辨率恰恰是边界模糊的元凶之一。HyperSeg解决的问题是:在超高分辨率输入下,如何兼顾速度和精度。

它的结构里有一个很有意思的设计:把输入分成多个分辨率分支,低分辨率分支用Transformer建模长距离依赖,高分辨率分支用轻量卷积保留细节,最后通过一个超分辨率辅助模块,把低分辨率语义信息上采样回高分辨率,同时让各分支的信息逐级融合。这种"基线网络+大感受野强化+细粒度重建"的组合,让它在保持高分辨率预测的同时还能跑到接近实时的速度。

源码同样开源,对环境要求不算苛刻,但训练数据量较大,最好直接按论文的配置跑原数据集。如果用在自定义数据上,注意类别数的改动要同时适配多个分支的head层输出维度,光改最外层会漏掉内部融合层的通道数目,这是大家复现这类多分支结构最容易漏掉的点。

3.4 Panoptic-PartFormer:全景分割和部件分割统一起来

Panoptic-PartFormer的目标不是单纯提升某一项分割精度,而是想把"场景级全景分割"和"物体级部件分割"放在同一个框架里。因为全景分割关心的是"不同物体之间的边界",部件分割关心的是"同一个物体内部的零件归属",两者任务不同但信息互补:知道一个物体是什么,能指导部件分割;知道部件怎么排布,也能反哺物体分类。

它的做法是在全景分割输出基础上引入一组部件类别标识,通过语义一致性约束让同一实例内部的部件互相兼容,最终在统一框架下同时输出语义、实例和部件。这类"多任务联合建模"的思想一直到今天仍有参考价值,尤其做行人解析、汽车解析这类细粒度任务时,这个统一框架天然比独立分割两个模型更高效。

代码层面,这类多head结构最考验代码组织能力,阅读源码时建议先从数据加载和label映射入手,因为全景类别和部件类别经常共用一张label图,只是编码方式不同,一旦映射关系理解错了,训练出来的模型指标再高也是假的。

4. 源码直接拿来用的复现建议

4.1 复现环境里最容易翻车的三处

第一是版本对齐问题。mmdetection系的老代码对mmcv版本很敏感,当年YOLOF、CBNet这些都在特定mmcv版本下跑通,新版mmcv改了算子注册机制,老配置文件直接跑会报一堆KeyError。我的做法是先看代码里的requirements.txt和CI配置,锁定主版本号,再在此基础上小修。

第二是数据集路径和标注格式。这类论文默认COCO格式,你如果换成自定义数据,最容易错的地方不是类别数,而是标注里的iscrowd字段——很多自建数据集根本没设置这个字段,导致训练时把crowd区域也当正样本,mAP曲线诡异震荡。务必把数据处理模块里的过滤条件检查一遍。

第三是学习率策略。检测和分割论文普遍用的8卡batch size对应的大学习率,你在单卡上复现如果直接把学习率复制过来,很容易一开始就loss爆炸。经验法则是线性缩放:单卡batch size缩到原来的八分之一,初始学习率也相应缩小8倍左右,这不算严谨但足够稳定起步。

4.2 这些代码里可以"偷"的工程技巧

看YOLOF源码时我学到的是"源码骨架和实验设计的高度统一":它连正样本采样方式都做成可配置项,方便做消融实验。这个习惯很值得借鉴——任何一个新的检测点,都应该把核心机制做成独立模块,否则后面做ablation时改来改去容易引入隐性bug。

看Panoptic DeepLab源码时,值得借鉴的是它把"后处理聚类"写成了独立可复用的模块,聚类参数全部暴露在配置文件里。你不需要源码级改动就能在自定义数据上调节搜索范围、阈值等参数,这对工程调优非常重要。以后你自己搭分割pipeline时,最好也把后处理从训练代码里抽离出来。

4.3 低配显卡怎么跑这些代码

如果你手里只有一张消费级显卡,直接跑CBNet双backbone或者Panoptic DeepLab的高分辨率配置大概率OOM。我的建议是分三步:先把backbone换成轻量级变体(或者把输入尺度降到训练下限),先把pipeline跑通;然后逐步提高分辨率,直到显存接近临界;最后再决定是否完整复现。这样一来,你至少能拿到"训练流程通顺+核心机制有效"的验证结果,而不是卡在第一步。

5. 按你的需求选读:入门、找idea、工程落地

5.1 刚入门的目标检测/分割方向,按这个顺序读

建议先读YOLOF,因为它结构最简单,又逼着你理解FPN的本质;接着读OTA,把标签分配这条主线补上;再读Panoptic DeepLab,理解分割任务从单任务到全景任务的演进动力。这三篇读透,你对检测分割两个方向的地图感就有了,后面读任何论文都能快速定位到"它改的是结构、分配、还是预训练"。

5.2 想发paper,从这两篇里找"还没做完"的点

OTA把标签分配做成了最优传输,但代价函数里的三个加权项都是人工设定的,后续工作能不能改成自适应权重?UP-DETR证明了patch重建预训练对检测有效,但重建任务和检测任务之间的gap仍然很大,有没有更适合检测的预训练任务设计?这些都是当时论文留下的明显空白,后来也真的衍生出了一大批工作。找idea不是去发明全新问题,而是找到现有方法里"还不够自洽"的接口。

5.3 工程落地优先盯这几个

跑实车或者跑真实业务场景,Panoptic DeepLab这类统一框架最省心,一个模型同时输出语义和实例,部署成本明显低于两套独立模型。HyperSeg适合实时场景,如果你需要高分辨率输出但算力有限,它比通用的编码器-解码器结构更灵活。YOLOF在推理时只有一个特征层,天然比FPN版检测器省内存,如果你在边缘设备上做检测,完全可以按照它的思路把项目里的多尺度头裁掉试试。

最后说点个人经验。我一直觉得CVPR论文汇总的价值不在"看个热闹",而在于把它当成一本"行业议题目录"来读。真正有效的读法是:先看这一年大家在纠结什么问题,再看每个问题有哪些解法分支,最后才是具体指标。回看CVPR 2021这些检测和分割工作,你会发现当年纠结的问题今天依然有效——尺度、分配、预训练、边界质量,没有一个被彻底解决,只是解法一代比一代精细。这也是为什么我建议你读源码而不只是读摘要,因为只有代码里那一条条具体的取舍,才会告诉你一个方法真正的边界和可扩展空间在哪。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询