Train BRIDGE models for the RBPs in different cell lines#

This notebook documents the training workflow implemented in main.py.

Including:

  • clear input/output expectations

  • step-by-step visibility into each feature modality

  • sanity checks like printing tensor shapes

  • a faithful end-to-end training run driven by the original CLI

0. Environment & project root#

We ensure the repo root is on sys.path so imports like utils.BRIDGE work.

import os, sys
from pathlib import Path

project_root = Path.cwd()
os.chdir(project_root.parent.parent)
project_root = Path.cwd()
print("project_root:", project_root)

assert (project_root / "utils").exists(), f"Cannot find utils/ under {project_root}. Open the notebook from repo root."
sys.path.insert(0, str(project_root))

print("Project root:", project_root)
print("Python:", sys.version.split()[0])
project_root: /fs1/private/user/wangyubo/code/BRIDGE
Project root: /fs1/private/user/wangyubo/code/BRIDGE
Python: 3.10.10

1. Configure run parameters#

These mirror the CLI arguments in main.py. Edit them as needed.

# --- Core inputs (match main.py defaults) ---
DATA_FILE = "AUH_HepG2"          # --data_file
DATA_PATH = "./dataset"          # --data_path
TRANSFORMER_PATH = "./RBPformer" # --Transformer_path

# --- Outputs ---
RESULTS_DIR = "./results"             # --results_dir
MODEL_SAVE_PATH = "./results/model"   # --model_save_path

# --- Runtime ---
SEED = 42
DEVICE_NUM = 0
USE_CPU = False   # True to force CPU

# --- Training hyperparams (CLI arguments) ---
LR = 0.001
EARLY_STOPPING = 10

# --- Constants from main.py ---
MAX_LENGTH = 101

# --- Sanity / smoke settings ---
SMOKE_TEST = True     # True: build embeddings/features for a small subset for quick shape checks
SMOKE_N = 8

print("DATA_FILE:", DATA_FILE)
print("DATA_PATH:", DATA_PATH)
print("TRANSFORMER_PATH:", TRANSFORMER_PATH)
print("RESULTS_DIR:", RESULTS_DIR)
print("MODEL_SAVE_PATH:", MODEL_SAVE_PATH)
DATA_FILE: AUH_HepG2
DATA_PATH: ./dataset
TRANSFORMER_PATH: ./RBPformer
RESULTS_DIR: ./results
MODEL_SAVE_PATH: ./results/model

2. Check required input files#

main.py expects two FASTA files:

  • {DATA_PATH}/{DATA_FILE}_neg.fa

  • {DATA_PATH}/{DATA_FILE}_pos.fa

from pathlib import Path

data_path = Path(DATA_PATH)
neg_fa = data_path / f"{DATA_FILE}_neg.fa"
pos_fa = data_path / f"{DATA_FILE}_pos.fa"

print("NEG FASTA:", neg_fa, "exists:", neg_fa.exists())
print("POS FASTA:", pos_fa, "exists:", pos_fa.exists())

assert neg_fa.exists() and pos_fa.exists(), (
    "Missing FASTA inputs. Please place *_neg.fa and *_pos.fa under DATA_PATH."
)
NEG FASTA: dataset/AUH_HepG2_neg.fa exists: True
POS FASTA: dataset/AUH_HepG2_pos.fa exists: True

3. Load sequences, structures, and labels#

read_fasta() should return sequences + structures + binary labels.

from utils.dataloaders import read_fasta
import numpy as np

sequences, structs, labels = read_fasta(str(neg_fa), str(pos_fa))
sequences = list(sequences)
structs = list(structs)
labels = np.asarray(labels)

print("Num sequences:", len(sequences))
print("Num structs:", len(structs))
print("Labels shape:", labels.shape, "Pos ratio:", float(labels.mean()) if labels.size else None)

print("\nExample sequence:", sequences[0][:60] + ("..." if len(sequences[0]) > 60 else ""))
print("Example struct  :", structs[0][:60] + ("..." if len(structs[0]) > 60 else ""))
Num sequences: 15002
Num structs: 15002
Labels shape: (15002, 1) Pos ratio: 0.33328890800476074

Example sequence: GATGCTGTTGTGCATGGACAGCTCTCCAGTGGATTCGATGGGCCATAGCAATCCTGTGAT...
Example struct  : -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0.485,0.097,0.0...

4. Fix seeds and select device (same policy as main.py)#

import random, torch, os
import numpy as np

def fix_seed(seed: int):
    torch.set_num_threads(1)
    random.seed(seed)
    os.environ["PYTHONHASHSEED"] = str(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)

fix_seed(SEED)

device = torch.device("cpu") if USE_CPU else torch.device(f"cuda:{DEVICE_NUM}" if torch.cuda.is_available() else "cpu")
if device.type == "cuda":
    torch.cuda.set_device(DEVICE_NUM)

print("Device:", device)
Device: cuda:0

5. Build transformer embeddings and attention (RBPformer)#

Calls build_Transformer_embeddings(...) and prints shapes.

from utils.gen_transformer_embedding import build_Transformer_embeddings

seq_for_run = sequences[:SMOKE_N] if SMOKE_TEST else sequences

Transformer_emb, attention_weight = build_Transformer_embeddings(
    sequences=list(seq_for_run),
    transformer_path=TRANSFORMER_PATH,
    device=device,
    k=1,
    transpose_to_ch_first=True,
)

def show_tensor(name, x):
    shp = getattr(x, "shape", None)
    dt = getattr(x, "dtype", None)
    dev = getattr(x, "device", None)
    print(f"{name:>18}: shape={shp} dtype={dt} device={dev} type={type(x)}")

show_tensor("Transformer_emb", Transformer_emb)
show_tensor("attention_weight", attention_weight)
   Transformer_emb: shape=(8, 512, 101) dtype=float32 device=None type=<class 'numpy.ndarray'>
  attention_weight: shape=(8, 101, 103) dtype=float32 device=None type=<class 'numpy.ndarray'>

6. Build structure tensor (fixed length = 101)#

from utils.structureFeatures import build_structure_tensor

struct_for_run = structs[:SMOKE_N] if SMOKE_TEST else structs
structure = build_structure_tensor(struct_for_run, MAX_LENGTH)

print("structure:", type(structure), "shape:", getattr(structure, "shape", None))
structure: <class 'numpy.ndarray'> shape: (8, 1, 101)

7. Load biochemical features (channel-first)#

from utils.FeatureEncoding import dealwithdata

biochem = dealwithdata(DATA_FILE)
biochem = biochem.transpose([0, 2, 1])

try:
    biochem_for_run = biochem[:SMOKE_N] if SMOKE_TEST else biochem
except Exception:
    biochem_for_run = biochem

print("biochem:", type(biochem_for_run), "shape:", getattr(biochem_for_run, "shape", None))
[INFO] Encoded 15002 sequences for AUH_HepG2, shape: (15002, 101, 99)
biochem: <class 'numpy.ndarray'> shape: (8, 99, 101)

8. Load motif prior matrix#

from utils.motif_prior.motif_prior import get_motif_prior_matrix

motif = get_motif_prior_matrix(DATA_FILE)
try:
    motif_for_run = motif[:SMOKE_N] if SMOKE_TEST else motif
except Exception:
    motif_for_run = motif

print("motif:", type(motif_for_run), "shape:", getattr(motif_for_run, "shape", None))
Valid motif file detected, skipping motif_prior: utils/motif_prior/output/AUH_HepG2/output/STRME_training_set.tab
motif: <class 'numpy.ndarray'> shape: (8, 1, 24)

9. Split modalities into train/test (aligned)#

from utils.utils import split_dataset
labels_for_run = labels[:SMOKE_N] if SMOKE_TEST else labels

(train_emb, train_attn, train_struc, train_motif, train_biochem, train_label), \
(test_emb, test_attn, test_struc, test_motif, test_biochem, test_label) = split_dataset(
    Transformer_emb,
    attention_weight,
    structure,
    motif_for_run if SMOKE_TEST else motif,
    biochem_for_run if SMOKE_TEST else biochem,
    labels_for_run,
)

def show(name, x):
    print(f"{name:>10}: shape={getattr(x,'shape',None)} type={type(x)}")

print("=== Train split ===")
for n, x in [("emb", train_emb), ("attn", train_attn), ("struc", train_struc), ("motif", train_motif), ("biochem", train_biochem), ("label", train_label)]:
    show(n, x)

print("\n=== Test split ===")
for n, x in [("emb", test_emb), ("attn", test_attn), ("struc", test_struc), ("motif", test_motif), ("biochem", test_biochem), ("label", test_label)]:
    show(n, x)
=== Train split ===
       emb: shape=(7, 512, 101) type=<class 'numpy.ndarray'>
      attn: shape=(7, 101, 103) type=<class 'numpy.ndarray'>
     struc: shape=(7, 1, 101) type=<class 'numpy.ndarray'>
     motif: shape=(7, 1, 24) type=<class 'numpy.ndarray'>
   biochem: shape=(7, 99, 101) type=<class 'numpy.ndarray'>
     label: shape=(7, 1) type=<class 'numpy.ndarray'>

=== Test split ===
       emb: shape=(1, 512, 101) type=<class 'numpy.ndarray'>
      attn: shape=(1, 101, 103) type=<class 'numpy.ndarray'>
     struc: shape=(1, 1, 101) type=<class 'numpy.ndarray'>
     motif: shape=(1, 1, 24) type=<class 'numpy.ndarray'>
   biochem: shape=(1, 99, 101) type=<class 'numpy.ndarray'>
     label: shape=(1, 1) type=<class 'numpy.ndarray'>

10. Create Dataset & DataLoader (inspect one batch)#

import torch
from torch.utils.data import DataLoader
from utils.utils import myDataset

train_set = myDataset(train_emb, train_attn, train_struc, train_motif, train_biochem, train_label)
test_set  = myDataset(test_emb,  test_attn,  test_struc,  test_motif,  test_biochem,  test_label)

train_loader = DataLoader(train_set, batch_size=32, shuffle=True)
test_loader  = DataLoader(test_set,  batch_size=32*8, shuffle=False)

batch = next(iter(train_loader))
print("Batch contains", len(batch), "tensors (emb, attn, struc, motif, biochem, label).")
for i, t in enumerate(batch):
    print(f"batch[{i}] shape={getattr(t,'shape',None)} dtype={getattr(t,'dtype',None)}")
Batch contains 6 tensors (emb, attn, struc, motif, biochem, label).
batch[0] shape=torch.Size([7, 512, 101]) dtype=torch.float32
batch[1] shape=torch.Size([7, 101, 103]) dtype=torch.float32
batch[2] shape=torch.Size([7, 1, 101]) dtype=torch.float64
batch[3] shape=torch.Size([7, 1, 24]) dtype=torch.float64
batch[4] shape=torch.Size([7, 99, 101]) dtype=torch.float64
batch[5] shape=torch.Size([7, 1]) dtype=torch.float32

11. Initialize BRIDGE and (optional) sanity-check forward pass#

from utils.BRIDGE import BRIDGE
from utils.utils import param_num

model = BRIDGE().to(device)
param_num(model)

emb, attn, struc, motif_, biochem_, y = batch
emb, attn, struc, motif_, biochem_ = emb.to(device), attn.to(device), struc.to(device), motif_.to(device), biochem_.to(device)

model.eval()
with torch.no_grad():
    try:
        out = model(emb, attn, struc, motif_, biochem_)
        print("Forward output shape:", getattr(out, "shape", None))
    except Exception as e:
        print("Forward call failed (signature mismatch or internal error).")
        print("Error:", e)
        print("Inputs:")
        print(" emb   :", emb.shape)
        print(" attn  :", attn.shape)
        print(" struc :", struc.shape)
        print(" motif :", motif_.shape)
        print(" biochem:", biochem_.shape)
---------------------------------
Total params: 19111841
Trainable params: 19111809
Non-trainable params: 32
---------------------------------
Forward call failed (signature mismatch or internal error).
Error: Input type (torch.cuda.DoubleTensor) and weight type (torch.cuda.FloatTensor) should be the same
Inputs:
 emb   : torch.Size([7, 512, 101])
 attn  : torch.Size([7, 101, 103])
 struc : torch.Size([7, 1, 101])
 motif : torch.Size([7, 1, 24])
 biochem: torch.Size([7, 99, 101])

12. Run full training (original CLI, no code modifications)#

import subprocess, shlex

cmd = (
    f"python main.py "
    f"--train "
    f"--data_file {DATA_FILE} "
    f"--data_path {DATA_PATH} "
    f"--Transformer_path {TRANSFORMER_PATH} "
    f"--results_dir {RESULTS_DIR} "
    f"--model_save_path {MODEL_SAVE_PATH} "
    f"--seed {SEED} "
    f"--device_num {DEVICE_NUM} "
    f"--lr {LR} "
    f"--early_stopping {EARLY_STOPPING}"
)

if USE_CPU:
    cmd += " --use_cpu"

print("Command:\n", cmd)

subprocess.run(shlex.split(cmd), check=True)
Command:
 python main.py --train --data_file AUH_HepG2 --data_path ./dataset --Transformer_path ./RBPformer --results_dir ./results --model_save_path ./results/model --seed 42 --device_num 0 --lr 0.001 --early_stopping 10
[INFO] Encoded 15002 sequences for AUH_HepG2, shape: (15002, 101, 99)
Valid motif file detected, skipping motif_prior: utils/motif_prior/output/AUH_HepG2/output/STRME_training_set.tab
[RUN] AUH_HepG2_20260201-111327
[DIR] logs=results/logs model=results/model metrics=results/metrics
[CFG] results/logs/AUH_HepG2_20260201-111327_config.json
---------------------------------
Total params: 19111841
Trainable params: 19111809
Non-trainable params: 32
---------------------------------
AUH_HepG2 	 Train Epoch: 1     avg.loss: 0.9430 Acc: 0.67%, AUC: 0.7725, PRC: 0.6533, MCC: 0.3516, lr: 0.000040
AUH_HepG2 	 Test  Epoch: 1     avg.loss: 0.7414 Acc: 0.76%, AUC: 0.8128 (0.8128), PRC: 0.6915, MCC: 0.4406, 1
AUH_HepG2 	 Train Epoch: 2     avg.loss: 0.6604 Acc: 0.77%, AUC: nan, PRC: 0.7539, MCC: 0.5123, lr: 0.000080
AUH_HepG2 	 Test  Epoch: 2     avg.loss: 0.7006 Acc: 0.78%, AUC: 0.8403 (0.8403), PRC: 0.7282, MCC: 0.4827, 2
AUH_HepG2 	 Train Epoch: 3     avg.loss: 0.6287 Acc: 0.79%, AUC: 0.8651, PRC: 0.7775, MCC: 0.5461, lr: 0.000120
AUH_HepG2 	 Test  Epoch: 3     avg.loss: 0.7367 Acc: 0.78%, AUC: 0.8452 (0.8452), PRC: 0.7359, MCC: 0.4668, 3
AUH_HepG2 	 Train Epoch: 4     avg.loss: 0.6201 Acc: 0.79%, AUC: 0.8721, PRC: 0.7910, MCC: 0.5588, lr: 0.000160
AUH_HepG2 	 Test  Epoch: 4     avg.loss: 0.8686 Acc: 0.76%, AUC: 0.8478 (0.8478), PRC: 0.7413, MCC: 0.4178, 4
AUH_HepG2 	 Train Epoch: 5     avg.loss: 0.6048 Acc: 0.79%, AUC: 0.8800, PRC: 0.8007, MCC: 0.5705, lr: 0.000200
AUH_HepG2 	 Test  Epoch: 5     avg.loss: 0.6453 Acc: 0.79%, AUC: 0.8520 (0.8520), PRC: 0.7531, MCC: 0.5214, 5
AUH_HepG2 	 Train Epoch: 6     avg.loss: 0.6226 Acc: 0.78%, AUC: 0.8839, PRC: 0.8084, MCC: 0.5613, lr: 0.000240
AUH_HepG2 	 Test  Epoch: 6     avg.loss: 0.6601 Acc: 0.79%, AUC: 0.8517 (0.8520), PRC: 0.7543, MCC: 0.5113, 5
AUH_HepG2 	 Train Epoch: 7     avg.loss: 0.5961 Acc: 0.80%, AUC: nan, PRC: 0.8240, MCC: 0.5918, lr: 0.000280
AUH_HepG2 	 Test  Epoch: 7     avg.loss: 0.9250 Acc: 0.76%, AUC: 0.8579 (0.8579), PRC: 0.7576, MCC: 0.4247, 7
AUH_HepG2 	 Train Epoch: 8     avg.loss: 0.5824 Acc: 0.81%, AUC: nan, PRC: 0.8306, MCC: 0.5991, lr: 0.000320
AUH_HepG2 	 Test  Epoch: 8     avg.loss: 0.6856 Acc: 0.79%, AUC: 0.8524 (0.8579), PRC: 0.7472, MCC: 0.5023, 7
AUH_HepG2 	 Train Epoch: 9     avg.loss: 0.5661 Acc: 0.81%, AUC: 0.9013, PRC: 0.8278, MCC: 0.6081, lr: 0.000360
AUH_HepG2 	 Test  Epoch: 9     avg.loss: 0.6287 Acc: 0.77%, AUC: 0.8549 (0.8579), PRC: 0.7650, MCC: 0.5169, 7
AUH_HepG2 	 Train Epoch: 10     avg.loss: 0.5546 Acc: 0.82%, AUC: nan, PRC: 0.8433, MCC: 0.6212, lr: 0.000400
AUH_HepG2 	 Test  Epoch: 10     avg.loss: 0.6168 Acc: 0.77%, AUC: 0.8651 (0.8651), PRC: 0.7691, MCC: 0.5315, 10
AUH_HepG2 	 Train Epoch: 11     avg.loss: 0.5457 Acc: 0.82%, AUC: 0.9132, PRC: 0.8519, MCC: 0.6326, lr: 0.000440
AUH_HepG2 	 Test  Epoch: 11     avg.loss: 0.6418 Acc: 0.81%, AUC: 0.8716 (0.8716), PRC: 0.7826, MCC: 0.5550, 11
AUH_HepG2 	 Train Epoch: 12     avg.loss: 0.5401 Acc: 0.83%, AUC: 0.9200, PRC: 0.8601, MCC: 0.6404, lr: 0.000480
AUH_HepG2 	 Test  Epoch: 12     avg.loss: 0.9026 Acc: 0.77%, AUC: 0.8577 (0.8716), PRC: 0.7636, MCC: 0.4637, 11
AUH_HepG2 	 Train Epoch: 13     avg.loss: 0.5141 Acc: 0.83%, AUC: 0.9228, PRC: 0.8625, MCC: 0.6522, lr: 0.000520
AUH_HepG2 	 Test  Epoch: 13     avg.loss: 0.6751 Acc: 0.79%, AUC: 0.8607 (0.8716), PRC: 0.7626, MCC: 0.5138, 11
AUH_HepG2 	 Train Epoch: 14     avg.loss: 0.5586 Acc: 0.82%, AUC: 0.9270, PRC: 0.8731, MCC: 0.6416, lr: 0.000560
AUH_HepG2 	 Test  Epoch: 14     avg.loss: 0.7381 Acc: 0.79%, AUC: 0.8576 (0.8716), PRC: 0.7608, MCC: 0.5121, 11
AUH_HepG2 	 Train Epoch: 15     avg.loss: 0.5283 Acc: 0.83%, AUC: 0.9331, PRC: 0.8792, MCC: 0.6602, lr: 0.000600
AUH_HepG2 	 Test  Epoch: 15     avg.loss: 0.9313 Acc: 0.78%, AUC: 0.8521 (0.8716), PRC: 0.7589, MCC: 0.4790, 11
AUH_HepG2 	 Train Epoch: 16     avg.loss: 0.5014 Acc: 0.84%, AUC: 0.9349, PRC: 0.8848, MCC: 0.6749, lr: 0.000640
AUH_HepG2 	 Test  Epoch: 16     avg.loss: 0.8296 Acc: 0.79%, AUC: 0.8591 (0.8716), PRC: 0.7590, MCC: 0.5095, 11
AUH_HepG2 	 Train Epoch: 17     avg.loss: 0.5296 Acc: 0.83%, AUC: 0.9419, PRC: 0.8921, MCC: 0.6697, lr: 0.000680
AUH_HepG2 	 Test  Epoch: 17     avg.loss: 0.6961 Acc: 0.80%, AUC: 0.8604 (0.8716), PRC: 0.7628, MCC: 0.5288, 11
AUH_HepG2 	 Train Epoch: 18     avg.loss: 0.4651 Acc: 0.85%, AUC: 0.9416, PRC: 0.8933, MCC: 0.6847, lr: 0.000720
AUH_HepG2 	 Test  Epoch: 18     avg.loss: 0.7184 Acc: 0.80%, AUC: 0.8674 (0.8716), PRC: 0.7731, MCC: 0.5378, 11
AUH_HepG2 	 Train Epoch: 19     avg.loss: 0.4540 Acc: 0.86%, AUC: 0.9491, PRC: 0.9107, MCC: 0.7065, lr: 0.000760
AUH_HepG2 	 Test  Epoch: 19     avg.loss: 0.6471 Acc: 0.80%, AUC: 0.8698 (0.8716), PRC: 0.7798, MCC: 0.5478, 11
AUH_HepG2 	 Train Epoch: 20     avg.loss: 0.4364 Acc: 0.87%, AUC: 0.9535, PRC: 0.9158, MCC: 0.7256, lr: 0.000800
AUH_HepG2 	 Test  Epoch: 20     avg.loss: 0.8620 Acc: 0.80%, AUC: 0.8663 (0.8716), PRC: 0.7757, MCC: 0.5257, 11
AUH_HepG2 	 Train Epoch: 21     avg.loss: 0.4233 Acc: 0.87%, AUC: 0.9591, PRC: 0.9241, MCC: 0.7362, lr: 0.000840
AUH_HepG2 	 Test  Epoch: 21     avg.loss: 0.6908 Acc: 0.81%, AUC: 0.8749 (0.8749), PRC: 0.7864, MCC: 0.5718, 21
AUH_HepG2 	 Train Epoch: 22     avg.loss: 0.4234 Acc: 0.87%, AUC: 0.9634, PRC: 0.9312, MCC: 0.7396, lr: 0.000880
AUH_HepG2 	 Test  Epoch: 22     avg.loss: 1.2706 Acc: 0.77%, AUC: 0.8554 (0.8749), PRC: 0.7710, MCC: 0.4520, 21
AUH_HepG2 	 Train Epoch: 23     avg.loss: 0.4021 Acc: 0.88%, AUC: 0.9632, PRC: 0.9309, MCC: 0.7434, lr: 0.000920
AUH_HepG2 	 Test  Epoch: 23     avg.loss: 0.7278 Acc: 0.79%, AUC: 0.8523 (0.8749), PRC: 0.7588, MCC: 0.5350, 21
AUH_HepG2 	 Train Epoch: 24     avg.loss: 0.4014 Acc: 0.88%, AUC: 0.9647, PRC: 0.9336, MCC: 0.7459, lr: 0.000960
AUH_HepG2 	 Test  Epoch: 24     avg.loss: 1.2410 Acc: 0.78%, AUC: 0.8611 (0.8749), PRC: 0.7717, MCC: 0.4822, 21
AUH_HepG2 	 Train Epoch: 25     avg.loss: 0.4047 Acc: 0.88%, AUC: 0.9722, PRC: 0.9478, MCC: 0.7584, lr: 0.001000
AUH_HepG2 	 Test  Epoch: 25     avg.loss: 1.3983 Acc: 0.77%, AUC: 0.8486 (0.8749), PRC: 0.7540, MCC: 0.4481, 21
AUH_HepG2 	 Train Epoch: 26     avg.loss: 0.3535 Acc: 0.90%, AUC: 0.9744, PRC: 0.9516, MCC: 0.7798, lr: 0.001040
AUH_HepG2 	 Test  Epoch: 26     avg.loss: 0.6569 Acc: 0.78%, AUC: 0.8746 (0.8749), PRC: 0.7945, MCC: 0.5527, 21
AUH_HepG2 	 Train Epoch: 27     avg.loss: 0.3733 Acc: 0.89%, AUC: 0.9742, PRC: 0.9532, MCC: 0.7788, lr: 0.001080
AUH_HepG2 	 Test  Epoch: 27     avg.loss: 1.6297 Acc: 0.74%, AUC: 0.8758 (0.8758), PRC: 0.7960, MCC: 0.3954, 27
AUH_HepG2 	 Train Epoch: 28     avg.loss: 0.3836 Acc: 0.90%, AUC: 0.9777, PRC: 0.9600, MCC: 0.7890, lr: 0.001120
AUH_HepG2 	 Test  Epoch: 28     avg.loss: 1.3335 Acc: 0.79%, AUC: 0.8640 (0.8758), PRC: 0.7800, MCC: 0.4942, 27
AUH_HepG2 	 Train Epoch: 29     avg.loss: 0.3304 Acc: 0.91%, AUC: nan, PRC: 0.9629, MCC: 0.8109, lr: 0.001160
AUH_HepG2 	 Test  Epoch: 29     avg.loss: 1.1825 Acc: 0.79%, AUC: 0.8585 (0.8758), PRC: 0.7668, MCC: 0.4945, 27
AUH_HepG2 	 Train Epoch: 30     avg.loss: 0.3124 Acc: 0.91%, AUC: 0.9818, PRC: 0.9661, MCC: 0.8168, lr: 0.001200
AUH_HepG2 	 Test  Epoch: 30     avg.loss: 0.7389 Acc: 0.82%, AUC: 0.8803 (0.8803), PRC: 0.7955, MCC: 0.5932, 30
AUH_HepG2 	 Train Epoch: 31     avg.loss: 0.3023 Acc: 0.92%, AUC: 0.9860, PRC: 0.9741, MCC: 0.8269, lr: 0.001240
AUH_HepG2 	 Test  Epoch: 31     avg.loss: 1.0296 Acc: 0.82%, AUC: 0.8827 (0.8827), PRC: 0.8044, MCC: 0.5682, 31
AUH_HepG2 	 Train Epoch: 32     avg.loss: 0.3227 Acc: 0.91%, AUC: 0.9853, PRC: 0.9722, MCC: 0.8197, lr: 0.001280
AUH_HepG2 	 Test  Epoch: 32     avg.loss: 0.7374 Acc: 0.81%, AUC: 0.8770 (0.8827), PRC: 0.7909, MCC: 0.5822, 31
AUH_HepG2 	 Train Epoch: 33     avg.loss: 0.2800 Acc: 0.92%, AUC: nan, PRC: 0.9770, MCC: 0.8358, lr: 0.001320
AUH_HepG2 	 Test  Epoch: 33     avg.loss: 0.7782 Acc: 0.79%, AUC: 0.8679 (0.8827), PRC: 0.7774, MCC: 0.5402, 31
AUH_HepG2 	 Train Epoch: 34     avg.loss: 0.2914 Acc: 0.92%, AUC: 0.9887, PRC: 0.9789, MCC: 0.8404, lr: 0.001360
AUH_HepG2 	 Test  Epoch: 34     avg.loss: 1.3249 Acc: 0.80%, AUC: 0.8685 (0.8827), PRC: 0.7915, MCC: 0.5288, 31
AUH_HepG2 	 Train Epoch: 35     avg.loss: 0.2792 Acc: 0.93%, AUC: 0.9903, PRC: 0.9814, MCC: 0.8502, lr: 0.001400
AUH_HepG2 	 Test  Epoch: 35     avg.loss: 0.8355 Acc: 0.81%, AUC: 0.8646 (0.8827), PRC: 0.7859, MCC: 0.5649, 31
AUH_HepG2 	 Train Epoch: 36     avg.loss: 0.2640 Acc: 0.93%, AUC: 0.9894, PRC: 0.9793, MCC: 0.8539, lr: 0.001440
AUH_HepG2 	 Test  Epoch: 36     avg.loss: 2.9426 Acc: 0.72%, AUC: 0.8563 (0.8827), PRC: 0.7678, MCC: 0.3092, 31
AUH_HepG2 	 Train Epoch: 37     avg.loss: 0.2431 Acc: 0.93%, AUC: 0.9904, PRC: 0.9824, MCC: 0.8616, lr: 0.001480
AUH_HepG2 	 Test  Epoch: 37     avg.loss: 1.4933 Acc: 0.78%, AUC: 0.8749 (0.8827), PRC: 0.7909, MCC: 0.4891, 31
AUH_HepG2 	 Train Epoch: 38     avg.loss: 0.2150 Acc: 0.94%, AUC: 0.9927, PRC: 0.9865, MCC: 0.8780, lr: 0.001520
AUH_HepG2 	 Test  Epoch: 38     avg.loss: 2.0791 Acc: 0.77%, AUC: 0.8727 (0.8827), PRC: 0.7939, MCC: 0.4598, 31
AUH_HepG2 	 Train Epoch: 39     avg.loss: 0.2081 Acc: 0.95%, AUC: 0.9928, PRC: 0.9859, MCC: 0.8850, lr: 0.001560
AUH_HepG2 	 Test  Epoch: 39     avg.loss: 1.4299 Acc: 0.80%, AUC: 0.8911 (0.8911), PRC: 0.8179, MCC: 0.5463, 39
AUH_HepG2 	 Train Epoch: 40     avg.loss: 0.2315 Acc: 0.94%, AUC: 0.9937, PRC: 0.9877, MCC: 0.8788, lr: 0.001600
AUH_HepG2 	 Test  Epoch: 40     avg.loss: 1.3055 Acc: 0.81%, AUC: 0.8832 (0.8911), PRC: 0.8123, MCC: 0.5466, 39
AUH_HepG2 	 Train Epoch: 41     avg.loss: 0.1907 Acc: 0.95%, AUC: 0.9945, PRC: 0.9898, MCC: 0.8914, lr: 0.001600
AUH_HepG2 	 Test  Epoch: 41     avg.loss: 1.1404 Acc: 0.82%, AUC: 0.8840 (0.8911), PRC: 0.8135, MCC: 0.5827, 39
AUH_HepG2 	 Train Epoch: 42     avg.loss: 0.2034 Acc: 0.95%, AUC: 0.9953, PRC: 0.9912, MCC: 0.8911, lr: 0.001600
AUH_HepG2 	 Test  Epoch: 42     avg.loss: 1.3949 Acc: 0.81%, AUC: 0.8816 (0.8911), PRC: 0.8097, MCC: 0.5457, 39
AUH_HepG2 	 Train Epoch: 43     avg.loss: 0.1916 Acc: 0.95%, AUC: 0.9954, PRC: 0.9915, MCC: 0.9023, lr: 0.001600
AUH_HepG2 	 Test  Epoch: 43     avg.loss: 1.6832 Acc: 0.80%, AUC: 0.8850 (0.8911), PRC: 0.8080, MCC: 0.5450, 39
AUH_HepG2 	 Train Epoch: 44     avg.loss: 0.1583 Acc: 0.96%, AUC: 0.9964, PRC: 0.9928, MCC: 0.9120, lr: 0.001600
AUH_HepG2 	 Test  Epoch: 44     avg.loss: 0.9043 Acc: 0.84%, AUC: 0.8951 (0.8951), PRC: 0.8296, MCC: 0.6301, 44
AUH_HepG2 	 Train Epoch: 45     avg.loss: 0.1360 Acc: 0.96%, AUC: 0.9969, PRC: 0.9937, MCC: 0.9196, lr: 0.001280
AUH_HepG2 	 Test  Epoch: 45     avg.loss: 1.1709 Acc: 0.82%, AUC: 0.8816 (0.8951), PRC: 0.8083, MCC: 0.5848, 44
AUH_HepG2 	 Train Epoch: 46     avg.loss: 0.1281 Acc: 0.97%, AUC: 0.9983, PRC: 0.9965, MCC: 0.9289, lr: 0.001280
AUH_HepG2 	 Test  Epoch: 46     avg.loss: 1.4194 Acc: 0.82%, AUC: 0.8701 (0.8951), PRC: 0.7995, MCC: 0.5845, 44
AUH_HepG2 	 Train Epoch: 47     avg.loss: 0.1550 Acc: 0.97%, AUC: nan, PRC: 0.9954, MCC: 0.9312, lr: 0.001280
AUH_HepG2 	 Test  Epoch: 47     avg.loss: 1.9364 Acc: 0.80%, AUC: 0.8881 (0.8951), PRC: 0.8128, MCC: 0.5420, 44
AUH_HepG2 	 Train Epoch: 48     avg.loss: 0.0938 Acc: 0.98%, AUC: 0.9994, PRC: 0.9987, MCC: 0.9492, lr: 0.001280
AUH_HepG2 	 Test  Epoch: 48     avg.loss: 1.5102 Acc: 0.82%, AUC: 0.8849 (0.8951), PRC: 0.8113, MCC: 0.5836, 44
AUH_HepG2 	 Train Epoch: 49     avg.loss: 0.0921 Acc: 0.98%, AUC: 0.9989, PRC: 0.9980, MCC: 0.9462, lr: 0.001280
AUH_HepG2 	 Test  Epoch: 49     avg.loss: 1.4120 Acc: 0.83%, AUC: 0.8886 (0.8951), PRC: 0.8187, MCC: 0.5934, 44
AUH_HepG2 	 Train Epoch: 50     avg.loss: 0.0948 Acc: 0.98%, AUC: 0.9991, PRC: 0.9981, MCC: 0.9457, lr: 0.001024
AUH_HepG2 	 Test  Epoch: 50     avg.loss: 2.7685 Acc: 0.80%, AUC: 0.8851 (0.8951), PRC: 0.8170, MCC: 0.5313, 44
AUH_HepG2 	 Train Epoch: 51     avg.loss: 0.0716 Acc: 0.98%, AUC: 0.9996, PRC: 0.9990, MCC: 0.9554, lr: 0.001024
AUH_HepG2 	 Test  Epoch: 51     avg.loss: 1.6782 Acc: 0.83%, AUC: 0.8904 (0.8951), PRC: 0.8261, MCC: 0.6006, 44
AUH_HepG2 	 Train Epoch: 52     avg.loss: 0.0657 Acc: 0.98%, AUC: 0.9996, PRC: 0.9993, MCC: 0.9616, lr: 0.001024
AUH_HepG2 	 Test  Epoch: 52     avg.loss: 1.2891 Acc: 0.82%, AUC: 0.8833 (0.8951), PRC: 0.8090, MCC: 0.5986, 44
AUH_HepG2 	 Train Epoch: 53     avg.loss: 0.0704 Acc: 0.98%, AUC: 0.9996, PRC: 0.9992, MCC: 0.9601, lr: 0.001024
AUH_HepG2 	 Test  Epoch: 53     avg.loss: 1.8944 Acc: 0.83%, AUC: 0.8889 (0.8951), PRC: 0.8185, MCC: 0.6036, 44
AUH_HepG2 	 Train Epoch: 54     avg.loss: 0.0629 Acc: 0.98%, AUC: 0.9995, PRC: 0.9989, MCC: 0.9659, lr: 0.001024
AUH_HepG2 	 Test  Epoch: 54     avg.loss: 1.5417 Acc: 0.83%, AUC: 0.8913 (0.8951), PRC: 0.8212, MCC: 0.6011, 44
Early stop at 55, BRIDGE 
AUH_HepG2 best: auc=0.8951 acc=0.8383 prc=0.8296 mcc=0.6301 (epoch=44)
[BEST] results/metrics/AUH_HepG2_20260201-111327_best.json
Time cost: 44.49 min
CompletedProcess(args=['python', 'main.py', '--train', '--data_file', 'AUH_HepG2', '--data_path', './dataset', '--Transformer_path', './RBPformer', '--results_dir', './results', '--model_save_path', './results/model', '--seed', '42', '--device_num', '0', '--lr', '0.001', '--early_stopping', '10'], returncode=0)

13. Locate the latest run artifacts#

from pathlib import Path
import json

metrics_dir = Path(RESULTS_DIR) / "metrics"
best_files = sorted(metrics_dir.glob(f"{DATA_FILE}_*_best.json"), key=lambda p: p.stat().st_mtime)

print("Found best summaries:", len(best_files))
if best_files:
    latest = best_files[-1]
    print("Latest best summary:", latest)
    with open(latest, "r", encoding="utf-8") as f:
        best = json.load(f)
    print(json.dumps(best, indent=2))
else:
    print("No best summary found yet. Train first.")
Found best summaries: 4
Latest best summary: results/metrics/AUH_HepG2_20260201-111327_best.json
{
  "run_name": "AUH_HepG2_20260201-111327",
  "data_file": "AUH_HepG2",
  "best_epoch": 44,
  "best_val_auc": 0.8950865000000001,
  "best_val_acc": 0.8383333333333334,
  "best_val_prc": 0.8295740030430263,
  "best_val_mcc": 0.630073216821487,
  "seed": 42,
  "device": "cuda:0",
  "checkpoint": "/fs1/private/user/wangyubo/code/BRIDGE/results/model/AUH_HepG2_20260201-111327.pth",
  "log_file": "/fs1/private/user/wangyubo/code/BRIDGE/results/logs/AUH_HepG2_20260201-111327.log",
  "config_file": "/fs1/private/user/wangyubo/code/BRIDGE/results/logs/AUH_HepG2_20260201-111327_config.json"
}