

TIGON——基于最优传输 (OT) 和神经网络 (NN) 构建细胞动力学轨迹
在这篇notebook中,你将了解到TIGON作为一种轨迹推断方法的基本原理以及代码实现。
参考文献: Sha, Y., Qiu, Y., Zhou, P. et al. Reconstructing growth and dynamic trajectories from single-cell transcriptomics data. Nat Mach Intell 6, 25–39 (2024).
TIGON基本介绍
TIGON的全称是Trajectory Inference with Growth via Optimal transport and Neural network,是一个基于最优传输和神经网络的细胞动力学推断方法。
- 问题的引入
研究者希望通过组学数据(如基因组,转录组等等),揭示细胞的基因表达如何随着时间变化。这个过程被称为组学动力学推断,它有助于我们进一步解释疾病进程、胚胎发育、细胞分化等一系列重要生命过程的原理。但是组学数据推断过程中存在的一个普遍困难是,组学检测的过程中会杀死细胞,也就是说,我们无法在不同时间跟踪同一细胞,只能得到一系列非配对的快照(unpaired snapshots)。
具体而言,我们的输入是一系列scRNA-seq快照: 这里我们有个时刻,每个时刻抽取了个细胞,每个细胞有个基因的转录量信息(即,每个时刻可以得到维基因表达空间中的个点0)。
我们希望利用上面这些输入数据,通过一些建模方法,推断每个细胞在基因表达空间中是如何运动的。
- (非平衡 & 动态)最优传输:(unbalanced & dynamic) Optimal Transport
最优传输问题可以给出两个分布之间使得某种代价最小的映射。具体的数学形式可以参考 (Kantorovich, 1942). 细胞动力学推断中的Waddington-OT (2019)就是基于此。
动态最优传输于2000年被提出 (Benamou, 2000), 可以看作是最优传输问题的一个动力学推广。现在给定初分布和末分布,最优传输问题等价于构造如下由速度场驱动的动力学系统: 并优化Wasserstein-2距离使之最小。Wasserstein-2距离定义为 上述优化问题得到的速度场驱动的动力学系统即可给出问题的最优传输方案。转录组动力学中被广泛使用的TrajectoryNet方法就是基于动态最优传输的。
上面问题的都代表概率分布,意味着它在全空间上积分为1保持不变。细胞数量并不是一成不变的,不仅如此,细胞数量的变化恰恰是我们希望关注的,尤其是在胚胎发育、癌症研究等议题中。总质量随时间变化的过程对应着非平衡动态最优传输。具体来说,动力学将由控制移动的速度场和使得质量改变的生灭率共同驱动: 而优化的对象变为Wasserstein-Fisher-Rao距离 这里的表示细胞在基因表达空间中的密度,它是一个随基因表达向量和时间变化的量。是自选的,实践中选取为1,TIGON的原文献中对取值的鲁棒性做了检验。
- 重建误差 (Reconstruction Error)
上面的非平衡最优传输问题是TIGON的核心思想。问题中有两条限制,即的初末状态。神经网络并不擅长处理这种限制,所以TIGON将之转化为了“重建误差”并加入目标函数(loss)中。
这里提供一个对“重建误差”的直观理解:当我们构建的细胞动力学系统,可以完全的fit输入数据时,重建误差为0;当系统较好的fit输入数据时,重建误差较小;而当系统不能够的fit输入数据时,重建误差很大。的推导过程需要不少偏微分方程 (PDE) 知识且比较复杂,有兴趣的同学可以去看原文献。这里只列出计算公式。 其中
- 神经网络 (Neural Networks)
该方法用两个MLP来拟合复杂函数:速度和增长。目标函数选取为: 其中是一个自选参数。总体来说,TIGON的介绍图如下:
- 推断细胞轨迹
得到速度场后,我们可以像“描电场线”一样画出细胞轨迹。
- 推断基因之间的调控关系以及基因对生长的贡献
速度场的Jacobian矩阵 第行列的元素可以描述源基因对目标基因的调控能力。
生长项的梯度 可以描述基因对细胞数量变化的调控作用。
这两个量我们可以以热图的形式画出。
下面我们进行代码实现。
准备
安装、导入相关的Python包
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting TorchDiffEqPack==1.0.1 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/fa/bb/31721405fabfffdf5ff2a3f713bcea78d245e081160490f4780fc7959c3b/TorchDiffEqPack-1.0.1-py3-none-any.whl (33 kB) Requirement already satisfied: torch in /opt/mamba/lib/python3.10/site-packages (from TorchDiffEqPack==1.0.1) (2.0.0+cu118) Requirement already satisfied: sympy in /opt/mamba/lib/python3.10/site-packages (from torch->TorchDiffEqPack==1.0.1) (1.11.1) Requirement already satisfied: filelock in /opt/mamba/lib/python3.10/site-packages (from torch->TorchDiffEqPack==1.0.1) (3.10.0) Requirement already satisfied: networkx in /opt/mamba/lib/python3.10/site-packages (from torch->TorchDiffEqPack==1.0.1) (3.0) Requirement already satisfied: typing-extensions in /opt/mamba/lib/python3.10/site-packages (from torch->TorchDiffEqPack==1.0.1) (4.5.0) Requirement already satisfied: triton==2.0.0 in /opt/mamba/lib/python3.10/site-packages (from torch->TorchDiffEqPack==1.0.1) (2.0.0) Requirement already satisfied: jinja2 in /opt/mamba/lib/python3.10/site-packages (from torch->TorchDiffEqPack==1.0.1) (3.1.2) Requirement already satisfied: cmake in /opt/mamba/lib/python3.10/site-packages (from triton==2.0.0->torch->TorchDiffEqPack==1.0.1) (3.26.0) Requirement already satisfied: lit in /opt/mamba/lib/python3.10/site-packages (from triton==2.0.0->torch->TorchDiffEqPack==1.0.1) (15.0.7) Requirement already satisfied: MarkupSafe>=2.0 in /opt/mamba/lib/python3.10/site-packages (from jinja2->torch->TorchDiffEqPack==1.0.1) (2.1.2) Requirement already satisfied: mpmath>=0.19 in /opt/mamba/lib/python3.10/site-packages (from sympy->torch->TorchDiffEqPack==1.0.1) (1.3.0) Installing collected packages: TorchDiffEqPack Successfully installed TorchDiffEqPack-1.0.1 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting torchdiffeq==0.2.3 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/2c/9b/b9c3e17f261e30f630511390e0dd33fc529073f1f2db222a1f09dc49a1ae/torchdiffeq-0.2.3-py3-none-any.whl (31 kB) Requirement already satisfied: torch>=1.3.0 in /opt/mamba/lib/python3.10/site-packages (from torchdiffeq==0.2.3) (2.0.0+cu118) Requirement already satisfied: scipy>=1.4.0 in /opt/mamba/lib/python3.10/site-packages (from torchdiffeq==0.2.3) (1.10.1) Requirement already satisfied: numpy<1.27.0,>=1.19.5 in /opt/mamba/lib/python3.10/site-packages (from scipy>=1.4.0->torchdiffeq==0.2.3) (1.24.2) Requirement already satisfied: filelock in /opt/mamba/lib/python3.10/site-packages (from torch>=1.3.0->torchdiffeq==0.2.3) (3.10.0) Requirement already satisfied: networkx in /opt/mamba/lib/python3.10/site-packages (from torch>=1.3.0->torchdiffeq==0.2.3) (3.0) Requirement already satisfied: typing-extensions in /opt/mamba/lib/python3.10/site-packages (from torch>=1.3.0->torchdiffeq==0.2.3) (4.5.0) Requirement already satisfied: triton==2.0.0 in /opt/mamba/lib/python3.10/site-packages (from torch>=1.3.0->torchdiffeq==0.2.3) (2.0.0) Requirement already satisfied: jinja2 in /opt/mamba/lib/python3.10/site-packages (from torch>=1.3.0->torchdiffeq==0.2.3) (3.1.2) Requirement already satisfied: sympy in /opt/mamba/lib/python3.10/site-packages (from torch>=1.3.0->torchdiffeq==0.2.3) (1.11.1) Requirement already satisfied: lit in /opt/mamba/lib/python3.10/site-packages (from triton==2.0.0->torch>=1.3.0->torchdiffeq==0.2.3) (15.0.7) Requirement already satisfied: cmake in /opt/mamba/lib/python3.10/site-packages (from triton==2.0.0->torch>=1.3.0->torchdiffeq==0.2.3) (3.26.0) Requirement already satisfied: MarkupSafe>=2.0 in /opt/mamba/lib/python3.10/site-packages (from jinja2->torch>=1.3.0->torchdiffeq==0.2.3) (2.1.2) Requirement already satisfied: mpmath>=0.19 in /opt/mamba/lib/python3.10/site-packages (from sympy->torch>=1.3.0->torchdiffeq==0.2.3) (1.3.0) Installing collected packages: torchdiffeq Successfully installed torchdiffeq-0.2.3 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting matplotlib Downloading https://pypi.tuna.tsinghua.edu.cn/packages/8d/9d/d06860390f9d154fa884f1740a5456378fb153ff57443c91a4a32bab7092/matplotlib-3.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.3 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.3/8.3 MB 40.6 MB/s eta 0:00:0000:0100:01 Requirement already satisfied: python-dateutil>=2.7 in /opt/mamba/lib/python3.10/site-packages (from matplotlib) (2.8.2) Collecting kiwisolver>=1.3.1 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/55/91/0a57ce324caf2ff5403edab71c508dd8f648094b18cfbb4c8cc0fde4a6ac/kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.6 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.6/1.6 MB 67.2 MB/s eta 0:00:00 Collecting contourpy>=1.0.1 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/99/e6/d11966962b1aa515f5586d3907ad019f4b812c04e4546cc19ebf62b5178e/contourpy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (322 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 322.0/322.0 kB 55.3 MB/s eta 0:00:00 Collecting cycler>=0.10 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl (8.3 kB) Requirement already satisfied: numpy>=1.23 in /opt/mamba/lib/python3.10/site-packages (from matplotlib) (1.24.2) Collecting pyparsing>=2.3.1 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/be/ec/2eb3cd785efd67806c46c13a17339708ddc346cbb684eade7a6e6f79536a/pyparsing-3.2.0-py3-none-any.whl (106 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 106.9/106.9 kB 36.9 MB/s eta 0:00:00 Collecting pillow>=8 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/41/c3/94f33af0762ed76b5a237c5797e088aa57f2b7fa8ee7932d399087be66a8/pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl (4.4 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.4/4.4 MB 74.5 MB/s eta 0:00:00ta 0:00:01 Collecting fonttools>=4.22.0 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/e5/12/9a45294a7c4520cc32936edd15df1d5c24af701d2f5f51070a9a43d7664b/fonttools-4.54.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.6/4.6 MB 94.8 MB/s eta 0:00:00:00:01 Requirement already satisfied: packaging>=20.0 in /opt/mamba/lib/python3.10/site-packages (from matplotlib) (23.0) Requirement already satisfied: six>=1.5 in /opt/mamba/lib/python3.10/site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0) Installing collected packages: pyparsing, pillow, kiwisolver, fonttools, cycler, contourpy, matplotlib Successfully installed contourpy-1.3.0 cycler-0.12.1 fonttools-4.54.1 kiwisolver-1.4.7 matplotlib-3.9.2 pillow-11.0.0 pyparsing-3.2.0 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting seaborn Downloading https://pypi.tuna.tsinghua.edu.cn/packages/83/11/00d3c3dfc25ad54e731d91449895a79e4bf2384dc3ac01809010ba88f6d5/seaborn-0.13.2-py3-none-any.whl (294 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 294.9/294.9 kB 8.6 MB/s eta 0:00:00 Requirement already satisfied: numpy!=1.24.0,>=1.20 in /opt/mamba/lib/python3.10/site-packages (from seaborn) (1.24.2) Requirement already satisfied: pandas>=1.2 in /opt/mamba/lib/python3.10/site-packages (from seaborn) (1.5.3) Requirement already satisfied: matplotlib!=3.6.1,>=3.4 in /opt/mamba/lib/python3.10/site-packages (from seaborn) (3.9.2) Requirement already satisfied: kiwisolver>=1.3.1 in /opt/mamba/lib/python3.10/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (1.4.7) Requirement already satisfied: pillow>=8 in /opt/mamba/lib/python3.10/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (11.0.0) Requirement already satisfied: contourpy>=1.0.1 in /opt/mamba/lib/python3.10/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (1.3.0) Requirement already satisfied: fonttools>=4.22.0 in /opt/mamba/lib/python3.10/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (4.54.1) Requirement already satisfied: cycler>=0.10 in /opt/mamba/lib/python3.10/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (0.12.1) Requirement already satisfied: pyparsing>=2.3.1 in /opt/mamba/lib/python3.10/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (3.2.0) Requirement already satisfied: packaging>=20.0 in /opt/mamba/lib/python3.10/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (23.0) Requirement already satisfied: python-dateutil>=2.7 in /opt/mamba/lib/python3.10/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (2.8.2) Requirement already satisfied: pytz>=2020.1 in /opt/mamba/lib/python3.10/site-packages (from pandas>=1.2->seaborn) (2022.7.1) Requirement already satisfied: six>=1.5 in /opt/mamba/lib/python3.10/site-packages (from python-dateutil>=2.7->matplotlib!=3.6.1,>=3.4->seaborn) (1.16.0) Installing collected packages: seaborn Successfully installed seaborn-0.13.2 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting matplotlib==3.5.3 Downloading https://pypi.tuna.tsinghua.edu.cn/packages/e5/ca/3ed0e1de9df496392a4c9d75b0c78f82fe5758c66bb875903cf7a9402f0b/matplotlib-3.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (11.9 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 11.9/11.9 MB 64.6 MB/s eta 0:00:0000:0100:01 Requirement already satisfied: numpy>=1.17 in /opt/mamba/lib/python3.10/site-packages (from matplotlib==3.5.3) (1.24.2) Requirement already satisfied: pyparsing>=2.2.1 in /opt/mamba/lib/python3.10/site-packages (from matplotlib==3.5.3) (3.2.0) Requirement already satisfied: cycler>=0.10 in /opt/mamba/lib/python3.10/site-packages (from matplotlib==3.5.3) (0.12.1) Requirement already satisfied: python-dateutil>=2.7 in /opt/mamba/lib/python3.10/site-packages (from matplotlib==3.5.3) (2.8.2) Requirement already satisfied: packaging>=20.0 in /opt/mamba/lib/python3.10/site-packages (from matplotlib==3.5.3) (23.0) Requirement already satisfied: pillow>=6.2.0 in /opt/mamba/lib/python3.10/site-packages (from matplotlib==3.5.3) (11.0.0) Requirement already satisfied: kiwisolver>=1.0.1 in /opt/mamba/lib/python3.10/site-packages (from matplotlib==3.5.3) (1.4.7) Requirement already satisfied: fonttools>=4.22.0 in /opt/mamba/lib/python3.10/site-packages (from matplotlib==3.5.3) (4.54.1) Requirement already satisfied: six>=1.5 in /opt/mamba/lib/python3.10/site-packages (from python-dateutil>=2.7->matplotlib==3.5.3) (1.16.0) Installing collected packages: matplotlib Attempting uninstall: matplotlib Found existing installation: matplotlib 3.9.2 Uninstalling matplotlib-3.9.2: Successfully uninstalled matplotlib-3.9.2 Successfully installed matplotlib-3.5.3 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
定义输入
构建神经网络 (MLP)
编写训练函数(实际上就是算Loss,比较琐碎)
算Loss需要用到TorchDiffEqPack和torchdiffeq这两个包的ODE求解器。我这里对这两个ODE求解器分别写了一个示例供大家理解参考。下面两个代码框不是TIGON源代码。
tensor([0.3752])
tensor([[1.0000], [0.3679], [0.1353], [0.0498], [0.0183], [0.0067]])
这里开始是TIGON训练函数的源代码
编写画图函数
(包括画速度场、速度场的Jacobian、增长项的梯度)
输入
一路回车即可
训练神经网络
提示: 这里程序运行开销很大,尽量开个比较好的GPU。如果没时间运行也没关系,运行好的结果已经放在了挂载的数据集文件中。不想运行的只需跳过即可,不影响后面代码的运行。
可视化
载入训练结果
上面代码的运行结果已经放在数据集文件夹中。无论你是否真的进行了训练,都可以继续运行下面代码:
Loaded ckpt from bohr/ProcessedDataInTIGON-9q96/v2/Output/ckpt_EMT.pth
绘制热图
它代表着基因调控关系
绘制热图
它代表着基因对生长的影响
绘制三维向量场



