Add neuron_segneuron: BANIS+ trained on EMNeuron (200k steps, EMA); model card
Browse filesMean VI 0.870 / ARE 0.104 on SegNeuron 8 evaluation volumes (TTA16, ABISS merge 0.6 chosen on held-out training chunks). Tutorial: PytorchConnectomics/pytorch_connectomics tutorials/neuron_segneuron.
- README.md +67 -3
- neuron_segneuron/banis+.yaml +156 -0
- neuron_segneuron/banis_emneuron_200k.ckpt +3 -0
README.md
CHANGED
|
@@ -1,3 +1,67 @@
|
|
| 1 |
-
---
|
| 2 |
-
license: mit
|
| 3 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
library_name: pytorch-connectomics
|
| 4 |
+
pipeline_tag: image-segmentation
|
| 5 |
+
tags:
|
| 6 |
+
- connectomics
|
| 7 |
+
- electron-microscopy
|
| 8 |
+
- em
|
| 9 |
+
- neuron-segmentation
|
| 10 |
+
- instance-segmentation
|
| 11 |
+
- 3d
|
| 12 |
+
- affinity
|
| 13 |
+
- mednext
|
| 14 |
+
- biology
|
| 15 |
+
- neuroscience
|
| 16 |
+
- pytorch
|
| 17 |
+
datasets:
|
| 18 |
+
- yanchaoz/EMNeuron
|
| 19 |
+
---
|
| 20 |
+
|
| 21 |
+
# PyTorch Connectomics pretrained models
|
| 22 |
+
|
| 23 |
+
Pretrained checkpoints for [PyTorch Connectomics](https://github.com/PytorchConnectomics/pytorch_connectomics)
|
| 24 |
+
(PyTC) tutorials: 3D electron-microscopy (EM) segmentation of neurons and mitochondria. Each
|
| 25 |
+
folder holds one model; its PyTC tutorial has the config, the commands and the full results.
|
| 26 |
+
|
| 27 |
+
| folder | task | model | data | result | tutorial |
|
| 28 |
+
|---|---|---|---|---|---|
|
| 29 |
+
| [`neuron_segneuron/`](neuron_segneuron) | **neuron instance segmentation, any EM volume** (zero-shot or fine-tune) | BANIS+ (MedNeXt-L affinities + ABISS watershed) | EMNeuron, 10 labeled EM sources | mean VI 0.870 on SegNeuron's 8 evaluation volumes | [`neuron_segneuron`](https://github.com/PytorchConnectomics/pytorch_connectomics/tree/master/tutorials/neuron_segneuron) |
|
| 30 |
+
| [`neuron_nisb/`](neuron_nisb) | neuron instance segmentation | BANIS+ (MedNeXt-L + cc3d) | NISB base | NERL 0.601 | [`neuron_nisb`](https://github.com/PytorchConnectomics/pytorch_connectomics/tree/master/tutorials/neuron_nisb) |
|
| 31 |
+
| [`mito_lucchi++/`](mito_lucchi%2B%2B) | mitochondria semantic segmentation | MedNeXt-S | Lucchi++ | Jaccard 0.935 | [`mito_lucchi++`](https://github.com/PytorchConnectomics/pytorch_connectomics/tree/master/tutorials/mito_lucchi%2B%2B) |
|
| 32 |
+
|
| 33 |
+
## Segment neurons in your EM volume
|
| 34 |
+
|
| 35 |
+
`neuron_segneuron/banis_emneuron_200k.ckpt` is the general-purpose neuron model: trained on
|
| 36 |
+
EMNeuron, the EM database of [SegNeuron](https://github.com/yanchaoz/SegNeuron): 10 labeled
|
| 37 |
+
sources (AxonEM-H, AxonEM-M, CREMI, FIB-25, Hemibrain, J0126, Kasthuri, three Mira volumes),
|
| 38 |
+
6-9 nm in xy and 8-50 nm in z. Start here for a new EM volume; fine-tune if you have labels.
|
| 39 |
+
|
| 40 |
+
```bash
|
| 41 |
+
git clone https://github.com/PytorchConnectomics/pytorch_connectomics && cd pytorch_connectomics
|
| 42 |
+
# install: see QUICKSTART.md; ABISS (github.com/PytorchConnectomics/ABISS) decodes affinities
|
| 43 |
+
# input: a directory of <name>_img.h5 (one 3D uint8 dataset, ZYX)
|
| 44 |
+
ABISS_HOME=/path/to/abiss tutorials/neuron_segneuron/predict.sh /path/to/volumes /path/to/output
|
| 45 |
+
# -> /path/to/output/<name>_seg.h5 (neuron ids) and <name>_aff.h5 (affinities)
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
`predict.sh` downloads the checkpoint on first use. `TTA=1` adds 16-view test-time
|
| 49 |
+
augmentation; `MERGE=0.7` (default 0.6) splits more if neurons are merged.
|
| 50 |
+
|
| 51 |
+
Fine-tune on labeled volumes (`<name>_img.h5` + `<name>_seg.h5` instance labels):
|
| 52 |
+
|
| 53 |
+
```bash
|
| 54 |
+
tutorials/neuron_segneuron/finetune.sh /path/to/train /path/to/val /path/to/run
|
| 55 |
+
ABISS_HOME=/path/to/abiss tutorials/neuron_segneuron/predict.sh <printed checkpoint> /path/to/volumes /path/to/output
|
| 56 |
+
```
|
| 57 |
+
|
| 58 |
+
Download only the checkpoint:
|
| 59 |
+
|
| 60 |
+
```bash
|
| 61 |
+
hf download pytc/tutorial neuron_segneuron/banis_emneuron_200k.ckpt --local-dir checkpoints
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
## Citation
|
| 65 |
+
|
| 66 |
+
If you use these models, cite PyTorch Connectomics (arXiv:2112.05754); for the EMNeuron
|
| 67 |
+
model also cite SegNeuron (Zhang et al., MICCAI 2024), whose data it was trained on.
|
neuron_segneuron/banis+.yaml
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# BANIS+ on EMNeuron, SegNeuron's train/val split, with the MedNeXt training
|
| 2 |
+
# speed knobs.
|
| 3 |
+
#
|
| 4 |
+
# data: python scripts/prepare_emneuron.py --src /path/to/EMNeuron --out /path/to/emneuron_pytc
|
| 5 |
+
# train: python scripts/main.py --config tutorials/neuron_segneuron/banis+.yaml
|
| 6 |
+
# infer: python scripts/main.py --config tutorials/neuron_segneuron/banis+.yaml --mode test \
|
| 7 |
+
# --checkpoint <run>/checkpoints/last.ckpt
|
| 8 |
+
# score: python scripts/evaluate_emneuron.py --pred-dir <run>/results --gt /path/to/EMNeuron/valid
|
| 9 |
+
#
|
| 10 |
+
# Recipe = ../banis+.yaml (6-channel affinity, MedNeXt-L/k3, per-channel
|
| 11 |
+
# class-balanced BCE, EMA 0.999, erosion 2, AdamW + cosine, 200k steps) with
|
| 12 |
+
# these changes:
|
| 13 |
+
#
|
| 14 |
+
# AFFINITY LAYOUT -- ABISS's, not BANIS's: channels x, y, z (axes 2, 1, 0 of
|
| 15 |
+
# the ZYX arrays) and each edge (i-1, i) stored at voxel i (`deepem` mode,
|
| 16 |
+
# ABISS "destination" storage). The predictions go to decode_abiss as they
|
| 17 |
+
# are; the BANIS layout (z, y, x at the source voxel) needs a channel reversal
|
| 18 |
+
# and a one-voxel shift first.
|
| 19 |
+
#
|
| 20 |
+
# PATCH -- EMNeuron mixes 6-9 nm xy with 8-50 nm z, and a third of its volumes
|
| 21 |
+
# hold only 31-50 sections, so the 128^3 cube becomes [32, 128, 128] ZYX
|
| 22 |
+
# (SegNeuron trains on 20 x 128 x 128). MedNeXt-L is stride-16: 32/16 = 2.
|
| 23 |
+
# Long-range offsets are 10 voxels in x/y and 4 sections in z (BANIS uses 10 on
|
| 24 |
+
# every axis of a 9x9x20 nm volume; 10 sections would span a third of the
|
| 25 |
+
# patch). Destination storage needs the voxel at i - offset, so target_context
|
| 26 |
+
# reads 4/10/10 voxels on the leading side.
|
| 27 |
+
#
|
| 28 |
+
# AUGMENTATION -- aug_banis permutes z with y/x and rotates in 3D, which is
|
| 29 |
+
# wrong for anisotropic sections. aug_em_neuron_fast keeps flips, xy
|
| 30 |
+
# quarter-turns, contrast/brightness/noise and one section defect per sample;
|
| 31 |
+
# motion blur rejoins the defect set, and an xy-only scale jitter (+-20%,
|
| 32 |
+
# independent per axis) stands in for SegNeuron's anisotropic scaling. No 3D
|
| 33 |
+
# elastic: its isotropic displacement would move 30-50 nm sections by many slices.
|
| 34 |
+
#
|
| 35 |
+
# SPEED -- the MedNeXt training knobs: torch.compile with the shift-sum
|
| 36 |
+
# depthwise conv, fused AdamW with merged parameter groups (bf16, so no fp16
|
| 37 |
+
# GradScaler blocks fused clipping), cudnn.benchmark, the numba affine
|
| 38 |
+
# resampler, and a frozen MedNeXt dummy tensor so DDP runs with
|
| 39 |
+
# find_unused_parameters=false.
|
| 40 |
+
|
| 41 |
+
_base_:
|
| 42 |
+
- ../banis+.yaml
|
| 43 |
+
- dataset.yaml
|
| 44 |
+
|
| 45 |
+
experiment_name: emneuron_banis+
|
| 46 |
+
description: >-
|
| 47 |
+
BANIS+ (6-channel affinity, MedNeXt-L/k3, class-balanced BCE, EMA, erosion 2)
|
| 48 |
+
on SegNeuron's EMNeuron split: ABISS-layout affinities decoded with ABISS,
|
| 49 |
+
[32,128,128] patches, anisotropic EM augmentation, and the MedNeXt speed
|
| 50 |
+
knobs (compile + shift-sum depthwise, fused AdamW, bf16).
|
| 51 |
+
|
| 52 |
+
default:
|
| 53 |
+
system:
|
| 54 |
+
num_workers: 8
|
| 55 |
+
model:
|
| 56 |
+
input_size: [32, 128, 128]
|
| 57 |
+
output_size: [32, 128, 128]
|
| 58 |
+
compile: true
|
| 59 |
+
mednext_depthwise_impl: shift_sum
|
| 60 |
+
mednext_freeze_dummy_tensor: true
|
| 61 |
+
data:
|
| 62 |
+
dataloader:
|
| 63 |
+
# 308 small chunks: preload them all (~17 GB per DDP rank); banis.yaml's
|
| 64 |
+
# `lazy` profile targets the large NISB zarr.
|
| 65 |
+
profile: cached
|
| 66 |
+
use_lazy_zarr: false
|
| 67 |
+
use_cache: false
|
| 68 |
+
use_preloaded_cache_train: true
|
| 69 |
+
use_preloaded_cache_val: true
|
| 70 |
+
patch_size: [32, 128, 128]
|
| 71 |
+
target_context: [4, 10, 10, 0, 0, 0]
|
| 72 |
+
batch_size: 4
|
| 73 |
+
label_transform:
|
| 74 |
+
targets:
|
| 75 |
+
- name: affinity
|
| 76 |
+
kwargs:
|
| 77 |
+
offsets: ["0-0-1", "0-1-0", "1-0-0", "0-0-10", "0-10-0", "4-0-0"]
|
| 78 |
+
affinity_mode: deepem
|
| 79 |
+
augmentation:
|
| 80 |
+
profile: aug_em_neuron_fast
|
| 81 |
+
motion_blur:
|
| 82 |
+
enabled: true
|
| 83 |
+
prob: 1.0
|
| 84 |
+
sections: [0, 5]
|
| 85 |
+
kernel_size: 11
|
| 86 |
+
sigma_range: [1.0, 3.0]
|
| 87 |
+
full_section_prob: 0.5
|
| 88 |
+
partial_ratio_range: [0.25, 0.75]
|
| 89 |
+
affine:
|
| 90 |
+
enabled: true
|
| 91 |
+
prob: 0.5
|
| 92 |
+
rotate_range: [0.0, 0.0, 0.0]
|
| 93 |
+
scale_range: [0.0, 0.2, 0.2]
|
| 94 |
+
shear_range: [0.0, 0.0, 0.0]
|
| 95 |
+
fast_resample: true
|
| 96 |
+
inference:
|
| 97 |
+
# Predict with the EMA weights the recipe trains and validates.
|
| 98 |
+
checkpoint_weights: ema
|
| 99 |
+
model:
|
| 100 |
+
# Short-range x, y, z: already ABISS's channel order.
|
| 101 |
+
select_channel: [0, 1, 2]
|
| 102 |
+
window:
|
| 103 |
+
# Infer at the trained window: MedNeXt's per-sample GroupNorm makes the
|
| 104 |
+
# forward pass depend on the window extent.
|
| 105 |
+
window_size: [32, 128, 128]
|
| 106 |
+
sw_batch_size: 16
|
| 107 |
+
decoding:
|
| 108 |
+
steps:
|
| 109 |
+
# ABISS ws: watershed, size-dependent single linkage, dust removal. The
|
| 110 |
+
# runner's default edge storage is "destination", which this model writes.
|
| 111 |
+
# Thresholds selected on the 10 tune/ chunks (TTA16, lowest mean VI) by
|
| 112 |
+
# scripts/evaluate_emneuron.py, which also fills voxels ABISS leaves
|
| 113 |
+
# unlabeled with the nearest segment before scoring.
|
| 114 |
+
- template: decoding_abiss
|
| 115 |
+
kwargs:
|
| 116 |
+
abiss_home: /path/to/abiss
|
| 117 |
+
cli_args:
|
| 118 |
+
ws_high_threshold: 0.9
|
| 119 |
+
ws_low_threshold: 0.05
|
| 120 |
+
ws_size_threshold: 1000000000
|
| 121 |
+
ws_dust_threshold: 0
|
| 122 |
+
ws_merge_function: max
|
| 123 |
+
ws_merge_threshold: 0.6
|
| 124 |
+
evaluation:
|
| 125 |
+
# VI / adapted Rand are scored by scripts/evaluate_emneuron.py with the
|
| 126 |
+
# SegNeuron evaluator's exact calls; the volumes have no NERL skeletons.
|
| 127 |
+
enabled: false
|
| 128 |
+
|
| 129 |
+
test:
|
| 130 |
+
# Destination storage leaves the first voxel of every axis without an inside
|
| 131 |
+
# edge, so the test pipeline crops it from deepem predictions. One voxel of
|
| 132 |
+
# reflect context per side, minus the trailing voxel here, keeps the saved
|
| 133 |
+
# affinity on the input grid: ABISS reads it with no shift or pad.
|
| 134 |
+
data:
|
| 135 |
+
data_transform:
|
| 136 |
+
pad_size: [1, 1, 1]
|
| 137 |
+
inference:
|
| 138 |
+
model:
|
| 139 |
+
crop_pad: [0, 1, 0, 1, 0, 1]
|
| 140 |
+
|
| 141 |
+
train:
|
| 142 |
+
optimization:
|
| 143 |
+
precision: "bf16-mixed"
|
| 144 |
+
benchmark: true
|
| 145 |
+
optimizer:
|
| 146 |
+
fused: true
|
| 147 |
+
merge_param_groups: true
|
| 148 |
+
ddp_find_unused_parameters: false
|
| 149 |
+
val_check_interval: 10000
|
| 150 |
+
val_steps_per_epoch: 50
|
| 151 |
+
monitor:
|
| 152 |
+
checkpoint:
|
| 153 |
+
# Step checkpoints every 25k plus last.ckpt; the reported model is the
|
| 154 |
+
# final step, so the val-loss top-1 copy is kept for diagnostics only.
|
| 155 |
+
save_top_k: 1
|
| 156 |
+
save_every_n_steps: 25000
|
neuron_segneuron/banis_emneuron_200k.ckpt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8b763de15418698c08d057da95060a536d12c8a136c8a99e0fb8faf65d6ab914
|
| 3 |
+
size 494572982
|