市中心的春熙停车场里,老王当了几十年协管员。过去他的绝活,是怀里揣着一沓厚厚的“模板卡”——卡片按车的长短、胖瘦裁成几十种规格。每来一辆车,他就举起卡片,一张张往车上比画:这张太窄,换那张;那张太长,再换一张方的……一天下来,几百张卡片在兜里进进出出上千回,能真正套中的却没几张。 后来老王换了个思路。他不再掏卡片,而是爬上瞭望台,眯着眼从高处往下看:“那辆车,中心就在 3 号立柱旁边,车长约 5 米,宽约 1.9 米。”不试模板,直接报出位置和大小,一报一个准。 老王的这套新本事,就是这篇要讲的主角——无锚框目标检测。咱们把它拆开看:传统的“模板卡”为什么吃力不讨好;“直接定位”又是怎么认出目标中心、量出目标尺寸的;这套思路从哪来、强在哪、如今用在哪。读完之后你再回头看摄像头画面,就能看懂算法是怎么“一眼圈出”每一辆车、每一个人了。
学懂 Anchor-free,你就能理解目标检测从“预设先验框”走向“端到端直接回归”的技术趋势,在工程选型(速度/精度/超参成本)时做出更专业的判断,这是 CenterNet、FCOS 等现代检测模型的核心底座。
可视化演示
通过Anchor-based锚框匹配局限、FCOS逐像素预测、CenterNet中心点热力图三个模式,展示Anchor-free方法如何消除预设锚框实现更简洁高效的目标检测。
本节配有交互动效(进入视口后自动加载,约 3KB)。
Anchor-based方法的固有局限 每个位置预设9个锚框3种尺度3种长宽比需大量超参数调优 IoU匹配阈值敏感小目标匹配困难正负样本极度不均衡 Anchors = positions × scales × ratios → IoU matching 锚框设计复杂且对新场景需重新统计分析
锚框机制
老王的模板卡可不是随便裁的。他在裁卡前会先做统计:这个车场常见的是轿车、SUV、小货车,所以卡片被分成 6 种长度、4 种宽度,一共 24 种规格,每种规格印一批,全部揣进兜里。“车场会停什么车,卡片就有什么规格”——这张卡,就是目标检测里鼎鼎大名的锚框(Anchor)。
把镜头从老王身上拉开,换成卷积网络看一张图:它先把图片层层浓缩成一张更小、更抽象的特征图,好比老王站到瞭望台看到的“缩小版车场”。传统检测器在这张特征图的每个格子上,都铺上预先设计好的若干个锚框——每个锚框对应一种预设的尺寸和长宽比。图片里目标有多大、比例是横是竖,全都提前被“猜”成了这批固定模板。
铺完之后,怎么判断哪个锚框算“套中”了车?业界用交并比(IoU)来丈量:把锚框和真实框当成两块区域,算它们重叠面积占合并面积的比重。
老王每天最头疼的,恰恰是“套没套中”的裁决——有的卡只盖住车头,有的卡罩住了半条车道。IoU 就是那个铁面无私的裁判:重合率达标才算套中。卡片虽多,真正能派上用场的,永远是极少数。
- 集合 A 与 B把锚框看作一块区域 A,真实目标看作另一块区域 B——对应老王手里的模板卡和真实车体。
- 交集 |A∩B|两片区域重叠的部分,面积越大,说明卡片盖住车身越多。
- 并集 |A∪B|两片区域合并后覆盖的总面积,重叠部分只算一次。
- 比值即 IoU重叠占比越高贴得越好,IoU 常以 0.5 为阈值划分正负样本。
设计动机
日子久了,老王腰酸背痛:一晚上两百辆车,平均每辆要试 50 张卡,其中 49 张连车的边都不沾。“我九成九的力气,都花在了翻没用的卡上。”这个抱怨,和学术界抛弃锚框的心路历程一模一样。
一张普通照片里常常只有几十个目标,而锚框法会在特征图每个位置铺好几个框,一张图轻松生成上万甚至几十万个候选框。于是绝大多数锚框面对的是空白背景——这就是著名的正负样本失衡。
失衡带来连锁反应:训练时模型被海量“没有目标”的例子淹没,要么学不到东西,要么被带偏,于是又得发明难例挖掘、Focal Loss 这类“补药”。更麻烦的是,锚框的尺寸和长宽比需要针对每个数据集手工设计——换成一批新数据(比如从汽车换成轮船),又得重调一遍。两阶段流程还要先生成候选区域、再分类回归,环节多,误差还会层层累积。
老王终于把整沓模板卡摔在桌上:问题不在他手笨,而在“预先定死的模板”这件事本身。与其用 99% 的力气做无用功,不如换一套不依赖模板的打法——这正是 Anchor-free 登场的理由。
- 总框数 N_all一张图生成的全部候选框总数,包含正负样本。
- 正样本 N_pos与真实目标 IoU 超过阈值、真正“套中”的锚框。
- 负样本占比总量减去正样本,再除以总量,就是被白白浪费的比例。
- ≈99.9%几万锚框对几十个目标,负样本占比往往高达 99% 以上。
无锚框总览
老王的崭新思路,是彻底扔掉卡片,在瞭望台上把整个车场当成一张大坐标图。他不再关心“车像哪张卡”,而是让每一个网格自己回答两个问题:“我这格有没有车?”以及“如果有,车的中心离我多远、车有多大?”
这个思路落到神经网络里,就是“密集预测”:检测器不再先生成一批候选框,而是对特征图上的每一个位置,直接输出一个向量——前半段是它属于各个类别的置信度,后半段是目标的几何信息(中心的偏移量、宽、高)。
这个“每个点自报家门”的设计,只是无锚框思想的总纲。具体怎么做几何部分的回归,江湖上分了两派:一派盯着目标的“角”,比如 CornerNet 找左上、右下两个角点;另一派盯着目标的“心”,比如 CenterNet 找中心点。后文两节,咱们分别跟着老王走一遍。
- 位置 (i,j)特征图上的任意一个网格,相当于车位地图上的一个坐标。
- 类别置信 p_c该位置属于第 c 类目标的概率,c = 1…C。
- 几何量回归中心相对该网格的偏移 Δx、Δy,以及目标宽 w、高 h。
- 端到端解码训练时用标注监督这些值,推理时直接从向量解码出框。
角点检测
老王摸索出一个省力窍门:既然一辆车要被框住,那框的左上角和右下角就是最好认的两个点——像车头和车尾的两个角灯。只要同时认出这两个角,把两点一连,车的包围框就画出来了。
CornerNet 就是这么干的。它不再回归“框本身”,而是让网络输出两张热力图:一张标出“哪儿是左上角”,一张标出“哪儿是右下角”。每张热力图上越亮的地方,代表网络越确信这里有一个角点。但“有两个角”还不够,得知道哪两个角属于同一辆车——CornerNet 额外为每个角点预测一个嵌入向量(embedding),训练时让同一辆车的两个角向量互相靠近,不同车辆的向量彼此远离,从而把左角、右角“配对”成一家人。
拿到左上角 $(x_1, y_1)$ 和右下角 $(x_2, y_2)$ 之后,目标框 B 由 min/max 运算直接拼出:
找角点时还有个细节:判断一个点是不是左上角,得参考它右边和下边的信息,于是 CornerNet 设计了角点池化,把该点右侧、下侧区域的最大值汇聚过来,让左上角“看得见”物体的轮廓。老王这招的代价是:两辆车紧挨着停时,左角和右角容易认串。嵌入向量就像他在每个角上贴了半张票据,只有票据对得上号的角才能凑成一辆车。角的组合多了,配对也就成了新的负担——这为后来的“中心点”思路埋下了伏笔。
- 左上角 (x1,y1)目标是左上角点,x1 和 y1 是它的两个坐标,来自左上角热力图的峰值。
- 右下角 (x2,y2)右下角点和它对称,来自右下角热力图。
- 取最小补齐左与上min 运算保证左边取更靠左的坐标、上边取更靠上的坐标。
- 取最大补齐右与下max 运算把框的右下边界补齐,两角点被“撑”成完整矩形。
中心点检测
老王进一步做减法:既然认角还要配对、像拼拼图,干脆只认一个点——车的正中心。中心认准了,再估个宽和高,框自然出来。这一下,配对问题消失了。
CenterNet 用一张类别热力图来“找中心”:网络在特征图的每个位置输出“这里离某个目标的中心有多近”的分数,数值越大越可能是中心,并且用高斯核把每个真实中心点“抹”成一个亮斑,让网络学起来更平滑。检测时,后处理只做一件事:用 3×3 的最大池化扫过热力图,凡是比周围 8 个邻居都亮的位置,就是一个局部峰值,取前 K 个峰值作为预测的中心——这一步替代了传统 NMS。
峰值得到中心点 $(c_x, c_y)$,再配合网络回归的宽 w 和高 h,包围框从中心向四周展开:
老王在瞭望台上看得越远,越难看清细节——特征图的网格就好比他的视力分辨率。他于是多报一句“我看偏了大概半格”(offset),把模糊补回来。中心点 + 偏移 + 宽高,三样凑齐,一帧画面里的所有车,就这么被“一眼”全圈了出来。
- 中心点 (cx,cy)来自热力图峰值,经 3×3 最大池化筛选后还原的位置。
- 半宽 w/2从中心向左、向右各展开一半宽度。
- 半高 h/2从中心向上、向下各展开一半高度。
- 解码成四角坐标中心减半宽/半高得左上角,加半宽/半高得右下角。
优势分析
把新老办法放在一起算账,老王乐了:以前翻卡片,每辆车要对几百上千张模板;现在只需盯着中心点一个位置,再把尺寸量出来。
算一笔账就清楚了。一张特征图有 H×W 个位置,锚框法每个位置要铺 K 种尺度、R 种长宽比的框:
优势可以列成四条:一是超参少了,不再为“锚框多大、什么比例”而调参;二是流程短了,训练时不用再做锚框匹配分配正负样本,模型更接近“输入图片、输出框”的端到端;三是正样本比例提高了,无数“空模板”不再参与计算,训练更稳;四是后处理轻了,CenterNet 这类方法用峰值提取代替复杂的 NMS 流水线,部署时省时省力。当然老王也明白,“省力”不等于“躺着赢”:他仍需调模型的深度、看台高度(网络结构和下采样倍率)。但相比过去被模板卡绑住手脚,Anchor-free 把工程师从“调锚框”里解放了出来,把精力真正还给数据与网络设计。
- 位置总数 H×W特征图被划分成 H 行 W 列网格,每个网格一个位置。
- 尺度数 K每个位置要试 K 种不同大小。
- 比例数 R每种尺度还要再试 R 种长宽比。
- 总数爆炸锚框总数是三者乘积,而 Anchor-free 只保留第一步的 H×W。
发展脉络
老王的手艺不是一天练成的。回看这些年,他的“无模板”之路经历了四步:先有人试过不贴卡片,再有人学会认角,又有人简化成认心,最后有人把“直接定位”推向了极致。
2015 年 DenseBox 最早在密集位置逐像素回归人脸框,是 Anchor-free 的先声;2018 年 CornerNet 把检测改造成“角点检测 + 配对”,第一次在 COCO 榜单上比肩两阶段方法,证明不靠锚框也能打;2019 年 CenterNet 用中心点取代角点配对,又快又稳;同年的 FCOS 换了一种全然不同的刻画方式——对每个像素直接回归它到目标框四条边的距离,并借助特征金字塔(FPN)在不同尺度上各自负责,让逐像素回归也能应对大小悬殊的目标。
但像素离目标中心越远,回归出的四边距离越不可信。FCOS 于是新增一个 centerness(中心度)分支,给每个位置打一个“我离中心多近”的分:越靠中心越接近 1,越靠边缘越接近 0,然后用它给该位置的框打分打折。
这条脉络,就是老王一路做减法的过程:去模板、去配对、去多余的后处理。从“满场试卡”到“直取中心”,Anchor-free 用事实证明:目标检测的“招数”越少,反而越接近问题的本质——先定位,再量尺寸。
- 四边距离 l,r,t,b像素到目标框左、右、上、下四条边的距离,由回归分支输出。
- 左右比值左右距离的较小者除以较大者,中心处为 1,越靠边越接近 0。
- 上下比值上下距离也做同样的运算。
- 相乘开根号两个比值相乘再开方,得到 0 到 1 的中心度,给该位置的检测框打分。
落地应用
老王退休后,他这套“无模板定位”的思路被移植到了很多比停车场更复杂的场景。只要“找目标 + 量大小”这个套路成立,Anchor-free 就能派上用场。
自动驾驶里,前视摄像头要在几十毫秒内同时圈出车、行人、骑行者,目标大小比例千变万化,锚框法要设计多套模板,Anchor-free 的中心点 + 宽高回归则天然省事;工业质检里,产品表面的划痕、凹坑形状随机,Anchor-free 对“没见过的缺陷”也容易给出响应;遥感图像里,船、飞机密密麻麻,峰值提取天然适配“每个峰对应一个目标”的密集场景。
如何衡量在某个场景里好不好用?学术界常用平均精度均值(mean Average Precision, mAP)——对每个类别算一条精度-召回曲线下的面积 AP,再对所有类别取平均:
mAP 高了,说明老王这套“先认中心、再量尺寸”的平均水准高;但具体到每个停车场,停车线划多密、车位朝向如何,仍要因地制宜地调网络。工具变了,“读懂场景”这件事,永远得靠算法工程师自己。
- 每个类别一个 AP对每一类分别画精度-召回曲线并求曲线下的面积。
- C 个类别求和把各类 AP 累加,反映所有类别的整体水平。
- 取平均得到 mAP除以类别数,得到一个综合精度指标。
AI 应用场景
自动驾驶实时感知
阶段:模型推理与部署
解决的问题:传统锚框法在车载芯片上要逐框评估数千个锚框,计算与显存压力大,且路上车辆、行人的大小比例多变,手工设计的锚框容易失配;Anchor-free 直接预测中心点加宽高,省去锚框分配和大量负样本计算,更适合 30 毫秒内出结果的实时管线。
具体案例:某自动驾驶公司在车规级芯片上部署 CenterNet 检测行人与车辆:输入 512×512 图像,backbone 用轻量 DLA-34,峰值提取只取前 100 个中心点。相比同类 anchor-based 单阶段模型,端到端时延从 45ms 降到 28ms,且白天、夜间场景切换时无需重新设计锚框比例。
工业表面缺陷检测
阶段:数据标注与训练策略
解决的问题:产品表面缺陷(划痕、凹坑、污渍)的大小和形状随机,锚框的尺寸/比例先验难以覆盖;Anchor-free 让模型对“没见过的新缺陷”也有响应,降低换产线时重新调锚框的成本。
具体案例:某面板厂用 FCOS 检测 LCD 屏幕缺陷:FPN 三层输出加 centerness 低质量框抑制,把漏检率从锚框方案的 2.1% 压到 1.3%;新增缺陷类型只需补充标注,无需改网络结构,训练流程明显缩短。
Python 演示
import numpy as np def max_pool(hmap, k=3): """3x3 最大池化: 仅保留比周围相邻位置都大的峰值点.""" H, W = hmap.shape out = np.full_like(hmap, -1e9) hp = np.pad(hmap, k // 2, mode='constant', constant_values=-1e9) for i in range(H): for j in range(W): out[i, j] = hp[i:i + k, j:j + k].max() return out def decode_boxes(hmap, wh, offset, stride=4, thresh=0.5): """Anchor-free 解码: 热力峰 -> 中心点 -> 左上/右下角.""" hits = np.where((hmap >= max_pool(hmap)) & (hmap > thresh)) boxes = [] for y, x in zip(hits[0], hits[1]): cx = (x + offset[0, y, x]) * stride cy = (y + offset[1, y, x]) * stride w, h = wh[0, y, x], wh[1, y, x] boxes.append((cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2, hmap[y, x])) return sorted(boxes, key=lambda b: -b[4]) if __name__ == '__main__': hmap = np.zeros((16, 16)) hmap[4, 5] = 0.9 # 目标 A 的中心落在 (4, 5) hmap[11, 11] = 0.8 # 目标 B 的中心落在 (11, 11) wh = np.zeros((2, 16, 16)) wh[0, 4, 5], wh[1, 4, 5] = 12.0, 8.0 wh[0, 11, 11], wh[1, 11, 11] = 16.0, 6.0 offset = np.zeros((2, 16, 16)) for x1, y1, x2, y2, s in decode_boxes(hmap, wh, offset): print('box=(%.1f, %.1f, %.1f, %.1f) score=%.2f' % (x1, y1, x2, y2, s))
hits = np.where((hmap >= max_pool(hmap)) & (hmap > thresh))峰值筛选:既是 3×3 邻域“最高点”,又超过置信阈值,才被当作目标中心。np.pad(hmap, k // 2, mode='constant', constant_values=-1e9)边界补极小值,让边缘像素也能正常做 3×3 池化。cx = (x + offset[0, y, x]) * stride中心坐标从特征图还原回原图:位置乘以步长,再加上预测的偏移修正。boxes.append((cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2, hmap[y, x]))由中心点向四周展开宽高一半,得到左上/右下角。for x1, y1, x2, y2, s in decode_boxes(hmap, wh, offset):主入口:模拟两张热力图,端到端打印出检测框。
常见误区
误区既然叫“无锚框”,那模型什么先验信息都不用,完全从零开始学,跟白纸一样。
正解“无锚框”去掉的只是“物体尺寸/比例的分布”这一手工先验,模型仍然保留 stride(下采样倍数)、多尺度特征、高斯核(把目标中心摊成一个峰)等结构假设。老王虽然没带模板卡,但“车一般停在车位内、中心在车体中间”这类常识还在脑子里——Anchor-free 去掉的是束缚,不是常识。
为何常见:"free"(无)字容易让人望文生义,以为模型完全零假设;其实 free 的对象特指 anchor 这项人工设计。
误区无锚框就没有重复框,后处理 NMS 可以整段删掉,一个不剩。
正解要看具体方法。CenterNet 用 3×3 最大池化提取峰,天然把每个目标压成唯一中心,确实省掉了传统 NMS;但 CornerNet 仍要合并角点候选,FCOS 也是“centerness 压低质量框 + 轻量 NMS”的组合。Anchor-free 更多是“减少/简化”后处理,而不是“后处理清零”,工程上仍需按模型验证。
为何常见:不少科普把 CenterNet 的“免 NMS”泛化成整个 Anchor-free 家族的特征;其实 NMS 只是被峰值提取这一算子替代或弱化。
误区新方法碾压老方法,换成 Anchor-free 我的指标一定上涨,不用再做对比实验。
正解精度上两者并无绝对输赢。Anchor-based(如 Faster R-CNN、仍用锚框设计的 YOLO 版本)在极小目标、极端宽高比目标、拥挤场景依然有竞争力;Anchor-free 的优势更多体现在实现简单、超参少、训练收敛稳定、部署友好。具体 mAP 高低取决于数据集分布、backbone 和训练策略,老王的新手艺更省力,不代表在每个停车场都必然赢。
为何常见:技术演进常被简化成“新必优于旧”,且论文榜单多为理想实验条件,掩盖了任务差异。
误区CenterNet 找到热力图最大值,这个点就是物体的精确中心,直接画框就行。
正解热力图是在 stride 下采样后的特征图上预测的,位置精度被限制在一个网格内(如 stride=4,误差最大 4 像素),直接当中心会导致小目标框偏差明显。CenterNet 额外回归一个中心偏移 offset(0~1 个网格内的亚像素修正),峰值点坐标 + 偏移 + 宽高三者合成才得到最终框。老王目测距离时说的“大概偏左半米”,就是 offset 的作用。
为何常见:人们习惯把热力图“最亮的位置”当作精确坐标,忽略了特征图分辨率被池化、卷积步步压缩的事实。
面试题
Q1. “Anchor-free“ 中的 ”free”(无)特指不依赖下列哪一项?
- A.卷积神经网络的卷积核
- B.预设尺寸比例的先验框← 正确答案
- C.训练数据集的标注信息
- D.特征金字塔的多层结构
答案:B。Anchor-free 抛弃的是手工设计的锚框(尺寸与长宽比先验),但卷积核、标注数据和特征金字塔它通通照用。就像老王扔掉了模板卡,可瞭望台和双眼还在。
Q2. CenterNet 的热力图峰值通常代表目标的什么信息?
- A.目标类别数量的多少
- B.目标中心所在的位置← 正确答案
- C.目标左上角的方向
- D.目标旋转角度的值
答案:B。CenterNet 把每个目标建模成中心处的一个高斯亮斑,热力图越亮代表越接近中心,峰值点就是目标的中心位置。认角是 CornerNet 的活儿,测旋转角不在 CenterNet 的设计里。
Q3. 下列哪些是 Anchor-free 代表性工作?
- A.CornerNet 两角点法← 正确答案
- B.CenterNet 中心点法← 正确答案
- C.FCOS 逐像素回归← 正确答案
- D.Faster R-CNN 区域建议
答案:ABC。CornerNet 用角点、CenterNet 用中心点、FCOS 用逐像素四边距离回归,都不需要预设锚框;Faster R-CNN 的 RPN 依赖大量锚框,属于 Anchor-based。就像老王的新手艺——不掏卡也能报出车位。
Q4. 采用“左上角 + 右下角两个关键点配对”思想的目标检测方法是?
- A.CenterNet 中心点法
- B.CornerNet 角点配对← 正确答案
- C.DenseBox 密集人脸框
- D.Faster R-CNN 候选区域
答案:B。CornerNet 预测两张热力图分别找左上角和右下角,再用嵌入向量把同一目标的两角配对;CenterNet 只看中心点,DenseBox 是早期逐像素回归,Faster R-CNN 是锚框两阶段方法。
Q5. 锚框法正负样本失衡的直接根源是?
- A.锚框的总数远多于真实目标数← 正确答案
- B.训练时图片的分辨率过低
- C.卷积核尺寸设置得过大
- D.损失函数只用了均方误差
答案:A。锚框法在特征图每个位置铺多个框,一张图上万个框,而真实目标只有几十个,绝大多数框落在背景上成为负样本。老王翻了几百张卡,真能套中的永远是少数——根源在于“卡太多、车太少”。
Q6. CenterNet 最终解码目标框时,需要哪三个量?
- A.锚框长宽比、中心偏移、旋转角
- B.热力峰值、中心偏移、宽高← 正确答案
- C.左上角点、右下角点、类别数
- D.区域建议、特征图、交并比
答案:B。CenterNet 用热力图峰值定位中心,offset 补偿下采样误差,宽高回归给出尺寸,三者合成包围框。它不需要锚框长宽比,也不需要配对两个角点。
Q7. 与传统锚框法相比,Anchor-free 的典型优势包括?
- A.省去手工设计锚框尺寸比例← 正确答案
- B.训练流程更简洁端到端← 正确答案
- C.正负样本数量完全均衡
- D.彻底告别所有后处理步骤
答案:AB。Anchor-free 最大的红利是不用调锚框、流程更短。但它并非绝对均衡,CenterNet 也有少量背景点;后处理上它简化而非消灭(如 FCOS 仍需轻量 NMS)。“完全”“彻底”这类绝对化表述通常都是错的。
Q8. CornerNet 通过什么机制把同一物体的两个角点准确配对?
- A.角点池化编码空间位置
- B.嵌入向量缩小同类距离← 正确答案
- C.热力图阈值筛选峰值
- D.特征金字塔多尺度融合
答案:B。CornerNet 为每个角点预测一个嵌入向量,训练让同一目标的两个角向量靠近、不同目标的角向量远离,推理时按向量距离配对。角点池化解决的是“角点看得到边界”,不是配对问题。
Q9. 关于 CenterNet 的描述,正确的有哪些?
- A.用 3×3 最大池化提取热力峰← 正确答案
- B.中心偏移补偿下采样误差← 正确答案
- C.宽高回归输出目标框尺寸← 正确答案
- D.必须先做候选区域生成
答案:ABC。CenterNet 后处理用最大池化筛峰,offset 修正在特征图网格上的量化误差,宽高分支给出框的尺寸,三管齐下得到最终框。它不需要 RPN 式的候选区域生成,这是 Anchor-free 的核心特征。
Q10. FCOS 引入 centerness 分支的主要目的是?
- A.加速卷积运算和显存占用
- B.降低偏离中心框的质量权重← 正确答案
- C.把回归目标改造成分类任务
- D.增加锚框尺度和长宽比例
答案:B。逐像素回归时,离目标中心远的像素预测的框质量差,centerness 给每个位置打一个“离中心多近”的分,训练时用它给框的质量打折,推理时压掉边缘低质量框。它不改变运算量,也不属于锚框设计——就像老王更信任“正对着车头”的估测,而不是斜着瞟一眼的估测。