PhenoSeq / README.md
naidooreed's picture
Update README.md
5c24e71 verified
|
Raw
History Blame Contribute Delete
7.6 kB
---
license: apache-2.0
tags:
- biology
- diffusion
- single-cell
- transcriptomics
- microscopy
- image-to-rna
- conditional-generation
- scgpt
- vit
datasets:
- altoslabs/scGeneScope
pipeline_tag: feature-extraction
model-index:
- name: PhenoSeq
results:
- task:
type: feature-extraction
name: Image-conditioned RNA-seq generation
metrics:
- type: loss
value: 0.1683
name: Validation MSE Loss (epoch 87)
---
# PhenoSeq: Image-Conditioned Diffusion for Single-Cell Transcriptomics
[![HuggingFace](https://img.shields.io/badge/πŸ€—%20HuggingFace-Sentinal4D/PhenoSeq-yellow)](https://huggingface.co/Sentinal4D/PhenoSeq)
[![Paper](https://img.shields.io/badge/Paper-OpenReview-blue)](https://openreview.net/forum?id=ACHMa1e8J1)
[![GitHub](https://img.shields.io/badge/GitHub-reednaidoo/PhenoSeq-black?logo=github)](https://github.com/reednaidoo/PhenoSeq)
PhenoSeq is a Gaussian diffusion model that **generates scGPT RNA-seq embeddings conditioned on ViT-L microscopy imaging features**. Given fluorescence microscopy images of a cell or well, it predicts a 512-dimensional scGPT embedding representing the transcriptomic state of individual cells β€” enabling image-to-transcriptome translation at single-cell resolution.
## Model summary
| Property | Value |
|---|---|
| Input | ViT-L imaging features β€” `(N, 5120)` per sample (5 fluorescence channels Γ— 1,024 dims) |
| Output | scGPT embeddings β€” `(n_cells, 512)` |
| Architecture | Cross-attention diffusion denoiser |
| Diffusion steps | 1,000 (cosine schedule) |
| Inference steps | 50 (DDIM, default) |
| Model parameters | ~168 M |
| Training dataset | [scGeneScope](https://huggingface.co/datasets/altoslabs/scGeneScope) |
| Best val MSE loss | 0.1683 (epoch 87) |
## Architecture
The denoiser uses a **cross-attention transformer** stack:
1. **Imaging encoder** β€” 2-layer self-attention transformer projects `(B, N, 5120)` β†’ `(B, N, 1024)` context.
2. **RNA + time input** β€” noisy scGPT embedding and sinusoidal time embedding are projected to `model_dim`.
3. **Cross-attention blocks** (Γ—6) β€” RNA queries attend to imaging context, with self-attention and adaptive layer normalization conditioned on the timestep.
4. **Output projection** β€” predicts noise `Ξ΅ ∈ ℝ^{512}` for the denoising objective.
The diffusion process uses a cosine beta schedule over T=1,000 steps with EMA weight averaging (decay 0.9999).
## Quick start
```bash
pip install torch numpy huggingface_hub
python example.py
```
```python
import numpy as np
from pipeline import PhenoSeqPipeline
pipe = PhenoSeqPipeline.from_pretrained("Sentinal4D/PhenoSeq")
# img_features: ViT-L embeddings β€” (n_cells, n_imaging_cells=16, 5120)
img_features = np.random.randn(8, 16, 5120).astype(np.float32)
rna_predictions = pipe(img_features) # β†’ (8, 512)
```
## Inputs and outputs
### Input: imaging features
`img_features` must be ViT-L image embeddings extracted from **5 fluorescence channels** using a ViT-L/14 backbone, resulting in 5 Γ— 1,024 = 5,120 dimensions per imaging cell. Each sample/well typically provides **N = 16** imaging cells (evenly spaced from the available pool) that form the conditioning context.
Shape: `(B, N, 5120)` where `B` is the number of target RNA cells to predict.
> **Imaging normalisation** β€” `img_norm.npz` contains the per-feature mean and std computed from the training split of scGeneScope. These are applied automatically by `PhenoSeqPipeline`. If you work with a different dataset you will need to recompute and supply your own normalisation stats.
### Output: RNA embeddings
Shape: `(B, 512)` β€” scGPT-space embeddings un-normalized back to the original scGPT embedding scale. These can be used directly for downstream tasks such as cell-type classification (see `classify_improved.py`), clustering, or trajectory inference.
## Imaging normalisation stats
The pipeline requires `img_norm.npz` (per-feature mean and std from the training split). This file is distributed alongside `best_model.pt` in this repo. If you retrain or use different data, regenerate it:
```bash
python save_img_norm.py --config config.yaml --output img_norm.npz
```
## Full inference on scGeneScope data
For large-scale inference over the cached scGeneScope data (`.npz` per sample):
```bash
# Fast (DDIM, 50 steps)
python infer.py --checkpoint best_model.pt --ddim_steps 50
# Val split only
python infer.py --checkpoint best_model.pt --split val --output_dir results/predictions
# Full DDPM sampling (slower, ~1000 steps)
python infer.py --checkpoint best_model.pt --ddim_steps 0
```
Output: one `{Sample_ID}.npz` per sample under `results/predictions/`, with key `X` of shape `(n_cells, 512)`.
## Downstream: cell-type classification
Predicted RNA embeddings can be evaluated with the included classifier:
```bash
python classify_improved.py
```
## Training
The model was trained from scratch on scGeneScope using:
```bash
python train.py --config config.yaml
```
## Data
Training and evaluation data come from the [scGeneScope](https://huggingface.co/datasets/altoslabs/scGeneScope) dataset (Altos Labs):
- **Imaging features**: ViT-L/14 embeddings extracted from 5-channel fluorescence microscopy images, stored as `.h5ad` files.
- **RNA-seq features**: scGPT cell embeddings (512-dim) from paired single-cell RNA-seq, stored as `.h5ad` files.
- Samples are matched by `Sample_ID` at well level.
Prepare the local cache before training:
```bash
python prepare_data.py
```
## Repository structure
```
PhenoSeq/
β”œβ”€β”€ pipeline.py ← self-contained inference pipeline (start here)
β”œβ”€β”€ best_model.pt ← trained checkpoint with EMA weights & RNA norm stats
β”œβ”€β”€ img_norm.npz ← imaging normalisation stats (mean/std, training split)
β”œβ”€β”€ config.yaml ← full training configuration
β”œβ”€β”€ infer.py ← batch inference over cached scGeneScope data
β”œβ”€β”€ save_img_norm.py ← helper to (re)generate img_norm.npz
β”œβ”€β”€ train.py ← training entry point
β”œβ”€β”€ prepare_data.py ← extract imaging/RNA features β†’ .npz cache
β”œβ”€β”€ models/
β”‚ β”œβ”€β”€ denoiser.py ← cross-attention denoiser
β”‚ β”œβ”€β”€ diffusion.py ← Gaussian diffusion process (forward + reverse)
β”‚ └── lit_module.py ← PyTorch Lightning training wrapper
└── data/
└── dataset.py ← paired imaging-RNA dataset & dataloader
```
## Requirements
```
torch>=2.0
anndata>=0.10
numpy>=1.24
scipy>=1.10
PyYAML>=6.0
tqdm>=4.65
# Optional: huggingface_hub (for from_pretrained with a Hub repo id)
```
Install:
```bash
pip install -r requirements.txt
```
## License
Apache 2.0 β€” see [LICENSE](LICENSE).
## Citation
If you use PhenoSeq, please cite our paper:
```bibtex
@inproceedings{naidoo2026phenoseq,
title = {Cell Painting Generates Single-Cell Transcriptomics via Conditional Diffusion},
author = {Naidoo, Reed and Hu, Jingyu and Tripodi, Giuseppe and Bakal, Chris and Chakraborti, Tapabrata},
booktitle = {ICML 2026 Workshop on Multi-modal Foundation Models and Large Language Models for Life Sciences (FM4LS)},
year = {2026},
url = {https://openreview.net/forum?id=ACHMa1e8J1}
}
```
Please also cite the training dataset:
```bibtex
@dataset{scgenescope,
author = {Altos Labs},
title = {scGeneScope},
year = {2024},
publisher = {HuggingFace},
url = {https://huggingface.co/datasets/altoslabs/scGeneScope}
}
```