Spaces:
Sleeping
Sleeping
Inter font; single Classify view; remove Videos + VLM tabs
Browse files- README.md +3 -6
- app.py +21 -38
- assets/videos/state_overlay.mp4 +0 -3
- assets/videos/trackid.mp4 +0 -3
README.md
CHANGED
|
@@ -18,12 +18,9 @@ cell-cycle state (interphase / pre-mitosis / mitosis) directly from short single
|
|
| 18 |
clips β replacing the *classify* stage of the conventional segment β track β classify
|
| 19 |
pipeline with a single clip β state model.
|
| 20 |
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 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
|
|
|
|
| 18 |
clips β replacing the *classify* stage of the conventional segment β track β classify
|
| 19 |
pipeline with a single clip β state model.
|
| 20 |
|
| 21 |
+
Pick a single-cell clip and the model classifies it into its cell-cycle state β shown
|
| 22 |
+
as **predicted vs actual**. The selector tags each clip β
correct / β misclassified so
|
| 23 |
+
you can inspect both. Held-out test-set metrics (n=5,312) are in the collapsible panel.
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
**Study finding:** in this small-data regime, **data scaling, not model scaling, is the
|
| 26 |
binding constraint** β moving the baseline from a small to a larger labelled dataset lifts
|
app.py
CHANGED
|
@@ -117,46 +117,29 @@ def _metrics_md() -> str:
|
|
| 117 |
return "\n".join(lines)
|
| 118 |
|
| 119 |
|
|
|
|
|
|
|
|
|
|
| 120 |
def build():
|
| 121 |
-
with gr.Blocks(title="Temporal State Prediction", theme=
|
| 122 |
gr.Markdown(HEADER)
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
with gr.Accordion("Held-out test-set metrics (all 5,312 clips)", open=False):
|
| 141 |
-
gr.Markdown(_metrics_md())
|
| 142 |
-
|
| 143 |
-
with gr.Tab("β‘ Videos"):
|
| 144 |
-
gr.Markdown("Whole field-of-view over the held-out sequence.")
|
| 145 |
-
with gr.Row():
|
| 146 |
-
so = ASSETS / "videos" / "state_overlay.mp4"
|
| 147 |
-
ti = ASSETS / "videos" / "trackid.mp4"
|
| 148 |
-
if so.exists():
|
| 149 |
-
gr.Video(str(so), label="Predicted cell-cycle state (blue=interphase, amber=pre-mitosis, red=mitosis)", autoplay=True)
|
| 150 |
-
if ti.exists():
|
| 151 |
-
gr.Video(str(ti), label="Trackastra-style tracking (colour = track ID)", autoplay=True)
|
| 152 |
-
|
| 153 |
-
with gr.Tab("β’ VLM point-reasoning (zero-shot)"):
|
| 154 |
-
gr.Markdown("A frontier VLM prompted to **point at each nucleus while reasoning**, then sum per state β "
|
| 155 |
-
"the 'visual primitives' recipe. Zero-shot baseline (no fine-tune); OOD-limited, shown for interpretability.")
|
| 156 |
-
vlm = ASSETS / "vlm" / "vlm_overlay.png"
|
| 157 |
-
if vlm.exists():
|
| 158 |
-
gr.Image(str(vlm), label="VLM predicted points (β) vs ground-truth centroids (Γ)")
|
| 159 |
-
gr.Markdown((ASSETS / "vlm" / "vlm_trace.md").read_text() if (ASSETS / "vlm" / "vlm_trace.md").exists() else "")
|
| 160 |
|
| 161 |
gr.Markdown("---\nModels: `DnaRnaProteins/vjepa2-cell-cycle-vit-l`, `DnaRnaProteins/unet-bilstm-cell-cycle-baseline` Β· "
|
| 162 |
"Data: MICCAI Cell Tracking Challenge (Fluo-N2DL-HeLa). Labels derived from lineage trees (no manual annotation).")
|
|
|
|
| 117 |
return "\n".join(lines)
|
| 118 |
|
| 119 |
|
| 120 |
+
THEME = gr.themes.Soft(font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui", "sans-serif"])
|
| 121 |
+
|
| 122 |
+
|
| 123 |
def build():
|
| 124 |
+
with gr.Blocks(title="Temporal State Prediction", theme=THEME) as demo:
|
| 125 |
gr.Markdown(HEADER)
|
| 126 |
+
gr.Markdown("**Select a single-cell clip below** β the model classifies that one clip into its cell-cycle state.")
|
| 127 |
+
valid = _valid_indices()
|
| 128 |
+
first = valid[0] if valid else 0
|
| 129 |
+
img0, md0 = _clip_view(first) if valid else (None, "_no clips found_")
|
| 130 |
+
with gr.Row():
|
| 131 |
+
sel_clip = gr.Image(value=img0, label="selected clip", height=300)
|
| 132 |
+
sel_md = gr.Markdown(md0)
|
| 133 |
+
selector = gr.Gallery(value=_selector_items(), columns=10, height=170,
|
| 134 |
+
object_fit="cover", label="βΌ pick a clip (β
correct Β· β misclassified)",
|
| 135 |
+
allow_preview=False)
|
| 136 |
+
|
| 137 |
+
def _on_select(evt: gr.SelectData):
|
| 138 |
+
return _clip_view(evt.index)
|
| 139 |
+
selector.select(_on_select, inputs=None, outputs=[sel_clip, sel_md])
|
| 140 |
+
|
| 141 |
+
with gr.Accordion("Held-out test-set metrics (all 5,312 clips)", open=False):
|
| 142 |
+
gr.Markdown(_metrics_md())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
|
| 144 |
gr.Markdown("---\nModels: `DnaRnaProteins/vjepa2-cell-cycle-vit-l`, `DnaRnaProteins/unet-bilstm-cell-cycle-baseline` Β· "
|
| 145 |
"Data: MICCAI Cell Tracking Challenge (Fluo-N2DL-HeLa). Labels derived from lineage trees (no manual annotation).")
|
assets/videos/state_overlay.mp4
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:991fc1ed3db265d3b86776566a89f4d911b0969247eaa19b6e9dd169c3fd72cc
|
| 3 |
-
size 22679054
|
|
|
|
|
|
|
|
|
|
|
|
assets/videos/trackid.mp4
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:fe2b552191a1b145602db385554e90040fa542b2c4536ad26ba4982db6cc871e
|
| 3 |
-
size 22132096
|
|
|
|
|
|
|
|
|
|
|
|