Record H1 nuance, four-scalar count and erratum pointer in the card
Browse files
README.md
CHANGED
|
@@ -1,168 +1,189 @@
|
|
| 1 |
-
---
|
| 2 |
-
license: cc-by-4.0
|
| 3 |
-
base_model: laion/CLIP-ViT-B-32-laion2B-s34B-b79K
|
| 4 |
-
pipeline_tag: zero-shot-classification
|
| 5 |
-
library_name: pointcal-c
|
| 6 |
-
tags:
|
| 7 |
-
- 3d
|
| 8 |
-
- point-cloud
|
| 9 |
-
- modelnet40-c
|
| 10 |
-
- clip
|
| 11 |
-
- calibration
|
| 12 |
-
- selective-prediction
|
| 13 |
-
- uncertainty
|
| 14 |
-
- zero-shot
|
| 15 |
-
---
|
| 16 |
-
|
| 17 |
-
# PointCal-C — selective zero-shot 3D recognition under corruption
|
| 18 |
-
|
| 19 |
-
A post-hoc **calibration and abstention head** on top of a frozen OpenCLIP
|
| 20 |
-
ViT-B/32, for zero-shot 3D point-cloud recognition under corruption, plus the
|
| 21 |
-
complete evaluation artifacts backing it.
|
| 22 |
-
|
| 23 |
-
Code: <https://github.com/crimsonKn1ght/pointcal-c>
|
| 24 |
-
|
| 25 |
-
## What the model is
|
| 26 |
-
|
| 27 |
-
The backbone is **never trained**. `laion/CLIP-ViT-B-32-laion2B-s34B-b79K` is
|
| 28 |
-
loaded frozen, in eval mode, with `requires_grad_(False)`.
|
| 29 |
-
|
| 30 |
-
The fitted model is **four scalars**, in `runs/full/results/calibration.json`,
|
| 31 |
-
fit on clean calibration objects only — corrupted labels, corruption identity
|
| 32 |
-
and severity never touch a fitted parameter:
|
| 33 |
-
|
| 34 |
-
| parameter | value | role |
|
| 35 |
-
|---|---|---|
|
| 36 |
-
| `temperature` | 1.2309 | divides logits before softmax |
|
| 37 |
-
| `bias` | -1.5723 | combined-score intercept |
|
| 38 |
-
| `weight_confidence` | +1.7071 | on `logit(p_calibrated)` |
|
| 39 |
-
| `weight_disagreement` | +4.9158 | on cross-view disagreement `d` |
|
| 40 |
-
|
| 41 |
-
Combined score: `sigmoid(bias + w_conf * logit(p_cal) + w_dis * d)`, where `d`
|
| 42 |
-
is `1 -` mean pairwise Jensen-Shannon divergence across the six views.
|
| 43 |
-
|
| 44 |
-
Converged, unclamped, not degenerate. Fit in 0.94 s on CPU.
|
| 45 |
-
|
| 46 |
-
## How inference works
|
| 47 |
-
|
| 48 |
-
```
|
| 49 |
-
point cloud (N,1024,3)
|
| 50 |
-
-> centroid-center, unit-radius normalize
|
| 51 |
-
-> 6 orthographic cameras [front right back left top bottom]
|
| 52 |
-
-> 64x64 splat raster + nearest-depth z-buffer -> upsample to 224x224
|
| 53 |
-
-> frozen OpenCLIP ViT-B/32 image encoder
|
| 54 |
-
-> per-view logits vs a fixed 8-template prompt ensemble <-- cached here
|
| 55 |
-
-> mean over views -> the prediction
|
| 56 |
-
-> four confidence scores over that one prediction
|
| 57 |
-
```
|
| 58 |
-
|
| 59 |
-
All four confidence methods (`msp`, `temperature`, `disagreement`, `combined`)
|
| 60 |
-
rank the **same** predictions. A confidence method that changed a prediction
|
| 61 |
-
would be a different classifier, and `assert_predictions_unchanged` raises if
|
| 62 |
-
one ever does.
|
| 63 |
-
|
| 64 |
-
## Results
|
| 65 |
-
|
| 66 |
-
All 75 corrupted conditions pooled against clean, 1975 evaluation objects,
|
| 67 |
-
95% bootstrap intervals resampled over base object IDs:
|
| 68 |
-
|
| 69 |
-
| | accuracy | ECE (MSP) | ECE (combined) | AURC (MSP) | AURC (combined) |
|
| 70 |
-
|---|---|---|---|---|---|
|
| 71 |
-
| clean | 0.2896 | 0.1160 | 0.0245 | 0.4339 | 0.4147 |
|
| 72 |
-
| corrupted | 0.2354 | 0.1416 | 0.0229 | 0.5217 | 0.5008 |
|
| 73 |
-
|
| 74 |
-
Accuracy degrades under corruption and MSP calibration degrades with it. The
|
| 75 |
-
clean-fit combined score holds ECE near **0.023** under shift and lowers AURC
|
| 76 |
-
by 0.021.
|
| 77 |
-
|
| 78 |
-
The ECE improvement is large and consistent. **The AURC gain is small** and
|
| 79 |
-
should be read against the intervals in `results.csv`, not as a headline. This
|
| 80 |
-
is a reliability audit and a bounded abstention baseline, not a
|
| 81 |
-
state-of-the-art claim.
|
| 82 |
-
|
| 83 |
-
Accuracy by severity: 0.2896 (clean), 0.2593, 0.2515, 0.2388, 0.2252, 0.2023 —
|
| 84 |
-
monotonically non-increasing.
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: cc-by-4.0
|
| 3 |
+
base_model: laion/CLIP-ViT-B-32-laion2B-s34B-b79K
|
| 4 |
+
pipeline_tag: zero-shot-classification
|
| 5 |
+
library_name: pointcal-c
|
| 6 |
+
tags:
|
| 7 |
+
- 3d
|
| 8 |
+
- point-cloud
|
| 9 |
+
- modelnet40-c
|
| 10 |
+
- clip
|
| 11 |
+
- calibration
|
| 12 |
+
- selective-prediction
|
| 13 |
+
- uncertainty
|
| 14 |
+
- zero-shot
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
# PointCal-C — selective zero-shot 3D recognition under corruption
|
| 18 |
+
|
| 19 |
+
A post-hoc **calibration and abstention head** on top of a frozen OpenCLIP
|
| 20 |
+
ViT-B/32, for zero-shot 3D point-cloud recognition under corruption, plus the
|
| 21 |
+
complete evaluation artifacts backing it.
|
| 22 |
+
|
| 23 |
+
Code: <https://github.com/crimsonKn1ght/pointcal-c>
|
| 24 |
+
|
| 25 |
+
## What the model is
|
| 26 |
+
|
| 27 |
+
The backbone is **never trained**. `laion/CLIP-ViT-B-32-laion2B-s34B-b79K` is
|
| 28 |
+
loaded frozen, in eval mode, with `requires_grad_(False)`.
|
| 29 |
+
|
| 30 |
+
The fitted model is **four scalars**, in `runs/full/results/calibration.json`,
|
| 31 |
+
fit on clean calibration objects only — corrupted labels, corruption identity
|
| 32 |
+
and severity never touch a fitted parameter:
|
| 33 |
+
|
| 34 |
+
| parameter | value | role |
|
| 35 |
+
|---|---|---|
|
| 36 |
+
| `temperature` | 1.2309 | divides logits before softmax |
|
| 37 |
+
| `bias` | -1.5723 | combined-score intercept |
|
| 38 |
+
| `weight_confidence` | +1.7071 | on `logit(p_calibrated)` |
|
| 39 |
+
| `weight_disagreement` | +4.9158 | on cross-view disagreement `d` |
|
| 40 |
+
|
| 41 |
+
Combined score: `sigmoid(bias + w_conf * logit(p_cal) + w_dis * d)`, where `d`
|
| 42 |
+
is `1 -` mean pairwise Jensen-Shannon divergence across the six views.
|
| 43 |
+
|
| 44 |
+
Converged, unclamped, not degenerate. Fit in 0.94 s on CPU.
|
| 45 |
+
|
| 46 |
+
## How inference works
|
| 47 |
+
|
| 48 |
+
```
|
| 49 |
+
point cloud (N,1024,3)
|
| 50 |
+
-> centroid-center, unit-radius normalize
|
| 51 |
+
-> 6 orthographic cameras [front right back left top bottom]
|
| 52 |
+
-> 64x64 splat raster + nearest-depth z-buffer -> upsample to 224x224
|
| 53 |
+
-> frozen OpenCLIP ViT-B/32 image encoder
|
| 54 |
+
-> per-view logits vs a fixed 8-template prompt ensemble <-- cached here
|
| 55 |
+
-> mean over views -> the prediction
|
| 56 |
+
-> four confidence scores over that one prediction
|
| 57 |
+
```
|
| 58 |
+
|
| 59 |
+
All four confidence methods (`msp`, `temperature`, `disagreement`, `combined`)
|
| 60 |
+
rank the **same** predictions. A confidence method that changed a prediction
|
| 61 |
+
would be a different classifier, and `assert_predictions_unchanged` raises if
|
| 62 |
+
one ever does.
|
| 63 |
+
|
| 64 |
+
## Results
|
| 65 |
+
|
| 66 |
+
All 75 corrupted conditions pooled against clean, 1975 evaluation objects,
|
| 67 |
+
95% bootstrap intervals resampled over base object IDs:
|
| 68 |
+
|
| 69 |
+
| | accuracy | ECE (MSP) | ECE (combined) | AURC (MSP) | AURC (combined) |
|
| 70 |
+
|---|---|---|---|---|---|
|
| 71 |
+
| clean | 0.2896 | 0.1160 | 0.0245 | 0.4339 | 0.4147 |
|
| 72 |
+
| corrupted | 0.2354 | 0.1416 | 0.0229 | 0.5217 | 0.5008 |
|
| 73 |
+
|
| 74 |
+
Accuracy degrades under corruption and MSP calibration degrades with it. The
|
| 75 |
+
clean-fit combined score holds ECE near **0.023** under shift and lowers AURC
|
| 76 |
+
by 0.021.
|
| 77 |
+
|
| 78 |
+
The ECE improvement is large and consistent. **The AURC gain is small** and
|
| 79 |
+
should be read against the intervals in `results.csv`, not as a headline. This
|
| 80 |
+
is a reliability audit and a bounded abstention baseline, not a
|
| 81 |
+
state-of-the-art claim.
|
| 82 |
+
|
| 83 |
+
Accuracy by severity: 0.2896 (clean), 0.2593, 0.2515, 0.2388, 0.2252, 0.2023 —
|
| 84 |
+
monotonically non-increasing.
|
| 85 |
+
|
| 86 |
+
### Pre-registered hypotheses
|
| 87 |
+
|
| 88 |
+
Of the four pre-registered hypotheses, three are mechanically checked. H2 and H3
|
| 89 |
+
resolve True. **H1 does not hold strictly:** accuracy, NLL, Brier and AURC all
|
| 90 |
+
worsen monotonically with severity, but ECE dips at severities 3→4 and again
|
| 91 |
+
from clean→1. A paired object-grouped bootstrap places both reversals within
|
| 92 |
+
noise of zero, so H1 is supported in direction but not as strict monotonicity.
|
| 93 |
+
H4 is read off the family-scope rows rather than reduced to a verdict.
|
| 94 |
+
|
| 95 |
+
## Repository contents
|
| 96 |
+
|
| 97 |
+
The expensive artifact is `runs/*/logits/` — per-view logits for every
|
| 98 |
+
condition under both prompt modes. Every metric, ablation, bootstrap interval
|
| 99 |
+
and figure here was computed on CPU from those caches, so **any re-analysis is
|
| 100 |
+
free**: a different aggregation, disagreement statistic, coverage level or
|
| 101 |
+
bootstrap depth costs no GPU time, because CLIP never runs again.
|
| 102 |
+
|
| 103 |
+
```
|
| 104 |
+
runs/<tier>/
|
| 105 |
+
logits/<condition>.npz per-view logits, both prompt modes (~1.4 MB each)
|
| 106 |
+
results/calibration.json the fitted scalars above
|
| 107 |
+
results/results.csv|.json metrics table with intervals
|
| 108 |
+
results/ablations.csv view-count, prompt-mode, disagreement ablations
|
| 109 |
+
results/predictions.npz per-sample confidences and correctness
|
| 110 |
+
results/results_summary.md auto-generated tables + hypothesis checks
|
| 111 |
+
figures/fig1..fig4 accuracy, ECE, risk-coverage, cost
|
| 112 |
+
provenance/ data manifest, run manifest, split audit
|
| 113 |
+
ledger_inference.json measured GPU-hours, dollars, throughput, memory
|
| 114 |
+
artifacts/split.json the frozen calibration/evaluation object split
|
| 115 |
+
env/requirements.lock.txt exact resolved environment (171 packages)
|
| 116 |
+
```
|
| 117 |
+
|
| 118 |
+
Tiers: `xs` (5 conditions, 100 objects), `s` (13 conditions), `full` (all 76 =
|
| 119 |
+
clean + 15 corruptions x 5 severities).
|
| 120 |
+
|
| 121 |
+
## Training / evaluation data
|
| 122 |
+
|
| 123 |
+
Evaluated on **ModelNet40-C** (2468 objects, 40 classes, 15 corruption types,
|
| 124 |
+
5 severities). The calibration scalars are fit on the clean split of 493
|
| 125 |
+
calibration objects; 1975 evaluation objects are held out.
|
| 126 |
+
|
| 127 |
+
The split is over **base object IDs**, not samples, and every corruption array
|
| 128 |
+
is verified row-aligned with the clean array, so holding an object out of
|
| 129 |
+
calibration holds it out under all 76 conditions. Audited: `overlap: 0`,
|
| 130 |
+
0 row-misaligned conditions, all 40 classes present on both sides.
|
| 131 |
+
|
| 132 |
+
## Compute
|
| 133 |
+
|
| 134 |
+
| tier | conditions | GPU-hours | USD | views/s | peak VRAM |
|
| 135 |
+
|---|---|---|---|---|---|
|
| 136 |
+
| xs | 5 | 0.001 | 0.0003 | 1091 | 2.5 GB |
|
| 137 |
+
| s | 13 | 0.015 | 0.004 | 2816 | 12.1 GB |
|
| 138 |
+
| full | 76 | 0.089 | 0.025 | 2808 | 12.1 GB |
|
| 139 |
+
|
| 140 |
+
**0.105 GPU-hours and about $0.03** of inference in total, on a single Runpod
|
| 141 |
+
RTX 4000 Ada at $0.28/hr (2026-08-16).
|
| 142 |
+
|
| 143 |
+
## Known defects
|
| 144 |
+
|
| 145 |
+
See **[ERRATUM.md](ERRATUM.md)** for the full list. In short: the `ledger` block
|
| 146 |
+
embedded in `runs/full/provenance/run_manifest.json` is wrong — it records a
|
| 147 |
+
cache-hit re-invocation, not the real run. **Trust `ledger_inference.json`,**
|
| 148 |
+
which every figure and the compute table above are derived from. `git_dirty` in
|
| 149 |
+
that manifest is not meaningful either, because the dirtiness check counts
|
| 150 |
+
expected untracked artifacts.
|
| 151 |
+
|
| 152 |
+
## Limitations
|
| 153 |
+
|
| 154 |
+
- `full` uses **200** bootstrap replicates, not the preregistered 1000. The CPU
|
| 155 |
+
bootstrap dominated runtime (~2 h at 1000 vs ~5 min of GPU work). Deeper
|
| 156 |
+
intervals recompute from the cached logits at no GPU cost.
|
| 157 |
+
- NLL and Brier require a distribution over all 40 classes, so they are reported
|
| 158 |
+
for `msp` and `temperature` only. For the two ranking scores they are `null`,
|
| 159 |
+
not a lookalike substitute.
|
| 160 |
+
- `delta_*_vs_clean` rows in `results.csv` carry `NaN` intervals: degradation is
|
| 161 |
+
reported as point estimates without paired bootstrap intervals. Method
|
| 162 |
+
differences should likewise not be read from the marginal intervals alone.
|
| 163 |
+
- Cross-view disagreement is prior art, and calibration degrading under 3D
|
| 164 |
+
corruption is a confirmation rather than a discovery.
|
| 165 |
+
- Absolute accuracy is low (~0.29 clean). This is zero-shot transfer of a 2D
|
| 166 |
+
model to depth renders, with no 3D training whatsoever.
|
| 167 |
+
- Severity is reported **1-indexed**, matching the on-disk release.
|
| 168 |
+
|
| 169 |
+
## Provenance
|
| 170 |
+
|
| 171 |
+
- Frozen spec hash: `ca487597c978ab17217bd640ab8bf95c8a21db0eaacd51ae5ba4b00618dcc820`
|
| 172 |
+
- Backbone checkpoint SHA-256:
|
| 173 |
+
`1bd3c7172de5b207ceac554f5ab5266166f3b9baccc9af5989bc801016d080ad`
|
| 174 |
+
- Split fingerprint: `cc5ed4b3ce7108154039f497d474f3ac6bdbfe7eb7dbfe4d0f90785e1829bb31`
|
| 175 |
+
|
| 176 |
+
## Licence and attribution
|
| 177 |
+
|
| 178 |
+
Cached logits and metrics are **derived from ModelNet40-C** and redistributed
|
| 179 |
+
under **CC BY 4.0**, as the source record declares.
|
| 180 |
+
|
| 181 |
+
- ModelNet40-C — Zenodo [6017834](https://zenodo.org/records/6017834),
|
| 182 |
+
DOI `10.5281/zenodo.6017834`, CC BY 4.0
|
| 183 |
+
- Generation code — <https://github.com/jiachens/ModelNet40-C>, BSD-3-Clause
|
| 184 |
+
- Underlying ModelNet40 carries its own original terms
|
| 185 |
+
- OpenCLIP — MIT · PointCal-C code — MIT
|
| 186 |
+
|
| 187 |
+
The multi-view depth-projection approach follows the PointCLIP paper (CVPR
|
| 188 |
+
2022); the projector is an independent reimplementation from the paper text,
|
| 189 |
+
with no PointCLIP repository code used.
|