非常好的问题!你提到的 SpatialHuman30M 数据集中采用了两大类空间转录组技术:成像型(imaging-based) 和 测序型(sequencing-based)。这是目前空间转录组研究中最核心的技术划分之一。
下面我会系统总结这两种方式的原理差异、技术代表、优缺点对比,并结合你列出的 Xenium、MERFISH、Visium、Visium HD 来分别讲解它们的技术特点与使用意义。
分类 | 成像型空间转录组 | 测序型空间转录组 |
---|---|---|
代表技术 | MERFISH, Xenium, seqFISH, CosMx | 10x Visium, Visium HD, Slide-seq |
数据获取方式 | 通过荧光成像识别RNA分子在组织切片中的位置 | 通过高通量测序读取转录本并结合位置条码还原空间分布 |
主要原理 | 原位杂交(FISH) + 图像识别 | 条码探针(barcode)定位 + RNA捕获 + RNA-seq |
直接在组织切片上,通过荧光探针原位杂交(FISH),结合高分辨率显微成像,将每个mRNA分子精确定位到单细胞甚至亚细胞水平。
技术 | 特点 |
---|---|
MERFISH | 基于多轮次荧光杂交编码,检测数百到数千个基因;精度高,分辨率达亚细胞级,空间结构精准 |
Xenium(10x Genomics) | 最新成像平台,支持 400+ 目标转录本检测,支持FFPE样本,兼具通量与空间分辨率 |
CosMx(NanoString) | 支持 RNA + 蛋白同时空间成像,适合细胞间互作分析 |
将组织切片放置在带有空间条码探针的芯片(如Visium)上,通过位置条码捕获组织中的mRNA,然后提取RNA进行高通量测序,将表达谱回推至空间位置。
技术 | 特点 |
---|---|
Visium | 主流平台,基于 55 μm 大小 spot,支持全转录组测序,空间分辨率中等 |
Visium HD | 10x 最新升级版,spot 缩小至 <5μm,空间分辨率接近单细胞 |
Slide-seqV2 | 用珠子阵列实现 10μm 分辨率的全转录组捕获,数据稀疏度高 |
比较维度 | Imaging-based(如Xenium, MERFISH) | Sequencing-based(如Visium) |
---|---|---|
空间分辨率 | ✅ 高(单细胞甚至亚细胞) | ⚠️ 中(Visium为55μm spot) |
检测通量 | ⚠️ 中(几百-几千基因) | ✅ 高(全转录组) |
成本 | 高 | 较低 |
适合用途 | 精细结构、生物互作验证 | Atlas构建、基因发现、区域表达 |
数据类型 | 图像 + 表达矩阵 | 表达矩阵 + 空间坐标 |
分析难度 | 图像分割复杂 | 表达建模复杂(需反卷积) |
技术 | 占比 | 使用目的 |
---|---|---|
Xenium (48%) | 大量使用,兼顾成像和商业可及性 | 在多个器官中精确定位细胞类型,用于组织微结构标注 |
MERFISH (40%) | 大规模精细标注 epithelial/免疫细胞位置 | 用作细胞互作、高保真空间验证 |
Visium/HD (12%) | 虽占比低,但是全转录组 backbone | 提供组织级表达图谱,是反卷积训练和标注核心来源 |
问题 | 答案 |
---|---|
为什么有成像和测序两类? | 因为两者各有优势:成像精准但通量低,测序全景但分辨率低,互补 |
Xenium和MERFISH的特点? | 都是成像型技术,分辨率极高,适合做cell type定位和组织微结构分析 |
Visium为什么也被使用? | 它是最成熟的测序型 ST平台,虽然分辨率不高,但可用于构建全器官转录组表达Atlas,是基础“骨架”数据 |
如果你需要,我可以:
是否继续?
A spatially resolved single-cell genomic atlas of the adult human breast 文章总结
你对空间结构分析部分的关注非常精准!这是目前空间组学中最具研究潜力的方向之一 —— 如何从表达数据中识别出组织结构与细胞互作的“空间逻辑”。下面我将围绕你关心的三项方法:
① Neighborhood enrichment analysis
② Graph-based tissue segmentation (STAGATE)
③ Spatial autocorrelation (Moran’s I)
进行详细解释,每一项都结合论文原文使用情况 + 原理 + 应用效果,帮助你建立空间建模完整认知。
识别不同细胞类型是否在组织切片中有特定的共定位模式,即:谁跟谁经常靠在一起?
在 Fig. 3 中,作者使用该方法分析:
原文:
“To investigate potential cell–cell interactions, we performed neighborhood enrichment analysis using spatial coordinates of smFISH-identified cells…”
应用 | 举例 |
---|---|
构建组织微环境图谱 | 发现免疫细胞聚集区域、上皮细胞嵌套结构 |
指导功能研究 | 识别免疫抑制区、旁分泌调控热点 |
增强空间反卷积可信度 | 如果某类细胞总是一起出现,可以作为结构先验 |
让ST表达数据不只是表达上的聚类,还能融合空间邻接信息,实现空间感知的组织分割。
工具名为:STAGATE
论文来源:Nature Communications, 2022
原文:
“We applied STAGATE to identify spatially coherent clusters that corresponded to histological regions across breast tissue…”
应用 | 说明 |
---|---|
提取组织功能模块 | 比如识别出整个腺泡区域 vs 免疫侵润区域 |
为反卷积提供区域先验 | Cluster 1可能是腺泡样结构,反卷积时只考虑上皮细胞亚型 |
跨样本组织结构对齐 | 多个患者的乳腺结构自动识别,便于meta分析 |
判断某个基因的表达在空间中是否“成片状”集中,还是“随机分布”。
I = N W ⋅ ∑ i ∑ j w i j ( x i − x ˉ ) ( x j − x ˉ ) ∑ i ( x i − x ˉ ) 2 I = \frac{N}{W} \cdot \frac{\sum_{i}\sum_{j} w_{ij}(x_i - \bar{x})(x_j - \bar{x})}{\sum_{i}(x_i - \bar{x})^2} I=WN⋅∑i(xi−xˉ)2∑i∑jwij(xi−xˉ)(xj−xˉ)
其中 w i j w_{ij} wij 是邻接矩阵, x i x_i xi 是表达值。
原文:
“We applied spatial autocorrelation analysis (Moran’s I) to the ST data to identify genes with spatially coherent expression patterns…”
应用 | 举例 |
---|---|
找到“空间 marker gene” | 比如某基因只在导管边缘表达,提示其结构功能作用 |
增强空间聚类可信度 | 可以作为 STAGATE 的空间特征补充输入 |
构建空间表达网络 | 聚集表达的基因可能共调控或功能相关 |
smFISH/CODEX定位的单细胞
↓
【1. Neighborhood Enrichment】
判断细胞类型间的空间共存关系
↓
反映微环境结构
ST表达谱
↓
[2. STAGATE 图聚类]
空间结构 + 表达模式 → 区域划分
↓
获得组织功能区域
ST表达谱
↓
[3. Moran’s I 空间自相关分析]
找到空间上富集的基因
方法 | 原理 | 在文中作用 | 应用意义 |
---|---|---|---|
Neighborhood Enrichment | 细胞间空间邻近频率统计 | 分析不同cell type是否共现 | 揭示细胞互动结构 |
STAGATE(图神经聚类) | GNN感知表达+空间图 | 拓扑一致的空间结构聚类 | 建立组织功能模块 |
Moran’s I | 空间统计:表达的聚集程度 | 找到空间显著表达基因 | 构建空间marker集 |
如果你希望深入分析或复现这些方法,我可以提供 Python 代码框架(如:用 scanpy
, squidpy
, torch-geometric
实现 STAGATE 和 Moran’s I),或帮助你将这些方法迁移到自己的数据集上。是否需要?
这部分内容围绕 scGPT-spatial 在细胞类型反卷积和基因表达插补任务中的应用 展开,结合技术原理与实验验证,展现其提升空间转录组数据解析能力的优势,以下是具体总结:
不同空间转录组技术存在互补性缺陷:
scGPT-spatial 聚焦解决这些问题,通过 参考数据驱动的细胞类型反卷积 + 基因表达插补,增强空间转录组数据的分辨率与基因覆盖度。
基于 Tangram 提出的 “检索式” 方法,核心流程分两步:
场景 1:MERFISH + scRNA-seq 参考(图 3C)
场景 2:Xenium + Visium 参考(图 3D)
scGPT-spatial 通过 检索式矩阵优化流程,有效解决空间转录组技术的 “混合细胞解析难”“基因覆盖不全” 问题:
(注:图中 A 是技术流程示意图,B - D 分别对应细胞反卷积、MERFISH 基因插补、Xenium 基因插补的实验结果可视化,用指标、热图、箱线图等对比不同方法表现 )
在细胞类型反卷积(cell - type deconvolution)任务中,ground truth(真实标签)的获取通常依赖于“金标准”数据或已知的参考信息 ,以下结合研究场景具体说明常见来源,也对应你提到的空间转录组研究里的反卷积场景:
单细胞测序(scRNA - seq)数据:
若研究目标是解析 Visium 等 “混合斑点” 的细胞类型,可先对同组织(或同类组织)做单细胞测序,筛选出 纯细胞类型的基因表达谱(比如纯上皮细胞、纯基质细胞的 scRNA - seq 数据 )。这些纯细胞的基因表达,就是反卷积中 “单个细胞类型应有的特征”,可作为反卷积的参考 ground truth 基础。
例如在文章里,反卷积会用 scRNA - seq 参考数据,本质是因为 scRNA - seq 能分离出纯细胞,其表达谱就是 “理想状态下该细胞类型的真实特征”,后续反卷积预测的混合斑点细胞占比,可与基于 scRNA - seq 推断的 “理论占比” 对比验证。
高分辨率成像技术数据(如 MERFISH、Xenium):
这类技术能实现单细胞 / 亚细胞分辨率的空间定位,若某组织先用 MERFISH 测过,已知每个小区域的纯细胞类型(比如明确标记出 “此处是纯内皮细胞” ),这些 高分辨率下的纯细胞标注,也能作为反卷积任务的 ground truth 。比如用 MERFISH 先给组织 “精准打标签”,再拿 Visium 低分辨率数据做反卷积,用 MERFISH 的标注验证结果。
组织学染色 + 专家注释:
对研究的组织切片,补充传统组织学染色(如免疫组化、荧光标记特定细胞类型),再由领域专家手动标注 “哪些区域是哪种细胞类型主导” 。这种 人工标注的 “细胞类型分布地图”,可作为反卷积结果的 ground truth 对比依据。
比如文章里提到的人类乳腺、胎儿肺数据集,可能就结合了这类专家注释的组织学信息,辅助确定 “真实的细胞类型分布”,用于验证反卷积是否准确。
公共数据库 / 已有研究的权威标注:
像人类大脑皮层、肿瘤组织等研究,已有大量公开的、经过验证的 “细胞类型空间分布” 标注(比如某脑区各层细胞类型的经典分布 )。新研究做反卷积时,可直接引用这些 领域内公认的标注 作为 ground truth ,验证算法是否能复现已知的细胞类型分布规律。
实际研究中,常 把 scRNA - seq 的纯细胞谱、高分辨率成像标注、组织学染色结果结合,交叉验证出更可靠的 ground truth 。比如:先用 scRNA - seq 确定组织里有哪些细胞类型及各自的基因特征,再用 MERFISH 看这些细胞在空间里的真实分布,最后结合组织学染色修正细节,形成一套 “多方共识” 的 ground truth ,用于反卷积模型的训练 / 验证。
简单说,反卷积的 ground truth 就是 “能精准反映‘每个空间位置实际细胞类型组成’的参考标准” ,核心靠 “纯细胞数据(scRNA - seq / 高分辨率成像) + 人工 / 领域标注 + 多技术交叉验证” 来构建,目的是给反卷积算法提供 “正确答案” ,判断其预测准不准~
如果你的研究场景里有特定数据集,想更细究,就得看对应论文 / 数据说明里的 “标注方法” 啦,不同研究可能结合自身数据特点选 ground truth 构建方式~
好的!咱们从 Tangram 核心逻辑 到 图中流程拆解 ,一步步讲清楚,保证你能看懂~
Tangram 是解决 “空间转录组数据解析” 的工具,主要干两件事:
核心逻辑是 “用‘参考数据’和‘目标数据’的‘矩阵匹配’,实现解析/插补” ,类似 “找参考和目标的映射关系,用参考‘补全/拆解’目标” 。
图里是 scGPT - spatial 结合 Tangram 逻辑的流程 ,但核心矩阵匹配逻辑和 Tangram 一致,咱们拆解成 3 步:
参考特征矩阵(粉色):
这是 “已知的、精准的细胞/基因特征” ,比如:
构建矩阵 ( M )(蓝色):
这是个 “待优化的映射关系” ,维度是 [目标斑点数 × 参考点/细胞数] 。简单说,( M ) 的每个元素 ( M_{i,j} ) ,表示 “参考里的第 ( j ) 个细胞/基因,对目标里的第 ( i ) 个斑点的‘贡献度’” 。
实际特征矩阵(黄色):
这是 “目标数据的特征” ,比如:
优化过程:
让 ( M \times \text{参考特征矩阵} \approx \text{实际特征矩阵} ) ,通过数学优化(比如非负矩阵分解、最小二乘法 ),调整 ( M ) 的值,直到 “参考×M” 尽可能接近 “实际特征” 。
这一步的核心是 “让 ( M ) 学到‘怎么用参考数据,去拟合目标数据的特征’” 。比如,若目标是混合斑点的基因表达,( M ) 就会学到 “哪些参考细胞类型,以什么比例混合,能生成目标斑点的表达” 。
反卷积(细胞类型拆解):
用 ( M \times \text{参考细胞类型矩阵} ) → 得到 “反卷积后的细胞类型比例” 。
解释:参考细胞类型矩阵里,存的是 “每个参考细胞属于哪种类型”(比如第 ( j ) 个参考细胞是上皮细胞,就标 1,其他标 0 )。乘以 ( M ) 后,就会算出 “每个目标斑点里,各种细胞类型的占比” 。
基因插补(补全基因表达):
用 ( M \times \text{参考基因表达矩阵} ) → 得到 “插补后的基因表达” 。
解释:参考基因表达矩阵里,存的是 “全基因的表达谱”(比如 Visium 测的全基因数据 )。乘以 ( M ) 后,就能给目标数据(比如 MERFISH 只测了几百个基因 )补全其他基因的表达。
简单总结 Tangram 逻辑:
图里的流程,就是把这一套逻辑可视化了:蓝色 ( M ) 是映射关系,粉色是参考,黄色是目标,优化 ( M ) 后,用 ( M ) 做反卷积/插补~
假设你想 “解析一碗混合果汁的成分”(类似解析混合斑点 ):
这样是不是就清楚啦?Tangram 本质是用 “矩阵匹配” 找参考和目标的关系,实现空间转录组数据的解析~ 核心就是 “用已知的精准参考,通过数学优化,解析未知的混合/低覆盖数据” !
你说得非常对,这种模型结构复杂的架构,确实应该**沿着“数据的流动顺序”**来讲,尤其是从 forward()
进入之后,怎么走 perceptual_forward()
和 generative_forward()
两条路径,它们又在内部如何处理,是需要结构清晰、流程式地梳理。
我们从 forward()
函数开始,带你一步步追踪数据是怎么在模型中流动的。你会清晰知道:
forward(**kwargs)
def forward(self, *args, **kwargs):
if "generative_training" not in kwargs:
return self.perceptual_forward(*args, **kwargs)
if kwargs.pop("generative_training"):
return self.generative_forward(*args, **kwargs)
else:
return self.perceptual_forward(*args, **kwargs)
根据 generative_training
参数选择模型走哪条路径:
False
→ 感知路径 perceptual_forward()
:输入一段表达值,输出预测与表示;True
→ 生成路径 generative_forward()
:输入一段“观测表达”,生成后续表达。perceptual_forward()
src: 基因ID序列
values: 对应表达值
src_key_padding_mask: mask
batch_labels: 可选,表示样本属于哪个批次
_encode()
def _encode(self, src, values, src_key_padding_mask, batch_labels)
src
→ GeneEncoder
→ gene token embeddingvalues
→ ValueEncoder
→ 表达值 embeddingtotal_embs
total_embs
送入 TransformerEncoder
→ transformer_output
⚠️ 如果有 batch_labels
,这个时候还没有用上,只是先保存下来。
self.decoder(...)
ExprDecoder
use_moe_dec=True
,用 MoeDecoder
走专家融合路径mlm_output = self.decoder(transformer_output)
如果设置了 explicit_zero_prob=True
,还会额外输出 zero_probs
表示稀疏概率。
_extend_output(...)
def _extend_output(self, transformer_output, CLS=True, MVC=True, ECS=True, ...)
会从 transformer_output
中提取 cell_emb
(方式有 cls/avg/w-pool),用于:
分支 | 功能 |
---|---|
ClsDecoder |
分类 |
MVCDecoder |
掩码值重建 |
AdversarialDiscriminator |
批次对抗 |
ECS Module |
相似度正则 loss |
MVCDecoder_Impute |
结合空间KNN进行表达补全(如果开启MVC_impute) |
所有这些模块的执行都取决于对应的布尔参数,如 CLS=True
才会执行分类任务。
generative_forward()
适用于生成式预训练:给出部分表达 → 生成另一部分表达。
pcpt_genes: 观测段 基因ID
pcpt_values: 观测段 表达值
pcpt_key_padding_mask: 观测段 mask
gen_genes: 生成段 基因ID
gen_key_padding_mask: 生成段 mask
transformer_generate()
def transformer_generate(self, pcpt_genes, pcpt_values, gen_genes, ...)
观测部分:
pcpt_genes
→ GeneEncoderpcpt_values
→ ValueEncoderpcpt_total_embs
生成部分:
gen_genes
→ GeneEncoderFlagEncoder(1)
表示“这是生成段” → gen_total_embs
拼接两个部分 → 输入 Transformer(共享结构)→ pcpt_output
, gen_output
transformer_output
transformer_output = cat([pcpt_output, gen_output])
decoder_output = self.decoder(transformer_output)
输出:
output["pcpt_preds"] = decoder_output[:pcpt_len]
output["gen_preds"] = decoder_output[pcpt_len:]
_extend_output(...)
同感知路径跟 perceptual_forward()
一样,会调用:
ClsDecoder
→ 分类MVCDecoder
→ 重建AdversarialDiscriminator
→ 批次ECS Module
→ 相似度约束MVCDecoder_Impute
→ 空间插值(使用 coordinates)forward()
├─ if generative_training:
│ └── generative_forward()
│ ├─ transformer_generate()
│ ├─ decoder (pcpt + gen)
│ └─ _extend_output() → 多任务
└── perceptual_forward()
├─ _encode()
├─ decoder
└─ _extend_output() → 多任务
我想知道数据在 forward 中是怎么一步步走的、在哪里被处理的。
答案总结如下:
步骤 | 哪个函数 | 做了什么 |
---|---|---|
入口 | forward |
判断走哪条路径(感知 or 生成) |
感知 | perceptual_forward → _encode |
将 src、values 编码成 total_embs,送入 Transformer |
生成 | generative_forward → transformer_generate |
编码观测和生成段,加上 flag 融合,送入 Transformer |
解码 | self.decoder() |
输出表达值(支持稀疏) |
多任务 | _extend_output() |
提取 cell_emb,调用分类、重建、对抗、ECS、空间插值等模块 |
如果你现在想:
.py
文件行号;我可以继续按你的节奏讲。现在是否需要把这段流程画成一张流程图?
你问的这句代码:
if input_cell_emb is not None:
pcpt_total_embs[:, 0, :] = input_cell_emb
在 transformer_generate()
函数中的作用是非常关键和特殊的,它强行覆盖了观测段序列中的第一个 token 的 embedding 表达。下面我从多个维度解释它的用意。
在 transformer_generate()
中:
pcpt_total_embs
是“观测段”输入部分,它由:
pcpt_token_embs + pcpt_values
构成,是 Transformer 的第一个输入。
input_cell_emb
是一个可选参数(Optional[Tensor]
),形状为:
(batch, embsize) or (batch, seq_len, embsize)
pcpt_total_embs[:, 0, :] = input_cell_emb
用外部提供的 cell embedding(input_cell_emb)替换掉观测段序列中的第一个 token 的 embedding。
也就是说:
pcpt_total_embs[:, 0, :]
是代表第一个 token(通常是 special token,比如
)的 embedding;用一个先验的 cell embedding 来“引导”Transformer在生成阶段如何编码上下文。
具体解释如下:
用意 | 描述 |
---|---|
① 引导生成 | 这相当于注入一个“高层语义表示”(整个细胞的embedding)给Transformer,以影响后续 token 的生成结果。 |
② 实现条件生成 | 如果你想“让这个模型模拟某个特定细胞”,就可以把那个细胞的 embedding 塞进去。 |
③ 控制潜在空间 | 这是常见于 CVAE / Diffusion / GPT-Conditional 生成中的一种做法:将先验表示注入模型。 |
④ 替换 [CLS] 位 |
该模型一般默认 token 0 是 [CLS] ,所以替换这一位就是替换整个序列的代表性 token。 |
假设你已经有一个训练好的模型,并得到了某个细胞的 cell_emb
表示。现在你想:
“基于这个细胞的语义表达,生成一段新的表达谱(即 gen_genes 的表达)。”
那么你就可以:
model.generate(
cell_emb=某个细胞的 cell_emb,
src=some_genes,
...
)
此时传入的 input_cell_emb
会用作 Transformer 的第一个 token 表示,用于调制 Transformer 的解码过程,从而实现 个性化、条件化的生成任务。
代码片段 | 作用 |
---|---|
pcpt_total_embs[:, 0, :] = input_cell_emb |
将整个输入序列的第一个位置(通常是 [CLS] token)替换为外部提供的 cell_emb ,用于条件控制或特定表达引导。 |
如你愿意,我可以帮你:
是否继续深入讲讲这种“条件注入机制”与 Transformer 控制生成的技术背景?
你的理解非常准确,而且已经抓住了核心逻辑。你说的这段:
✅ “这段代码负责生成一个 CLS token 的矩阵,有了这个细胞特征矩阵,接下来做其他任务就可以使用关于这个细胞的预训练信息了。”
完全正确。
下面我来帮你系统性地确认你的理解,并补充一些细节,帮你把整个细胞 embedding 的使用闭环构建完整。
这段代码的功能可以总结为:
get_batch_cell_embeddings(...)
的作用:将原始表达矩阵 AnnData(或类似 count_matrix)通过模型编码器处理,抽取每个细胞的
cell_emb
(即 Transformer 的[CLS]
输出向量),作为细胞的预训练表示。
genes = np.insert(..., 0, )
→ 在最前加
token;values = np.insert(..., 0, pad_value)
→ 对应地为
位置填一个无用值(稍后不参与预测)。_encode()
模型编码函数调用embeddings = model._encode(
input_gene_ids,
input_expr,
src_key_padding_mask,
batch_labels,
)
这一步走的路径是:
GeneEncoder
ValueEncoder
TransformerEncoder
hidden_states
你只取了:
embeddings = embeddings[:, 0, :] # 只取第一个 token,即 的位置
这就是 细胞的全局表示 cell embedding。
cell_embeddings
每一行代表一个细胞的全局向量(长度为 embsize
),比如 (num_cells, 512)
,你还做了 L2 归一化。
得到这个细胞表示矩阵之后,你可以在下游任务中使用它作为细胞的语义特征。
这是重点补充!
你前面看到:
if input_cell_emb is not None:
pcpt_total_embs[:, 0, :] = input_cell_emb
这句话就是:
把你这个 cell embedding 塞进 Transformer 的输入序列首位,让模型以这个“预设细胞语义”来生成后续表达值。
这种做法被称为 “prompt injection” / “semantic priming”。
你也可以直接拿这些 cell_embeddings
去做:
AdversarialDiscriminator
)你还可以:
用法 | 描述 |
---|---|
降维可视化 | 对 cell_embeddings 做 UMAP / PCA 可视化 |
和标签对齐 | 用已有的 cell type 标签训练分类器 |
生成实验 | 将 cell_emb 作为 prompt 做表达生成、perturbation simulation |
多模态融合 | 用其他模态(ATAC / 图像)训练模型,把它对齐到同一个 cell_emb 空间 |
你这段 get_batch_cell_embeddings()
是整个预训练模型的重要桥梁模块:
它将 稀疏的原始表达矩阵 → 通过 Transformer 提取 → 成为稠密的语义表示向量(CLS),进而作为各种下游任务的基础。
如你需要,我可以:
是否接下来你想看看“如何将这些 cell_emb 用在一个分类或生成任务中”?我可以写出完整调用示例。