Upload README.md with huggingface_hub
Browse files
README.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
pipeline_tag: image-segmentation
|
| 4 |
+
tags:
|
| 5 |
+
- vesuvius
|
| 6 |
+
- herculaneum
|
| 7 |
+
- fibers
|
| 8 |
+
- computed-tomography
|
| 9 |
+
- 3d-segmentation
|
| 10 |
+
- dino-guided
|
| 11 |
+
- self-distillation
|
| 12 |
+
- self-supervised
|
| 13 |
+
- volumetric-imaging
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
# PHerc. Paris 4 — 2-class fiber segmentation, DINO-embedding-guided self-training (step 10000)
|
| 17 |
+
|
| 18 |
+
Segments **fiber vs. background** (2 classes — not an orientation split, see
|
| 19 |
+
below) in 3D, directly in micro-CT of **PHerc. Paris 4**, trained with **no
|
| 20 |
+
fixed ground truth**: a pseudo-label is regenerated every step from a frozen
|
| 21 |
+
teacher UNet's own predictions, adaptively thresholded and refined against a
|
| 22 |
+
DINO-embedding similarity map.
|
| 23 |
+
|
| 24 |
+
**This is a precursor / component checkpoint, not villa's flagship 4-class
|
| 25 |
+
fiber/ink model.** It is published because it is real, verified lineage: per
|
| 26 |
+
villa's own [`scripts/fiber_5class/train.py`](https://github.com/ScrollPrize/villa/blob/main/scripts/fiber_5class/train.py)
|
| 27 |
+
(PR [#985](https://github.com/ScrollPrize/villa/pull/985)) module docstring,
|
| 28 |
+
*this exact checkpoint* — referred to there by its W&B run ID, "ihoo3tpl ckpt"
|
| 29 |
+
— is loaded as the frozen **fiber teacher** input to villa's separate, later,
|
| 30 |
+
4-class (background / vertical fiber / horizontal-angular fiber / ink)
|
| 31 |
+
self-distillation trainer. See **Relationship to the 4-class model** below;
|
| 32 |
+
we do not currently have that 4-class model's weights to publish.
|
| 33 |
+
|
| 34 |
+
## Model details
|
| 35 |
+
|
| 36 |
+
| | |
|
| 37 |
+
|---|---|
|
| 38 |
+
| Architecture | `vesuvius` `NetworkFromConfig` 3D UNet (`shared_encoder` / `shared_decoder` / `task_heads`, the same family used across villa's segmentation models), single `fibers` head |
|
| 39 |
+
| Output | **2 channels**, softmax. Channel 0 = background, channel 1 = fiber foreground — confirmed via villa's own `label_generator.py::_to_fg_prob`, the function that loads this exact checkpoint as a frozen teacher (2-channel case: `softmax(logits, dim=1)[:, 1:2]`) |
|
| 40 |
+
| Input | 1-channel CT, 256³ patches |
|
| 41 |
+
| This checkpoint | step **10000** · W&B run [`ps256_fiber_dinoguided__dino362500__cls3__embbackbone__ddp8__20260522`](https://wandb.ai/vesuvius-challenge/vesuvius_fibers_3d/runs/ihoo3tpl) (`ihoo3tpl`, project `vesuvius_fibers_3d`, state **finished**) |
|
| 42 |
+
| Weights | `model` (raw) and `ema` (**EMA — recommended for inference**, decay 0.9995) |
|
| 43 |
+
| Optimisation | SGD + Nesterov (lr 0.005, momentum 0.99, weight_decay 3e-5), cosine LR, 1500-step warmup, bf16 mixed precision, BCE + soft Dice (0.1 label smoothing each), batch size 2 × 8 GPUs (`ddp8`), 12000 total iterations |
|
| 44 |
+
| Trained on | PHerc. Paris 4, 2.4 µm scan (`s3://vesuvius-challenge-open-data/PHercParis4/volumes/20260411134726-2.400um-0.2m-78keV-masked.zarr/`) |
|
| 45 |
+
|
| 46 |
+
## Training procedure: DINO-embedding-guided dynamic pseudo-labeling
|
| 47 |
+
|
| 48 |
+
Unlike a conventional teacher→student distillation with a fixed label set,
|
| 49 |
+
this run generates a **new pseudo-label every step** from:
|
| 50 |
+
|
| 51 |
+
1. A frozen self-trained fiber UNet's own probability map —
|
| 52 |
+
[`scrollprize/fiber_selftrain_teacher_epoch30`](https://huggingface.co/scrollprize/fiber_selftrain_teacher_epoch30)
|
| 53 |
+
(the same checkpoint also **warm-starts** this model's own weights, i.e.
|
| 54 |
+
this is continued self-training, not distillation from an unrelated
|
| 55 |
+
architecture).
|
| 56 |
+
2. An Otsu-adaptive light/dark voxel threshold (`otsu_light_threshold=70`,
|
| 57 |
+
plus `otsu_min_light_voxels`, `otsu_fallback_threshold`,
|
| 58 |
+
`otsu_tail_floor_percentile`, `otsu_min_tail_voxels`).
|
| 59 |
+
3. A similarity map between the
|
| 60 |
+
[supcon-fine-tuned DINO backbone, step 362500](https://huggingface.co/scrollprize/dinovol_v2_ps8_supcon3class_step362500)'s
|
| 61 |
+
dense patch embeddings and a single reference "fiber" prototype embedding
|
| 62 |
+
(`avg_fiber_embedding__864d_backbone.npz`, bundled in that backbone's repo),
|
| 63 |
+
computed at stride 128 and blended in with `dino_blend_sigma=4.0`.
|
| 64 |
+
|
| 65 |
+
We reconstructed this description from the run's own config field names
|
| 66 |
+
(`dynamic_label.*`); the specific script implementing this exact blend was not
|
| 67 |
+
found in the available `villa` repository snapshot (unlike the 4-class
|
| 68 |
+
pipeline discussed below, whose source we did read directly), so treat the
|
| 69 |
+
precise algorithmic combination as a well-supported inference, not a verbatim
|
| 70 |
+
account of the code.
|
| 71 |
+
|
| 72 |
+
### Checkpoint provenance: a mid-run bugfix
|
| 73 |
+
|
| 74 |
+
This run's own config records `resume_from_ckpt` pointing at its own
|
| 75 |
+
`ckpt_002000.pth`, under the *same* W&B run ID (`ihoo3tpl`) — confirming
|
| 76 |
+
training paused at step 2000 and resumed later in the same run (verified both
|
| 77 |
+
via the W&B API and by loading this checkpoint's own embedded config directly,
|
| 78 |
+
which lists `wandb_run_id: ihoo3tpl` and the matching `resume_from_ckpt`
|
| 79 |
+
path). This lines up exactly with the two checkpoints produced:
|
| 80 |
+
|
| 81 |
+
- `step_002000__resume_point__pre_dark_mask_fix.pth` — **not published here**
|
| 82 |
+
(superseded).
|
| 83 |
+
- `step_010000__post_dark_mask_fix__latest.pth` — **this repo.**
|
| 84 |
+
|
| 85 |
+
The filenames describe this as a fix to "dark voxel masking." We can confirm
|
| 86 |
+
the resume-at-step-2000 mechanics precisely (embedded config + matching
|
| 87 |
+
filenames + same run ID) but **cannot independently confirm the exact nature
|
| 88 |
+
of the underlying bug/fix** — plausible candidate parameters visible in the
|
| 89 |
+
(post-fix) config relate to dark/light voxel handling (`input_mask_threshold`,
|
| 90 |
+
`otsu_light_threshold`, the dataset's `dark_threshold`), but we only have the
|
| 91 |
+
post-fix config, not a diff against the pre-fix run.
|
| 92 |
+
|
| 93 |
+
## Metrics
|
| 94 |
+
|
| 95 |
+
**This run has no held-out validation metric** — its W&B summary contains no
|
| 96 |
+
`val_*` key at all, because the entire pipeline is label-free self-training
|
| 97 |
+
(there is no independent ground truth to validate against). Final logged
|
| 98 |
+
values at step 11999 (of a 12000-step schedule; run marked **finished**):
|
| 99 |
+
|
| 100 |
+
| metric | value |
|
| 101 |
+
|---|---|
|
| 102 |
+
| `loss` (bce + dice) | 0.7824 |
|
| 103 |
+
| `loss_bce` | 0.3318 |
|
| 104 |
+
| `loss_dice` | 0.4506 |
|
| 105 |
+
| `pseudo_fg_frac` (dynamic label's foreground fraction) | 0.132 |
|
| 106 |
+
| `sim_mean` (mean DINO-embedding similarity to the reference) | 0.432 |
|
| 107 |
+
| `otsu_threshold` (final adaptive cut) | 0.503 |
|
| 108 |
+
| `lr` | ≈1.1×10⁻¹⁰ (cosine-annealed to ~0) |
|
| 109 |
+
|
| 110 |
+
These are training-loop / pseudo-label-consistency statistics, not accuracy
|
| 111 |
+
against independently verified ground truth.
|
| 112 |
+
|
| 113 |
+
## Relationship to the 4-class fiber/ink model — please read before assuming this is that model
|
| 114 |
+
|
| 115 |
+
Villa's actual finished 4-class (background / vertical fiber / horizontal-angular
|
| 116 |
+
fiber / ink) self-distillation model — matching
|
| 117 |
+
[`scripts/fiber_5class`](https://github.com/ScrollPrize/villa/tree/main/scripts/fiber_5class)
|
| 118 |
+
exactly (watershed-from-minima + per-instance PCA orientation split + ink-teacher
|
| 119 |
+
override + dark-voxel guard) — is a **separate** checkpoint: W&B run
|
| 120 |
+
[`p4_4class_ddp8_20260526`](https://wandb.ai/vesuvius-challenge/paris4-full-features/runs/36pykwky)
|
| 121 |
+
(`36pykwky`, project `paris4-full-features`, state finished, created
|
| 122 |
+
2026-05-26 — four days after this run). Its config confirms it uses this
|
| 123 |
+
checkpoint's lineage as its frozen fiber teacher, plus a separate frozen ink
|
| 124 |
+
teacher that we do not have. **We do not currently have that 4-class model's
|
| 125 |
+
weight files**: its training `out_dir` was an ephemeral cloud-instance scratch
|
| 126 |
+
path (`/ephemeral/fiber_5class_ckpts/p4_4class_ddp8_20260526`), not S3, and a
|
| 127 |
+
scoped search of `s3://philodemos/giorgio/PHercParis4/` turned up only
|
| 128 |
+
DINO-backbone checkpoints and what appears to be stitched inference *output*
|
| 129 |
+
(not model weights). **It is not published on HuggingFace at this time.**
|
| 130 |
+
|
| 131 |
+
For reference, that run's self-consistency metrics (student vs. its own
|
| 132 |
+
pseudo-label on the training crop — again, not held-out validation):
|
| 133 |
+
`dice_0_bg`=0.961, `dice_1_vert_fiber`=0.673, `dice_2_horiz_fiber`=0.705,
|
| 134 |
+
`dice_3_ink`=0.791, `dice_fg_mean`=0.723.
|
| 135 |
+
|
| 136 |
+
## Prior / sibling work
|
| 137 |
+
|
| 138 |
+
An earlier, independently-trained, **supervised** 2-class horizontal/vertical
|
| 139 |
+
fiber model (traced from WebKnossos skeleton annotations via cross-frame affine
|
| 140 |
+
registration, villa PR [#825](https://github.com/ScrollPrize/villa/pull/825))
|
| 141 |
+
is already published as [`scrollprize/fiber_hz_vt`](https://huggingface.co/scrollprize/fiber_hz_vt)
|
| 142 |
+
(W&B run `xnjpitfg`, project `fibers`, `val_hzvt_mean_dice`=0.60,
|
| 143 |
+
`val_hzvt_mean_iou`=0.52). That model predicts horizontal-vs-vertical
|
| 144 |
+
orientation from real annotations; this model predicts fiber-vs-background
|
| 145 |
+
from self-generated pseudo-labels. They are not directly comparable.
|
| 146 |
+
|
| 147 |
+
## Files
|
| 148 |
+
|
| 149 |
+
| File | Size | Role |
|
| 150 |
+
|---|---|---|
|
| 151 |
+
| `step_010000__post_dark_mask_fix__latest.pth` | ~2.1 GB | `model` (raw) + `ema.model_state` (recommended for inference) + `optimizer` + embedded `config`. |
|
| 152 |
+
| `config.json` | — | The same training config embedded in the checkpoint, for quick inspection without loading the full file. |
|
| 153 |
+
|
| 154 |
+
## Usage
|
| 155 |
+
|
| 156 |
+
```python
|
| 157 |
+
import torch
|
| 158 |
+
from huggingface_hub import hf_hub_download
|
| 159 |
+
|
| 160 |
+
path = hf_hub_download(
|
| 161 |
+
"scrollprize/fiber_dinoguided_2class_step010000",
|
| 162 |
+
"step_010000__post_dark_mask_fix__latest.pth",
|
| 163 |
+
)
|
| 164 |
+
ckpt = torch.load(path, map_location="cpu", weights_only=False)
|
| 165 |
+
state = ckpt["ema"]["model_state"] # recommended over ckpt["model"]
|
| 166 |
+
# Build with vesuvius' NetworkFromConfig (target "fibers", out_channels=2,
|
| 167 |
+
# in_channels=1, patch_size 256^3) then load_state_dict(state).
|
| 168 |
+
```
|
| 169 |
+
The `vesuvius` package is in <https://github.com/ScrollPrize/villa>.
|
| 170 |
+
|
| 171 |
+
## Related models
|
| 172 |
+
|
| 173 |
+
- **Frozen fiber teacher / weight init for this run:** [`scrollprize/fiber_selftrain_teacher_epoch30`](https://huggingface.co/scrollprize/fiber_selftrain_teacher_epoch30)
|
| 174 |
+
- **Frozen DINO backbone used for guidance:** [`scrollprize/dinovol_v2_ps8_supcon3class_step362500`](https://huggingface.co/scrollprize/dinovol_v2_ps8_supcon3class_step362500)
|
| 175 |
+
- **Prior supervised hz/vt model:** [`scrollprize/fiber_hz_vt`](https://huggingface.co/scrollprize/fiber_hz_vt)
|
| 176 |
+
|
| 177 |
+
## Links
|
| 178 |
+
|
| 179 |
+
- **Code:** <https://github.com/ScrollPrize/villa> — PR [#825](https://github.com/ScrollPrize/villa/pull/825) (cross-frame affine infra), PR [#985](https://github.com/ScrollPrize/villa/pull/985) (`scripts/fiber_5class`, the downstream 4-class trainer that consumes this checkpoint)
|
| 180 |
+
- **W&B run:** <https://wandb.ai/vesuvius-challenge/vesuvius_fibers_3d/runs/ihoo3tpl>
|
| 181 |
+
- **Data:** <https://scrollprize.org/data_browser>
|
| 182 |
+
- **Vesuvius Challenge:** <https://scrollprize.org>
|
| 183 |
+
|
| 184 |
+
## License
|
| 185 |
+
|
| 186 |
+
MIT.
|