DL0124 3D Occupancy Flow

What is 3D Occupancy Flow? What is the tradeoff for predicting dense spatiotemporal occupancy grids instead of discrete 3D bounding-box trajectories?

Answer

3D Occupancy Flow is a joint perception-and-forecasting output format that replaces the list of tracked objects with a dense grid: for every voxel (or BEV cell) and every future waypoint the network predicts an occupancy probability plus a flow vector describing how the mass in that cell moves. Waymo’s Occupancy Flow Fields formulation predicts three quantities per waypoint on a 256 \times 256 BEV grid covering roughly 80\ \text{m} \times 80\ \text{m}: observed occupancy, occluded occupancy, and backward flow. Camera-only 3D variants such as Occ3D on nuScenes predict a 200 \times 200 \times 16 voxel grid at 0.4\ \text{m} resolution, and Tesla presented an occupancy network with an occupancy-flow head at its 2022 AI Day. The appeal is that free space and obstacle geometry become class-agnostic and non-parametric: a tipped-over mattress, an articulated trailer, a swinging crane boom, and an overhanging branch all get represented without appearing in a detector taxonomy, and probability mass can sit on both branches of a fork at once without a mode head or non-maximum suppression. The cost is that a grid has no notion of an object, so instance identity, track continuity, and per-agent attributes disappear, and the output tensor grows by roughly two orders of magnitude, which pushes cost onto compute, memory, label pipelines, and the loss function’s handling of a grid where the overwhelming majority of voxels are empty. In practice this is why most production stacks run occupancy flow alongside a box pipeline rather than as a drop-in replacement.

(1) Dense Spatiotemporal Output: the head emits o_t(v) and f_t(v) for every cell and every future timestep, not a parametric box with a heading and a velocity per agent.
(2) Class-Agnostic Geometry: anything that occupies space is representable, which removes the long-tail detection failure where an unlisted object class becomes invisible to the planner.
(3) Backward Flow, Not Forward: predicting motion from t back to t-1 makes warping a gather with one source per cell, so mass never collides during the warp and a flow-grounded occupancy consistency check becomes well defined.
(4) Non-Parametric Multimodality: a grid holds several futures simultaneously as spread probability mass, but that same property makes averaged modes look like blur or ghost occupancy rather than a ranked set of hypotheses.
(5) Identity Is What You Give Up: without instance IDs, right-of-way logic, interaction-aware conditioning, and per-object intent signals such as turn indicators lose their handle on the scene.
(6) Cost Scales With The Grid: output size grows as H W D T, dense labels require multi-sweep LiDAR accumulation and voxelization, and roughly 95% or more of voxels are empty, so class imbalance dominates the occupancy loss.

Diagram contrasting two forecasting pipelines from the same sensor input: an object-centric branch running detector, tracker, and trajectory predictor to emit sparse box waypoints, and an occupancy-centric branch running a BEV or voxel encoder with occupancy and backward-flow heads to emit a dense spatiotemporal grid

Figure 1: The object-centric branch (detect → track → forecast) produces a sparse, identity-carrying output limited by its taxonomy; the occupancy branch skips detection and data association entirely and produces a dense, class-agnostic grid with no instance IDs.

The deeper tradeoff is not really compute, it is what the downstream planner can express. A box trajectory is a commitment: this vehicle, with this ID, will be here in 3 seconds with this probability, which lets a planner reason about yielding to a specific agent, replay a scenario in simulation, and produce an auditable explanation for a maneuver. Occupancy flow is a statement about space, which is exactly what collision checking and drivable-free-space queries want, but a grid that hedges between “the cyclist goes straight” and “the cyclist turns” paints both corridors at moderate probability, and a naive cost function that treats any occupancy above a threshold as blocked yields the freezing-robot behavior. Occupancy flow partially recovers correspondence without identity: warping the previous occupancy along the predicted backward flow and multiplying it against the current occupancy gives a differentiable consistency term, so the model is penalized for teleporting mass even though it never names an object.

Mathematical Formulation:
0 \leq o_t(v) \leq 1
\hat{o}_t = o_t \odot \mathcal{W}(o_{t-1}, f_t)
\mathcal{L} = \mathcal{L}_{occ} + \lambda \mathcal{L}_{flow}
\mathcal{L}_{occ} = \sum_{t=1}^{T} \sum_{v} \mathrm{BCE}(o_t(v), y_t(v))
\mathcal{L}_{flow} = \sum_{t=1}^{T} \sum_{v \in \Omega_t} \lVert f_t(v) - f_t^{*}(v) \rVert_1
N_{occ} = 200 \cdot 200 \cdot 16 \cdot 8 = 5.12 \times 10^{6}
N_{box} = 50 \cdot 6 \cdot 16 \cdot 5 = 2.40 \times 10^{4}

Where:

  • o_t(v) is the predicted occupancy probability of cell v at future waypoint t, and f_t(v) is the backward flow vector pointing to where that mass sat at t-1.
  • \mathcal{W} is the warp operator that gathers o_{t-1} along f_t (bilinear or trilinear), and \hat{o}_t is the flow-grounded occupancy used both as a loss term and as an evaluation metric.
  • y_t(v) is the voxelized ground-truth occupancy label, f_t^{*} the ground-truth flow, and \Omega_t the set of genuinely occupied cells to which the flow loss is masked.
  • t \in \{1, \ldots, T\} indexes waypoints and v indexes the H \times W \times D grid; \lambda balances the two terms, and \mathrm{BCE} is usually replaced by a focal or class-balanced variant because empty voxels dominate.
  • N_{occ} counts predicted occupancy values for a 200 \times 200 \times 16 grid over 8 waypoints, and N_{box} counts a comparable box head with 50 agents, 6 modes, 16 waypoints, and 5 numbers per waypoint.
  • Required initial condition: o_0 and the whole grid must be expressed in the ego frame at t = 0, so ego motion is compensated before flow is interpreted as agent motion.
Grid diagram showing occupancy at time t minus one in light dashed cells and predicted occupancy at time t in solid cells, with backward flow arrows drawn from each occupied cell at time t to the cell its mass came from, alongside the flow-grounded occupancy product equation

Figure 2: Backward flow assigns each occupied cell at time t a single source cell at t-1, so the warp is a gather rather than a scatter and the consistency product o_t \odot \mathcal{W}(o_{t-1}, f_t) penalizes mass that appears without a plausible origin.

Resolution and horizon are the two knobs that make or break the design. Halving the voxel size multiplies the tensor by 8 in 3D, and every additional waypoint is another full grid, so a 0.2\ \text{m} grid over a 5-second horizon at 2\ \text{Hz} is far beyond a real vehicle compute budget once flow channels and semantics are added. Going the other way is not free either: at 0.4\ \text{m} voxels a pedestrian walking at 1.4\ \text{m/s} moves less than one voxel per 0.2\ \text{s} frame, so the flow target is sub-voxel and the occupancy channel alone cannot express the motion, which is precisely why the flow head is kept as a continuous regression rather than a discrete cell-to-cell assignment.

Log-scale bar chart of predicted output size per inference: 24000 numbers for multi-modal box trajectories, 524288 for a 256 by 256 BEV occupancy grid over 8 waypoints, 5.12 million for a 200 by 200 by 16 voxel grid over 8 waypoints, and 20.48 million once three flow channels are added

Figure 3: Output size is where the tradeoff becomes concrete: the 3D voxel grid predicts about 213x more numbers than a multi-modal box head, and adding a 3-channel flow field multiplies that by another 4 before any semantic classes are included.

Property3D occupancy flowBox trajectoriesHybrid stack
Output per inferenceMillions of per-cell values, occupancy plus flow per waypointTens of thousands of numbers, a few modes per tracked agentBoth, sharing one BEV or voxel backbone
Unlisted geometryRepresented, since occupancy is class-agnosticDropped if no detector class fits itCovered by the occupancy branch
Instance identityNone; only flow-based correspondenceExplicit IDs, attributes, and track historyIDs from the box branch, geometry from the grid
MultimodalityImplicit in the probability field, no mode count to tuneExplicit ranked modes with confidencesExplicit modes for interaction, field for collision checks
SupervisionAccumulated multi-sweep LiDAR voxelized into dense labelsHuman box and track annotations onlyBoth label pipelines must be maintained
Typical failure modeBlurred or ghost occupancy that makes the planner over-conservativeMissed detection or ID switch removes an obstacle entirelyDisagreement between branches needs an arbitration policy

Login to view more content


Log in to track your progress

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *