File size: 7,602 Bytes
281cc2c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
---
license: mit
library_name: pytorch
tags:
  - 3d-reconstruction
  - camera-pose-estimation
  - pointmap
  - multi-camera-rig
  - autonomous-driving
  - waymo
  - dust3r
datasets:
  - waymo_open_dataset
metrics:
  - pointmap_err
  - pose_deg
  - rig_deg
model-index:
  - name: rig3r-waymo
    results:
      - task:
          type: camera-pose-estimation
          name: Multi-camera rig pose estimation
        dataset:
          type: waymo_open_dataset
          name: Waymo Open Dataset (mini subset, held-out val split)
        metrics:
          - type: pose_deg
            value: 1.4403
            name: Pose rotation error (deg)
          - type: rig_deg
            value: 1.4075
            name: Rig rotation error (deg)
          - type: pointmap_err
            value: 0.2159
            name: Pointmap L2 error (scale-normalized)
---

# Open-Rig3R — Waymo (epoch 50)

Unofficial open reimplementation of **Rig3R**: a rig-aware transformer that takes multiple
camera views and predicts per-view pointmaps plus pose and rig raymaps, so a whole camera
rig is reconstructed jointly instead of one camera at a time.

Code: [engichang1467/Open-Rig3R](https://github.com/engichang1467/Open-Rig3R)

This checkpoint is epoch 50 of 50 from a single run on a Waymo mini subset. It is a
**research checkpoint from a reimplementation**, not a reproduction of the paper's
published numbers — see [Limitations](#limitations) before using it for anything.

## Results

Held-out Waymo val split, at the end of training:

| Metric | Value |
|---|---|
| Pointmap L2 error (scale-normalized) | **0.2159** |
| Pose rotation error | **1.440°** |
| Rig rotation error | **1.408°** |
| Pose centre error | 0.0156 |
| Rig centre error | 0.0161 |

### Read the validation curve carefully

`val/total` **rises** from 0.395 (epoch 6) to 0.961 (epoch 50). That is not overfitting,
and epoch 6 is not the better checkpoint.

The pointmap term is `C * err - alpha * log(C)`, where `C` is the model's own predicted
confidence. Over training `C` climbs from 1.2 to 9.98, saturating against the
`conf_max: 10.0` ceiling. The same geometric error therefore costs roughly 10x more at
epoch 50 than at epoch 6. Meanwhile the unweighted error stays flat or improves
(`pointmap_err` 0.279 → 0.216) and both angular errors fall monotonically
(14.10° → 1.44°, 14.16° → 1.41°).

| epoch | val/total | pointmap | **pointmap_err** | conf_mean | pose_deg | rig_deg |
|---|---|---|---|---|---|---|
| 6 | **0.395** | 0.253 | 0.2239 | 3.26 | 3.01 | 3.02 |
| 25 | 0.621 | 0.532 | 0.2187 | 6.86 | 1.63 | 1.59 |
| 50 | 0.961 | 0.880 | **0.2159** | 9.98 | **1.440** | **1.408** |

`val/total` is confounded by confidence saturation and should not be used for model
selection on this run. Select on `pointmap_err`, `pose_deg`, and `rig_deg` — all of which
plateau by roughly epoch 45 and are best at epoch 50.

## Usage

This is a plain `state_dict`, not a `transformers` `PreTrainedModel` — there is no
`from_pretrained`. Load it into the `Rig3R` class from the repo, with the **same
architecture arguments the checkpoint was trained with** (the class defaults differ and
will not load):

```python
from huggingface_hub import hf_hub_download
from safetensors.torch import load_file
from models.rig3r import Rig3R

model = Rig3R(
    encoder_ckpt=None,        # weights come from the checkpoint below, not from DUSt3R
    img_size=128,
    patch_size=16,
    embed_dim=1024,
    num_decoder_layers=2,     # NOT the class default of 6
    num_heads=8,
    mlp_dim=4096,             # NOT the class default of 2048
    metadata_dropout=0.5,
)

path = hf_hub_download("mca183/rig3r-waymo", "model.safetensors")
model.load_state_dict(load_file(path))
model.eval()

# images: (B, V, 3, 128, 128) — V = n_frames * num_cameras, e.g. 2 * 5 = 10 for the full Waymo rig
# metadata is optional; the decoder is trained with per-field dropout so it runs without it
outputs = model(images, metadata=None)
```

`forward` returns a dict:

| key | shape | notes |
|---|---|---|
| `pointmap` | `(B, V, H*W, 3)` | dense per-pixel 3D points |
| `pointmap_conf` | `(B, V, H*W, 1)` | per-pixel confidence — saturated, see [Limitations](#limitations) |
| `pose_raymap` | `(B, V, P, 6)` | centre + unit direction per patch |
| `rig_raymap` | `(B, V, P, 6)` | centre + unit direction per patch |
| `camera_center_pose` | `(B, V, 3)` | one centre per view |
| `camera_center_rig` | `(B, V, 3)` | one centre per view |
| `features` | `(B, V, P, C)` | decoder patch features, for downstream heads |

`P = (128 / 16)^2 = 64` patches per view.

## Architecture

| | |
|---|---|
| Total parameters | 340.2 M (373 tensors, fp32) |
| Encoder | 303.2 M — DUSt3R ViT-L/16, **frozen** during training |
| Rig-aware decoder | 37.0 M — 2 pre-norm transformer layers, 8 heads, MLP dim 4096 |
| Heads | `pointmap_head`, `pose_raymap_head`, `rig_raymap_head` |
| Embedding dim | 1024 |
| Input resolution | 128 x 128, patch size 16 |

Encoder initialized from `DUSt3R_ViTLarge_BaseDecoder_512_dpt` and kept frozen, so only
the 37.0 M decoder and heads were trained.

## Training

| | |
|---|---|
| Dataset | Waymo Open Dataset, mini subset, full 5-camera rig (FRONT, FRONT_LEFT, FRONT_RIGHT, SIDE_LEFT, SIDE_RIGHT) |
| Views per sample | 10 (`n_frames: 2` x 5 cameras) |
| Epochs | 50 |
| Batch size | 8 |
| Optimizer | AdamW, lr 1e-4, weight decay 0.01 |
| Scheduler | Cosine annealing, `eta_min` 1e-6 |
| Precision | bf16 autocast, no grad scaler |
| Loss weights | `w_point` 1.0, `w_pose` 1.0, `w_rig` 1.0 |
| Confidence regularizer | `alpha` 0.2, `beta` 1.0, `conf_max` 10.0 |
| Metadata dropout | 0.5 per field (frame index exempt) |
| Seed | 0 |
| Hardware | NVIDIA A100 80GB PCIe |
| Wall clock | ~3h 20m |

`conf_max: 10.0` is a deliberate deviation from the paper: Eq. 3 leaves `-alpha*log(C)`
unbounded below, so the ceiling floors the pointmap term at `-alpha*log(10) = -0.46`.
Setting it to `null` restores Eq. 3 exactly.

## Limitations

- **Reimplementation, not the paper.** Unofficial; numbers here are not comparable to published Rig3R results.
- **Mini subset.** Trained on a small Waymo subset, not the full dataset. Generalization is untested.
- **128 x 128 input.** Well below the paper's resolution; pointmap detail is correspondingly coarse.
- **Shallow decoder.** 2 layers rather than 6, and the encoder is frozen throughout.
- **Waymo domain only.** Driving scenes, one rig geometry. No indoor, handheld, or non-automotive evaluation.
- **Single run, no held-out test.** Metrics are val-split only, one seed, no ablations.
- **Confidence is saturated.** `conf_mean` sits at the `conf_max` ceiling of 10.0, so predicted confidence is not calibrated and should not be read as an uncertainty estimate.

## Dataset terms

Trained on the Waymo Open Dataset, which carries its own license and terms of use. Using
this model does not grant any rights to that data — obtain it from Waymo directly and
comply with their terms.

## License

MIT (see the [source repo](https://github.com/engichang1467/Open-Rig3R)). Copyright 2025
Michael Chang. The DUSt3R encoder initialization and the Waymo Open Dataset carry their
own separate licenses.

## Citation

Rig3R (original paper):

```bibtex
@article{rig3r,
  title  = {Rig3R: Rig-Aware Conditioning for Learned 3D Reconstruction},
  year   = {2025}
}
```

This reimplementation:

```bibtex
@software{open_rig3r,
  author = {Chang, Michael},
  title  = {Open-Rig3R: An open reimplementation of Rig3R},
  url    = {https://github.com/engichang1467/Open-Rig3R},
  year   = {2025}
}
```