Spatial tissue niche discovery
Here we will use slideseqv2_mouse_hippocampus datasets as an example to illustrate how Garfield performs spatial tissue niche discovery for multiple batches. Data access: https://singlecell.broadinstitute.org/single_cell/study/SCP815/highly-sensitive-spatial-transcriptomics-at-near-cellular-resolution-with-slide-seqv2.
[1]:
import os
os.chdir('/data2/zhouwg_data/project/Garfield')
os.getcwd()
[1]:
'/data2/zhouwg_data/project/Garfield'
[2]:
# load packages
import os
import warnings
import Garfield as gf
import scanpy as sc
warnings.simplefilter(action="ignore", category=FutureWarning)
warnings.simplefilter(action='ignore', category=UserWarning)
gf.__version__
[2]:
'1.0.0'
[3]:
# Load data
# Define paths
st_data_folder_path = "/home/zhouweige/zhouwg_data/project/Garfield_tutorials/data" # spatially resolved transcriptomics data
dataset = "slideseqv2_mouse_hippocampus"
cell_type_key = "cell_type"
adata = sc.read_h5ad(f"{st_data_folder_path}/{dataset}.h5ad")
adata.var_names_make_unique(join="++")
adata
[3]:
AnnData object with n_obs × n_vars = 41786 × 4000
obs: 'cell_type', 'batch'
obsm: 'spatial'
layers: 'counts'
[4]:
# check the celltype information of this dataset
adata.obs['cell_type'].value_counts()
[4]:
cell_type
CA1_CA2_CA3_Subiculum 7649
DentatePyramids 6606
Astrocytes 6543
Interneurons 3672
Oligodendrocytes 3602
Subiculum_Entorhinal_cl2 2896
Endothelial_Stalk 1991
Subiculum_Entorhinal_cl3 1985
Polydendrocytes 1449
Endothelial_Tip 1317
Microglia 1298
Mural 1027
Neurogenesis 938
Ependymal 813
Name: count, dtype: int64
[5]:
# check the batch information of this dataset
adata.obs['batch'].value_counts()
[5]:
batch
sample1 41786
Name: count, dtype: int64
[6]:
# Ensure adata.X is counts.
adata.X = adata.layers['counts'].copy()
adata.X.max()
[6]:
169.0
Integrating spatially resolved transcriptomics data using Garfield
For spatial niche discovery from spatially resolved transcriptomics data, we should adjust the following paremeters, and all parameter introductions can be found in Garfield_Model_Parameters.
[7]:
# set workdir
workdir = '/home/zhouweige/zhouwg_data/project/Garfield_tutorials/result/garfield_spRNA_mouse_hippocampus'
gf.settings.set_workdir(workdir)
### modify parameter
user_config = dict(
## Input options
adata_list=adata,
profile='spatial',
data_type='single-modal',
sample_col=None,
weight=0.5,
## Preprocessing options
graph_const_method='mu_std', # mu_std, Radius, KNN, Squidpy
used_hvg=True,
min_cells=3,
min_features=0,
keep_mt=False,
target_sum=1e4,
rna_n_top_features=3000,
n_components=50,
n_neighbors=5,
metric='euclidean',
svd_solver='arpack',
# datasets
used_pca_feat=False,
adj_key='connectivities',
# data split parameters
edge_val_ratio=0.1,
edge_test_ratio=0.,
node_val_ratio=0.1,
node_test_ratio=0.,
## Model options
augment_type='dropout',
svd_q=5,
use_FCencoder=True,
conv_type='GAT', # GAT or GATv2Conv or GCN
gnn_layer=2,
hidden_dims=[128, 128],
bottle_neck_neurons=20,
cluster_num=20,
drop_feature_rate=0.2,
drop_edge_rate=0.2,
num_heads=3,
dropout=0.2,
concat=True,
used_edge_weight=False,
used_DSBN=False,
used_mmd=False,
# data loader parameters
num_neighbors=5,
loaders_n_hops=2,
edge_batch_size=4096,
node_batch_size=256, # None
# loss parameters
include_edge_recon_loss=True,
include_gene_expr_recon_loss=True,
lambda_latent_contrastive_instanceloss=1.0,
lambda_latent_contrastive_clusterloss=0.5,
lambda_gene_expr_recon=1., #
lambda_edge_recon=1., #
lambda_latent_adj_recon_loss=2.,
lambda_omics_recon_mmd_loss=0.2,
# train parameters
n_epochs_no_edge_recon=0,
learning_rate=0.001,
weight_decay=1e-05,
gradient_clipping=5,
# other parameters
latent_key='garfield_latent',
reload_best_model=True,
use_early_stopping=True,
early_stopping_kwargs=None,
monitor=True,
device_id=0,
seed=2024,
verbose=True
)
dict_config = gf.settings.set_gf_params(user_config)
Saving results in: /home/zhouweige/zhouwg_data/project/Garfield_tutorials/result/garfield_spRNA_mouse_hippocampus
[8]:
from Garfield.model import Garfield
# Initialize model
model = Garfield(dict_config)
--- DATA LOADING AND PREPROCESSING ---
/home/zhouweige/anaconda3/envs/Garfield/lib/python3.9/site-packages/scipy/sparse/_index.py:143: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
self._set_arrayXarray(i, j, x)
------Calculating spatial graph...
COSINE SIM GRAPH DECODER -> dropout_rate: 0.2
[9]:
# Train model
model.train()
--- INITIALIZING TRAINER ---
Using GPU: device-0
Number of training nodes: 37607
Number of validation nodes: 4179
Number of training edges: 246872
Number of validation edges: 27430
Edge batch size: 4096
Node batch size: 256
--- MODEL TRAINING ---
Epoch 1/100 |--------------------| 1.0% val_auroc_score: 0.7848; val_auprc_score: 0.7722; val_best_acc_score: 0.7072; val_best_f1_score: 0.7397; train_kl_reg_loss: 5.3870; train_edge_recon_loss: 1128.2625; train_gene_expr_recon_loss: 5881.1682; train_lambda_latent_adj_recon_loss: 507.5772; train_lambda_latent_contrastive_instanceloss: 7.9475; train_lambda_latent_contrastive_clusterloss: 3.6782; train_global_loss: 7534.0206; train_optim_loss: 7534.0206; val_kl_reg_loss: 6.1536; val_edge_recon_loss: 1083.1054; val_gene_expr_recon_loss: 5576.5709; val_lambda_latent_adj_recon_loss: 281.4440; val_lambda_latent_contrastive_instanceloss: 7.7274; val_lambda_latent_contrastive_clusterloss: 3.6211; val_global_loss: 6958.6225; val_optim_loss: 6958.6225
Epoch 2/100 |--------------------| 2.0% val_auroc_score: 0.8478; val_auprc_score: 0.8315; val_best_acc_score: 0.7703; val_best_f1_score: 0.7877; train_kl_reg_loss: 11.4613; train_edge_recon_loss: 1104.2606; train_gene_expr_recon_loss: 5569.7317; train_lambda_latent_adj_recon_loss: 396.2759; train_lambda_latent_contrastive_instanceloss: 7.7764; train_lambda_latent_contrastive_clusterloss: 3.5816; train_global_loss: 7093.0875; train_optim_loss: 7093.0875; val_kl_reg_loss: 10.3879; val_edge_recon_loss: 958.1587; val_gene_expr_recon_loss: 5412.4221; val_lambda_latent_adj_recon_loss: 247.5001; val_lambda_latent_contrastive_instanceloss: 7.2457; val_lambda_latent_contrastive_clusterloss: 3.2742; val_global_loss: 6638.9887; val_optim_loss: 6638.9887
Epoch 3/100 |--------------------| 3.0% val_auroc_score: 0.8699; val_auprc_score: 0.8576; val_best_acc_score: 0.7905; val_best_f1_score: 0.8012; train_kl_reg_loss: 16.8834; train_edge_recon_loss: 1079.7648; train_gene_expr_recon_loss: 5482.7694; train_lambda_latent_adj_recon_loss: 337.1196; train_lambda_latent_contrastive_instanceloss: 7.5458; train_lambda_latent_contrastive_clusterloss: 3.3266; train_global_loss: 6927.4095; train_optim_loss: 6927.4095; val_kl_reg_loss: 14.0382; val_edge_recon_loss: 942.1677; val_gene_expr_recon_loss: 5430.3401; val_lambda_latent_adj_recon_loss: 238.6033; val_lambda_latent_contrastive_instanceloss: 7.1921; val_lambda_latent_contrastive_clusterloss: 2.9268; val_global_loss: 6635.2683; val_optim_loss: 6635.2683
Epoch 4/100 |--------------------| 4.0% val_auroc_score: 0.8961; val_auprc_score: 0.8795; val_best_acc_score: 0.8228; val_best_f1_score: 0.8309; train_kl_reg_loss: 21.4036; train_edge_recon_loss: 1062.1254; train_gene_expr_recon_loss: 5422.4451; train_lambda_latent_adj_recon_loss: 307.0592; train_lambda_latent_contrastive_instanceloss: 7.4323; train_lambda_latent_contrastive_clusterloss: 3.0600; train_global_loss: 6823.5256; train_optim_loss: 6823.5256; val_kl_reg_loss: 17.9631; val_edge_recon_loss: 921.3791; val_gene_expr_recon_loss: 5400.9174; val_lambda_latent_adj_recon_loss: 230.3073; val_lambda_latent_contrastive_instanceloss: 7.1721; val_lambda_latent_contrastive_clusterloss: 2.7270; val_global_loss: 6580.4661; val_optim_loss: 6580.4661
Epoch 5/100 |█-------------------| 5.0% val_auroc_score: 0.9090; val_auprc_score: 0.8964; val_best_acc_score: 0.8357; val_best_f1_score: 0.8425; train_kl_reg_loss: 25.5544; train_edge_recon_loss: 1046.1013; train_gene_expr_recon_loss: 5415.6353; train_lambda_latent_adj_recon_loss: 287.4162; train_lambda_latent_contrastive_instanceloss: 7.3693; train_lambda_latent_contrastive_clusterloss: 2.9010; train_global_loss: 6784.9775; train_optim_loss: 6784.9775; val_kl_reg_loss: 20.8134; val_edge_recon_loss: 906.2025; val_gene_expr_recon_loss: 5326.2641; val_lambda_latent_adj_recon_loss: 222.6087; val_lambda_latent_contrastive_instanceloss: 7.1553; val_lambda_latent_contrastive_clusterloss: 2.6319; val_global_loss: 6485.6759; val_optim_loss: 6485.6759
Epoch 6/100 |█-------------------| 6.0% val_auroc_score: 0.9114; val_auprc_score: 0.8985; val_best_acc_score: 0.8368; val_best_f1_score: 0.8443; train_kl_reg_loss: 28.9820; train_edge_recon_loss: 1036.2737; train_gene_expr_recon_loss: 5392.3060; train_lambda_latent_adj_recon_loss: 273.4741; train_lambda_latent_contrastive_instanceloss: 7.3133; train_lambda_latent_contrastive_clusterloss: 2.7849; train_global_loss: 6741.1340; train_optim_loss: 6741.1340; val_kl_reg_loss: 25.0810; val_edge_recon_loss: 908.6509; val_gene_expr_recon_loss: 5372.3361; val_lambda_latent_adj_recon_loss: 219.8521; val_lambda_latent_contrastive_instanceloss: 7.1244; val_lambda_latent_contrastive_clusterloss: 2.5197; val_global_loss: 6535.5644; val_optim_loss: 6535.5644
Epoch 7/100 |█-------------------| 7.0% val_auroc_score: 0.9144; val_auprc_score: 0.9027; val_best_acc_score: 0.8392; val_best_f1_score: 0.8470; train_kl_reg_loss: 31.9467; train_edge_recon_loss: 1028.0276; train_gene_expr_recon_loss: 5397.0987; train_lambda_latent_adj_recon_loss: 263.5325; train_lambda_latent_contrastive_instanceloss: 7.2752; train_lambda_latent_contrastive_clusterloss: 2.7025; train_global_loss: 6730.5832; train_optim_loss: 6730.5832; val_kl_reg_loss: 28.3704; val_edge_recon_loss: 909.8115; val_gene_expr_recon_loss: 5316.6828; val_lambda_latent_adj_recon_loss: 218.3748; val_lambda_latent_contrastive_instanceloss: 7.1163; val_lambda_latent_contrastive_clusterloss: 2.4582; val_global_loss: 6482.8141; val_optim_loss: 6482.8141
Epoch 8/100 |█-------------------| 8.0% val_auroc_score: 0.9176; val_auprc_score: 0.9056; val_best_acc_score: 0.8439; val_best_f1_score: 0.8529; train_kl_reg_loss: 34.7242; train_edge_recon_loss: 1019.9997; train_gene_expr_recon_loss: 5364.1691; train_lambda_latent_adj_recon_loss: 254.7003; train_lambda_latent_contrastive_instanceloss: 7.2467; train_lambda_latent_contrastive_clusterloss: 2.6258; train_global_loss: 6683.4658; train_optim_loss: 6683.4658; val_kl_reg_loss: 30.9783; val_edge_recon_loss: 904.0569; val_gene_expr_recon_loss: 5328.9678; val_lambda_latent_adj_recon_loss: 213.3122; val_lambda_latent_contrastive_instanceloss: 7.1096; val_lambda_latent_contrastive_clusterloss: 2.3953; val_global_loss: 6486.8202; val_optim_loss: 6486.8202
Epoch 9/100 |█-------------------| 9.0% val_auroc_score: 0.9215; val_auprc_score: 0.9107; val_best_acc_score: 0.8483; val_best_f1_score: 0.8548; train_kl_reg_loss: 37.6573; train_edge_recon_loss: 1013.4732; train_gene_expr_recon_loss: 5346.9208; train_lambda_latent_adj_recon_loss: 248.7668; train_lambda_latent_contrastive_instanceloss: 7.2233; train_lambda_latent_contrastive_clusterloss: 2.5597; train_global_loss: 6656.6010; train_optim_loss: 6656.6010; val_kl_reg_loss: 34.9444; val_edge_recon_loss: 904.8325; val_gene_expr_recon_loss: 5278.8454; val_lambda_latent_adj_recon_loss: 213.0423; val_lambda_latent_contrastive_instanceloss: 7.1197; val_lambda_latent_contrastive_clusterloss: 2.3675; val_global_loss: 6441.1519; val_optim_loss: 6441.1519
Epoch 10/100 |██------------------| 10.0% val_auroc_score: 0.9253; val_auprc_score: 0.9157; val_best_acc_score: 0.8538; val_best_f1_score: 0.8599; train_kl_reg_loss: 40.0304; train_edge_recon_loss: 1007.8231; train_gene_expr_recon_loss: 5328.1161; train_lambda_latent_adj_recon_loss: 243.4221; train_lambda_latent_contrastive_instanceloss: 7.2154; train_lambda_latent_contrastive_clusterloss: 2.5188; train_global_loss: 6629.1260; train_optim_loss: 6629.1260; val_kl_reg_loss: 37.3020; val_edge_recon_loss: 902.2868; val_gene_expr_recon_loss: 5272.3921; val_lambda_latent_adj_recon_loss: 211.4311; val_lambda_latent_contrastive_instanceloss: 7.1061; val_lambda_latent_contrastive_clusterloss: 2.3183; val_global_loss: 6432.8364; val_optim_loss: 6432.8364
Epoch 11/100 |██------------------| 11.0% val_auroc_score: 0.9284; val_auprc_score: 0.9207; val_best_acc_score: 0.8556; val_best_f1_score: 0.8609; train_kl_reg_loss: 42.1992; train_edge_recon_loss: 1003.3689; train_gene_expr_recon_loss: 5320.7985; train_lambda_latent_adj_recon_loss: 238.6463; train_lambda_latent_contrastive_instanceloss: 7.2006; train_lambda_latent_contrastive_clusterloss: 2.4720; train_global_loss: 6614.6855; train_optim_loss: 6614.6855; val_kl_reg_loss: 40.6042; val_edge_recon_loss: 900.4749; val_gene_expr_recon_loss: 5286.1482; val_lambda_latent_adj_recon_loss: 208.3427; val_lambda_latent_contrastive_instanceloss: 7.0959; val_lambda_latent_contrastive_clusterloss: 2.2627; val_global_loss: 6444.9286; val_optim_loss: 6444.9286
Epoch 12/100 |██------------------| 12.0% val_auroc_score: 0.9303; val_auprc_score: 0.9233; val_best_acc_score: 0.8571; val_best_f1_score: 0.8621; train_kl_reg_loss: 44.3698; train_edge_recon_loss: 998.3073; train_gene_expr_recon_loss: 5308.4645; train_lambda_latent_adj_recon_loss: 234.5036; train_lambda_latent_contrastive_instanceloss: 7.1910; train_lambda_latent_contrastive_clusterloss: 2.4309; train_global_loss: 6595.2672; train_optim_loss: 6595.2672; val_kl_reg_loss: 42.7152; val_edge_recon_loss: 902.3191; val_gene_expr_recon_loss: 5268.0654; val_lambda_latent_adj_recon_loss: 208.6045; val_lambda_latent_contrastive_instanceloss: 7.0970; val_lambda_latent_contrastive_clusterloss: 2.2379; val_global_loss: 6431.0391; val_optim_loss: 6431.0391
Epoch 13/100 |██------------------| 13.0% val_auroc_score: 0.9336; val_auprc_score: 0.9250; val_best_acc_score: 0.8619; val_best_f1_score: 0.8669; train_kl_reg_loss: 46.1923; train_edge_recon_loss: 994.2458; train_gene_expr_recon_loss: 5297.0569; train_lambda_latent_adj_recon_loss: 230.6976; train_lambda_latent_contrastive_instanceloss: 7.1839; train_lambda_latent_contrastive_clusterloss: 2.3983; train_global_loss: 6577.7748; train_optim_loss: 6577.7748; val_kl_reg_loss: 46.1184; val_edge_recon_loss: 898.5275; val_gene_expr_recon_loss: 5255.3697; val_lambda_latent_adj_recon_loss: 205.7938; val_lambda_latent_contrastive_instanceloss: 7.0965; val_lambda_latent_contrastive_clusterloss: 2.2186; val_global_loss: 6415.1247; val_optim_loss: 6415.1247
Epoch 14/100 |██------------------| 14.0% val_auroc_score: 0.9349; val_auprc_score: 0.9261; val_best_acc_score: 0.8631; val_best_f1_score: 0.8682; train_kl_reg_loss: 47.6387; train_edge_recon_loss: 990.7952; train_gene_expr_recon_loss: 5296.9750; train_lambda_latent_adj_recon_loss: 228.0738; train_lambda_latent_contrastive_instanceloss: 7.1751; train_lambda_latent_contrastive_clusterloss: 2.3696; train_global_loss: 6573.0274; train_optim_loss: 6573.0274; val_kl_reg_loss: 45.9330; val_edge_recon_loss: 895.7226; val_gene_expr_recon_loss: 5225.4683; val_lambda_latent_adj_recon_loss: 202.6950; val_lambda_latent_contrastive_instanceloss: 7.0972; val_lambda_latent_contrastive_clusterloss: 2.1968; val_global_loss: 6379.1128; val_optim_loss: 6379.1128
Epoch 15/100 |███-----------------| 15.0% val_auroc_score: 0.9361; val_auprc_score: 0.9274; val_best_acc_score: 0.8647; val_best_f1_score: 0.8698; train_kl_reg_loss: 49.0725; train_edge_recon_loss: 988.3823; train_gene_expr_recon_loss: 5296.1879; train_lambda_latent_adj_recon_loss: 225.4141; train_lambda_latent_contrastive_instanceloss: 7.1702; train_lambda_latent_contrastive_clusterloss: 2.3497; train_global_loss: 6568.5768; train_optim_loss: 6568.5768; val_kl_reg_loss: 48.3474; val_edge_recon_loss: 896.2615; val_gene_expr_recon_loss: 5237.8419; val_lambda_latent_adj_recon_loss: 202.6539; val_lambda_latent_contrastive_instanceloss: 7.1008; val_lambda_latent_contrastive_clusterloss: 2.1894; val_global_loss: 6394.3949; val_optim_loss: 6394.3949
Epoch 16/100 |███-----------------| 16.0% val_auroc_score: 0.9379; val_auprc_score: 0.9298; val_best_acc_score: 0.8670; val_best_f1_score: 0.8719; train_kl_reg_loss: 50.3630; train_edge_recon_loss: 985.6939; train_gene_expr_recon_loss: 5272.6490; train_lambda_latent_adj_recon_loss: 222.4369; train_lambda_latent_contrastive_instanceloss: 7.1643; train_lambda_latent_contrastive_clusterloss: 2.3290; train_global_loss: 6540.6361; train_optim_loss: 6540.6361; val_kl_reg_loss: 50.1794; val_edge_recon_loss: 894.4276; val_gene_expr_recon_loss: 5202.4649; val_lambda_latent_adj_recon_loss: 202.8389; val_lambda_latent_contrastive_instanceloss: 7.0885; val_lambda_latent_contrastive_clusterloss: 2.1455; val_global_loss: 6359.1449; val_optim_loss: 6359.1449
Epoch 17/100 |███-----------------| 17.0% val_auroc_score: 0.9387; val_auprc_score: 0.9303; val_best_acc_score: 0.8680; val_best_f1_score: 0.8728; train_kl_reg_loss: 51.4169; train_edge_recon_loss: 983.4045; train_gene_expr_recon_loss: 5285.5260; train_lambda_latent_adj_recon_loss: 220.2423; train_lambda_latent_contrastive_instanceloss: 7.1549; train_lambda_latent_contrastive_clusterloss: 2.3026; train_global_loss: 6550.0473; train_optim_loss: 6550.0473; val_kl_reg_loss: 50.9615; val_edge_recon_loss: 892.9413; val_gene_expr_recon_loss: 5205.1772; val_lambda_latent_adj_recon_loss: 199.4189; val_lambda_latent_contrastive_instanceloss: 7.0920; val_lambda_latent_contrastive_clusterloss: 2.1472; val_global_loss: 6357.7381; val_optim_loss: 6357.7381
Epoch 18/100 |███-----------------| 18.0% val_auroc_score: 0.9391; val_auprc_score: 0.9303; val_best_acc_score: 0.8689; val_best_f1_score: 0.8730; train_kl_reg_loss: 52.3619; train_edge_recon_loss: 980.9914; train_gene_expr_recon_loss: 5283.2702; train_lambda_latent_adj_recon_loss: 218.3410; train_lambda_latent_contrastive_instanceloss: 7.1553; train_lambda_latent_contrastive_clusterloss: 2.2937; train_global_loss: 6544.4135; train_optim_loss: 6544.4135; val_kl_reg_loss: 52.9606; val_edge_recon_loss: 892.3161; val_gene_expr_recon_loss: 5223.5675; val_lambda_latent_adj_recon_loss: 198.7384; val_lambda_latent_contrastive_instanceloss: 7.0897; val_lambda_latent_contrastive_clusterloss: 2.1517; val_global_loss: 6376.8239; val_optim_loss: 6376.8239
Epoch 19/100 |███-----------------| 19.0% val_auroc_score: 0.9392; val_auprc_score: 0.9307; val_best_acc_score: 0.8683; val_best_f1_score: 0.8740; train_kl_reg_loss: 53.6962; train_edge_recon_loss: 979.7246; train_gene_expr_recon_loss: 5278.8383; train_lambda_latent_adj_recon_loss: 217.6898; train_lambda_latent_contrastive_instanceloss: 7.1508; train_lambda_latent_contrastive_clusterloss: 2.2790; train_global_loss: 6539.3787; train_optim_loss: 6539.3787; val_kl_reg_loss: 52.9283; val_edge_recon_loss: 891.2258; val_gene_expr_recon_loss: 5276.3486; val_lambda_latent_adj_recon_loss: 196.0161; val_lambda_latent_contrastive_instanceloss: 7.0874; val_lambda_latent_contrastive_clusterloss: 2.1156; val_global_loss: 6425.7215; val_optim_loss: 6425.7215
Epoch 20/100 |████----------------| 20.0% val_auroc_score: 0.9396; val_auprc_score: 0.9300; val_best_acc_score: 0.8696; val_best_f1_score: 0.8741; train_kl_reg_loss: 54.7219; train_edge_recon_loss: 977.0739; train_gene_expr_recon_loss: 5273.4524; train_lambda_latent_adj_recon_loss: 214.7041; train_lambda_latent_contrastive_instanceloss: 7.1474; train_lambda_latent_contrastive_clusterloss: 2.2570; train_global_loss: 6529.3568; train_optim_loss: 6529.3568; val_kl_reg_loss: 54.8765; val_edge_recon_loss: 892.5430; val_gene_expr_recon_loss: 5252.6808; val_lambda_latent_adj_recon_loss: 196.6868; val_lambda_latent_contrastive_instanceloss: 7.0819; val_lambda_latent_contrastive_clusterloss: 2.1001; val_global_loss: 6405.9689; val_optim_loss: 6405.9689
Epoch 21/100 |████----------------| 21.0% val_auroc_score: 0.9419; val_auprc_score: 0.9336; val_best_acc_score: 0.8721; val_best_f1_score: 0.8771; train_kl_reg_loss: 55.9248; train_edge_recon_loss: 975.8963; train_gene_expr_recon_loss: 5255.5584; train_lambda_latent_adj_recon_loss: 213.8182; train_lambda_latent_contrastive_instanceloss: 7.1440; train_lambda_latent_contrastive_clusterloss: 2.2400; train_global_loss: 6510.5816; train_optim_loss: 6510.5816; val_kl_reg_loss: 56.4149; val_edge_recon_loss: 889.6046; val_gene_expr_recon_loss: 5198.2423; val_lambda_latent_adj_recon_loss: 196.1945; val_lambda_latent_contrastive_instanceloss: 7.0856; val_lambda_latent_contrastive_clusterloss: 2.0940; val_global_loss: 6349.6357; val_optim_loss: 6349.6357
Epoch 22/100 |████----------------| 22.0% val_auroc_score: 0.9422; val_auprc_score: 0.9346; val_best_acc_score: 0.8721; val_best_f1_score: 0.8776; train_kl_reg_loss: 56.9404; train_edge_recon_loss: 975.1945; train_gene_expr_recon_loss: 5251.8127; train_lambda_latent_adj_recon_loss: 212.9738; train_lambda_latent_contrastive_instanceloss: 7.1415; train_lambda_latent_contrastive_clusterloss: 2.2308; train_global_loss: 6506.2938; train_optim_loss: 6506.2938; val_kl_reg_loss: 57.0986; val_edge_recon_loss: 889.3088; val_gene_expr_recon_loss: 5204.8764; val_lambda_latent_adj_recon_loss: 193.6755; val_lambda_latent_contrastive_instanceloss: 7.0878; val_lambda_latent_contrastive_clusterloss: 2.1027; val_global_loss: 6354.1497; val_optim_loss: 6354.1497
Epoch 23/100 |████----------------| 23.0% val_auroc_score: 0.9420; val_auprc_score: 0.9336; val_best_acc_score: 0.8720; val_best_f1_score: 0.8773; train_kl_reg_loss: 57.7304; train_edge_recon_loss: 972.8330; train_gene_expr_recon_loss: 5244.1349; train_lambda_latent_adj_recon_loss: 210.5924; train_lambda_latent_contrastive_instanceloss: 7.1421; train_lambda_latent_contrastive_clusterloss: 2.2189; train_global_loss: 6494.6517; train_optim_loss: 6494.6517; val_kl_reg_loss: 58.9109; val_edge_recon_loss: 888.5466; val_gene_expr_recon_loss: 5232.9234; val_lambda_latent_adj_recon_loss: 193.4982; val_lambda_latent_contrastive_instanceloss: 7.0829; val_lambda_latent_contrastive_clusterloss: 2.0864; val_global_loss: 6383.0485; val_optim_loss: 6383.0485
Epoch 24/100 |████----------------| 24.0% val_auroc_score: 0.9436; val_auprc_score: 0.9346; val_best_acc_score: 0.8749; val_best_f1_score: 0.8792; train_kl_reg_loss: 58.5212; train_edge_recon_loss: 971.9691; train_gene_expr_recon_loss: 5243.5717; train_lambda_latent_adj_recon_loss: 210.2255; train_lambda_latent_contrastive_instanceloss: 7.1351; train_lambda_latent_contrastive_clusterloss: 2.2029; train_global_loss: 6493.6255; train_optim_loss: 6493.6255; val_kl_reg_loss: 59.3352; val_edge_recon_loss: 890.0997; val_gene_expr_recon_loss: 5238.8110; val_lambda_latent_adj_recon_loss: 194.7279; val_lambda_latent_contrastive_instanceloss: 7.0863; val_lambda_latent_contrastive_clusterloss: 2.0925; val_global_loss: 6392.1526; val_optim_loss: 6392.1526
Epoch 25/100 |█████---------------| 25.0% val_auroc_score: 0.9438; val_auprc_score: 0.9359; val_best_acc_score: 0.8750; val_best_f1_score: 0.8795; train_kl_reg_loss: 59.2990; train_edge_recon_loss: 970.9260; train_gene_expr_recon_loss: 5265.2547; train_lambda_latent_adj_recon_loss: 208.6764; train_lambda_latent_contrastive_instanceloss: 7.1365; train_lambda_latent_contrastive_clusterloss: 2.2007; train_global_loss: 6513.4933; train_optim_loss: 6513.4933; val_kl_reg_loss: 59.5585; val_edge_recon_loss: 887.8429; val_gene_expr_recon_loss: 5210.1071; val_lambda_latent_adj_recon_loss: 191.6170; val_lambda_latent_contrastive_instanceloss: 7.0896; val_lambda_latent_contrastive_clusterloss: 2.0841; val_global_loss: 6358.2992; val_optim_loss: 6358.2992
Reducing learning rate: metric has not improved more than 0.0 in the last 4 epochs.
New learning rate is 0.0001.
Epoch 26/100 |█████---------------| 26.0% val_auroc_score: 0.9446; val_auprc_score: 0.9367; val_best_acc_score: 0.8745; val_best_f1_score: 0.8793; train_kl_reg_loss: 59.7228; train_edge_recon_loss: 969.2287; train_gene_expr_recon_loss: 5232.8439; train_lambda_latent_adj_recon_loss: 208.1203; train_lambda_latent_contrastive_instanceloss: 7.1374; train_lambda_latent_contrastive_clusterloss: 2.2018; train_global_loss: 6479.2550; train_optim_loss: 6479.2550; val_kl_reg_loss: 60.6127; val_edge_recon_loss: 887.4112; val_gene_expr_recon_loss: 5133.7036; val_lambda_latent_adj_recon_loss: 191.0741; val_lambda_latent_contrastive_instanceloss: 7.0808; val_lambda_latent_contrastive_clusterloss: 2.0602; val_global_loss: 6281.9426; val_optim_loss: 6281.9426
Epoch 27/100 |█████---------------| 27.0% val_auroc_score: 0.9438; val_auprc_score: 0.9347; val_best_acc_score: 0.8751; val_best_f1_score: 0.8805; train_kl_reg_loss: 59.9173; train_edge_recon_loss: 969.1290; train_gene_expr_recon_loss: 5229.4897; train_lambda_latent_adj_recon_loss: 207.7686; train_lambda_latent_contrastive_instanceloss: 7.1336; train_lambda_latent_contrastive_clusterloss: 2.1899; train_global_loss: 6475.6282; train_optim_loss: 6475.6282; val_kl_reg_loss: 60.7459; val_edge_recon_loss: 887.9291; val_gene_expr_recon_loss: 5167.0638; val_lambda_latent_adj_recon_loss: 190.4045; val_lambda_latent_contrastive_instanceloss: 7.0770; val_lambda_latent_contrastive_clusterloss: 2.0720; val_global_loss: 6315.2923; val_optim_loss: 6315.2923
Epoch 28/100 |█████---------------| 28.0% val_auroc_score: 0.9445; val_auprc_score: 0.9354; val_best_acc_score: 0.8750; val_best_f1_score: 0.8804; train_kl_reg_loss: 60.0907; train_edge_recon_loss: 968.2249; train_gene_expr_recon_loss: 5243.8397; train_lambda_latent_adj_recon_loss: 207.8056; train_lambda_latent_contrastive_instanceloss: 7.1319; train_lambda_latent_contrastive_clusterloss: 2.1862; train_global_loss: 6489.2790; train_optim_loss: 6489.2790; val_kl_reg_loss: 61.0254; val_edge_recon_loss: 886.7026; val_gene_expr_recon_loss: 5215.5517; val_lambda_latent_adj_recon_loss: 192.0533; val_lambda_latent_contrastive_instanceloss: 7.0826; val_lambda_latent_contrastive_clusterloss: 2.0794; val_global_loss: 6364.4950; val_optim_loss: 6364.4950
Epoch 29/100 |█████---------------| 29.0% val_auroc_score: 0.9448; val_auprc_score: 0.9369; val_best_acc_score: 0.8758; val_best_f1_score: 0.8803; train_kl_reg_loss: 59.9719; train_edge_recon_loss: 968.2728; train_gene_expr_recon_loss: 5228.9737; train_lambda_latent_adj_recon_loss: 207.6368; train_lambda_latent_contrastive_instanceloss: 7.1318; train_lambda_latent_contrastive_clusterloss: 2.1875; train_global_loss: 6474.1745; train_optim_loss: 6474.1745; val_kl_reg_loss: 60.9045; val_edge_recon_loss: 887.8273; val_gene_expr_recon_loss: 5192.4658; val_lambda_latent_adj_recon_loss: 190.7073; val_lambda_latent_contrastive_instanceloss: 7.0761; val_lambda_latent_contrastive_clusterloss: 2.0699; val_global_loss: 6341.0510; val_optim_loss: 6341.0510
Epoch 30/100 |██████--------------| 30.0% val_auroc_score: 0.9455; val_auprc_score: 0.9371; val_best_acc_score: 0.8766; val_best_f1_score: 0.8807; train_kl_reg_loss: 60.1584; train_edge_recon_loss: 968.0897; train_gene_expr_recon_loss: 5235.3950; train_lambda_latent_adj_recon_loss: 207.0717; train_lambda_latent_contrastive_instanceloss: 7.1310; train_lambda_latent_contrastive_clusterloss: 2.1928; train_global_loss: 6480.0386; train_optim_loss: 6480.0386; val_kl_reg_loss: 61.2421; val_edge_recon_loss: 886.7793; val_gene_expr_recon_loss: 5209.3997; val_lambda_latent_adj_recon_loss: 191.9946; val_lambda_latent_contrastive_instanceloss: 7.0864; val_lambda_latent_contrastive_clusterloss: 2.0714; val_global_loss: 6358.5735; val_optim_loss: 6358.5735
Reducing learning rate: metric has not improved more than 0.0 in the last 4 epochs.
New learning rate is 1e-05.
Epoch 31/100 |██████--------------| 31.0% val_auroc_score: 0.9461; val_auprc_score: 0.9385; val_best_acc_score: 0.8766; val_best_f1_score: 0.8815; train_kl_reg_loss: 60.2164; train_edge_recon_loss: 968.0784; train_gene_expr_recon_loss: 5225.1694; train_lambda_latent_adj_recon_loss: 207.3752; train_lambda_latent_contrastive_instanceloss: 7.1328; train_lambda_latent_contrastive_clusterloss: 2.1873; train_global_loss: 6470.1596; train_optim_loss: 6470.1596; val_kl_reg_loss: 61.1259; val_edge_recon_loss: 886.3493; val_gene_expr_recon_loss: 5189.7393; val_lambda_latent_adj_recon_loss: 192.0157; val_lambda_latent_contrastive_instanceloss: 7.0793; val_lambda_latent_contrastive_clusterloss: 2.0729; val_global_loss: 6338.3822; val_optim_loss: 6338.3822
Epoch 32/100 |██████--------------| 32.0% val_auroc_score: 0.9453; val_auprc_score: 0.9377; val_best_acc_score: 0.8760; val_best_f1_score: 0.8808; train_kl_reg_loss: 60.1959; train_edge_recon_loss: 968.2590; train_gene_expr_recon_loss: 5237.1731; train_lambda_latent_adj_recon_loss: 207.1313; train_lambda_latent_contrastive_instanceloss: 7.1311; train_lambda_latent_contrastive_clusterloss: 2.1876; train_global_loss: 6482.0780; train_optim_loss: 6482.0780; val_kl_reg_loss: 61.1736; val_edge_recon_loss: 887.1943; val_gene_expr_recon_loss: 5212.0062; val_lambda_latent_adj_recon_loss: 191.6209; val_lambda_latent_contrastive_instanceloss: 7.0895; val_lambda_latent_contrastive_clusterloss: 2.0963; val_global_loss: 6361.1807; val_optim_loss: 6361.1807
Epoch 33/100 |██████--------------| 33.0% val_auroc_score: 0.9467; val_auprc_score: 0.9385; val_best_acc_score: 0.8785; val_best_f1_score: 0.8829; train_kl_reg_loss: 60.2250; train_edge_recon_loss: 967.8500; train_gene_expr_recon_loss: 5237.6586; train_lambda_latent_adj_recon_loss: 206.6367; train_lambda_latent_contrastive_instanceloss: 7.1301; train_lambda_latent_contrastive_clusterloss: 2.1838; train_global_loss: 6481.6842; train_optim_loss: 6481.6842; val_kl_reg_loss: 61.1430; val_edge_recon_loss: 886.0104; val_gene_expr_recon_loss: 5205.8841; val_lambda_latent_adj_recon_loss: 190.2358; val_lambda_latent_contrastive_instanceloss: 7.0813; val_lambda_latent_contrastive_clusterloss: 2.0675; val_global_loss: 6352.4224; val_optim_loss: 6352.4224
Epoch 34/100 |██████--------------| 34.0% val_auroc_score: 0.9453; val_auprc_score: 0.9364; val_best_acc_score: 0.8768; val_best_f1_score: 0.8817; train_kl_reg_loss: 60.2026; train_edge_recon_loss: 968.1556; train_gene_expr_recon_loss: 5221.0603; train_lambda_latent_adj_recon_loss: 207.4286; train_lambda_latent_contrastive_instanceloss: 7.1327; train_lambda_latent_contrastive_clusterloss: 2.1960; train_global_loss: 6466.1759; train_optim_loss: 6466.1759; val_kl_reg_loss: 61.1081; val_edge_recon_loss: 886.8730; val_gene_expr_recon_loss: 5185.8363; val_lambda_latent_adj_recon_loss: 191.4617; val_lambda_latent_contrastive_instanceloss: 7.0747; val_lambda_latent_contrastive_clusterloss: 2.0495; val_global_loss: 6334.4030; val_optim_loss: 6334.4030
Stopping early: metric has not improved more than 0.0 in the last 8 epochs.
If the early stopping criterion is too strong, please instantiate it with different parameters in the train method.
Model training finished after 22 min 46 sec.
Using best model state, which was in epoch 26.
--- MODEL EVALUATION ---
val AUROC score: 0.9449
val AUPRC score: 0.9367
val best accuracy score: 0.8758
val best F1 score: 0.8801
val MSE score: 0.2599
[10]:
# Compute latent neighbor graph
latent_key = 'garfield_latent'
sc.pp.neighbors(model.adata,
use_rep=latent_key,
key_added=latent_key)
# Compute UMAP embedding
sc.tl.umap(model.adata,
neighbors_key=latent_key)
Visualize Garfield Latent Space
[11]:
sc.settings.set_figure_params(dpi=100, facecolor='white')
## cell distribution colored by original celltype
sc.pl.umap(model.adata, color=['cell_type'], show=True, size=3)
[12]:
# Compute latent Leiden clustering
latent_leiden_resolution = 0.5
latent_cluster_key = f"latent_leiden_{str(latent_leiden_resolution)}"
latent_key = "garfield_latent"
sc.tl.leiden(adata=model.adata,
resolution=latent_leiden_resolution,
key_added=latent_cluster_key,
neighbors_key=latent_key)
len(model.adata.obs[latent_cluster_key].unique())
[12]:
12
[13]:
# Visualize cell-level annotated data in physical space
model.adata.obsm['spatial'][:, 1] *= -1 # 翻转 y 坐标 手动修正
sc.pl.embedding(model.adata, basis="spatial",
color=["cell_type"],
ncols=1, wspace=0.20, edges=False)
## niches
sc.pl.embedding(model.adata, basis="spatial",
color=[latent_cluster_key],
ncols=1, wspace=0.20, edges=False)
[14]:
# Save trained model
model_folder_path = f"{workdir}/model"
os.makedirs(model_folder_path, exist_ok=True)
model.save(dir_path=model_folder_path,
overwrite=True,
save_adata=True,
adata_file_name="adata_ref.h5ad")
Model saved successfully using pickle at /home/zhouweige/zhouwg_data/project/Garfield_tutorials/result/garfield_spRNA_mouse_hippocampus/model/attr.pkl
[ ]: