本文以地平线 Open Explorer(OE)中的 CenterPoint 参考算法为主线,系统梳理 CenterPoint 的模型结构设计、Head 与 box 语义拆分方式,以及在工具链中从训练、导出到编译部署的完整工程语义。
文末通过 nuScenes → KITTI 的一次实际配置修改,作为参考算法“应用级改造”的示例,帮助理解这些设计在真实项目中的影响范围。
一、CenterPoint 是一个怎样的 3D 检测模型?
它的核心思想并不是“直接预测 3D 框”,而是:
- 在 BEV 平面 上预测目标中心点(center)
围绕 center 回归目标的几何属性
中心偏移(x, y)
高度(z)
尺寸(w, l, h)
朝向(yaw)
速度(vx, vy,可选)
二、CenterPoint 的 Head 设计与 box 语义拆分
Head 名称 | 维度 | 语义 |
|---|---|---|
reg | 2 | x, y(BEV 平面中心偏移) |
height | 1 | z |
dim | 3 | w, l, h |
rot | 2 | sin(yaw), cos(yaw) |
vel | 2 | vx, vy |
几个关键点需要强调:
- rot 使用 sin / cos 表达
这是为了避免角度回归的周期不连续问题,因此训练回归维度中,yaw 始终占用 2 个通道。 - Head 的 insertion order 很重要
CenterPoint 在 deploy 模式下会按 Head key 的顺序扁平化输出,这直接影响导出 HBIR 和最终推理输出 tensor 的语义顺序。
三、box_size 的真正含义:训练回归 vs 推理输出
在 CenterPoint 中,经常会看到如下配置:
需要明确的是:
box_size 表示的是 postprocess 之后,最终输出给下游使用的 box 物理维度,而不是训练阶段的回归维度。
3.1 nuScenes 场景:box_size = 9
在 nuScenes 数据集中,CenterPoint 通常开启 velocity,因此最终输出 box 语义为:
这 9 个量分别来自:
reg → x, y
height → z
dim → w, l, h
rot → yaw(由 sin/cos 反解)
vel → vx, vy
3.2 训练回归维度(code_size)与 box_size 并不相同
一个容易混淆的点是:
训练阶段回归维度(code_size)
推理阶段输出维度(box_size)
以 nuScenes 为例:
训练回归维度 = 10
reg(2) + height(1) + dim(3) + rot(2) + vel(2)
推理输出维度 = 9
yaw 从 sin/cos 合并为 1 个角度
四、deploy 模式下的输入与输出语义(工具链视角)
4.1 is_deploy=False:训练 / 评估路径
在训练或评估阶段:
- 输入:example["points"](raw point cloud)
处理流程:
动态点数
非规则张量
不适合直接导出为静态 IR
4.2 is_deploy=True:导出 / 部署路径
在导出 HBIR 或部署推理时:
不再接收 raw 点云
输入变为:
流程变为:
原因很明确:
- BPU / IR 编译需要 静态、确定形状的输入
点云体素化包含动态结构,不利于导出
将点云预处理放到外部流水线(CPU / DSP)更可控,也更利于性能调优
4.3 deploy_inputs 的语义约束
在 OE 示例中,deploy_inputs 通常形如:
- features: [1, C, P, M]
- coors: [M, 4],格式为 [batch_idx, z, y, x]
五、编译阶段的输出语义:output_layout 与 transpose_dim
在模型编译配置中,常见如下设置:
这里需要区分两个概念:
- 真正生效的,是 transpose_dim
工具链会在输出节点插入 transpose
- output_layout 更多是 语义标注
也就是说:
是否从 NCHW 转为 NHWC,取决于 transpose_dim,而不是 output_layout 字符串本身。
output_layout 与 transpose_dim 保持一致,避免下游推理或解析代码误读输出格式。
六、参考算法的一次应用修改示例:nuScenes → KITTI
将 nuScenes 的 CenterPoint 配置修改为 KITTI 使用。
6.1 目标差异
KITTI 不定义 velocity
最终推理输出 box 语义应为:
即:
- 推理 box_size = 7
- 训练回归维度仍为 8(rot 使用 sin/cos)
6.2 修改不是“改一个字段”,而是系统性同步
这类修改必须同步覆盖以下模块:
- Head(移除 vel)
Target / Loss(不再生成或监督 velocity)
PostProcess / BBoxCoder(不再 decode vel)
deploy flatten 输出顺序
下游解析与评测逻辑
一个实用的自检原则是:
训练回归维度 = len(code_weights) = target anno_box dim
推理输出维度 = postprocess.box_size
二者必须分别自洽,否则一定存在隐患。
七、小结
CenterPoint 在地平线工具链中并不是一个“只改配置就能安全迁移”的模型:
- box 语义来自 Head 设计
训练与推理的维度并不等价
deploy 模式下的输入、输出和编译布局都有严格约束
- 一个看似简单的 with_velocity 开关,实际影响的是 跨模块的系统行为
