第8章

第8章:占据网络 (Occupancy Network)

从多视图图像预测 3D 语义占据,涵盖稠密/稀疏占据、时序融合、3D Gaussian Splatting 与 NeRF。

Occupancy Network3D 体素化时序占据融合NeRF3D Gaussian Splatting

从 3D 框到体素占据 -- 通用的 3D 场景理解


前言

传统的 3D 检测用规则边界框(Bounding Box)表示物体,但现实世界充满了不规则形状的物体和通用障碍物。特斯拉在 2022 AI Day 上提出的 Occupancy Network 通过预测 3D 体素网格的占据状态和语义类别,实现了真正的通用场景理解。

学完本章你将获得:

- Occupancy Network 的完整设计理念

- BEV 特征到 3D 体素的维度扩展技术

- 时序占据融合的实现方法

- 3D Gaussian Splatting 在 Occupancy 中的前沿应用

- 一套完整可运行的占据预测代码


第一部分:为什么要 Occupancy Network?

1.1 3D 检测的局限性

问题 具体表现
形状假设 3D 框假设物体是长方体,无法表示弯曲的道路、不规则障碍物
通用物体 无法表示"非标准"物体:散落货物、施工路障、倒下的树
遮挡推理 被遮挡区域的信息丢失,无法预测"后面有什么"
细粒度 框级粒度太粗,无法用于精细的路径规划(如狭窄空间穿行)

1.2 Occupancy 的解决方案

将世界建模为 3D 体素网格,每个体素预测:

- 是否占据 (occupied / free)

- 语义类别 (car, pedestrian, road, building, vegetation, ...)

- 可选运动状态 (static / moving)


第二部分:体素表示

2.1 体素空间定义


X 范围: [-50m, 50m]  (前后方向)
Y 范围: [-50m, 50m]  (左右方向)
Z 范围: [-5m, 3m]    (高度方向)

体素大小: 0.5m
→ 体素维度: 200 × 200 × 16 = 640,000 个体素

2.2 语义类别

典型 Occupancy 类别(17 类):


car, truck, bus, trailer, construction_vehicle,
pedestrian, motorcycle, bicycle,
traffic_cone, barrier,
driveable_surface, sidewalk, terrain, manmade,
vegetation, building, free_space

2.3 数据格式

每个体素的 label 是一个整数 (0-16),其中 0 通常表示 free_space(空)。

Ground truth 生成方法:

1. LiDAR 点云聚合 → 体素占据真值

2. 3D 框内外点分类 → 语义标签

3. NeRF/NeuS 重建 → 稠密 Occupancy ground truth


第三部分:Occupancy Network 架构

3.1 整体流程


多相机图像 → Image Backbone → BEV Features
→ BEV to 3D 维度扩展 → 3D 体素特征
→ 3D CNN / Transformer → 逐体素分类

3.2 BEV → 3D 维度扩展

这是从 2D BEV 到 3D 体素的关键步骤:


# BEV features: (B, D_bev, H_bev, W_bev)
# 目标: (B, D_occ, D_z, H_bev, W_bev)

bev_to_3d = nn.Linear(D_bev, D_z * D_occ)
h = bev_to_3d(bev_features.permute(0, 2, 3, 1))
h = h.reshape(B, H_bev, W_bev, D_z, D_occ)
h = h.permute(0, 4, 3, 1, 2)  # → (B, D_occ, D_z, H_bev, W_bev)

3.3 3D 卷积处理

BEV → 3D 后的特征通过 3D 卷积进一步处理:


occ_conv = nn.Sequential(
    nn.Conv3d(hidden_dim, hidden_dim, 3, padding=1),
    nn.BatchNorm3d(hidden_dim), nn.ReLU(),
    nn.Conv3d(hidden_dim, num_classes, 1),
)

3.4 输出与 Loss

输出:每个体素的类别 logits → softmax 得到概率。

Loss 设计:

- 主 Loss: Cross-Entropy(所有体素)

- 辅助 Loss: Focal Loss(类别不平衡)、Lovasz-Softmax(IoU 优化)


第四部分:时序占据融合

4.1 动机

单帧 Occupancy 在以下场景容易失败:

- 物体被严重遮挡时

- 远处的体素(信息稀疏)

- 快速移动物体

时序融合通过整合多帧信息增强预测。

4.2 融合方法


历史帧 Occupancy → 自车运动补偿对齐 → 与当前帧融合

方法1(简单):直接拼接+3D卷积
方法2(精细):可学习的时序注意力
方法3(高效):只融合前1-4帧

自车运动补偿:


# 将 t-1 时刻的体素变换到 t 时刻的坐标系
T_warp = T_ego_t @ T_ego_t_minus_1.inverse()
occ_warped = spatial_transform(occ_history, T_warp)
occ_fused = fuse(occ_current, occ_warped)

第五部分:3D Gaussian Splatting 与 Occupancy

5.1 什么是 3D Gaussian Splatting?

3D Gaussian Splatting (3DGS) 是一种新兴的场景表示方法,用一组 3D 高斯椭球体表示场景,可以快速可微分渲染。

每个高斯球体由以下参数定义:

- 均值 μ (位置)

- 协方差 Σ (形状 + 朝向)

- 颜色 c (SH 系数)

- 透明度 α

5.2 3DGS 在 Occupancy 中的应用

1. 作为 Occupancy 的连续替代:3DGS 比离散体素有更高的分辨率

2. 新视角合成:从 Occupancy 中提取高斯来渲染任意视角

3. 自监督训练:渲染图像与原图对比做自监督

5.3 从 Occupancy 到 Gaussian


Occupancy Voxel → 每个占据体素 → 初始化为一个 Gaussian
→ Gaussian 参数可学习/可优化
→ 渲染:Splatting (投影到图像 + α-blending)
→ Loss: 渲染图像 vs 真实图像 (Photometric Loss)

常见问题

Q: Occupancy Network 的计算量有多大?

标准设置 (200x200x16, 0.5m) 的 Occupancy 计算量约为 3D 检测的 3-5x。实际部署时通常使用稀疏卷积或下采样加速。

Q: 如何获取 Occupancy 的 ground truth?

- LiDAR 点云聚合 + 3D 框标签:最常用

- 4D 标注(Occ3D/nuScenes):带有语义标签的稠密占据

- 自监督(NeRF/3DGS 重建):无需标注

Q: 体素分辨率和类别数的权衡?

- 粗分辨率 (1m) + 多类别:适合场景级理解

- 细分辨率 (0.25m) + 少类别:适合精细避障

- 工业界趋势:0.5m + 17 类

Q: Occupancy 和 NeRF 的关系?

NeRF 用 MLP 隐式表示场景,Occupancy 用显式体素。两者可以结合:从 Occupancy 预测中提取 Nerf-like 的密度,用于新视角合成验证。


下一步

完成本章后,建议:

1. 运行 Occupancy Network 演示,理解输出格式

2. 尝试不同的体素分辨率

3. 研究 3DGS 渲染的可视化效果

4. 进入第9章:端到端多任务感知


本章项目地址: vla_learn/chapter08_occupancy_network/
预计学习时间: 2-3 天(含代码和概念理解)