Back to Blog

PIE: Generalizing Perturbation Effects across Unseen Perturbations, Contexts and Datasets

从 Perturb-seq 的实验限制出发,理解 PIE 如何直接预测细胞群体层面的扰动效应,并泛化到未见过的扰动、细胞背景和数据集。

· 22 min read

在扰动生物学中,我们希望回答一个看似直接的问题:如果改变细胞中的某个基因,或者给细胞加入一种药物,它的基因表达会怎样变化?

PIE 关注的不只是如何拟合已经做过的实验,而是一个更有挑战性的问题:模型能否把已有实验中学到的规律,推广到未见过的扰动、细胞背景和数据集?

文章目录

术语速览

在介绍模型之前,先明确几个会反复出现的概念。

术语 通俗理解 在本文中是什么
Gene expression,基因表达 某个基因产生多少 RNA 模型预测的主要读数
Perturbation,扰动 主动改变细胞的某个因素 基因压低或小分子药物处理
Context,细胞背景 在什么样的细胞及状态下做实验 某种细胞系,也可以包含细胞因子刺激
Control,对照 没有接受目标扰动的细胞 用来判断扰动引起了什么变化
Differential expression,差异表达(DE) 干预组和对照组之间,某个基因的表达存在统计学差异 PIE 的一个核心预测目标

从 Perturb-seq 说起

本文中的遗传扰动主要通过 CRISPRi 实现,核心实验技术是 Perturb-seq。

可以先把 Perturb-seq 理解为:将基因扰动与单细胞 RNA 测序结合起来,从而知道每个细胞接受了什么干预,同时测量它的基因表达。原始数据大致可以表示成下面的矩阵:

细胞 接受的扰动 基因 A 表达 基因 B 表达 基因 C 表达 ……
细胞 1 对照 … … … …
细胞 2 对照 … … … …
细胞 3 压低 A … … … …
细胞 4 压低 A … … … …

同一种扰动通常会测量许多个细胞。即使这些细胞来自同一细胞系,它们之间也会存在生物学差异;与此同时,测量过程本身也会引入噪声。

这里有一个决定任务定义的关键限制:常规单细胞 RNA 测序需要破坏细胞,因此无法测量同一个细胞在干预前后的完整转录组。

实验通常得到的是:

一群对照细胞,以及另一群受到干预的细胞。

这意味着我们能够比较两群细胞,却没有每个细胞精确配对的“干预前—干预后”真值。

这正是 PIE 改变任务定义的出发点。

PIE 的核心想法:直接预测群体层面的扰动效应

一些方法会尝试生成“干预后单个细胞的表达状态”,再从生成的细胞中计算差异表达。

PIE 则直接问:

在这个细胞背景下施加这种扰动,哪些基因会改变?往哪个方向改变?改变多少?

因此,PIE 的一个训练样本可以写成:

\[(\text{细胞背景 } c,\ \text{扰动 } p)\]

对应的标签,是这一实验条件下每个基因的群体响应。

PIE 的一个重要选择,是让监督目标直接对应实验中能够较可靠计算的群体效应。这样做的代价是:模型不直接生成单细胞层面的异质性。

例如,一个基因可能在一半细胞中升高、在另一半细胞中降低,最终的群体平均值几乎不变。仅依靠群体平均响应,很难完整描述这种情况。

PIE 预测什么?

对于每个输出基因,PIE 同时给出三类结果。

输出 回答的问题 怎么理解
DE 概率 这个基因会不会发生差异表达? 一个分类或排序任务
Log fold change(LFC) 表达升高还是降低?比例变化多大? 带正负号的变化幅度
Delta expression 群体平均表达改变了多少? 干预组与对照组的平均表达差

其中,LFC 定义为:

\[\mathrm{LFC} = \log_2 \frac{\text{干预组平均归一化表达}}{\text{对照组平均归一化表达}}\]

直观上:

  • $\mathrm{LFC}=1$:平均表达变为原来的两倍;
  • $\mathrm{LFC}=-1$:平均表达变为原来的一半。

第三个输出 delta expression,是在 log 归一化表达空间中计算的均值之差,与 LFC 并不是同一个量。

在具体实现中,PIE 会把 delta expression 划分成若干区间,预测它属于哪个区间,而不是直接进行连续数值回归。

还需要注意:DE 是一个统计学标签。 本文通过 Wilcoxon 检验及多重检验校正来定义 DE。因此,“是否 DE”不仅受生物学效应影响,还会受到细胞数量、噪声和统计功效的影响。它不能被简单理解为“这个基因是否参与了响应”。

PIE 靠什么预测没有做过的实验?

PIE 主要依赖两类信息。

1. 已有的生物学知识

如果告诉模型“压低基因 A”,模型需要知道 A 是什么,而不能只接收到一个没有含义的编号。

对于遗传扰动,作者使用了以下信息:

信息 帮助模型知道什么
NCBI Gene 描述和注释 基因功能、通路及相关知识
ESM2 蛋白序列表示 目标基因编码蛋白的序列特征
STRING 网络表示 这个蛋白与哪些蛋白存在关联
DepMap 数据 这个基因被敲除后,对不同细胞系生存的影响

细胞背景则使用 Cellosaurus 中的细胞系描述。

对于药物扰动,输入包括药物描述、剂量和 SMILES 表示,以及其他实验中的转录、存活和形态响应。

因此,PIE 并不是一个只依靠表达矩阵训练的模型,而是在整合知识库、蛋白表示、网络信息和既有实验。

2. 与每个输出基因有关的实验线索

模型还会参考三种与输出基因有关的证据。假设现在要预测“在细胞 X 中压低 A”的效果:

证据 模型能够参考什么
对照平均表达 未处理的 X 细胞中,每个基因表达多少?
相同扰动的证据 在其他细胞中压低 A 时,哪些基因通常会响应?
相同背景的证据 在 X 细胞中施加其他扰动时,哪些基因通常容易响应?

后两类证据来自训练数据的汇总统计,包括响应的均值、标准差,以及上调、下调的比例。它们并不是待预测条件的实验结果。

因此,PIE 的预测更像是:

综合目标基因的功能、细胞的初始状态,以及相关干预实验的经验,推测这一次扰动可能引起的响应。

读懂 Figure 1:PIE 的模型接口

给定“细胞背景 $c$ + 扰动 $p$”,PIE 会对指定的每个基因 $g$,预测它是否发生差异表达,以及表达变化的方向和幅度。

PIE 模型架构:知识来源与逐基因证据经过 Encoder、Processor 和 Decoder,最终产生 DE、LFC 与 delta expression 三类预测。
Figure 1. PIE 的整体架构。左上角描述实验条件,左下角提供逐基因证据,中间的 Encoder–Processor–Decoder 融合这些信息,右侧的三个预测头输出群体层面的扰动响应。

先固定一个例子:我们究竟要求模型做什么?

假设我们要预测:

在 K562 细胞中,用 CRISPRi 压低基因 A,会让其他基因发生什么变化?

这里有三个不同的角色:

符号 本例 含义
$c$ K562 在什么细胞背景下做实验
$p$ CRISPRi 压低 A 施加什么干预
$g$ A、B、C、D…… 要预测哪个基因的响应

扰动基因 A 是输入条件的一部分,输出则覆盖成千上万个基因。

假设这次需要预测 $G=6{,}642$ 个基因,那么一次模型调用会返回:

  • 6,642 个差异表达概率;
  • 6,642 个带正负号的 LFC;
  • 6,642 个表达变化量的分箱分布。

一个样本代表一次实验条件,而不是一个细胞,也不是一个基因。 一个样本内部包含成千上万个逐基因预测任务。可以先把它写成:

\[\underbrace{(\text{K562},\ \text{压低 A})}_{\text{一个实验条件}} \longrightarrow \underbrace{\{\text{A 的响应},\text{B 的响应},\ldots\}}_{\text{所有输出基因的响应}}\]

不过,“输入一个细胞名称和一个基因名称”只是概念上的说法。真正送入网络的是下面这些数值特征。

1. Knowledge Sources:这是什么实验条件?

先看 Figure 1 左上角的 Knowledge Sources。这条路径回答:

在什么细胞中,对什么对象做干预?

对于“K562 中压低 A”,作者准备了以下资料,再将它们转换成 embedding:

来源 本例中使用的内容 原始表示
Context Description K562 的 Cellosaurus 描述 一个 3,072 维文本向量
Perturbation Description 基因 A 的 NCBI Gene 描述 一个 3,072 维文本向量
NCBI Gene Annotations A 的 GO、疾病关联、基因分组等注释 一串 2,048 维文本 token 向量
ESM2 A 编码蛋白的序列表示 对残基表示平均池化后的一个向量
STRING A 在蛋白关联网络中的表示 一个 512 维向量
DepMap 敲除 A 对不同细胞系存活的影响 跨 1,186 个细胞系的数值特征

这里有两个细节很重要。

第一,这条路径中的 ESM2 表示针对的是被扰动基因 A 所编码的蛋白,并不是把细胞中所有蛋白的序列都输入 ESM2。

第二,图中的 token 不能一律理解成一个氨基酸或一个基因。这里的 token 是一个可以被 attention 读取的向量:它可以代表整段细胞描述,也可以代表注释文本中的一个 token。

作者把各来源的向量分别映射到统一的 768 维,加上表示数据来源的类型向量,再将它们拼接起来:

\[X_{c,p}\in\mathbb{R}^{M\times768}\]

其中,$M$ 是这个实验条件拥有的知识 token 总数。不同基因的资料长度和数据库覆盖率不同,因此 $M$ 可以变化。如果某个数据库没有基因 A 的资料,就省略该来源对应的 token。

到这里,左上角已经准备好了一组“关于 K562 和 A 的知识向量”。

2. Per-gene Evidence:每个输出基因已有何种实验证据?

再看 Figure 1 左下角的 Per-gene evidence。它回答的不是“A 是什么”,而是:

对于要预测的基因 B,手里已经有哪些关于 B 表达行为的线索?

注意,我们现在从被扰动的 A,切换到了输出基因 B。每一个输出基因都有自己的三类证据:

证据通道 对输出基因 B 来说,具体是什么
Control Mean Evidence 未处理 K562 细胞中,B 的平均表达
Same-pert Evidence 在其他细胞背景中压低 A 时,B 通常怎样变化
Same-context Evidence 在 K562 中进行其他扰动时,B 通常怎样变化

最容易混淆的是后两项:

Same-pert:干预对象不变,换细胞背景。
Same-context:细胞背景不变,换干预对象。

例如,在预测“K562 中压低 A”时:

  • 已知“在 HepG2 中压低 A,B 会怎样变化”,属于 Same-pert;
  • 已知“在 K562 中压低 C,B 会怎样变化”,属于 Same-context;
  • “在 K562 中压低 A,B 的真实变化”是本次预测目标,不能作为证据输入。

两个响应通道并不输入所有原始细胞,而是输入训练响应的汇总统计,包括:

  • B 的表达变化量的均值和标准差;
  • B 的 LFC 的均值和标准差;
  • B 被判为上调或下调的比例;
  • 是否存在可用证据,以及贡献了多少个响应等辅助信息。

随后,各统计模块分别进行编码和拼接,再通过 fusion MLP,得到:

\[e_{c,p,B}\in\mathbb{R}^{128}\]

对所有输出基因重复这个过程:

\[E_{c,p}\in\mathbb{R}^{G\times128}\]

因此,左下角并不是一个全局的“细胞表达向量”,而是为每个输出基因准备的一份实验证据。同一个输出基因 B,在不同的待预测条件下,其证据向量也会发生变化。

3. NCBI Gene Info:现在要预测谁?

此时我们已经有了:

  • 左上角:这次实验是什么;
  • 左下角:每个输出基因已有的实验证据。

还缺一个问题:

模型怎样知道当前要输出的是 B,而不是 C?

作者为每个输出基因也准备了 NCBI Gene 描述的文本 embedding。以 B 为例:

\[t_B\in\mathbb{R}^{3072}\]

它先经过 query MLP,被映射到 768 维;随后,B 的 128 维证据向量经过 query adapter 映射到相同维度。二者相加并归一化:

\[q_{c,p,B}=\operatorname{Norm}\!\left[ \operatorname{MLP}_{\mathrm{gene}}(t_B) +\operatorname{Adapter}_{\mathrm{evidence}}(e_{c,p,B}) \right]\]

最终得到:

\[q_{c,p,B}\in\mathbb{R}^{768}\]

这就是 gene query。可以把它理解成一个带有背景的问题:

“我是基因 B,已有这些实验证据。请告诉我,在 K562 中压低 A 后,我会怎样变化?”

所有输出基因的问题合在一起:

\[Q_{c,p}\in\mathbb{R}^{G\times768}\]

这也解释了 Figure 1 中两个看起来相似、实际角色不同的 NCBI 输入:

位置 描述谁 作用
左上角 NCBI Gene Info 被扰动的基因 A 说明“干预对象是谁”
下方 NCBI Gene Info 每个输出基因 B、C、D…… 说明“现在预测谁”

即使输出基因恰好也是 A,它在两条路径中仍然承担不同的角色,并使用不同的投影模块。

4. Encoder–Processor–Decoder:模型在传递什么?

现在再看图中间的蓝色大框。

Encoder:让固定数量的 latent 读取实验知识

模型首先维护一组可学习的初始向量:

\[Z_0\in\mathbb{R}^{512\times768}\]

这 512 个 latent 是模型参数,并不是 512 个细胞、512 个基因或 512 条实验。它们通过 cross-attention 读取左上角的知识 token:

\[Z_{\mathrm{enc}}=\operatorname{Encoder}(Z_0,X_{c,p})\]
Attention 中的角色 来自哪里
Query 512 个 latent
Key、Value 细胞背景与扰动的知识 token

无论知识输入包含多少个 token,读取后始终得到:

\[Z_{\mathrm{enc}}\in\mathbb{R}^{512\times768}\]

Processor:让 latent 彼此交流

Processor 使用 latent 之间的 self-attention:

\[Z_{\mathrm{proc}}=\operatorname{Processor}(Z_{\mathrm{enc}})\]

张量形状仍然保持为:

\[Z_{\mathrm{proc}}\in\mathbb{R}^{512\times768}\]

可以把它理解成模型整合后的“本次实验条件表示”。

Decoder:让每个输出基因读取条件表示

这一次,cross-attention 的方向发生了变化:

Attention 中的角色 来自哪里
Query 每个基因的 gene query
Key、Value Processor 输出的 latent

于是:

\[H_{c,p}=\operatorname{Decoder}(Q_{c,p},Z_{\mathrm{proc}}) \in\mathbb{R}^{G\times768}\]

其中第 B 行:

\[h_{c,p,B}\in\mathbb{R}^{768}\]

表示“结合本次细胞背景、扰动知识和 B 的实验证据后,得到的 B 的响应特征”。

这里有一个关键的结构细节:输出基因的 query 之间没有直接的 self-attention。 B、C、D 都会读取共享的 latent,但在解码时不会彼此直接交换信息。

因此,这套结构并没有显式构建一个“B 调控 C、C 再调控 D”的动态模拟过程。

5. 三个 Prediction Heads:把逐基因特征变成答案

对于输出基因 B,decoder 会生成一个 768 维特征。进入每个预测头之前,作者还会通过 task adapter,再融合一次 B 的证据向量:

\[\widetilde h_B^{(t)}=h_B+\operatorname{MLP}_t([h_B,e_B])\]

其中,$t$ 代表不同任务,每个任务拥有自己的 adapter。因此,Figure 1 中的 evidence 有两处用途:

  1. 在 decoder 之前,帮助构造 gene query;
  2. 在预测头之前,帮助不同任务使用实验证据。

随后,模型产生三个输出:

预测头 每个基因的直接输出 后续如何使用
DE head 两个 logits 通过 softmax 得到 DE / 非 DE 概率
LFC head 一个实数 正负分别表示上调或下调
$\Delta$-expression head $K$ 个 logits 通过 softmax 得到变化量分箱的概率分布

对于一个包含 $G$ 个输出基因的实验条件,直接输出的张量形状为:

\[\begin{aligned} \text{DE logits}&:\quad G\times2\\ \text{LFC}&:\quad G\times1\\ \text{Delta logits}&:\quad G\times K \end{aligned}\]

这里的 $K$ 是表达变化量的分箱数量,并不是细胞数量。在主基准的不同训练折中,作者使用了 13 或 17 个 bin。

最终结果可以整理成下面的形式。表中数值仅作示例,并非论文结果:

输出基因 DE 概率 预测 LFC 预测 $\Delta$-expression
A 0.98 −1.6 −0.7
B 0.85 +0.8 +0.3
C 0.09 −0.1 0.0
D 0.72 −0.6 −0.2

这张表描述的是 K562 中压低 A 后,细胞群体的响应。模型并没有在这里生成一批单细胞表达矩阵。

6. 三个训练标签怎样得到?

训练时,“K562 中压低 A”这个条件已经真正做过实验。作者拥有:

  • 一群未处理的 K562 对照细胞;
  • 一群受到 A 扰动的 K562 细胞。

随后,作者针对每个输出基因 B 计算三个标签:

任务 真值怎样得到 训练范围
是否 DE 两群细胞进行 Wilcoxon 检验,BH 校正后 FDR < 0.05 通过表达过滤的基因
LFC 干预组与对照组平均归一化表达的 $\log_2$ 比值 真值中的 DE 基因
$\Delta$-expression 干预组平均 log 归一化表达 − 对照组平均 log 归一化表达 所有具有有效 $\Delta$ 的测量基因

相应的训练目标包括:

  • DE 分类损失;
  • LFC 数值的 Huber 损失;
  • LFC 正负方向的损失;
  • $\Delta$-expression 分箱分布的交叉熵损失。

必须把标签和证据分开理解:

目标条件的真实响应,用来监督模型。
其他训练条件的响应汇总,可以作为证据输入。

模型并不是把本次实验的答案放入输入,再学习输出同一个答案。

7. 换成“新细胞”或“新扰动”时,少了什么?

模型结构不会改变,主要变化在于哪些证据可用:

测试情况 对照均值 Same-pert 证据 Same-context 证据
新细胞,已见扰动 有 有相关训练响应时可用 无
已见细胞,新扰动 有 无 有相关训练响应时可用
新细胞,新扰动 有 无 无

知识库资料仍然会按照数据库的实际覆盖情况提供。

因此,“新细胞 + 新扰动”并不意味着模型只输入两个名称。 它仍然可以获得:

  • 细胞背景的描述;
  • 扰动对象的各种知识特征;
  • 每个输出基因的描述;
  • 新细胞背景中,每个基因的未扰动对照均值。

缺失的响应证据会被置空,并通过 presence flag 等机制标记。训练时,作者也会随机屏蔽响应证据,使模型适应证据缺失的情况。

把 Figure 1 压缩成一份模型接口

模型所需内容 数值形式 在图中的位置
细胞背景和扰动的知识 $M\times768$ 个知识 token 左上角 → Encoder
每个输出基因的描述 每个基因一个文本向量,再映射到 768 维 下方 → gene queries
每个输出基因的实验证据 $G\times128$ 左下角 → query adapter 和 task adapters
返回结果 DE:$G\times2$;LFC:$G\times1$;$\Delta$:$G\times K$ 最右侧三个 heads

读 Figure 1 时,只需要抓住两条路径:左上角告诉模型“这是什么实验”;左下角和下方告诉模型“现在预测哪个基因,以及它有哪些已有证据”。 中间的 Encoder–Processor–Decoder 将两者结合,最右侧再逐基因输出答案。