Joint analyse of RNA+ADT multimodal dataset using VIMCCA

This tutorial shows loading, preprocessing, VIMCCA joint analyse of 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 use the CITE-seq dataset from (Stuart, Butler et al, Cell 2019), which consists of 30,672 scRNA-seq profiles measured alongside a panel of 25 antibodies from bone marrow. The object contains two assays, RNA and antibody-derived tags (ADT).

[2]:
base_path = '/Users/wangyuwei/data/'
file_rna = base_path + 'bmcite_rna.h5ad'
file_atac = base_path + 'bmcite_adt.h5ad'

adata_rna = sc.read_h5ad(file_rna)
adata_adt = sc.read_h5ad(file_atac)

Processing with scanpy

Here, we filter genes that expressed in less than ten cells. We then apply CPM normalization for each cell so that every cell have same total count after normalization. Finally, we performed a log transformation. As for ADT count data, we p erformed the same op erations excepting for ltering genes since there are only 25 proteins

[3]:
# filter genes
sc.pp.filter_genes(adata_rna, min_cells=10)
# CMP
sc.pp.normalize_total(adata_rna, target_sum=1e6)
sc.pp.normalize_total(adata_adt, target_sum=1e6)
# log transformation
sc.pp.log1p(adata_rna)
sc.pp.log1p(adata_adt)
# scale genes to unit variance
sc.pp.scale(adata_rna)
sc.pp.scale(adata_adt)

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_rna,
    adata_adt,
    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, 16313)]      0
__________________________________________________________________________________________________
encoder_z (Functional)          [(None, 8), (None, 8 2098384     inputs_x[0][0]
                                                                 inputs_x[0][0]
__________________________________________________________________________________________________
inputs_y (InputLayer)           [(None, 25)]         0
__________________________________________________________________________________________________
decoder_x (Functional)          (None, 16313)        2114553     encoder_z[0][2]
__________________________________________________________________________________________________
decoder_y (Functional)          (None, 25)           13401       encoder_z[1][2]
__________________________________________________________________________________________________
dense (Dense)                   (None, 128)          2088192     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, 25)           0           inputs_y[0][0]
                                                                 decoder_y[0][0]
__________________________________________________________________________________________________
dense_2 (Dense)                 (None, 16)           1040        dropout_1[0][0]
__________________________________________________________________________________________________
tf.math.subtract (TFOpLambda)   (None, 16313)        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, 25)           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, 16313)        0           tf.math.subtract[0][0]
                                                                 tf.math.reduce_mean_2[0][0]
__________________________________________________________________________________________________
tf.convert_to_tensor_1 (TFOpLam (None, 25)           0           decoder_y[0][0]
__________________________________________________________________________________________________
tf.cast_1 (TFOpLambda)          (None, 25)           0           inputs_y[0][0]
__________________________________________________________________________________________________
tf.math.square_1 (TFOpLambda)   (None, 25)           0           tf.math.subtract_3[0][0]
__________________________________________________________________________________________________
dropout_2 (Dropout)             (None, 16)           0           activation_2[0][0]
__________________________________________________________________________________________________
tf.convert_to_tensor (TFOpLambd (None, 16313)        0           decoder_x[0][0]
__________________________________________________________________________________________________
tf.cast (TFOpLambda)            (None, 16313)        0           inputs_x[0][0]
__________________________________________________________________________________________________
tf.math.square (TFOpLambda)     (None, 16313)        0           tf.math.subtract_1[0][0]
__________________________________________________________________________________________________
tf.math.squared_difference_1 (T (None, 25)           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, 16313)        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: 4,226,338
Trainable params: 4,225,090
Non-trainable params: 1,248
__________________________________________________________________________________________________
Epoch 1/50
240/240 [==============================] - 22s 76ms/step - loss: 8360.1504
Epoch 2/50
240/240 [==============================] - 18s 76ms/step - loss: 8018.1430
Epoch 3/50
240/240 [==============================] - 18s 77ms/step - loss: 7970.6398
Epoch 4/50
240/240 [==============================] - 18s 76ms/step - loss: 8000.3285
Epoch 5/50
240/240 [==============================] - 19s 79ms/step - loss: 7954.0166
Epoch 6/50
240/240 [==============================] - 19s 77ms/step - loss: 7884.0260
Epoch 7/50
240/240 [==============================] - 19s 79ms/step - loss: 7931.1389
Epoch 8/50
240/240 [==============================] - 18s 77ms/step - loss: 7974.4825
Epoch 9/50
240/240 [==============================] - 18s 76ms/step - loss: 7912.1709
Epoch 10/50
240/240 [==============================] - 18s 77ms/step - loss: 7896.6996
Epoch 11/50
240/240 [==============================] - 18s 77ms/step - loss: 7900.2621
Epoch 12/50
240/240 [==============================] - 18s 77ms/step - loss: 7874.1914
Epoch 13/50
240/240 [==============================] - 19s 78ms/step - loss: 7942.4368
Epoch 14/50
240/240 [==============================] - 19s 78ms/step - loss: 7886.5864
Epoch 15/50
240/240 [==============================] - 19s 79ms/step - loss: 7894.0089
Epoch 16/50
240/240 [==============================] - 19s 79ms/step - loss: 7876.6730
Epoch 17/50
240/240 [==============================] - 19s 79ms/step - loss: 7883.4861
Epoch 18/50
240/240 [==============================] - 18s 75ms/step - loss: 7900.2163
Epoch 19/50
240/240 [==============================] - 19s 78ms/step - loss: 7860.8634
Epoch 20/50
240/240 [==============================] - 19s 79ms/step - loss: 7854.9731
Epoch 21/50
240/240 [==============================] - 19s 79ms/step - loss: 7878.8360
Epoch 22/50
240/240 [==============================] - 19s 79ms/step - loss: 7866.1971
Epoch 23/50
240/240 [==============================] - 19s 79ms/step - loss: 7843.3864
Epoch 24/50
240/240 [==============================] - 19s 80ms/step - loss: 7851.1333
Epoch 25/50
240/240 [==============================] - 19s 80ms/step - loss: 7845.9774
Epoch 26/50
240/240 [==============================] - 19s 80ms/step - loss: 7866.2525
Epoch 27/50
240/240 [==============================] - 19s 79ms/step - loss: 7898.9007
Epoch 28/50
240/240 [==============================] - 19s 79ms/step - loss: 7896.1642
Epoch 29/50
240/240 [==============================] - 19s 80ms/step - loss: 7877.3989
Epoch 30/50
240/240 [==============================] - 19s 80ms/step - loss: 7870.3543
Epoch 31/50
240/240 [==============================] - 19s 80ms/step - loss: 7874.1612
Epoch 32/50
240/240 [==============================] - 19s 79ms/step - loss: 7817.3327
Epoch 33/50
240/240 [==============================] - 18s 76ms/step - loss: 7850.2255
Epoch 34/50
240/240 [==============================] - 18s 75ms/step - loss: 7891.9772
Epoch 35/50
240/240 [==============================] - 17s 71ms/step - loss: 7812.6359
Epoch 36/50
240/240 [==============================] - 17s 71ms/step - loss: 7845.0270
Epoch 37/50
240/240 [==============================] - 17s 71ms/step - loss: 7870.1003
Epoch 38/50
240/240 [==============================] - 18s 74ms/step - loss: 7905.2164
Epoch 39/50
240/240 [==============================] - 19s 79ms/step - loss: 7841.8232
Epoch 40/50
240/240 [==============================] - 19s 78ms/step - loss: 7865.0429
Epoch 41/50
240/240 [==============================] - 19s 78ms/step - loss: 7883.2060
Epoch 42/50
240/240 [==============================] - 19s 78ms/step - loss: 7856.6624
Epoch 43/50
240/240 [==============================] - 19s 78ms/step - loss: 7814.9983
Epoch 44/50
240/240 [==============================] - 19s 79ms/step - loss: 7872.8078
Epoch 45/50
240/240 [==============================] - 19s 79ms/step - loss: 7865.7604
Epoch 46/50
240/240 [==============================] - 19s 79ms/step - loss: 7822.7538
Epoch 47/50
240/240 [==============================] - 19s 80ms/step - loss: 7892.6051
Epoch 48/50
240/240 [==============================] - 19s 81ms/step - loss: 7875.3245
Epoch 49/50
240/240 [==============================] - 20s 81ms/step - loss: 7863.9091
Epoch 50/50
240/240 [==============================] - 19s 80ms/step - loss: 7845.1268

Visualization

[5]:
adata_rna.obsm['X_vimcca'] = z
sc.pp.neighbors(adata_rna, use_rep='X_vimcca')
sc.tl.leiden(adata_rna, resolution=3)
sc.tl.umap(adata_rna)
[6]:
sc.pl.umap(adata_rna, color='celltype.l2')
../_images/tutorials_vimcca_bmcite_rna_protein_tutorial_10_0.png

We can explore marker genes

[7]:
sc.pl.umap(adata_rna, color=['S100A8'])
../_images/tutorials_vimcca_bmcite_rna_protein_tutorial_12_0.png
[ ]: