Add model card
Browse files
README.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
tags:
|
| 4 |
+
- segmentation
|
| 5 |
+
- 3d
|
| 6 |
+
- seismic
|
| 7 |
+
- geoscience
|
| 8 |
+
- promptable
|
| 9 |
+
- unet
|
| 10 |
+
- pytorch
|
| 11 |
+
library_name: pytorch
|
| 12 |
+
pipeline_tag: image-segmentation
|
| 13 |
+
---
|
| 14 |
+
|
| 15 |
+
# GeoSeg3D — Promptable 3D Segmentation of Seismic Geo-Bodies
|
| 16 |
+
|
| 17 |
+
A 4-channel 3D-UNet (4.77 M parameters) that extracts a single,
|
| 18 |
+
topologically-connected geological body (salt dome, paleo-channel, reef)
|
| 19 |
+
from a seismic probability cube, refinable by `+` / `−` user clicks at
|
| 20 |
+
interactive rate (~17 ms warm per click on RTX 5090).
|
| 21 |
+
|
| 22 |
+
The model is the AI core of the GeoSeg3D prototype; the full pipeline
|
| 23 |
+
(SEG-Y I/O, prompt heatmaps, single-CC + border-safe morphology
|
| 24 |
+
post-processing, Gradio web viewer, multi-seed evaluation harness)
|
| 25 |
+
lives in the GitHub repository:
|
| 26 |
+
|
| 27 |
+
> 🔗 **Code:** https://github.com/Cooler5D/geoseg3d
|
| 28 |
+
> 📓 **Walk-through notebook:** [`notebooks/demo.ipynb`](https://github.com/Cooler5D/geoseg3d/blob/master/notebooks/demo.ipynb)
|
| 29 |
+
> 📄 **Spec-format report:** [`REPORT.md`](https://github.com/Cooler5D/geoseg3d/blob/master/REPORT.md)
|
| 30 |
+
|
| 31 |
+
---
|
| 32 |
+
|
| 33 |
+
## Model details
|
| 34 |
+
|
| 35 |
+
| | |
|
| 36 |
+
|---|---|
|
| 37 |
+
| Architecture | 3D-UNet, base width 32, three down-levels (/1 /2 /4 /8) |
|
| 38 |
+
| Input channels | 4 — `[seismic, probability, pos_heatmap, neg_heatmap]` |
|
| 39 |
+
| Bottleneck | identity-init FiLM gate (γ=1, β=0 at start) |
|
| 40 |
+
| Regularisation | Dropout3d (p=0.1) — also used at inference for MC Dropout uncertainty |
|
| 41 |
+
| Parameters | 4,766,497 |
|
| 42 |
+
| Training data | 200 procedural synthetic scenes (cube 80³), 24 val |
|
| 43 |
+
| Targets | 3 classes: salt dome / paleo-channel / reef |
|
| 44 |
+
| Loss | BCE + Dice + 3.0·prompt-consistency (margin=10) + 2.0·click-region BCE |
|
| 45 |
+
| Augmentation | RandConv (p=0.3), σ jitter U[4, 12], D4 axial flips |
|
| 46 |
+
| Optimiser | AdamW, lr 1e-3, cosine schedule |
|
| 47 |
+
| Epochs | 30 (~16 min on RTX 5090, bf16 mixed precision) |
|
| 48 |
+
| Best ckpt selection | prompted Dice on val (selecting on no-prompt Dice removes prompt incentive) |
|
| 49 |
+
|
| 50 |
+
**Provenance:** the file `promptable.pt` ships with a sidecar
|
| 51 |
+
`promptable.pt.geoseg3d.json` carrying SHA-256, file size, training
|
| 52 |
+
timestamp, exact `torch.__version__`, Python version, platform, and
|
| 53 |
+
parameter count. The loader recomputes the hash at load and warns on
|
| 54 |
+
mismatch.
|
| 55 |
+
|
| 56 |
+
---
|
| 57 |
+
|
| 58 |
+
## Intended use
|
| 59 |
+
|
| 60 |
+
**Primary:** research prototype for the AI R&D task "promptable 3D
|
| 61 |
+
segmentation of one geo-body from a seismic probability cube". The model
|
| 62 |
+
is meant to be the AI core of a SAM-like interactive segmentation
|
| 63 |
+
pipeline for seismic interpretation.
|
| 64 |
+
|
| 65 |
+
**Inputs the model expects** (see `geoseg3d.PromptableSegmenter.from_cubes`):
|
| 66 |
+
- `seismic`: 3D float array, axis order `(Z, Y, X) = (samples, crosslines, inlines)`
|
| 67 |
+
- `probability`: 3D float array, same shape, values in `[0, 1]`
|
| 68 |
+
- `pos_clicks`, `neg_clicks`: lists of `(z, y, x)` voxel coordinates
|
| 69 |
+
|
| 70 |
+
**Out of scope:** standalone segmentation from raw seismic without a
|
| 71 |
+
probability cube; bodies that span the cube boundary
|
| 72 |
+
(`predict_logits_tiled` is the production path for cubes >256³ but is
|
| 73 |
+
not validated end-to-end on real surveys).
|
| 74 |
+
|
| 75 |
+
---
|
| 76 |
+
|
| 77 |
+
## How to use
|
| 78 |
+
|
| 79 |
+
```python
|
| 80 |
+
import torch
|
| 81 |
+
from huggingface_hub import hf_hub_download
|
| 82 |
+
from geoseg3d.segmenter_v2 import PromptableSegmenter
|
| 83 |
+
|
| 84 |
+
# Download the canonical checkpoint + provenance sidecar
|
| 85 |
+
ckpt_path = hf_hub_download(repo_id="Cooler3D/geoseg3d", filename="promptable.pt")
|
| 86 |
+
hf_hub_download(repo_id="Cooler3D/geoseg3d", filename="promptable.pt.geoseg3d.json")
|
| 87 |
+
|
| 88 |
+
# Build the segmenter (FiLM is auto-detected from the state-dict keys)
|
| 89 |
+
seg = PromptableSegmenter.from_cubes(
|
| 90 |
+
seismic=my_seismic_cube, # (Z, Y, X) float32
|
| 91 |
+
probability=my_probability_cube, # (Z, Y, X) float32, in [0, 1]
|
| 92 |
+
checkpoint=ckpt_path,
|
| 93 |
+
)
|
| 94 |
+
|
| 95 |
+
# Add positive / negative seeds and read the mask back
|
| 96 |
+
seg.add_positive((40, 40, 40))
|
| 97 |
+
seg.add_negative((10, 10, 10))
|
| 98 |
+
mask = seg.get_mask() # (Z, Y, X) uint8, single connected component
|
| 99 |
+
|
| 100 |
+
# Optional: MC Dropout uncertainty
|
| 101 |
+
mean, std = seg.predict_uncertainty(n_samples=10)
|
| 102 |
+
```
|
| 103 |
+
|
| 104 |
+
The full Gradio web viewer (click directly on a slice to drop a seed)
|
| 105 |
+
ships in the GitHub repository:
|
| 106 |
+
|
| 107 |
+
```bash
|
| 108 |
+
python -m geoseg3d webdemo --encoder /path/to/promptable.pt
|
| 109 |
+
# → http://localhost:7860
|
| 110 |
+
```
|
| 111 |
+
|
| 112 |
+
---
|
| 113 |
+
|
| 114 |
+
## Evaluation
|
| 115 |
+
|
| 116 |
+
**Multi-seed synthetic** (30 OOD seeds, cube 80³, three target classes,
|
| 117 |
+
mean ± std):
|
| 118 |
+
|
| 119 |
+
| Configuration | salt | channel | reef |
|
| 120 |
+
|---|---|---|---|
|
| 121 |
+
| Threshold(prob) + largest CC, **no AI** | 0.988 ± 0.002 | 0.171 ± 0.295 | 0.440 ± 0.143 |
|
| 122 |
+
| Promptable, no prompts (model alone) | 0.995 ± 0.001 | **0.658 ± 0.346** | **0.727 ± 0.177** |
|
| 123 |
+
| Promptable, +/− clicks, blend OFF | 0.995 ± 0.001 | **0.721 ± 0.229** | 0.724 ± 0.187 |
|
| 124 |
+
| Promptable, +/− clicks, blend ON (UX path) | 0.992 ± 0.001 | 0.384 ± 0.273 | 0.659 ± 0.187 |
|
| 125 |
+
|
| 126 |
+
**Headline number:** on the hard `channel` class, threshold-only median
|
| 127 |
+
IoU is 0.000 (thin sinuous bodies break into disjoint connected
|
| 128 |
+
components at the 0.5 cut). The trained network alone — no prompts, no
|
| 129 |
+
inference blend — lifts median to **0.814**. This is the project's
|
| 130 |
+
strongest "AI as core" evidence.
|
| 131 |
+
|
| 132 |
+
**F3 sim-to-real check** (Yalaudah 2019, Zechstein salt sub-cube,
|
| 133 |
+
probability computed from real seismic via class-independent local-std
|
| 134 |
+
heuristic — labels never enter the probability):
|
| 135 |
+
|
| 136 |
+
| Path | IoU | Dice |
|
| 137 |
+
|---|---:|---:|
|
| 138 |
+
| Promptable, no prompts (AI alone) | **0.709** | 0.830 |
|
| 139 |
+
|
| 140 |
+
Honest scope: real-data validation is **salt only**. Channel/reef on
|
| 141 |
+
real seismic (TGS Salt / SEAM / Volve) is on the future-work list.
|
| 142 |
+
|
| 143 |
+
For paired Wilcoxon p-values, full distribution stats, and ablation
|
| 144 |
+
discussion see [`README.md`](https://github.com/Cooler5D/geoseg3d/blob/master/README.md#multi-seed-synthetic-the-load-bearing-numbers).
|
| 145 |
+
|
| 146 |
+
---
|
| 147 |
+
|
| 148 |
+
## Limitations
|
| 149 |
+
|
| 150 |
+
1. Real-data validation covers Zechstein salt only; channels and reefs
|
| 151 |
+
are validated on synthetic only.
|
| 152 |
+
2. The concat-at-input architecture doesn't scale beyond ~256³ cubes on
|
| 153 |
+
32 GB VRAM; `predict_logits_tiled` is the production path but is not
|
| 154 |
+
validated end-to-end.
|
| 155 |
+
3. The click effect on `channel` is **directional but not statistically
|
| 156 |
+
established** at n=30 (paired Wilcoxon p=0.56, mean Δ +0.063 IoU,
|
| 157 |
+
median Δ −0.001).
|
| 158 |
+
4. `click_region_loss` uses GT as target — generalising the synthetic
|
| 159 |
+
prior locally rather than just enforcing "respect the click". A
|
| 160 |
+
constraint-style region loss is on the future-work list.
|
| 161 |
+
|
| 162 |
+
---
|
| 163 |
+
|
| 164 |
+
## Reproducing
|
| 165 |
+
|
| 166 |
+
```bash
|
| 167 |
+
git clone https://github.com/Cooler5D/geoseg3d
|
| 168 |
+
cd geoseg3d
|
| 169 |
+
uv venv --python 3.12 .venv && .venv\Scripts\activate
|
| 170 |
+
uv pip install --pre torch torchvision --index-url https://download.pytorch.org/whl/nightly/cu128
|
| 171 |
+
uv pip install -e .[viz,dev,web]
|
| 172 |
+
|
| 173 |
+
python scripts/cache_scenes.py --out data/cache_train --n 200 --cube 80
|
| 174 |
+
python scripts/cache_scenes.py --out data/cache_val --n 24 --cube 80
|
| 175 |
+
python -m geoseg3d.train_promptable \
|
| 176 |
+
--cache-train data/cache_train --cache-val data/cache_val \
|
| 177 |
+
--out checkpoints/promptable.pt --epochs 30
|
| 178 |
+
```
|
| 179 |
+
|
| 180 |
+
Training takes ~16 min on RTX 5090 (Blackwell, sm_120).
|
| 181 |
+
|
| 182 |
+
---
|
| 183 |
+
|
| 184 |
+
## Citation
|
| 185 |
+
|
| 186 |
+
If you use this model in research, please cite:
|
| 187 |
+
|
| 188 |
+
```
|
| 189 |
+
@misc{mursalov2026geoseg3d,
|
| 190 |
+
author = {Mursalov, Nadir},
|
| 191 |
+
title = {GeoSeg3D: Promptable 3D Segmentation of Geological Bodies from Seismic Probability Cubes},
|
| 192 |
+
year = {2026},
|
| 193 |
+
url = {https://github.com/Cooler5D/geoseg3d},
|
| 194 |
+
}
|
| 195 |
+
```
|
| 196 |
+
|
| 197 |
+
---
|
| 198 |
+
|
| 199 |
+
## License
|
| 200 |
+
|
| 201 |
+
MIT — see `LICENSE` in the source repository.
|