본문 바로가기
AI & Data Analysis/Deep Learning

[ScRAT] SPILT Dataset Results

by doraemin_dev 2025. 8. 8.

COVID 데이터셋에 대하여, 단일 데이터(.h5ad)가 아닌, 직접 (5개의 repeat) * (5개의 fold)를 나눠주고 지정하여 결과를 확인해보자


먼저, 단일 데이터로 Hyperparameter Tuning을 해주었다

HMAIL (HA) 논문의 baseline model인 ScRAT의 Hyperparamter

 

learning rate 값은 1e-4로 고정, augmentation False한 나머지 값에 대해 Tuning 수행 결과 (run_hyperparameter_tuning.sh)  :

run_hyparparameter_tuning.sh
0.00MB

    learning_rate  head  dropout  weight_decay  emb_dim  test_auc
80         0.0001     4      0.0        0.0001        8  0.944444
94         0.0001     4      0.5        0.0010       64  0.933333
57         0.0001     2      0.5        0.0010       32  0.933333
86         0.0001     4      0.3        0.0010        8  0.927778
91         0.0001     4      0.5        0.0100       64  0.922222
77         0.0001     4      0.0        0.0010        8  0.916667
33         0.0001     1      0.7        0.0001       32  0.911111
79         0.0001     4      0.0        0.0001       64  0.911111
76         0.0001     4      0.0        0.0010       64  0.911111
37         0.0001     2      0.0        0.0100       64  0.911111


7번째이긴 하나, 가장 메모리 효율적이라 7번째 하이퍼파라미터 값을 선택하자. (cardio에서 실행됨)

    learning_rate  head  dropout  weight_decay  emb_dim  test_auc
33         0.0001     1      0.7        0.0001       32  0.911111

 

가장 높은 AUC 값은 0.94.

선택한 하이퍼파라미터의 AUC 값은 0.91.

 

참고로, HA 논문의 ScRAT 결과 값은 AUC 0.83+-0.04


이제 Covid split data로 결과를 확인해보자

 직접 (5개의 repeat) * (5개의 fold)를 나눠준 데이터들이다.

  • 각 train data의 patient unique count: 40
  • 각 test data의 patient unique count: 10

1. cell type : manual annotation (18개)

['Developing Ciliated Cells', 'Squamous Cells', 'Secretory Cells', 'Macrophages', 'B Cells', ..., 'Developing Secretory and Goblet Cells', 'Plasmacytoid DCs', 'Enteroendocrine Cells', 'Erythroblasts', 'Mast Cells']
Length: 18
Categories (18, object): ['B Cells', 'Basal Cells', 'Ciliated Cells', 'Dendritic Cells', ..., 'Plasmacytoid DCs', 'Secretory Cells', 'Squamous Cells', 'T Cells']
manual_annotation
Ciliated Cells                           6879
Secretory Cells                          3129
Developing Ciliated Cells                2934
Squamous Cells                           1874
Goblet Cells                             1470
Basal Cells                              1437
T Cells                                   994
Erythroblasts                             985
Macrophages                               837
Deuterosomal Cells                        468
Developing Secretory and Goblet Cells     364
Ionocytes                                 304
Mitotic Basal Cells                       237
Dendritic Cells                           132
B Cells                                    48
Enteroendocrine Cells                      25
Plasmacytoid DCs                           12
Mast Cells                                  8
Name: count, dtype: int64

2. cell type : singleR annotaion (36개 + Nan)

* nan으로 지정된 데이터가 4개나 있어서, 'Unknown'으로 설정해주고 mixup()을 실행했다.

['Epithelial_cells', 'Platelets', 'Keratinocytes', 'Macrophage', 'B_cell', ..., 'MEP', 'BM & Prog.', 'Pro-B_cell_CD34+', 'Pro-Myelocyte', NaN]
Length: 37
Categories (36, object): ['Astrocyte', 'BM', 'BM & Prog.', 'B_cell', ..., 'Smooth_muscle_cells', 'T_cells', 'Tissue_stem_cells', 'iPS_cells']
singler_annotation
Epithelial_cells        15305
Keratinocytes            1437
T_cells                   705
NK_cell                   545
Gametocytes               480
Neutrophils               467
Neurons                   467
Monocyte                  388
Macrophage                362
Erythroblast              167
DC                        163
Astrocyte                 151
Platelets                 146
HSC_-G-CSF                141
Smooth_muscle_cells       122
HSC_CD34+                 102
Embryonic_stem_cells      101
Endothelial_cells          98
B_cell                     86
Myelocyte                  86
CMP                        79
...
Pro-B_cell_CD34+           18
MSC                        17
iPS_cells                  14
Name: count, dtype: int64

 

실행

run_covid.sh
0.00MB

########################## Covid split Dataset #############################

log_file="logs_covid_split/manual_annotation.txt"
echo "▶ Running with: lr=0.0001, heads=1, dropout=0.7, weight_decay=0.0001, emb_dim=32"
echo "▶ Output: ${log_file}"
CUDA_VISIBLE_DEVICES=0,1 PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128 \
python main.py \
  --task custom_covid \
  --dataset /data/project/kim89/0804_data \
  --learning_rate 0.0001 \
  --epochs 100 \
  --heads 1 \
  --dropout 0.7 \
  --weight_decay 0.0001 \
  --emb_dim 32 \
  --pca False \
  --repeat 5 \
  --cell_type_annotation manual_annotation > "$log_file" 2>&1
  
# log_file 이름 수정하기
# cell_type_annotation 수정하기(singler_annotation 또는 manual_annotation)
# augment_num 여부 수정하기

# < 메모리 사용 >
# |    0   N/A  N/A   2657033      C   python                                    23154MiB |
# |    1   N/A  N/A   2657033      C   python                                    23542MiB |


# < mixup() 실행 시, 메모리 사용 : 메모리 차지가 더 작다...(?) >
# |    0   N/A  N/A   2666702      C   python                                    12722MiB |
# |    1   N/A  N/A   2666702      C   python                                    10510MiB |

 

결과

logs_covid_split/manual_annotation_augment.txt
📌 Repeat 0: 평균 AUC = 0.9524, 표준편차 = 0.0522
NaN 개수: 0 / 전체 5개
📌 Repeat 1: 평균 AUC = 0.9619, 표준편차 = 0.0467
NaN 개수: 0 / 전체 5개
📌 Repeat 2: 평균 AUC = 0.9429, 표준편차 = 0.0356
NaN 개수: 0 / 전체 5개
📌 Repeat 3: 평균 AUC = 0.9238, 표준편차 = 0.0933
NaN 개수: 0 / 전체 5개
📌 Repeat 4: 평균 AUC = 0.9048, 표준편차 = 0.1444
NaN 개수: 0 / 전체 5개
=> mean ± std = 0.9372 ± 0.0229

logs_covid_split/singler_annotation_augment.txt
📌 Repeat 0: 평균 AUC = 0.9429, 표준편차 = 0.0555
NaN 개수: 0 / 전체 5개
📌 Repeat 1: 평균 AUC = 0.9619, 표준편차 = 0.0555
NaN 개수: 0 / 전체 5개
📌 Repeat 2: 평균 AUC = 0.9429, 표준편차 = 0.0467
NaN 개수: 0 / 전체 5개
📌 Repeat 3: 평균 AUC = 0.9333, 표준편차 = 0.0713
NaN 개수: 0 / 전체 5개
📌 Repeat 4: 평균 AUC = 0.9619, 표준편차 = 0.0356
NaN 개수: 0 / 전체 5개
=> mean ± std = 0.9486 ± 0.0128

이번엔 Cardio split data로도 결과를 확인해보자

 직접 (5개의 repeat) * (5개의 fold)를 나눠준 데이터들이다.

  • 각 train data의 patient unique count: 33
  • 각 train data의 patient unique count: 9

 

1. cell type : manual annotation (13개)

['cardiac muscle cell', 'fat cell', 'vascular associated smooth muscle cell', 'macrophage', 'endocardial cell', ..., 'pericyte cell', 'cardiac neuron', 'lymphocyte', 'mast cell', 'mesothelial cell']
Length: 13
Categories (13, object): ['cardiac endothelial cell', 'cardiac muscle cell', 'cardiac neuron', 'cardiac ventricle fibroblast', ..., 'mast cell', 'mesothelial cell', 'pericyte cell', 'vascular associated smooth muscle cell']
manual_annotation
cardiac muscle cell                       120353
cardiac ventricle fibroblast              113212
cardiac endothelial cell                   80093
pericyte cell                              54544
macrophage                                 46083
vascular associated smooth muscle cell     14650
lymphocyte                                 13615
endocardial cell                            5029
endothelial cell of lymphatic vessel        4297
fat cell                                    4295
mast cell                                   3729
cardiac neuron                              3097
mesothelial cell                             215
Name: count, dtype: int64

2. cell type : singleR annotaion (36개 + Nan)

['Neurons', 'Smooth_muscle_cells', 'Osteoblasts', 'Endothelial_cells', 'MSC', ..., 'Pro-Myelocyte', 'Pre-B_cell_CD34-', 'BM', 'GMP', 'Pro-B_cell_CD34+']
Length: 37
Categories (36, object): ['Astrocyte', 'BM', 'BM & Prog.', 'B_cell', ..., 'Smooth_muscle_cells', 'T_cells', 'Tissue_stem_cells', 'iPS_cells']
singler_annotation
Endothelial_cells       115561
Smooth_muscle_cells      88175
Neurons                  49810
Fibroblasts              35767
Astrocyte                26373
Macrophage               24180
Osteoblasts              23810
Neutrophils              14999
Chondrocytes             13074
Neuroepithelial_cell     12199
Platelets                10110
T_cells                   6793
NK_cell                   6776
MSC                       5860
Monocyte                  5811
Tissue_stem_cells         5195
iPS_cells                 4598
Erythroblast              2742
DC                        2146
HSC_-G-CSF                1873
Embryonic_stem_cells      1332
...
Pro-B_cell_CD34+            43
GMP                         42
Pro-Myelocyte               30
Name: count, dtype: int64

 

실행

run_cardio.sh
0.00MB

########################## Cardio split Dataset #############################
# max_split_size_mb:32로 수정함
# --batch_size 1로 수정함

log_file="logs_cardio_split/manual_annotation.txt"
echo "▶ Running with: lr=0.0001, heads=1, dropout=0.7, weight_decay=0.0001, emb_dim=32"
echo "▶ Output: ${log_file}"
CUDA_VISIBLE_DEVICES=0 PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:32 \
python main.py \
  --task custom_cardio \
  --dataset /data/project/kim89/0805_data \
  --learning_rate 0.0001 \
  --epochs 100 \
  --heads 1 \
  --dropout 0.7 \
  --weight_decay 0.0001 \
  --emb_dim 32 \
  --pca False \
  --repeat 5 \
  --cell_type_annotation manual_annotation \
  --batch_size 1 > "$log_file" 2>&1
  
  
# log_file 이름 수정하기
# cell_type_annotation 수정하기(singler_annotation 또는 manual_annotation)
# augment_num 여부 수정하기

 

결과

logs_cardio_split/manual_annotation_augment.txt
📌 Repeat 0: 평균 AUC = 0.8630, 표준편차 = 0.1288
NaN 개수: 0 / 전체 5개
📌 Repeat 1: 평균 AUC = 0.9167, 표준편차 = 0.0497
NaN 개수: 0 / 전체 5개
📌 Repeat 2: 평균 AUC = 0.9056, 표준편차 = 0.0598
NaN 개수: 0 / 전체 5개
📌 Repeat 3: 평균 AUC = 0.9296, 표준편차 = 0.0646
NaN 개수: 0 / 전체 5개
📌 Repeat 4: 평균 AUC = 0.8611, 표준편차 = 0.0824
NaN 개수: 0 / 전체 5개
=> mean ± std = 0.8952 ± 0.0314


logs_cardio_split/singler_annotation_augment.txt
📌 Repeat 0: 평균 AUC = 0.8722, 표준편차 = 0.0778
NaN 개수: 0 / 전체 5개
📌 Repeat 1: 평균 AUC = 0.8963, 표준편차 = 0.0849
NaN 개수: 0 / 전체 5개
📌 Repeat 2: 평균 AUC = 0.9000, 표준편차 = 0.0716
NaN 개수: 0 / 전체 5개
📌 Repeat 3: 평균 AUC = 0.8926, 표준편차 = 0.1185
NaN 개수: 0 / 전체 5개
📌 Repeat 4: 평균 AUC = 0.9222, 표준편차 = 0.0754
NaN 개수: 0 / 전체 5개
=> mean ± std = 0.8967 ± 0.0179

이번엔 kidney split data로도 결과를 확인해보자

 직접 (5개의 repeat) * (5개의 fold)를 나눠준 데이터들이다.

  • 각 train data의 patient unique count: 61
  • 각 train data의 patient unique count: 16

1. cell type : manual annotation (25개)

['conventional dendritic cell', 'T cell', 'plasma cell', 'kidney interstitial cell', 'mononuclear phagocyte', ..., 'kidney collecting duct intercalated cell', 'podocyte', 'parietal epithelial cell', 'kidney connecting tubule epithelial cell', 'kidney loop of Henle thin descending limb epi...]
Length: 25
Categories (25, object): ['T cell', 'mononuclear phagocyte', 'endothelial cell', 'B cell', ..., 'kidney loop of Henle thin descending limb epi..., 'kidney collecting duct principal cell', 'kidney collecting duct intercalated cell', 'mast cell']
manual_annotation
epithelial cell of proximal tubule                           45779
kidney loop of Henle thick ascending limb epithelial cell    33845
kidney collecting duct principal cell                        25539
endothelial cell                                             13920
kidney collecting duct intercalated cell                     12550
T cell                                                       10238
kidney distal convoluted tubule epithelial cell               7874
kidney interstitial cell                                      5082
kidney connecting tubule epithelial cell                      4449
kidney loop of Henle thin ascending limb epithelial cell      3965
kidney loop of Henle thin descending limb epithelial cell     3840
conventional dendritic cell                                   2990
monocyte                                                      2796
B cell                                                        2606
mononuclear phagocyte                                         2029
cytotoxic T cell                                              1721
kidney interstitial alternatively activated macrophage        1703
mature NK T cell                                              1670
natural killer cell                                           1201
plasma cell                                                    867
parietal epithelial cell                                       733
non-classical monocyte                                         420
podocyte                                                       413
plasmacytoid dendritic cell, human                             292
mast cell                                                      114
Name: count, dtype: int64

2. cell type : singleR annotaion (36개 + Nan)

['DC', 'T_cells', 'B_cell', 'Fibroblasts', 'Macrophage', ..., 'MEP', 'BM & Prog.', 'Erythroblast', NaN, 'Gametocytes']
Length: 37
Categories (36, object): ['Astrocyte', 'BM', 'BM & Prog.', 'B_cell', ..., 'Smooth_muscle_cells', 'T_cells', 'Tissue_stem_cells', 'iPS_cells']
singler_annotation
Epithelial_cells        54477
Hepatocytes             25373
Endothelial_cells       16685
Smooth_muscle_cells     14104
Astrocyte               10427
T_cells                  9548
Neurons                  7905
Neuroepithelial_cell     7714
Fibroblasts              6975
Macrophage               3724
Monocyte                 3055
Embryonic_stem_cells     2903
B_cell                   2682
HSC_-G-CSF               2305
NK_cell                  2284
CMP                      1692
Chondrocytes             1577
iPS_cells                1570
Pre-B_cell_CD34-         1564
Keratinocytes            1348
DC                       1199
GMP                      1181
Tissue_stem_cells         849
Osteoblasts               842
BM                        774
MSC                       733
MEP                       573
BM & Prog.                479
Platelets                 385
Pro-Myelocyte             382
Neutrophils               333
Pro-B_cell_CD34+          289
HSC_CD34+                 261
Erythroblast              188
Myelocyte                  81
Gametocytes                48
Name: count, dtype: int64



실행

run_kidney.sh
0.00MB

########################## Kidney split Dataset #############################

log_file="logs_kidney_split/manual_annotation.txt"
echo "▶ Running with: lr=0.0001, heads=1, dropout=0.7, weight_decay=0.0001, emb_dim=32"
echo "▶ Output: ${log_file}"
CUDA_VISIBLE_DEVICES=0,1,2,3 PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128 \
python main.py \
  --task custom_kidney \
  --dataset /data/project/kim89/0819_kidney \
  --learning_rate 0.0001 \
  --epochs 100 \
  --heads 1 \
  --dropout 0.7 \
  --weight_decay 0.0001 \
  --emb_dim 32 \
  --pca False \
  --repeat 5 \
  --cell_type_annotation manual_annotation > "$log_file" 2>&1
  
# log_file 이름 수정하기
# cell_type_annotation 수정하기(singler_annotation 또는 manual_annotation)
# augment_num 여부 수정하기

# < 메모리 사용 >
# |    2   N/A  N/A   2642904      C   python                                    22756MiB |
# |    3   N/A  N/A   2642904      C   python                                    19998MiB |

# < mixup() 실행 시, 메모리 사용 >
# |    2   N/A  N/A   2676606      C   python                                    22150MiB |
# |    3   N/A  N/A   2676606      C   python                                    20216MiB |

split data 추가 시, 수정해야할 것

dataloader.py
 - 라벨 정의
 - cell type 정의

main.py
 - data 경로 정의


ScRAT 코드에서 cell type annotation  용도 :

더보기

ScRAT 코드에서 cell type annotation은 크게 두 가지 용도로 사용됩니다.


1. Mixup 데이터 증강 시, 같은 cell type끼리만 섞기 위해 사용

  • utils.py의 mixups() 함수에서,
    cell type annotation(cell_type)을 숫자로 매핑(all_ct)한 뒤,
    동일한 cell type(=cell population)끼리만 mixup을 수행합니다.
  • 이렇게 하는 이유는 다른 세포 유형을 섞으면 생물학적으로 의미가 없고, 오히려 학습을 방해할 수 있기 때문입니다.
  • 만약 한 sample에만 존재하는 cell type이면, 해당 type은 Gaussian noise를 추가하여 mixup을 대체합니다.
  • 이 과정은 원 논문에서도 명시되어 있습니다:
  • “although our model does not require cell type information, during the sample mixup, we only mix cells of the same cell population…”

2. Attention 해석 단계에서 ‘critical cell types’ 식별

  • ScRAT 모델은 학습 중 attention weight를 통해 high-attention cells를 찾습니다.
  • 평가 단계에서, 만약 cell type annotation이 제공되면,
    • 각 cell type별 High-attention Occurrence Value(HOV)와 Relevance score(R-score)를 계산하여,
    • phenotype과 가장 관련 있는 critical cell types를 도출합니다.
  • 이 부분은 모델 해석(interpretability)과 생물학적 분석에만 사용되며, 예측 자체에는 필수적이지 않습니다.

3. 데이터 로딩 시 cell type 정보 관리

  • dataloader.py의 Covid_data()와 Custom_data_from_loaded()에서,
    cell type 정보(cell_type, cell_type_large)를 함께 불러옵니다.
  • cell_type_large는 더 세분화된 annotation으로, 주로 attention 분석 단계에서 활용됩니다.
  • 학습 파이프라인에서는 주로 train_cell_type이 mixup에 쓰입니다.

정리

  • 모델 학습(augmentation): mixup 시 같은 cell type끼리만 섞도록 사용 → 데이터 생물학적 일관성 유지.
  • 모델 해석(post-hoc): attention weight와 결합해 phenotype과 관련 있는 cell type 찾기 → 해석 및 생물학적 통찰 제공.
  • 필수 여부: 학습 자체에는 필수는 아니지만, mixup 성능 향상과 해석 가능성을 위해 중요한 역할.

--------

scrat method?
왜 case 나누는지?
성능 다른 이유