Joint analyse of RNA + ATAC multimodal dataset using VIMCCA

This tutorial shows loading, preprocessing, VIMCCA joint analyse of RNA + ATAC multimodal dataset.

Import packages

Here, we’ll import scbean along with other popular packages.

[1]:
import matplotlib
matplotlib.use('TkAgg')
import scanpy as sc
from scbean.model import vimcca

# Command for Jupyter Notebooks only
%matplotlib inline
import warnings
warnings.filterwarnings('ignore')
from matplotlib.axes._axes import _log as matplotlib_axes_logger
matplotlib_axes_logger.setLevel('ERROR')

Loading dataset

This tutorial uses multimodal single cell data of human PBMCs from a healthy donor, which measured 36,601 genes and 106,056 peaks on 10,412 cells at the same time, which can be downloaded from 10X Genomics.

[2]:
base_path = '/Users/zhongyuanke/data/'
file_rna = base_path + 'multimodal/atac_pbmc_10k/rna_filt.csv'
file_atac = base_path + 'multimodal/atac_pbmc_10k/atac.h5ad'

adata_x = sc.read_csv(file_rna)
adata_y = sc.read_h5ad(file_atac)

Preprocessing using scanpy

Here, we filter and normalize each modal separately.

[3]:
sc.pp.filter_genes(adata_x, min_cells=10)
sc.pp.filter_genes(adata_y, min_cells=10)
sc.pp.log1p(adata_x)
sc.pp.log1p(adata_y)
sc.pp.scale(adata_x)
sc.pp.scale(adata_y)

Joint analyse using VIMCCA

The returned z represents the complementary low-dimensional features of the two modalities learned by VIMCCA, which can be used for downstream analysis.

[4]:
z = vimcca.fit_integration(
    adata_x,
    adata_y,
    sparse_x=False,
    sparse_y=False,
    hidden_layers=[128, 64, 16, 8],
    epochs=50,
    weight=5
)
Model: "VIMCCA_mlp"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to
==================================================================================================
inputs_x (InputLayer)           [(None, 21602)]      0
__________________________________________________________________________________________________
encoder_z (Functional)          [(None, 8), (None, 8 2775376     inputs_x[0][0]
                                                                 inputs_x[0][0]
__________________________________________________________________________________________________
inputs_y (InputLayer)           [(None, 105949)]     0
__________________________________________________________________________________________________
decoder_x (Functional)          (None, 21602)        2796834     encoder_z[0][2]
__________________________________________________________________________________________________
decoder_y (Functional)          (None, 105949)       13677597    encoder_z[1][2]
__________________________________________________________________________________________________
dense (Dense)                   (None, 128)          2765184     inputs_x[0][0]
__________________________________________________________________________________________________
batch_normalization (BatchNorma (None, 128)          384         dense[0][0]
__________________________________________________________________________________________________
activation (Activation)         (None, 128)          0           batch_normalization[0][0]
__________________________________________________________________________________________________
dropout (Dropout)               (None, 128)          0           activation[0][0]
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 64)           8256        dropout[0][0]
__________________________________________________________________________________________________
batch_normalization_1 (BatchNor (None, 64)           192         dense_1[0][0]
__________________________________________________________________________________________________
activation_1 (Activation)       (None, 64)           0           batch_normalization_1[0][0]
__________________________________________________________________________________________________
dropout_1 (Dropout)             (None, 64)           0           activation_1[0][0]
__________________________________________________________________________________________________
tf.math.subtract_2 (TFOpLambda) (None, 105949)       0           inputs_y[0][0]
                                                                 decoder_y[0][0]
__________________________________________________________________________________________________
dense_2 (Dense)                 (None, 16)           1040        dropout_1[0][0]
__________________________________________________________________________________________________
tf.math.subtract (TFOpLambda)   (None, 21602)        0           inputs_x[0][0]
                                                                 decoder_x[0][0]
__________________________________________________________________________________________________
tf.math.reduce_mean_4 (TFOpLamb (1, 1)               0           tf.math.subtract_2[0][0]
__________________________________________________________________________________________________
batch_normalization_2 (BatchNor (None, 16)           48          dense_2[0][0]
__________________________________________________________________________________________________
tf.math.reduce_mean_2 (TFOpLamb (1, 1)               0           tf.math.subtract[0][0]
__________________________________________________________________________________________________
tf.math.subtract_3 (TFOpLambda) (None, 105949)       0           tf.math.subtract_2[0][0]
                                                                 tf.math.reduce_mean_4[0][0]
__________________________________________________________________________________________________
activation_2 (Activation)       (None, 16)           0           batch_normalization_2[0][0]
__________________________________________________________________________________________________
tf.math.subtract_1 (TFOpLambda) (None, 21602)        0           tf.math.subtract[0][0]
                                                                 tf.math.reduce_mean_2[0][0]
__________________________________________________________________________________________________
tf.convert_to_tensor_1 (TFOpLam (None, 105949)       0           decoder_y[0][0]
__________________________________________________________________________________________________
tf.cast_1 (TFOpLambda)          (None, 105949)       0           inputs_y[0][0]
__________________________________________________________________________________________________
tf.math.square_1 (TFOpLambda)   (None, 105949)       0           tf.math.subtract_3[0][0]
__________________________________________________________________________________________________
dropout_2 (Dropout)             (None, 16)           0           activation_2[0][0]
__________________________________________________________________________________________________
tf.convert_to_tensor (TFOpLambd (None, 21602)        0           decoder_x[0][0]
__________________________________________________________________________________________________
tf.cast (TFOpLambda)            (None, 21602)        0           inputs_x[0][0]
__________________________________________________________________________________________________
tf.math.square (TFOpLambda)     (None, 21602)        0           tf.math.subtract_1[0][0]
__________________________________________________________________________________________________
tf.math.squared_difference_1 (T (None, 105949)       0           tf.convert_to_tensor_1[0][0]
                                                                 tf.cast_1[0][0]
__________________________________________________________________________________________________
tf.math.reduce_mean_5 (TFOpLamb ()                   0           tf.math.square_1[0][0]
__________________________________________________________________________________________________
z_log_var (Dense)               (None, 8)            136         dropout_2[0][0]
__________________________________________________________________________________________________
z_mean (Dense)                  (None, 8)            136         dropout_2[0][0]
__________________________________________________________________________________________________
tf.math.squared_difference (TFO (None, 21602)        0           tf.convert_to_tensor[0][0]
                                                                 tf.cast[0][0]
__________________________________________________________________________________________________
tf.math.reduce_mean_3 (TFOpLamb ()                   0           tf.math.square[0][0]
__________________________________________________________________________________________________
tf.math.reduce_mean_1 (TFOpLamb (None,)              0           tf.math.squared_difference_1[0][0
__________________________________________________________________________________________________
tf.math.truediv_2 (TFOpLambda)  ()                   0           tf.math.reduce_mean_5[0][0]
__________________________________________________________________________________________________
tf.math.truediv_3 (TFOpLambda)  ()                   0           tf.math.reduce_mean_5[0][0]
__________________________________________________________________________________________________
tf.math.log_1 (TFOpLambda)      ()                   0           tf.math.reduce_mean_5[0][0]
__________________________________________________________________________________________________
tf.__operators__.add_2 (TFOpLam (None, 8)            0           z_log_var[0][0]
__________________________________________________________________________________________________
tf.math.square_2 (TFOpLambda)   (None, 8)            0           z_mean[0][0]
__________________________________________________________________________________________________
tf.math.reduce_mean (TFOpLambda (None,)              0           tf.math.squared_difference[0][0]
__________________________________________________________________________________________________
tf.math.truediv (TFOpLambda)    ()                   0           tf.math.reduce_mean_3[0][0]
__________________________________________________________________________________________________
tf.math.truediv_1 (TFOpLambda)  ()                   0           tf.math.reduce_mean_3[0][0]
__________________________________________________________________________________________________
tf.math.log (TFOpLambda)        ()                   0           tf.math.reduce_mean_3[0][0]
__________________________________________________________________________________________________
tf.math.multiply_2 (TFOpLambda) (None,)              0           tf.math.reduce_mean_1[0][0]
                                                                 tf.math.truediv_2[0][0]
__________________________________________________________________________________________________
tf.math.multiply_3 (TFOpLambda) ()                   0           tf.math.truediv_3[0][0]
                                                                 tf.math.log_1[0][0]
__________________________________________________________________________________________________
tf.math.subtract_4 (TFOpLambda) (None, 8)            0           tf.__operators__.add_2[0][0]
                                                                 tf.math.square_2[0][0]
__________________________________________________________________________________________________
tf.math.exp (TFOpLambda)        (None, 8)            0           z_log_var[0][0]
__________________________________________________________________________________________________
tf.math.multiply (TFOpLambda)   (None,)              0           tf.math.reduce_mean[0][0]
                                                                 tf.math.truediv[0][0]
__________________________________________________________________________________________________
tf.math.multiply_1 (TFOpLambda) ()                   0           tf.math.truediv_1[0][0]
                                                                 tf.math.log[0][0]
__________________________________________________________________________________________________
tf.__operators__.add_1 (TFOpLam (None,)              0           tf.math.multiply_2[0][0]
                                                                 tf.math.multiply_3[0][0]
__________________________________________________________________________________________________
tf.math.subtract_5 (TFOpLambda) (None, 8)            0           tf.math.subtract_4[0][0]
                                                                 tf.math.exp[0][0]
__________________________________________________________________________________________________
tf.__operators__.add (TFOpLambd (None,)              0           tf.math.multiply[0][0]
                                                                 tf.math.multiply_1[0][0]
__________________________________________________________________________________________________
tf.math.multiply_5 (TFOpLambda) (None,)              0           tf.__operators__.add_1[0][0]
__________________________________________________________________________________________________
tf.math.reduce_sum (TFOpLambda) (None,)              0           tf.math.subtract_5[0][0]
__________________________________________________________________________________________________
tf.__operators__.add_3 (TFOpLam (None,)              0           tf.__operators__.add[0][0]
                                                                 tf.math.multiply_5[0][0]
__________________________________________________________________________________________________
tf.math.multiply_4 (TFOpLambda) (None,)              0           tf.math.reduce_sum[0][0]
__________________________________________________________________________________________________
tf.__operators__.add_4 (TFOpLam (None,)              0           tf.__operators__.add_3[0][0]
                                                                 tf.math.multiply_4[0][0]
__________________________________________________________________________________________________
tf.math.reduce_mean_6 (TFOpLamb ()                   0           tf.__operators__.add_4[0][0]
__________________________________________________________________________________________________
add_loss (AddLoss)              ()                   0           tf.math.reduce_mean_6[0][0]
==================================================================================================
Total params: 19,249,807
Trainable params: 19,248,559
Non-trainable params: 1,248
__________________________________________________________________________________________________
Epoch 1/50
82/82 [==============================] - 37s 405ms/step - loss: 272711.4548
Epoch 2/50
82/82 [==============================] - 32s 386ms/step - loss: 267430.2125
Epoch 3/50
82/82 [==============================] - 32s 386ms/step - loss: 268638.5151
Epoch 4/50
82/82 [==============================] - 32s 389ms/step - loss: 265024.8099
Epoch 5/50
82/82 [==============================] - 32s 389ms/step - loss: 268585.0049
Epoch 6/50
82/82 [==============================] - 32s 391ms/step - loss: 269783.4025
Epoch 7/50
82/82 [==============================] - 32s 389ms/step - loss: 265431.6602
Epoch 8/50
82/82 [==============================] - 32s 388ms/step - loss: 265769.7515
Epoch 9/50
82/82 [==============================] - 34s 410ms/step - loss: 266398.4091
Epoch 10/50
82/82 [==============================] - 34s 414ms/step - loss: 264023.6071
Epoch 11/50
82/82 [==============================] - 33s 402ms/step - loss: 266286.0422
Epoch 12/50
82/82 [==============================] - 32s 392ms/step - loss: 265949.2319
Epoch 13/50
82/82 [==============================] - 32s 389ms/step - loss: 266293.0431
Epoch 14/50
82/82 [==============================] - 32s 389ms/step - loss: 265597.0043
Epoch 15/50
82/82 [==============================] - 32s 389ms/step - loss: 264444.5740
Epoch 16/50
82/82 [==============================] - 32s 388ms/step - loss: 264731.1980
Epoch 17/50
82/82 [==============================] - 32s 386ms/step - loss: 263372.2605
Epoch 18/50
82/82 [==============================] - 32s 388ms/step - loss: 267339.5373
Epoch 19/50
82/82 [==============================] - 32s 389ms/step - loss: 265664.4770
Epoch 20/50
82/82 [==============================] - 32s 389ms/step - loss: 267976.1517
Epoch 21/50
82/82 [==============================] - 32s 388ms/step - loss: 266376.4639
Epoch 22/50
82/82 [==============================] - 32s 390ms/step - loss: 267400.9733
Epoch 23/50
82/82 [==============================] - 32s 391ms/step - loss: 265539.0680
Epoch 24/50
82/82 [==============================] - 32s 390ms/step - loss: 265095.6453
Epoch 25/50
82/82 [==============================] - 32s 391ms/step - loss: 264469.7901
Epoch 26/50
82/82 [==============================] - 32s 389ms/step - loss: 266486.6114
Epoch 27/50
82/82 [==============================] - 32s 387ms/step - loss: 266558.6306
Epoch 28/50
82/82 [==============================] - 32s 390ms/step - loss: 263573.2054
Epoch 29/50
82/82 [==============================] - 32s 390ms/step - loss: 265883.4108
Epoch 30/50
82/82 [==============================] - 32s 391ms/step - loss: 265141.4642
Epoch 31/50
82/82 [==============================] - 32s 390ms/step - loss: 266669.8739
Epoch 32/50
82/82 [==============================] - 32s 391ms/step - loss: 262926.7907
Epoch 33/50
82/82 [==============================] - 32s 394ms/step - loss: 265554.4025
Epoch 34/50
82/82 [==============================] - 31s 380ms/step - loss: 264294.5343
Epoch 35/50
82/82 [==============================] - 32s 391ms/step - loss: 265461.8264
Epoch 36/50
82/82 [==============================] - 32s 392ms/step - loss: 266107.0840
Epoch 37/50
82/82 [==============================] - 32s 389ms/step - loss: 264410.0425
Epoch 38/50
82/82 [==============================] - 32s 389ms/step - loss: 264802.0941
Epoch 39/50
82/82 [==============================] - 32s 389ms/step - loss: 263412.3658
Epoch 40/50
82/82 [==============================] - 32s 387ms/step - loss: 264649.5151
Epoch 41/50
82/82 [==============================] - 32s 386ms/step - loss: 266106.8445
Epoch 42/50
82/82 [==============================] - 32s 386ms/step - loss: 264748.9928
Epoch 43/50
82/82 [==============================] - 32s 388ms/step - loss: 264953.5787
Epoch 44/50
82/82 [==============================] - 32s 389ms/step - loss: 264890.0520
Epoch 45/50
82/82 [==============================] - 32s 392ms/step - loss: 264456.3564
Epoch 46/50
82/82 [==============================] - 32s 387ms/step - loss: 265602.6593
Epoch 47/50
82/82 [==============================] - 32s 387ms/step - loss: 262839.4851
Epoch 48/50
82/82 [==============================] - 32s 385ms/step - loss: 265261.6766
Epoch 49/50
82/82 [==============================] - 32s 388ms/step - loss: 264242.9130
Epoch 50/50
82/82 [==============================] - 32s 391ms/step - loss: 266154.8140

Visualization

[5]:
adata_x.obsm['X_vimcca'] = z
sc.pp.neighbors(adata_x, use_rep='X_vimcca')
sc.tl.leiden(adata_x, resolution=3)
sc.tl.umap(adata_x)
[6]:
sc.pl.umap(adata_x, color='leiden', legend_loc='on data', s=3)
../_images/tutorials_vimcca_atac_rna_tutorial_11_0.png