传统3D目标检测的问题做智能驾驶或机器人感知的朋友应该都很熟悉。每一帧点云或图像进来模型输出一堆长方体框每个框带着类别、朝向、尺寸、速度后面的跟踪和决策也基本只对这些框做处理。这个范式统治了很多年可越做到后期越会碰到一个尴尬场景明明前边有障碍物但目标类别不在训练集里3D检测器就是认不出来。占据网络Occupancy Networks正是在这个背景下被推到台前的。它不再回答“这里有什么物体、框应该画在哪”而是回答“三维空间中每个位置是否被占据、属于什么语义”把感知从“找物体”改成了“理解空间”。这篇文章我不打算只聊概念会把它背后的动机、与常规检测的差异、数据问题和落地时真正会踩的坑一次讲清楚。1. 传统3D目标检测的问题出在哪1.1 检测框是一种过度压缩的空间表达3D目标检测的核心输出是长方体框通常用中心点坐标、长宽高、朝向角再加一个类别标签来表示一个目标。这个表达在数学上很干净后处理也好算但从“对空间的理解”角度看它牺牲了太多信息。一辆正常行驶的小轿车用长方体框去近似确实八九不离十。但自然世界里的物体不是长方体的集合。路边伸出来的树枝、货车上面捆绑的货物、倒下的施工围挡、半挂车和车头之间的空隙这些东西要么没法塞进一个框里要么一个框里包含了大量空白空间。更麻烦的是框和框之间有重叠、有遮挡检测器在推理时还要做NMS也就是用一个框把另一个框压掉。这个操作对“规则物体”是合理的但对非规则障碍物经常会误伤附近真正的小目标。我见过不少团队在处理“框怎么转、怎么膨胀、怎么和目标占用对齐”这类问题时非常痛苦。框的朝向差5度车尾预留的膨胀区域可能就偏了半米尺寸差20厘米对狭窄街道上的通过性判断就是完全不同的结果。这些误差不是调一调阈值就能解决的而是因为检测框这个抽象层次本身就太低了。你把一个连续、不规则的占据空间压成十几个参数下游想恢复细节信息已经丢了怎么修都有天花板。1.2 闭集类别是长尾事故的漏斗传统3D检测的另一个硬约束是类别闭集。训练之前你会定一个类别表通常是车、人、自行车、摩托车、卡车、锥桶这类有限集合。检测头的分类分支就只能在这些类之间做选择。遇到一个不在类别表里的东西模型没有“垃圾桶”类可以放大概率会直接当成背景忽略。长尾问题在真实路况中非常致命。一辆大车的轮胎掉在路中间、一个被风吹来的铁皮、一块没有标记的施工碎石这些东西在数据集中出现的频率极低但事故风险极高。用检测框范式即使你把这些物体加进类别表它们依然属于小样本标注量不够模型照样学不稳。而且今天加一个“轮胎”明天马路中间出现一个“油桶”类别表会无限膨胀但你的训练数据永远追不上现实的长尾分布。占据网络的思路在这件事上完全不同。它要求模型回答的是“这个体素有没有东西”语义类别只是附加属性。哪怕模型不知道那个东西具体是什么只要判断出“是非地面、非可通行区域”就足以让下游规划避让。几何占据本身是一个开放的能力它不需要你提前枚举所有障碍物种类的关不关注已知物体。1.3 3D框标注的成本和一致性难题3D目标检测对标注的依赖比很多人想象中大得多。2D框只要框出二维范围相对直观3D框要求标注员在稀疏点云或视频画面中确定物体的三维朝向、长宽高还要处理遮挡和截断。一个被树挡了一半的行人不同标注员给出的框可能相差很大一辆半挂车车头和挂车之间是断开的有的标注员标成一个框有的标成两个跨帧标签很难保持一致。这种不一致会直接体现训出来的模型上。模型不是学不会检测而是学到的框边界是“平均噪声”的结果。你以为模型输出的长宽高是对真实物体的估计其实它是对一锅标注偏差取中间值。想彻底解决就得引入复杂的质检、仲裁、多次重标成本直线上升。相比之下占据网络的标签有更强的物理一致性。你可以从激光雷达点云、多帧融合、语义分割结果自动生成占据标签人工只需要抽检修正。这并不代表标注完全免费但它把大量标注工作从“人肉画框”变成了“算法生成人工审核”边际成本低很多。2. 占据网络到底在做什么2.1 核心定义把三维空间切成人人能听懂的小格子占据网络的基本思路并不复杂。它把自车周围的三维空间划成一个个小立方体也就是体素然后对每个体素做分类这个位置是空闲的、被占据的还是没有被观测到的未知区域。如果被占据再进一步判断它属于哪一类语义比如地面、车辆、行人、锥桶、树木、建筑物或者干脆就是“通用障碍物”。你可以把它理解成“三维版语义分割”。2D语义分割是对图像每个像素做分类占据网络是对空间每个体素做分类。不同之处在于它多了一个“未知”状态也就是告诉下游“这里我也没有看清别把这里当成一定可通行”。这一点对规划非常友好因为它把不确定性也带进了场景表达。当然输出不一定是硬分类。实际工程里更多是输出每个体素被占据的概率、语义类别分布以及一个“观测置信度”。规划模块拿到这些概率可以算碰撞风险和可通行区域而不是只能看到一堆互相重叠的框。2.2 输入可以是纯视觉也可以是多传感器融合占据网络不是某个特定传感器方案的专属。纯视觉方案里模型从多个相机图像提取特征再把2D特征提升到三维空间通过类似三维空间查询的方式生成体素特征。由于图像天然带有语义信息这类方案对颜色、纹理、路牌、车道线这类“视觉特征明确”的物体比较敏感但深度估计弱晚上、逆光、雨雾天气会吃力。激光雷达方案则直接以点云作为输入几何信息非常精确。点云可以转化成稀疏体素再通过稀疏卷积或局部注意力来提取特征输出占用结果。因为激光雷达测距准确这类方案对几何边界更稳但对远处小物体的召回会受点云稀疏程度限制。真正稳定的是融合方案。相机提供语义激光雷达提供几何两者在同一个三维体素空间里对齐让占据网络在近距离细边界和远距离类别判断上都能受益。融合的代价是标定、时间同步和特征对齐的工作量更大但一旦跑通稳定性通常比单传感器好一个量级。选哪一种要看你的硬件平台和算力预算而不是只看谁更“新”。2.3 占据不是感知终点而是一个中间表达很多人问输出一堆体素之后到底怎么用的答案是占据张量本身就是下游规划可以直接消费的“代价地图”。传统管线里3D检测框输出后通常要做一步“框转栅格”把每个框膨胀成一个带安全距离的障碍区再叠加到局部地图上。这个膨胀半径是手调的框大一点小一点都会影响结果。占据网络天然就是体素表达你可以直接把占据概率作为代价函数的一环规划器在评估一条轨迹时对路径穿过的体素做积分碰撞风险一目了然。同时有语义信息后还能做规则约束。比如“行人语义”可以要求更宽的绕行距离“地面语义”可以引导可行驶区域“车辆语义”可以进入预测模块做行为判断。占据网络把感知输出的格式统一了省掉了大量“框转栅格”“框转障碍物”的胶水代码。3. 为什么说它正在取代传统3D目标检测3.1 从“物体假设”走向“空间假设”传统检测器有一个隐藏前提世界是由可枚举的物体构成的。检测器要做的是在图像或点云里找到这些物体再把它们框出来。可现实道路不是这样组织的。它处处是连续的地形、遮蔽的视野、不确定的边界很多障碍物不具备“一个完整物体”的形态。占据网络的底层假设是世界是由占据空间和自由空间组成的。我不需要先判断“那是什么物体”我只要判断“那个格子能不能走”。这个假设更接近移动机器人避障的真实需求。对低速园区车来说路边灌木丛、突出树干、临时堆放的物料它不需要分清具体类别只需要不让车撞上去。“能否通行”是下游真正关心的问题占据网络直接面向这个问题建模。3.2 对长尾和未知障碍更鲁棒前面讲过类别表是检测器的瓶颈。占据网络通过“通用障碍物”或“未知占据”这种类别把长尾问题消解掉了。它不需要每个障碍物都分得那么细只需要知道“这里不安全”至于它是掉落的轮胎还是倒下的路牌对一层避障逻辑来说并不重要。实际项目里我把这一点看得比模型结构更重。路上最常见的风险不是一辆逆行车辆而是各种高度不高、形状奇怪、不在类别表里的东西。传统检测对这些目标基本无能为力因为分类器没有见过它们而占据网络只要在训练数据里有“各种物体占据空间”的样本就能学到通用的“几何障碍”概念。这种泛化能力不是调参调出来的是换了一种预测目标之后天然带来的。3.3 几何边界更细语义和几何解耦3D检测框对边界的描述太粗占据网络则能做到体素级别的边界判断。比如路沿高出来15厘米传统检测不会把它当目标但占据网络可以在贴近路沿的体素上连续输出“非地面”。在泊车、窄路通行、园区低速场景里这种细腻度对通过性判断很重要。同时语义和几何是解耦的。一个体素可以先被判断为“占据”再被判断为“是车”。即使语义分支犯了错几何占据仍然能拦住规划器。而传统检测框架里如果分类器把行人漏成背景这个目标就直接消失了没有任何兜底。这个“几何兜底”特性是很多车规团队愿意迁到占据网络的核心原因。3.4 更方便做时序和端到端占据输出是一个规则的空间张量天然适合做时序融合。你可以把上一帧的占据结果做坐标变换和累积再和当前帧的预测融合得到一个时间上更稳定的局部占用地图。检测框的时序通常要靠目标跟踪、匈牙利匹配、卡尔曼滤波这一整套流程中间任何一环出错轨迹就断了。端到端方面占据张量还可以往预测方向扩展。很多团队已经在做“未来占据预测”输入历史多帧观测输出未来1秒或3秒每个体素会不会被占据。这种表达往下游规划传递时可以直接评估一条轨迹在未来时刻的碰撞风险比“先检测再预测轨迹”的传统级联结构简单得多。它也天然可微可以让规划损失反传到感知网络做真正的端到端训练。下面用一张表快速对比两类方案的核心差异维度传统3D目标检测占据网络输出表达稀疏框类别稠密体素语义长尾障碍弱依赖类别表强支持通用占据几何精度框级边界粗体素级边界细下游对接需要框转栅格张量可直接即代价地图时序融合依赖跟踪后处理可做空间张量累积计算开销相对低明显更高标注成本人工画框一致性难可基于点云自动生成4. 落地实操数据、模型、训练与部署4.1 占据标签到底怎么来训练占据网络最现实的问题是标签。体素数量动辄几十万不可能让人去逐个标。目前常见的做法是“传感器数据驱动的自动标注”。最基本的一条路线是用激光雷达点云做多帧拼接把同一目标的多次扫描叠到一起得到更密的点云。然后从传感器原点出发对每个激光点做射线投射。射线穿过的体素如果没有命中点就标记为“空闲”射线终点处有点标记为“占据”完全没有射线覆盖的区域标记为“未知”。这样生成的标签天然包含观测不确定性比人工画框更物理合理。语义部分可以借助已有的2D或3D语义分割模型给点云打类别再把点级标签映射到体素上。这样得到的语义标签会有一点噪声尤其是远处和遮挡区域。我在实际项目里看到很多团队对标签噪声非常焦虑但占据网络对“局部语义噪声”并没有那么敏感它更看重几何占据的准确性。语义错几个体素通常不如“占用和空闲搞反了”影响大。标签生成时还有一个细节地面、路面、车道线这类“可行驶但被占用的表面”怎么处理。如果是纯避障地面可以统一作为“可通行”如果要做车道保持和路径引导就需要把地面单独分出来作为一类语义。类别集合怎么定不完全取决于模型而取决于下游规划需要哪些信息。4.2 体素范围和大小怎么定占据网络落地第一件事不是选模型而是定“空间范围”和“体素大小”。这两个参数直接决定张量尺寸、计算量和精度。假设你的感知范围是前向左右各51.2米纵向-2米到5米如果用0.4米×0.4米×0.8米的体素那么空间网格大约是256×256×9约59万个体素。如果只看被占据和未知体素这个量级用稀疏卷积可以跑如果用稠密3D卷积处理显存会很难受。把体素改成0.2米×0.2米×0.2米网格直接变成上千万量级绝大多数车载平台根本扛不住。实际项目里我不会对全空间用同一个分辨率。常用做法是靠近自车的区域用细体素比如0.2米或0.25米保证近距离精细建图中远距离用0.4米到0.8米的粗体素保证召回范围更远处甚至只预测“有没有危险物体”而不做精细语义。这种变分辨率方案比硬套一个立方体网格要实用得多。还要注意纵向范围。大部分物体都在路面以上把Z轴范围定太大会浪费大量体算定太小又会漏掉行人上半身、公交车等高度较高的目标。我见过不少项目组把Z轴拉到6米结果大量体素在无人关心的天空区域里参与计算。比较好的做法是先从当地交通参与者的高度分布确定一个合理上限再留出一些余量。4.3 常见的模型结构与损失设计模型方面我自己搭过一条比较稳的基线可以给新手参考一个通用的2D图像主干提取多视角特征把特征映射到目标三维体素空间再经过几层3D卷积或稀疏卷积解码最后对每个体素输出“空闲/占据/未知”三分类以及多个语义类别的概率分布。几何和语义分开建模这个设计很重要。有些实现喜欢让一个分类头直接输出“地面/车辆/行人/建筑/背景”把“空闲”也作为一个类别混进去。这样做不是不行但类别不平衡很容易把“空闲”堆到压倒性比例导致模型对几何边界不敏感。我更倾向于把几何占据当成第一优先语义作为第二个分支两者的损失分开加权。这样就算语义分支不稳定几何分支仍然能兜住安全底线。损失设计上除了常规的交叉熵我会加上边界感知的权重。激光雷达点云可以提供物体表面位置把靠近表面的体素单独强调出来让模型更在意“边界体素”而不是那些内部已经被判定为占据的体素。这样做会让最终占据结果的轮廓更干净而不是一整片模糊的膨胀区域。训练里还有一个绕不开的问题类别不均衡。空闲体素占了绝大多数占据体素很少。如果直接算平均交叉熵模型会很聪明地把几乎全部空间预测成空闲因为这样损失数字很好看。解决办法包括使用加权交叉熵、Focal Loss、困难样本挖掘或者在每个训练batch里对空闲、占据、未知做均衡采样。这些技术不神秘但非常影响实际效果。4.4 部署时要注意的坑占据网络在推理阶段的输出是三维张量直接交给规划器前通常要做一个“降维投影”或“膨胀处理”。一种常用做法是把三维占据结果按高度层投影到地面2D网格生成二维代价地图。但直接做最大池化投影会把高处物体也投射到地面导致上方过街天桥这类目标造成误刹车。正确做法是分高度带处理与车头高度相关的高度层突出显示高处的天桥、标志牌单独处理或直接忽略。这个细节我在不止一个项目里见过翻车模型明明检测到了天桥车却在天桥下面刹停了。部署效率方面建议优先考虑支持稀疏卷积的推理框架。稠密3D卷积的并行效率在GPU上并不差但显存占用很容易成为瓶颈若目标平台是嵌入式设备需要对体素做稀疏化并尽量把Z轴方向的计算压缩到最少。把模型量化到FP16或INT8之前一定要重点评估近处边界体素的变化因为量化最容易损失的恰恰是这种高频细节。5. 常见问题与排查技巧5.1 模型预测的“未知区域”全是空闲现象是车前方一片没有点云信息的区域模型直接给成了可通行这让规划器毫无防备。原因通常是训练时把“未知”类别权重设得过低或者自动标注里射线未覆盖区域被粗暴标成了空闲。排查方向很明确先检查标签生成逻辑确认“没被观测到”和“确实空闲”是两种状态。标签如果混了再怎么调损失都白搭。我在项目里会把未知类别的初始权重调得比空闲高一点模型在不确定时会更倾向输出“我不知道”而不是自信地告诉你“可以走”。5.2 体素边界模糊轮廓像磨了皮占据结果看起来所有物体都是一坨糊状边界像沙画问题一般出在三个方面体素尺寸太大、损失函数里没有边界加权、或者是3D卷积解码层数太多把空间细节磨平了。排查时先看一眼可视化把预测结果叠加到原始点云上如果物体轮廓明显比点云粗一圈多半是体素分辨率不够。如果轮廓内部也出现大量空洞就要检查标签生成时的“占据”标准是否太严导致只有少数点命中的表面被判为空闲。边界问题我最推荐加一个“表面体素加权”的损失项效果往往立竿见影。5.3 远处目标被抹平50米外的一个小锥桶在0.8米体素里可能只落在一两个体素中特征太弱很容易被周围空闲体素淹没。解决思路有两个一是变分辨率让中远距离也保持一个基础体素密度二是允许模型在远处输出较低置信度的占据不要为了图干净就把远处全部压成空闲。另外时序融合对远处小目标非常有帮助。单帧一个体素的信噪比太低但连续几帧都在同一位置出现微弱占据信号累积起来就足够可靠了。很多项目一开始只做单帧预测效果不理想加上3到5帧的占据累积之后远处召回明显提升。5.4 占据结果在连续帧里来回跳单帧预测的噪声比较大再加上自车运动估计有误差同一面墙前一秒在x位置下一秒可能偏移了一两个体素。这个现象在视觉方案里更明显。我的建议是保留一个较低成本的“占据栅格累积器”。每一帧预测结果先经过坐标变换到自车坐标系再和一个历史栅格做加权融合历史权重随时间指数衰减。这本质上就是传统栅格地图里的占用更新但输入从单线雷达换成了神经网络预测。累积器不一定要很复杂但对稳定性提升非常明显而且完全不影响端到端训练的可行性。5.5 显存不够时怎么办这个问题几乎是必踩的。占据网络对运行时显存的要求比普通检测高不少解决办法依次是缩小Z轴范围、扩大体素尺寸、换稀疏卷积、固定图像输入分辨率、关闭不需要的多尺度特征。不要一上来就压缩输入图像分辨率那样会直接损害远距离召回。优先把空间表达里的无效计算砍掉收益最大。6. 关于落地的最后一点个人取舍如果只让我留一条经验我会说不要把占据网络当成一个“更大的检测头”要把它当成场景表达的升级。先想清楚下游规划到底需要什么再决定体素粒度、类别集合和未知语义的处理方式。很多团队纠结“用哪个模型结构”结果发现数据标签、空间范围设计和部署推理才是真正拉开差距的地方。传统的3D框不会一夜之间消失但我确实看到越来越多项目把它退化成占据网络输出之后的一个附属属性——在需要目标ID、轨迹预测和意图理解的地方再用它其余空间理解的任务全部交给占据表达。这个变化不是赶潮流而是因为自动驾驶和机器人真正需要回答的问题从来不是“这里有几个框”而是“这里到底能不能走”。
阅读完成 · 觉得有帮助?