masoudc commited on
Commit
01c4f63
·
verified ·
1 Parent(s): 6eb88bd

Initial demo: classification gallery + state-overlay/tracking videos

Browse files
.gitattributes CHANGED
@@ -33,3 +33,15 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ assets/gallery/fp_int2prem_0.gif filter=lfs diff=lfs merge=lfs -text
37
+ assets/gallery/miss_mit2int_0.gif filter=lfs diff=lfs merge=lfs -text
38
+ assets/gallery/miss_prem2int_0.gif filter=lfs diff=lfs merge=lfs -text
39
+ assets/gallery/miss_prem2int_1.gif filter=lfs diff=lfs merge=lfs -text
40
+ assets/gallery/ok_interphase_0.gif filter=lfs diff=lfs merge=lfs -text
41
+ assets/gallery/ok_interphase_1.gif filter=lfs diff=lfs merge=lfs -text
42
+ assets/gallery/ok_mitosis_0.gif filter=lfs diff=lfs merge=lfs -text
43
+ assets/gallery/ok_mitosis_1.gif filter=lfs diff=lfs merge=lfs -text
44
+ assets/gallery/ok_premitosis_0.gif filter=lfs diff=lfs merge=lfs -text
45
+ assets/gallery/ok_premitosis_1.gif filter=lfs diff=lfs merge=lfs -text
46
+ assets/videos/state_overlay.mp4 filter=lfs diff=lfs merge=lfs -text
47
+ assets/videos/trackid.mp4 filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,13 +1,33 @@
1
  ---
2
- title: Cell Cycle State Demo
3
- emoji: 📉
4
- colorFrom: yellow
5
- colorTo: purple
6
  sdk: gradio
7
- sdk_version: 6.16.0
8
- python_version: '3.13'
9
  app_file: app.py
10
  pinned: false
 
 
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Temporal Cell State Prediction
3
+ emoji: 🔬
4
+ colorFrom: blue
5
+ colorTo: red
6
  sdk: gradio
7
+ sdk_version: 5.49.1
 
8
  app_file: app.py
9
  pinned: false
10
+ license: mit
11
+ short_description: Frozen V-JEPA-2 predicts cell-cycle state in microscopy
12
  ---
13
 
14
+ # Temporal Cell State Prediction in Microscopy
15
+
16
+ A frozen **V-JEPA-2 ViT-L** encoder + a small attentive-pool head predicts per-cell
17
+ cell-cycle state (interphase / pre-mitosis / mitosis) directly from short single-cell
18
+ clips — replacing the *classify* stage of the conventional segment → track → classify
19
+ pipeline with a single clip → state model.
20
+
21
+ This Space serves **pre-computed** results (no heavy model load on the free CPU tier):
22
+
23
+ 1. **Classification gallery** — correct calls + the characteristic failure modes.
24
+ 2. **Videos** — whole-FOV predicted-state overlay + a Trackastra-style tracking view.
25
+ 3. **Counting** — the same frozen encoder probed for per-state cell counts (honest: beats a null on total, not per-state).
26
+ 4. **VLM point-reasoning** — a zero-shot "point at each nucleus then sum" baseline.
27
+
28
+ **Study finding:** in this small-data regime, **data scaling, not model scaling, is the
29
+ binding constraint** — moving the baseline from a small to a larger labelled dataset lifts
30
+ macro-F1 far more than an ~80× larger encoder does.
31
+
32
+ - Models: [`DnaRnaProteins/vjepa2-cell-cycle-vit-l`](https://huggingface.co/DnaRnaProteins/vjepa2-cell-cycle-vit-l), [`DnaRnaProteins/unet-bilstm-cell-cycle-baseline`](https://huggingface.co/DnaRnaProteins/unet-bilstm-cell-cycle-baseline)
33
+ - Data: MICCAI Cell Tracking Challenge — Fluo-N2DL-HeLa. Labels derived from lineage trees (no manual annotation).
__pycache__/app.cpython-314.pyc ADDED
Binary file (9.18 kB). View file
 
app.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Temporal Cell State Prediction — interactive demo (HF Space).
3
+
4
+ Frozen V-JEPA-2 ViT-L + a small attentive-pool head predicts per-cell cell-cycle
5
+ state (interphase / pre-mitosis / mitosis) directly from short single-cell clips,
6
+ replacing the classify stage of the segment->track->classify pipeline.
7
+
8
+ The Space serves PRE-COMPUTED results (no heavy model load on the free CPU tier):
9
+ a classification gallery (successes + failure modes), state-overlay + tracking videos,
10
+ the per-state counting probe, and a zero-shot VLM point-reasoning baseline.
11
+
12
+ Thesis of the study: in this small-data regime, *data scaling*, not model scaling,
13
+ is the binding constraint.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import json
19
+ from pathlib import Path
20
+
21
+ import gradio as gr
22
+
23
+ ASSETS = Path(__file__).parent / "assets"
24
+
25
+
26
+ def _load_json(name: str, default):
27
+ p = ASSETS / name
28
+ return json.loads(p.read_text()) if p.exists() else default
29
+
30
+
31
+ METRICS = _load_json("metrics.json", {})
32
+ GALLERY = _load_json("gallery/gallery_manifest.json", [])
33
+
34
+
35
+ # ── Header / thesis ───────────────────────────────────────────────────────────
36
+ HEADER = """
37
+ # 🔬 Temporal Cell State Prediction in Microscopy
38
+ **Frozen V-JEPA-2 ViT-L + attentive-pool head → per-cell cell-cycle state**, straight from a tracked clip —
39
+ no segment→track→**classify** hand-off.
40
+
41
+ > **Finding:** a frozen video foundation model is competitive with a purpose-built
42
+ > morphology–temporal baseline, and the binding constraint is **data scale, not model capacity.**
43
+ """
44
+
45
+
46
+ def _metrics_md() -> str:
47
+ m = METRICS
48
+ if not m:
49
+ return "_metrics.json not found_"
50
+ cm = m.get("confusion")
51
+ lines = [
52
+ "### Held-out HeLa (sequence 02, n=%s)" % m.get("n", "?"),
53
+ "",
54
+ "| model | macro-F1 | mitosis F1 | mitosis event P/R (±3fr) |",
55
+ "|---|---|---|---|",
56
+ f"| U-Net+BiLSTM baseline (3.8M) | {m.get('baseline_macro_f1','?')} | {m.get('baseline_mitosis_f1','?')} | {m.get('baseline_mit_pr','?')} |",
57
+ f"| **frozen V-JEPA-2 head-only** | **{m.get('vjepa_macro_f1','?')}** | {m.get('vjepa_mitosis_f1','?')} | {m.get('vjepa_mit_pr','?')} |",
58
+ "",
59
+ f"*Data scaling (GOWT1→HeLa) lifts the same baseline +0.186 macro-F1; ~80× model scaling adds only +0.046.*",
60
+ f"*Seed band: {m.get('seed_band','0.635 ± 0.098')} — single-seed gaps <0.08 are not significant.*",
61
+ ]
62
+ if cm:
63
+ lines += [
64
+ "",
65
+ "**Confusion matrix** (rows = true, cols = pred):",
66
+ "",
67
+ "| true ⧵ pred | interphase | pre-mitosis | mitosis | recall |",
68
+ "|---|---|---|---|---|",
69
+ ]
70
+ names = ["interphase", "pre-mitosis", "mitosis"]
71
+ for i, nm in enumerate(names):
72
+ row = cm[i]; rec = row[i] / max(sum(row), 1)
73
+ lines.append(f"| **{nm}** | {row[0]} | {row[1]} | {row[2]} | {rec:.2f} |")
74
+ lines.append("")
75
+ lines.append("*Dominant error: pre-mitosis→interphase — a soft, lineage-defined 8-frame window with no sharp morphological boundary.*")
76
+ return "\n".join(lines)
77
+
78
+
79
+ def _gallery_items():
80
+ items = []
81
+ for g in GALLERY:
82
+ img = ASSETS / "gallery" / g.get("gif", g.get("png", ""))
83
+ if img.exists():
84
+ tag = "✅" if g.get("correct") else "❌"
85
+ items.append((str(img), f"{tag} {g['title']} — {g['caption']}"))
86
+ return items
87
+
88
+
89
+ def build():
90
+ with gr.Blocks(title="Cell State Prediction Demo", theme=gr.themes.Soft()) as demo:
91
+ gr.Markdown(HEADER)
92
+ with gr.Tabs():
93
+ with gr.Tab("① Classification gallery"):
94
+ gr.Markdown("Single-cell clips → predicted state. Correct calls **and** the characteristic failure modes.")
95
+ gr.Gallery(value=_gallery_items(), columns=4, height=420,
96
+ object_fit="contain", label="input clip → prediction")
97
+ gr.Markdown(_metrics_md())
98
+
99
+ with gr.Tab("② Videos"):
100
+ gr.Markdown("Whole field-of-view over the held-out sequence.")
101
+ with gr.Row():
102
+ so = ASSETS / "videos" / "state_overlay.mp4"
103
+ ti = ASSETS / "videos" / "trackid.mp4"
104
+ if so.exists():
105
+ gr.Video(str(so), label="Predicted cell-cycle state (blue=interphase, amber=pre-mitosis, red=mitosis)", autoplay=True)
106
+ if ti.exists():
107
+ gr.Video(str(ti), label="Trackastra-style tracking (colour = track ID)", autoplay=True)
108
+
109
+ with gr.Tab("③ VLM point-reasoning (zero-shot)"):
110
+ gr.Markdown("A frontier VLM prompted to **point at each nucleus while reasoning**, then sum per state — "
111
+ "the 'visual primitives' recipe. Zero-shot baseline (no fine-tune); OOD-limited, shown for interpretability.")
112
+ vlm = ASSETS / "vlm" / "vlm_overlay.png"
113
+ if vlm.exists():
114
+ gr.Image(str(vlm), label="VLM predicted points (○) vs ground-truth centroids (×)")
115
+ gr.Markdown((ASSETS / "vlm" / "vlm_trace.md").read_text() if (ASSETS / "vlm" / "vlm_trace.md").exists() else "")
116
+
117
+ gr.Markdown("---\nModels: `DnaRnaProteins/vjepa2-cell-cycle-vit-l`, `DnaRnaProteins/unet-bilstm-cell-cycle-baseline` · "
118
+ "Data: MICCAI Cell Tracking Challenge (Fluo-N2DL-HeLa). Labels derived from lineage trees (no manual annotation).")
119
+ return demo
120
+
121
+
122
+ if __name__ == "__main__":
123
+ build().launch()
assets/gallery/fp_int2prem_0.gif ADDED

Git LFS Details

  • SHA256: 6a4faeb44091663c281770665ffa6097f3caad1b086cccf873553b6d7d4f4b75
  • Pointer size: 131 Bytes
  • Size of remote file: 261 kB
assets/gallery/fp_int2prem_0.png ADDED
assets/gallery/gallery_manifest.json ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "gif": "ok_interphase_0.gif",
4
+ "png": "ok_interphase_0.png",
5
+ "true": "interphase",
6
+ "pred": "interphase",
7
+ "conf": 1.0,
8
+ "caption": "true=interphase -> pred=interphase (1.00)",
9
+ "category": "ok_interphase",
10
+ "title": "Correct: interphase",
11
+ "cell_id": 2,
12
+ "t": 9,
13
+ "correct": true
14
+ },
15
+ {
16
+ "gif": "ok_interphase_1.gif",
17
+ "png": "ok_interphase_1.png",
18
+ "true": "interphase",
19
+ "pred": "interphase",
20
+ "conf": 1.0,
21
+ "caption": "true=interphase -> pred=interphase (1.00)",
22
+ "category": "ok_interphase",
23
+ "title": "Correct: interphase",
24
+ "cell_id": 460,
25
+ "t": 62,
26
+ "correct": true
27
+ },
28
+ {
29
+ "gif": "ok_premitosis_0.gif",
30
+ "png": "ok_premitosis_0.png",
31
+ "true": "pre-mitosis",
32
+ "pred": "pre-mitosis",
33
+ "conf": 1.0,
34
+ "caption": "true=pre-mitosis -> pred=pre-mitosis (1.00)",
35
+ "category": "ok_premitosis",
36
+ "title": "Correct: pre-mitosis",
37
+ "cell_id": 369,
38
+ "t": 45,
39
+ "correct": true
40
+ },
41
+ {
42
+ "gif": "ok_premitosis_1.gif",
43
+ "png": "ok_premitosis_1.png",
44
+ "true": "pre-mitosis",
45
+ "pred": "pre-mitosis",
46
+ "conf": 1.0,
47
+ "caption": "true=pre-mitosis -> pred=pre-mitosis (1.00)",
48
+ "category": "ok_premitosis",
49
+ "title": "Correct: pre-mitosis",
50
+ "cell_id": 259,
51
+ "t": 32,
52
+ "correct": true
53
+ },
54
+ {
55
+ "gif": "ok_mitosis_0.gif",
56
+ "png": "ok_mitosis_0.png",
57
+ "true": "mitosis",
58
+ "pred": "mitosis",
59
+ "conf": 1.0,
60
+ "caption": "true=mitosis -> pred=mitosis (1.00)",
61
+ "category": "ok_mitosis",
62
+ "title": "Correct: mitosis",
63
+ "cell_id": 711,
64
+ "t": 44,
65
+ "correct": true
66
+ },
67
+ {
68
+ "gif": "ok_mitosis_1.gif",
69
+ "png": "ok_mitosis_1.png",
70
+ "true": "mitosis",
71
+ "pred": "mitosis",
72
+ "conf": 1.0,
73
+ "caption": "true=mitosis -> pred=mitosis (1.00)",
74
+ "category": "ok_mitosis",
75
+ "title": "Correct: mitosis",
76
+ "cell_id": 298,
77
+ "t": 32,
78
+ "correct": true
79
+ },
80
+ {
81
+ "gif": "miss_prem2int_0.gif",
82
+ "png": "miss_prem2int_0.png",
83
+ "true": "pre-mitosis",
84
+ "pred": "interphase",
85
+ "conf": 1.0,
86
+ "caption": "true=pre-mitosis -> pred=interphase (1.00)",
87
+ "category": "miss_prem2int",
88
+ "title": "Failure: pre-mitosis read as interphase",
89
+ "cell_id": 584,
90
+ "t": 38,
91
+ "correct": false
92
+ },
93
+ {
94
+ "gif": "miss_prem2int_1.gif",
95
+ "png": "miss_prem2int_1.png",
96
+ "true": "pre-mitosis",
97
+ "pred": "interphase",
98
+ "conf": 1.0,
99
+ "caption": "true=pre-mitosis -> pred=interphase (1.00)",
100
+ "category": "miss_prem2int",
101
+ "title": "Failure: pre-mitosis read as interphase",
102
+ "cell_id": 302,
103
+ "t": 8,
104
+ "correct": false
105
+ },
106
+ {
107
+ "gif": "miss_mit2int_0.gif",
108
+ "png": "miss_mit2int_0.png",
109
+ "true": "mitosis",
110
+ "pred": "interphase",
111
+ "conf": 1.0,
112
+ "caption": "true=mitosis -> pred=interphase (1.00)",
113
+ "category": "miss_mit2int",
114
+ "title": "Failure: missed mitosis (read as interphase)",
115
+ "cell_id": 586,
116
+ "t": 46,
117
+ "correct": false
118
+ },
119
+ {
120
+ "gif": "fp_int2prem_0.gif",
121
+ "png": "fp_int2prem_0.png",
122
+ "true": "interphase",
123
+ "pred": "pre-mitosis",
124
+ "conf": 1.0,
125
+ "caption": "true=interphase -> pred=pre-mitosis (1.00)",
126
+ "category": "fp_int2prem",
127
+ "title": "Failure: interphase over-called pre-mitosis",
128
+ "cell_id": 783,
129
+ "t": 8,
130
+ "correct": false
131
+ }
132
+ ]
assets/gallery/miss_mit2int_0.gif ADDED

Git LFS Details

  • SHA256: 5da69d47546d0728259732967fd6b71ec470a89f69b3383d1d81657b9f042697
  • Pointer size: 131 Bytes
  • Size of remote file: 270 kB
assets/gallery/miss_mit2int_0.png ADDED
assets/gallery/miss_prem2int_0.gif ADDED

Git LFS Details

  • SHA256: d6d1a32f26b4611fd6166f3a7b25f2e3909d7d6d0800be6f961b1e0e51ed5604
  • Pointer size: 131 Bytes
  • Size of remote file: 271 kB
assets/gallery/miss_prem2int_0.png ADDED
assets/gallery/miss_prem2int_1.gif ADDED

Git LFS Details

  • SHA256: f1f0fac4ba327da20a6916b5c383012140340278e74ca84cef7a0529662061b3
  • Pointer size: 131 Bytes
  • Size of remote file: 265 kB
assets/gallery/miss_prem2int_1.png ADDED
assets/gallery/ok_interphase_0.gif ADDED

Git LFS Details

  • SHA256: 22ea4871356b1b93dec1e520f38092ecce96db78dde76f5bfb0b73062446f771
  • Pointer size: 131 Bytes
  • Size of remote file: 243 kB
assets/gallery/ok_interphase_0.png ADDED
assets/gallery/ok_interphase_1.gif ADDED

Git LFS Details

  • SHA256: 93df867a84ee6b2fb9667dcfffe3c07df0e1d194d1b26396be6ffade6a430f8a
  • Pointer size: 131 Bytes
  • Size of remote file: 285 kB
assets/gallery/ok_interphase_1.png ADDED
assets/gallery/ok_mitosis_0.gif ADDED

Git LFS Details

  • SHA256: b077b1351fce3a6b91c1397a57335abd4d2900cfafc6ff90cb301fa9924016eb
  • Pointer size: 131 Bytes
  • Size of remote file: 274 kB
assets/gallery/ok_mitosis_0.png ADDED
assets/gallery/ok_mitosis_1.gif ADDED

Git LFS Details

  • SHA256: 7c1ba118db05774cba1b71485066195504fb66643aa8353798aa5eee21d5cf24
  • Pointer size: 131 Bytes
  • Size of remote file: 277 kB
assets/gallery/ok_mitosis_1.png ADDED
assets/gallery/ok_premitosis_0.gif ADDED

Git LFS Details

  • SHA256: 63291c5fe5b721b52f2b5b6d5319c6ade26dee7dcfee5a2cc7e7225c94a47ab0
  • Pointer size: 131 Bytes
  • Size of remote file: 282 kB
assets/gallery/ok_premitosis_0.png ADDED
assets/gallery/ok_premitosis_1.gif ADDED

Git LFS Details

  • SHA256: ac032ef1987e9b1bca8d5e4832b7144ede507fef89a7234b84c3b7a41365ce31
  • Pointer size: 131 Bytes
  • Size of remote file: 267 kB
assets/gallery/ok_premitosis_1.png ADDED
assets/metrics.json ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "baseline_macro_f1": "0.629",
3
+ "baseline_mitosis_f1": "0.599",
4
+ "baseline_mit_pr": "0.65 / 0.62",
5
+ "vjepa_mitosis_f1": "0.681",
6
+ "vjepa_mit_pr": "0.69 / 0.74",
7
+ "seed_band": "0.635 \u00b1 0.098 (3 seeds)",
8
+ "counting_md": "**Total count:** the density head beats a mean-count null and a classical blob detector by ~3\u20135\u00d7. **Per-state:** it does *not* beat the null \u2014 interphase MAE stays high and pre-mitosis/mitosis look low only because predicting ~0 is almost right. The data bottleneck recurs (report Appendix C).",
9
+ "n": 5312,
10
+ "vjepa_macro_f1": "0.6776",
11
+ "confusion": [
12
+ [
13
+ 4550,
14
+ 211,
15
+ 52
16
+ ],
17
+ [
18
+ 173,
19
+ 136,
20
+ 14
21
+ ],
22
+ [
23
+ 44,
24
+ 7,
25
+ 125
26
+ ]
27
+ ]
28
+ }
assets/videos/state_overlay.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:991fc1ed3db265d3b86776566a89f4d911b0969247eaa19b6e9dd169c3fd72cc
3
+ size 22679054
assets/videos/trackid.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fe2b552191a1b145602db385554e90040fa542b2c4536ad26ba4982db6cc871e
3
+ size 22132096
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ gradio>=5