Anchor-Free机制回顾:CenterNet, FCOS

张开发
2026/5/4 15:51:48 15 分钟阅读
Anchor-Free机制回顾:CenterNet, FCOS
上周调一个老项目模型输出突然飘了。排查半天发现是anchor尺寸配置和预处理resize对不上——输入分辨率从512改成640anchor还是那套旧参数检测框全挤在图像中央。这种问题在anchor-based方案里太常见了每次改输入尺寸都得重新聚类计算部署时还得在配置文件里小心翼翼对齐。这让我想起当年切到anchor-free方案时那种解脱感终于不用再伺候这些预设框了。Anchor-Free的本质是回归逻辑的简化传统YOLO系列依赖anchor作为先验本质是在预设框基础上做微调。而anchor-free直接把目标建模成关键点或特征点让网络学习从这些点到边界框的映射。CenterNet把目标看作一个点通常是中心点FCOS则把目标框内的每个点都视为正样本。这两种思路看似不同其实都在解决同一个问题如何让检测器更直接地学习空间关系。CenterNet的简洁性很吸引人。它把目标检测变成关键点估计网络输出热图峰值位置就是目标中心再配合局部偏移量和尺寸回归。调试时最直观的感受是后处理变简单了——不需要NMS非极大值抑制吗其实还是需要的但压力小了很多因为热图本身就有抑制重复预测的能力。不过这里踩过坑热图分辨率低的时候小目标中心点容易丢失需要把下采样倍数控制好。别在backbone里无脑堆叠stride2的卷积小目标数据集上建议用空洞卷积或者特征金字塔保持分辨率。FCOS的思路更“密集”。它让特征图上每个点都预测框用中心度centerness来抑制低质量预测。这种方案在工程上有个好处和语义分割的兼容性强多任务学习时结构干净。但实际部署时发现正负样本不平衡问题比想象中严重——特征图上大部分位置都是负样本需要靠Focal Loss和样本筛选策略压住。有个经验centerness分支的学习率可以设小一点这个头训崩了整个模型就废了。代码里的细节决定成败# CenterNet风格的热图解码简化版defdecode_heatmap(heatmap,offset,size):# heatmap: [H, W, C] 这里C是类别数# 找峰值——别用全局max局部极值更鲁棒peaksfind_local_maxima(heatmap,kernel3)# 3x3窗口找极大值# 偏移量补偿注意训练时用的归一化坐标pred_ctrpeaksoffset[peaks]# 这里踩过坑offset要取对应位置# 尺寸还原记得指数变换pred_hwexp(size[peaks])*stride# 别忘记乘下采样倍数returnpred_ctr,pred_hwanchor-free方案的后处理往往比anchor-based更吃CPU因为峰值查找和排序操作多。部署时可以考虑用CUDA核函数重写解码部分特别是CenterNet的热图峰值查找纯Python实现能拖慢整个流水线。个人经验与建议小目标场景慎用CenterNet。热图机制天生对密集小目标不友好分辨率损失后几个像素的偏差就能让IoU掉一大截。可以试试在FPN特征金字塔的浅层特征上做预测牺牲速度保召回率。FCOS的centerness分支容易学偏。训练初期经常出现centerness全趋近0的情况导致召回率暴跌。可以尝试先训两个epoch再启用centerness分支或者用GT centerness做教师信号缓一缓。部署时注意数值稳定性。anchor-free方案经常涉及exp、pow这些指数运算量化时容易溢出。建议训练时就加入范围约束比如把尺寸预测输出用sigmoid压到合理区间。不要神话anchor-free。它解决了anchor mismatch问题但带来了正负样本平衡、定位精度敏感等新挑战。工业场景里混用方案有时更有效——我们有个项目在主干网络用FCOS在专用小目标检测头里保留了几组细粒度anchor效果比纯anchor-free提升7个点。说到底模型结构是工具解决问题才是目的。下次遇到anchor配置烦恼时不妨问问自己这个场景真的需要预设框吗或许答案就在问题之外。

更多文章