Run dynamic cross-cell-type prediction of RBP–RNA interactions#
This notebook documents main.py --dynamic_predict.
Dynamic prediction differs from validation only by which checkpoint name is loaded:
resolve_dynamic_model_name(DATA_FILE)returns a namemain.pyloads:{model_save_path}/{resolved_name}.pth
0. Setup & parameters#
import os, sys
from pathlib import Path
project_root = Path.cwd()
os.chdir(project_root.parent.parent.parent)
project_root = Path.cwd()
print("project_root:", project_root)
assert (project_root / "utils").exists(), "Open this notebook from repo root."
sys.path.insert(0, str(project_root))
DATA_FILE = "AUH_HepG2"
DATA_PATH = "./dataset"
TRANSFORMER_PATH = "./RBPformer"
MODEL_SAVE_PATH = "./results/model"
SEED = 42
DEVICE_NUM = 0
USE_CPU = False
MAX_LENGTH = 101
print("DATA_FILE:", DATA_FILE)
project_root: /fs1/private/user/wangyubo/code/BRIDGE
DATA_FILE: AUH_HepG2
1. Resolve the dynamic checkpoint name#
from pathlib import Path
from utils.utils import resolve_dynamic_model_name
resolved = resolve_dynamic_model_name(DATA_FILE)
ckpt = Path(MODEL_SAVE_PATH) / f"{resolved}.pth"
print("Resolved dynamic model name:", resolved)
print("Expected checkpoint path:", ckpt)
print("Exists:", ckpt.exists())
if not ckpt.exists():
print("\nNo checkpoint found under the expected name.")
print("Copy or symlink a trained checkpoint to this filename (no code change needed).")
print("Example:")
print(f" cp /path/to/your_checkpoint.pth {ckpt}")
Resolved dynamic model name: AUH_K562
Expected checkpoint path: results/model/AUH_K562.pth
Exists: True
2. Rebuild test split and evaluate (print modality shapes)#
import random, torch
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
from utils.dataloaders import read_fasta
from utils.gen_transformer_embedding import build_Transformer_embeddings
from utils.structureFeatures import build_structure_tensor
from utils.FeatureEncoding import dealwithdata
from utils.motif_prior.motif_prior import get_motif_prior_matrix
from utils.utils import split_dataset, myDataset
from torch.utils.data import DataLoader
from pathlib import Path
import numpy as np
data_path = Path(DATA_PATH)
neg_fa = data_path / f"{DATA_FILE}_neg.fa"
pos_fa = data_path / f"{DATA_FILE}_pos.fa"
assert neg_fa.exists() and pos_fa.exists(), "Missing FASTA files."
sequences, structs, labels = read_fasta(str(neg_fa), str(pos_fa))
sequences, structs = list(sequences), list(structs)
labels = np.asarray(labels)
Transformer_emb, attention_weight = build_Transformer_embeddings(
sequences=sequences,
transformer_path=TRANSFORMER_PATH,
device=device,
k=1,
transpose_to_ch_first=True,
)
structure = build_structure_tensor(structs, MAX_LENGTH)
biochem = dealwithdata(DATA_FILE).transpose([0, 2, 1])
motif = get_motif_prior_matrix(DATA_FILE)
print("Transformer_emb:", getattr(Transformer_emb, "shape", None))
print("attention_weight:", getattr(attention_weight, "shape", None))
print("structure:", getattr(structure, "shape", None))
print("biochem:", getattr(biochem, "shape", None))
print("motif:", getattr(motif, "shape", None))
print("labels:", labels.shape)
(_, _, _, _, _, _), \
(test_emb, test_attn, test_struc, test_motif, test_biochem, test_label) = split_dataset(
Transformer_emb,
attention_weight,
structure,
motif,
biochem,
labels,
)
test_set = myDataset(test_emb, test_attn, test_struc, test_motif, test_biochem, test_label)
test_loader = DataLoader(test_set, batch_size=32*8, shuffle=False)
print("Test size:", len(test_set))
[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
Transformer_emb: (15002, 512, 101)
attention_weight: (15002, 101, 103)
structure: (15002, 1, 101)
biochem: (15002, 99, 101)
motif: (15002, 1, 24)
labels: (15002, 1)
Test size: 3000
3. Load dynamic checkpoint and report metrics#
import torch
import torch.nn as nn
from utils.BRIDGE import BRIDGE
from utils.train_loop import validate
if not ckpt.exists():
raise FileNotFoundError(f"Dynamic checkpoint not found: {ckpt}")
model = BRIDGE().to(device)
model.load_state_dict(torch.load(ckpt, map_location=device))
model.eval()
criterion = nn.BCEWithLogitsLoss(pos_weight=torch.tensor(2).to(device))
met, y_all, p_all = validate(model, device, test_loader, criterion)
print("Dynamic prediction metrics")
print("AUC :", met.auc)
print("ACC :", met.acc)
print("AUPRC:", met.prc)
print("MCC :", met.mcc)
Dynamic prediction metrics
AUC : 0.8140310000000001
ACC : 0.7746666666666666
AUPRC: 0.7315971195404499
MCC : 0.46596121150192704
4. Alternative: run main.py --dynamic_predict (CLI)#
import subprocess, shlex
cmd = (
f"python main.py "
f"--dynamic_predict "
f"--data_file {DATA_FILE} "
f"--data_path {DATA_PATH} "
f"--Transformer_path {TRANSFORMER_PATH} "
f"--model_save_path {MODEL_SAVE_PATH} "
f"--seed {SEED} "
f"--device_num {DEVICE_NUM}"
)
print("Command:\n", cmd)
# Uncomment to run:
# subprocess.run(shlex.split(cmd), check=True)