Paper · 2022-03-31 · cs.CV
BEVFormer: Learning Bird's-Eye-View Representation from Multi-Camera Images via Spatiotemporal Transformers
BEVFormer turns six surround-camera images into one bird's-eye-view (BEV) grid using learnable grid queries. Spatial cross-attention samples image features at projected 3D pillar points; temporal self-attention fuses the ego-aligned previous BEV. Author-reported: 56.9 NDS on nuScenes test (V2-99 backbone with extra pre-training), 51.7 NDS on val (ResNet-101).
Bird's-eye-view (BEV) representationBird's-eye-view perceptionObject detectionAttention mechanismautonomous-driving3d-object-detectionbevmulti-cameratemporal-fusion
arXivPDFCodeMarkdown13 min read
AI-compiled by claude-haiku-5-5 on 2026-10-19, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
A self-driving car has several cameras around it. Older camera-only systems handle each camera's picture on its own and then try to join the detections together afterwards, which works poorly. BEVFormer instead builds one map of the area around the car, seen from above. Each cell of that map is a spot on the road, and it looks up the camera pictures where that spot could appear.
The map is also carried over from one moment to the next. The previous map is moved to match how the car has moved, and it is blended with the current one. That helps with things a single photo shows poorly, such as how fast something is moving and whether an object is partly hidden.
The finished map can feed a 3D object detector or a model that labels the road (drivable area, lanes). The authors report better results than earlier camera-only methods on the nuScenes driving dataset, and results close to some laser-based (LiDAR) systems. Those numbers are the authors' own.
TL;DR
- Input: six surround cameras of nuScenes, plus the previous BEV map §4.1 §3.1.
- A 6-layer transformer encoder turns learnable grid queries (200 × 200) into a BEV map §3.1 §4.2.
- Spatial cross-attention reads camera features where each cell's 3D points project; temporal self-attention reads the previous map §3.3 §3.4.
- Author-reported 56.9 NDS on nuScenes test with a VoVNet-99 backbone that was pre-trained on extra depth data; 51.7 NDS on val with ResNet-101 tab. 1 tab. 2.
- Code is public (Apache-2.0) and matches the paper in most settings; see Paper vs code for the exceptions.
Problem
3D perception for driving needs 3D boxes or a semantic map from several cameras §1. Processing each camera alone and merging afterwards leaves information between cameras unused and hurts accuracy and efficiency §1 §2. A bird's-eye-view (BEV) grid is a common shared representation, but BEV methods that lift image features with predicted depth are sensitive to depth errors, and BEV methods have not clearly beaten other paradigms on 3D detection §1. Stacking BEV features from several past timestamps adds computation and can bring in disturbing information §2 §3.4.
Velocity is also hard to estimate from camera-only detectors without temporal information §4.3.
Method
BEVFormer keeps a fixed set of learnable BEV queries, one per grid cell, and updates them through six encoder layers §3.1 §3.2. The grid is centred on the ego car. Each layer has three parts: temporal self-attention over the current queries and the previous BEV, spatial cross-attention over the multi-camera features, and a feed-forward network §3.1. The previous BEV is passed unchanged to every layer §4.2. The output BEV map feeds a 3D detection head, or a map segmentation head for vehicles, road (drivable area) and lane §3.1 §3.5.
Grid and reference points. A query at grid position (x, y) covers a cell of side s metres. Its real-world coordinates are given by equation 3, with the ego car at the centre §3.2 eq. 3. For spatial attention, the query is lifted to a pillar: N_ref = 4 heights are placed above the cell, and each 3D point is projected into every camera with that camera's matrix T_i §3.3 eq. 4.
x' = (x - \tfrac{W}{2}) \times s; \quad y' = (y - \tfrac{H}{2}) \times s eq. 3
\mathcal{P}(p,i,j) = (x_{ij}, y_{ij}), \; z_{ij}[x_{ij}, y_{ij}, 1]^T = T_i [x', y', z'_j, 1]^T eq. 4
Spatial cross-attention. A query only reads the cameras in which at least one of its projected points lands. It samples image features around each such point with deformable attention, then averages over the views that were hit §3.3 eq. 2. Deformable attention on 2D features is given by equation 1 §2 eq. 1.
\text{DeformAttn}(q, p, x) = \sum_{i=1}^{N_\text{head}} \mathcal{W}_i \sum_{j=1}^{N_\text{key}} \mathcal{A}_{ij} \cdot \mathcal{W}'_i x(p + \Delta p_{ij}) eq. 1
\text{SCA}(Q_p, F_t) = \frac{1}{|\mathcal{V}_\text{hit}|} \sum_{i \in \mathcal{V}_\text{hit}} \sum_{j=1}^{N_\text{ref}} \text{DeformAttn}(Q_p, \mathcal{P}(p,i,j), F_t^i) eq. 2
Temporal self-attention. The previous BEV B'{t-1} is first aligned to the current grid using ego-motion §3.4. Then each query attends to the set {Q, B'{t-1}} with deformable attention, and the sampling offsets are predicted from the concatenation of Q and B'_{t-1} §3.4 eq. 5. For the first frame of a sequence, the history is replaced by a copy of the current queries, which makes this layer ordinary self-attention §3.4.
\text{TSA}(Q_p, \{Q, B'_{t-1}\}) = \sum_{V \in \{Q, B'_{t-1}\}} \text{DeformAttn}(Q_p, p, V) eq. 5
Pseudocode. Written from §3.1 and the equations above. The paper gives no algorithm box, so the layout is ours. Details the code adds are in Paper vs code.
# BEVFormer encoder, one timestamp t [§3.1]
# Input: images (6, H, W, 3); prev_bev (H_bev * W_bev, C) or None
# Output: bev (H_bev * W_bev, C)
def bevformer_encode(images, prev_bev, ego_shift, ego_yaw_delta):
# Per-camera multi-scale features with C = 256 [§4.2]
features = fpn(backbone(images))
# Learnable grid queries plus learnable positional embedding [§3.2]
queries = bev_queries + bev_positional_embedding
# Move the history into the current ego frame [§3.4]
# [code: projects/mmdet3d_plugin/bevformer/modules/transformer.py#L122-L156]
if prev_bev is not None:
prev_bev = shift_and_rotate(prev_bev, ego_shift, ego_yaw_delta)
for layer in range(6):
# Temporal self-attention on the current and aligned history [§3.4]
queries = temporal_self_attention(queries, prev_bev)
# Spatial cross-attention into the camera features [§3.3]
queries = spatial_cross_attention(queries, features)
# Feed-forward block [§3.1]
queries = feed_forward(queries)
return queries# Spatial cross-attention for one BEV cell p [§3.3] [eq. 2]
# Input: query (C,) at cell p; features per camera
# Output: aggregated query (C,)
def spatial_cross_attention(query, p, features, cameras):
# N_ref heights above the cell; the range is given in Pitfalls [§4.2]
pillar = [(x_p, y_p, z_j) for z_j in anchor_heights]
hits = []
for i, camera in enumerate(cameras):
# Project the 3D points with the camera matrix [eq. 4]
points_2d = project(camera, pillar)
# Keep the view if a point lies in front of and inside the image
if any_point_inside_image(points_2d):
hits.append((i, points_2d))
total = zeros(C)
for view, points_2d in hits:
# Deformable attention around each projected point [eq. 1]
total = total + deform_attn(query, points_2d, features[view])
# Average over the views that were hit [eq. 2]
return total / max(len(hits), 1)Hyperparameters
| Name | Value | Where | Notes |
|---|---|---|---|
| Backbone (default) | ResNet-101-DCN, init from FCOS3D checkpoint | §4.2 | code freezes stage 1 and uses frozen BN bevformer_base.py |
| Backbone (alt.) | VoVNet-99 (V2-99), init from DD3D checkpoint | §4.2 tab. 1 | used for the 56.9 NDS test row; no V2-99 config in the repo |
| Feature levels | 1/16, 1/32, 1/64 | §4.2 | code: 4 FPN outputs from C3 (1/8), see Paper vs code bevformer_base.py |
| Channels C | 256 | §4.2 | code: FFN width 512 bevformer_base.py |
| BEV grid (nuScenes) | 200 × 200 | §4.2 | bevformer_base.py |
| Cell size s | 0.512 m | §4.2 | range ±51.2 m on x and y |
| Encoder layers | 6 | §3.1 §4.2 | bevformer_base.py |
| Reference heights per pillar N_ref | 4 | §4.2 | |
| Anchor height range | uniform from −5 m to 3 m | §4.2 | code uses 4 cell centres: −4.5, −2.17, 0.17, 2.5 m (see Pitfalls) |
| Sampling points per reference point, per head (spatial) | 4 | §4.2 | code: 8 per head and level, split over 4 anchors, so 2 per anchor spatial_cross_attention.py |
| Sampling points (temporal) | not stated | §3.4 | code default 4 per head temporal_self_attention.py |
| Attention heads | not stated | — | code default 8 spatial_cross_attention.py |
| History frames per training sample | 3 (plus the current frame) | §3.6 | code: 3 of the previous 4 dataset indices (see Paper vs code) nuscenes_dataset.py |
| Frame queue length (default) | 4 | app. C tab. 7 | |
| Training epochs | 24 | app. A.1 | |
| Batch size | 1 sample (6 images) per GPU | app. A.1 | number of GPUs not stated |
| Learning rate | 2 × 10⁻⁴ | §4.2 app. A.1 | |
| Backbone LR multiplier | 0.1 | app. A.1 | bevformer_base.py |
| Optimiser | AdamW, weight decay 1 × 10⁻² | app. A.1 | |
| LR schedule | cosine annealing | app. A.1 | code adds linear warmup over 500 iterations and minimum LR ratio 1e-3 bevformer_base.py |
| Gradient clipping | not stated | — | code: max norm 35 bevformer_base.py |
| Object queries | 900; keep the top 300 boxes at inference | app. A.3 | |
| Box parameters | 10: (l, w, h), (x, y, z), (cos θ, sin θ), (v_x, v_y) | app. A.3 | |
| Regression loss | L1 only | §3.5 app. A.3 | code weight 0.25, GIoU weight 0 bevformer_base.py |
| Classification loss | not stated | — | code: focal loss, γ = 2, α = 0.25, weight 2 bevformer_base.py |
| Label matching | not stated | — | code: Hungarian matching with focal cost 2 and L1 cost 0.25 bevformer_base.py |
| Input image shape (latency test) | 900 × 1600 | tab. 6 | |
| Waymo BEV grid | 300 × 220; x ∈ [−35, 75] m, y ∈ [−75, 75] m; s = 0.5 m; ego at (70, 150) | §4.2 | no Waymo BEVFormer config in the repo |
Results
Author-reported. nuScenes: 6 cameras, 10 classes, metric NDS and mAP §4.1. Baselines are as listed in each table. The paper says the 56.9 NDS test result is comparable to LiDAR-based SSN (56.9) and PointPainting (58.1) §4.3 tab. 1.
nuScenes test tab. 1
| Method | Modality | Backbone | NDS ↑ | mAP ↑ | mATE ↓ | mASE ↓ | mAOE ↓ | mAVE ↓ | mAAE ↓ |
|---|---|---|---|---|---|---|---|---|---|
| SSN | L | — | 0.569 | 0.463 | — | — | — | — | — |
| CenterPoint-Voxel | L | — | 0.655 | 0.580 | — | — | — | — | — |
| PointPainting | L&C | — | 0.581 | 0.464 | 0.388 | 0.271 | 0.496 | 0.247 | 0.111 |
| FCOS3D | C | R101 | 0.428 | 0.358 | 0.690 | 0.249 | 0.452 | 1.434 | 0.124 |
| PGD | C | R101 | 0.448 | 0.386 | 0.626 | 0.245 | 0.451 | 1.509 | 0.127 |
| BEVFormer-S | C | R101 | 0.462 | 0.409 | 0.650 | 0.261 | 0.439 | 0.925 | 0.147 |
| BEVFormer | C | R101 | 0.535 | 0.445 | 0.631 | 0.257 | 0.405 | 0.435 | 0.143 |
| DD3D | C | V2-99* | 0.477 | 0.418 | 0.572 | 0.249 | 0.368 | 1.014 | 0.124 |
| DETR3D | C | V2-99* | 0.479 | 0.412 | 0.641 | 0.255 | 0.394 | 0.845 | 0.133 |
| BEVFormer-S | C | V2-99* | 0.495 | 0.435 | 0.589 | 0.254 | 0.402 | 0.842 | 0.131 |
| BEVFormer | C | V2-99* | 0.569 | 0.481 | 0.582 | 0.256 | 0.375 | 0.378 | 0.126 |
* VoVNet-99 was pre-trained on depth estimation with extra data tab. 1 caption.
nuScenes val tab. 2
| Method | Backbone | NDS ↑ | mAP ↑ | mATE ↓ | mASE ↓ | mAOE ↓ | mAVE ↓ | mAAE ↓ |
|---|---|---|---|---|---|---|---|---|
| FCOS3D | R101 | 0.415 | 0.343 | 0.725 | 0.263 | 0.422 | 1.292 | 0.153 |
| PGD | R101 | 0.428 | 0.369 | 0.683 | 0.260 | 0.439 | 1.268 | 0.185 |
| DETR3D | R101 | 0.425 | 0.346 | 0.773 | 0.268 | 0.383 | 0.842 | 0.216 |
| BEVFormer-S | R101 | 0.448 | 0.375 | 0.725 | 0.272 | 0.391 | 0.802 | 0.200 |
| BEVFormer | R101 | 0.517 | 0.416 | 0.673 | 0.274 | 0.372 | 0.394 | 0.198 |
Waymo val, vehicles tab. 3. The first four numeric columns are APH at 3D IoU 0.5 and 0.7 for LEVEL_1 and LEVEL_2; NDS and AP use the nuScenes metrics.
| Method | Modality | IoU 0.5 L1 | IoU 0.5 L2 | IoU 0.7 L1 | IoU 0.7 L2 | NDS† | AP | ATE | ASE | AOE |
|---|---|---|---|---|---|---|---|---|---|---|
| PointPillars | L | 0.866 | 0.801 | 0.638 | 0.557 | 0.685 | 0.838 | 0.143 | 0.132 | 0.070 |
| DETR3D | C | 0.220 | 0.216 | 0.055 | 0.051 | 0.394 | 0.388 | 0.741 | 0.156 | 0.108 |
| BEVFormer | C | 0.280 | 0.241 | 0.061 | 0.052 | 0.426 | 0.440 | 0.679 | 0.157 | 0.101 |
| CaDNN (front camera only) | C | 0.175 | 0.165 | 0.050 | 0.045 | — | — | — | — | — |
| BEVFormer (front camera only) | C | 0.308 | 0.277 | 0.077 | 0.069 | — | — | — | — | — |
† NDS with ATE and AAE set to 1 tab. 3 caption.
Joint detection and segmentation, nuScenes val tab. 4. Segmentation is BEV IoU.
| Method | Det | Seg | NDS ↑ | mAP ↑ | Car | Vehicles | Road | Lane |
|---|---|---|---|---|---|---|---|---|
| Lift-Splat† | ✗ | ✓ | — | — | 32.1 | 32.1 | 72.9 | 20.0 |
| FIERY† | ✗ | ✓ | — | — | — | 38.2 | — | — |
| VPN* | ✓ | ✗ | 0.333 | 0.253 | — | — | — | — |
| VPN* | ✗ | ✓ | — | — | 31.0 | 31.8 | 76.9 | 19.4 |
| VPN* | ✓ | ✓ | 0.334 | 0.257 | 36.6 | 37.3 | 76.0 | 18.0 |
| Lift-Splat* | ✓ | ✗ | 0.397 | 0.348 | — | — | — | — |
| Lift-Splat* | ✗ | ✓ | — | — | 42.1 | 41.7 | 77.7 | 20.0 |
| Lift-Splat* | ✓ | ✓ | 0.410 | 0.344 | 43.0 | 42.8 | 73.9 | 18.3 |
| BEVFormer-S | ✓ | ✗ | 0.448 | 0.375 | — | — | — | — |
| BEVFormer-S | ✗ | ✓ | — | — | 43.1 | 43.2 | 80.7 | 21.3 |
| BEVFormer-S | ✓ | ✓ | 0.453 | 0.380 | 44.3 | 44.4 | 77.6 | 19.8 |
| BEVFormer | ✓ | ✗ | 0.517 | 0.416 | — | — | — | — |
| BEVFormer | ✗ | ✓ | — | — | 44.8 | 44.8 | 80.1 | 25.7 |
| BEVFormer | ✓ | ✓ | 0.520 | 0.412 | 46.8 | 46.7 | 77.5 | 23.9 |
* Same heads, with VPN or Lift-Splat as the BEV encoder. † Results taken from their papers tab. 4 caption.
BEV encoder comparison, nuScenes val tab. 5. Memory is GPU memory during training.
| Method | Attention | NDS ↑ | mAP ↑ | mATE ↓ | mAOE ↓ | Params | FLOPs | Memory |
|---|---|---|---|---|---|---|---|---|
| VPN* | — | 0.334 | 0.252 | 0.926 | 0.598 | 111.2M | 924.5G | ~20G |
| Lift-Splat* | — | 0.397 | 0.348 | 0.784 | 0.537 | 74.0M | 1087.7G | ~20G |
| BEVFormer-S † | Global | 0.404 | 0.325 | 0.837 | 0.442 | 62.1M | 1245.1G | ~36G |
| BEVFormer-S ‡ | Points | 0.423 | 0.351 | 0.753 | 0.442 | 68.1M | 1264.3G | ~20G |
| BEVFormer-S | Local (deformable) | 0.448 | 0.375 | 0.725 | 0.391 | 68.7M | 1303.5G | ~20G |
† Trained with global attention in spatial cross-attention and fp16 weights; single-scale features, 100 × 100 BEV. ‡ Interacts only with reference points, no learned offsets or weights tab. 5 caption.
Latency, nuScenes val tab. 6. Measured on a V100 with ResNet-101-DCN and 900 × 1600 input.
| Config | MS | BEV | Layers | Backbone (ms) | BEVFormer (ms) | Head (ms) | FPS | NDS ↑ | mAP ↑ |
|---|---|---|---|---|---|---|---|---|---|
| Default | ✓ | 200 × 200 | 6 | 391 | 130 | 19 | 1.7 | 0.517 | 0.416 |
| A | ✗ | 200 × 200 | 6 | 387 | 87 | 19 | 1.9 | 0.511 | 0.406 |
| B | ✓ | 100 × 100 | 6 | 391 | 53 | 18 | 2.0 | 0.504 | 0.402 |
| C | ✓ | 200 × 200 | 1 | 391 | 25 | 19 | 2.1 | 0.501 | 0.396 |
| D | ✗ | 100 × 100 | 1 | 387 | 7 | 18 | 2.3 | 0.478 | 0.374 |
Ablations, nuScenes val.
- Frames used in training tab. 7: NDS 0.448 (1), 0.490 (2), 0.510 (3), 0.517 (4), 0.517 (5). Four frames is the default because gains level off from 4 on.
- Design switches tab. 8: NDS 0.510 without ego alignment (A), 0.513 without random frame sampling (R), 0.513 without using the history for offsets and weights (B), 0.517 for the full model.
- Robustness to camera extrinsics noise at level 4 fig. 6, app. B: NDS drops 15.2% for BEVFormer-S, 17.3% for BEVFormer-S (point) and 14.3% for BEVFormer. Training with noisy extrinsics drops BEVFormer by 8.9%, and BEVFormer (global) drops 4.0%. At the harshest noise, BEVFormer-S (global) reaches 38.8 NDS against 38.0 for BEVFormer-S app. B.
- Occlusion §4.5 fig. 3: at 0–40% visibility, BEVFormer's recall beats BEVFormer-S and DETR3D by more than 6.0 points.
- Velocity: mAVE on nuScenes test falls from 0.925 (BEVFormer-S, R101) to 0.435 (BEVFormer, R101) tab. 1.
Paper vs code
Code: fundamentalvision/BEVFormer
at 66b65f3a1f58caf0507cb2a971b9c0e7f842376c. The first author's repository
(zhiqi-li/BEVFormer) only points to it. The paper's abstract links the first
repository. Apache-2.0.
- FPN levels. Paper: 1/16, 1/32, 1/64 §4.2. Code: four FPN outputs from the three ResNet stages, which includes 1/8 bevformer_base.py bevformer_base.py.
- Sampling points in spatial attention. Paper: four sampling points per reference point, per head §4.2. Code: 8 points per head and level, split over the four anchors, which gives 2 per anchor bevformer_base.py spatial_cross_attention.py.
- Temporal combination. Paper eq. 5 sums over {Q, B'} eq. 5. Code averages the two streams temporal_self_attention.py.
- Ego alignment. Paper: align the history by ego-motion §3.4. Code also rotates the previous BEV by the change in yaw about the centre (100, 100) transformer.py and shifts the history reference points by the ego translation encoder.py. A comment in the code calls that shift a bug kept to reproduce the paper's numbers.
- History sampling in training. Paper: three extra samples from the past 2 s §3.6. Code: takes the four previous dataset indices, drops one at random, and keeps the current frame nuscenes_dataset.py. The 2 s window matches only if the index spacing is about 2 s; not checked here.
- Loss and matching. Paper: L1 for boxes only; no classification loss or matching method named §3.5 app. A.3. Code: focal classification loss and Hungarian matching bevformer_base.py.
- Training additions not in the paper. Linear warm-up, minimum LR ratio, gradient clipping at 35, GridMask, photometric distortion, frozen stage 1 and frozen BN bevformer_base.py bevformer_base.py bevformer_base.py bevformer_base.py.
- Small model. The paper's BEVFormer-S is the static variant §4.2.
The repo's
bevformer_small.pyis a different, lighter model: 150 × 150 BEV, three layers, C5 only, queue length 3 bevformer_small.py bevformer_small.py. No config for the paper's BEVFormer-S is listed. - Missing configs. No Waymo BEVFormer config and no V2-99 config in the repo; the paper's Waymo settings and VoVNet-99 numbers cannot be reproduced from it §4.2 tab. 1.
No discrepancies found in the optimiser, learning rate, epochs, batch size, query count or BEV grid size.
Pitfalls
- Test-set number depends on extra pre-training. The 56.9 NDS row uses a VoVNet-99 initialised from a depth-estimation model trained on extra data tab. 1 caption. The ResNet-101 row (53.5 NDS test, 51.7 val) is the like-for-like comparison tab. 1 tab. 2.
- Anchor heights are not the stated range. Paper: uniform from −5 m to 3 m §4.2. Code: four cell centres in that range, −4.5, −2.17, 0.17 and 2.5 m encoder.py encoder.py. Use the code's values to reproduce results.
- Cell index versus centre. Eq. 3 uses x and y with no half-cell offset eq. 3. The code uses cell centres, (i + 0.5) s, so grid positions are offset by half a cell (0.256 m at s = 0.512 m) encoder.py.
- Projection needs fp32. The code forces fp32 and disables TF32 during point sampling encoder.py. Points with depth ≤ 1e-5 are masked out by clamping the divisor encoder.py.
- Rotation units. The code passes
can_bus[-1]to a rotation that works in degrees, and the dataset writes yaw in degrees can_bus.ipynb transformer.py. Check the units if you rebuild the ego data. - Inference is stateful. Frames must run in time order. The history resets when the scene token changes or when
video_test_modeis off bevformer.py. The first frame of each scene has zeroed ego-motion nuscenes_dataset.py. - Training history has no gradient. Past frames are encoded under
torch.no_grad, so gradients flow only through the current frame nuscenes_dataset.py bevformer.py §4.2. - Spatial attention is a Python loop. Per-camera gathering and scatter run as nested Python loops over batch and cameras, which limits throughput spatial_cross_attention.py spatial_cross_attention.py. Latency is 130 ms per frame on V100 for the default tab. 6.
- Memory cost. Global attention in spatial cross-attention needs about 36 GB against about 20 GB for deformable attention, and the paper says dense attention is unaffordable at this scale tab. 5 app. A.4.
- Temporal cost is small but not zero. The history pass adds a no-grad forward per training sample, and inference needs the previous BEV kept in memory §3.6 bevformer.py.
- Waymo and V2-99 are not reproducible from the repo. Only nuScenes configs exist .
- Figure and table numbers. This card cites tables and figures in TeX order (1 to 8 and figs. 1 to 9). Check against the compiled PDF before publishing.
Lineage
- Builds on: Deformable DETR, arXiv:2010.04159 (the deformable attention is adapted from it) §2 temporal_self_attention.py.
- Compared against (named, no cards): DETR3D, FCOS3D, PGD, DD3D, VPN, Lift-Splat, CaDNN, PointPillars, SSN, PointPainting, CenterPoint tab. 1 tab. 3 tab. 4.
- Map head is built on Panoptic SegFormer's mask decoder (named, no card) §3.5.
Source and license
Adapted from “BEVFormer: Learning Bird's-Eye-View Representation from Multi-Camera Images via Spatiotemporal Transformers” by Zhiqi Li, Wenhai Wang, Hongyang Li, Enze Xie, Chonghao Sima, Tong Lu, Qiao Yu, Jifeng Dai (arXiv:2203.17270), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/fundamentalvision/BEVFormer at commit 66b65f3a1f58 (Apache-2.0). Any quoted code is shown under that license.