### Install Project Dependencies Source: https://github.com/mysorf-9239/ugts-dti/blob/main/README.md Installs project dependencies using uv. Ensure you have git and uv installed. ```bash git clone https://github.com/your-repo/UGTS-DTI.git cd UGTS-DTI make install ``` -------------------------------- ### Initialize and Use SimpleMIDTI Teacher Model Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Initializes the SimpleMIDTI teacher model with specified dimensions, attention heads, and layers. Demonstrates building graphs and performing a forward pass to get logits for drug-protein pairs. ```python import torch import torch.nn as nn from src.models.teacher.interaction_gnn import SimpleMIDTI from src.models.teacher.builders import build_midti_graphs import numpy as np nD, nP, dim = 50, 30, 256 device = torch.device("cpu") teacher = SimpleMIDTI( n_drug=nD, n_prot=nP, dim=dim, # embedding dimension n_heads=8, # attention heads per DIA block dia_layers=2, # number of stacked DIA blocks dropout=0.1, mlp_hidden=128, # hidden size of final prediction MLP ).to(device) feat_drug = nn.Parameter(torch.randn(nD, dim, device=device) * 0.01) feat_prot = nn.Parameter(torch.randn(nP, dim, device=device) * 0.01) graphs = build_midti_graphs( feat_drug.detach().cpu().numpy(), feat_prot.detach().cpu().numpy(), np.array([[0,0],[1,2],[3,5]]), k_dd=10, k_pp=10, device=device, ) # Query a batch of 4 drug-protein pairs d_idx = torch.tensor([0, 1, 3, 10], device=device) p_idx = torch.tensor([0, 2, 5, 1], device=device) logits = teacher(graphs, feat_drug, feat_prot, d_idx, p_idx) print(logits.shape) # torch.Size([4]) print(torch.sigmoid(logits)) # binding probabilities ``` -------------------------------- ### Programmatic Invocation of DTI Model Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Equivalent programmatic invocation mirroring the main.py script. This setup includes data preparation, model initialization, and optimizer configuration for DTI prediction. Outputs are saved to output///test_predictions.csv. ```python import torch, torch.nn as nn from src.utils.config import load_config from src.utils.engine import setup_seed from src.data.processor import prepare_dataloaders from src.models.student.hdn import get_model from src.models.teacher import SimpleMIDTI, build_midti_graphs from src.models.fusion import UncertaintyGatedFusion from src.core.trainer import Trainer cfg = load_config("configs/default.yaml") setup_seed(cfg.seed) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") train_loader, valid_loader, test_loader, nD, nP, dp_pairs, drug_id2local, prot_id2local = \ prepare_dataloaders(cfg.dataset, batch_size=cfg.train.batch_size) student = get_model(cfg.model.student).model.to(device) feat_drug = nn.Parameter(torch.randn(nD, cfg.model.dim, device=device) * 0.01) feat_prot = nn.Parameter(torch.randn(nP, cfg.model.dim, device=device) * 0.01) teacher = SimpleMIDTI(nD, nP, dim=cfg.model.dim, **cfg.model.teacher).to(device) fusion = UncertaintyGatedFusion(student, teacher, **cfg.model.fusion).to(device) optimizer = torch.optim.Adam( list(fusion.parameters()) + [feat_drug, feat_prot], lr=cfg.train.lr, weight_decay=cfg.train.weight_decay, ) # → outputs saved to output///test_predictions.csv ``` -------------------------------- ### Run with Custom Configuration Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Execute the main script with a specified configuration file. ```bash uv run python -m src.main --config configs/smoke.yaml ``` -------------------------------- ### Execute Training with Default Settings Source: https://github.com/mysorf-9239/ugts-dti/blob/main/README.md Run the main Python script with default configuration settings. ```bash uv run python -m src.main ``` -------------------------------- ### Execute Training with Custom Configuration Source: https://github.com/mysorf-9239/ugts-dti/blob/main/README.md Run the main Python script, overwriting default settings with a custom configuration file specified by its path. ```bash uv run python -m src.main --config configs/your_config.yaml ``` -------------------------------- ### Run Full Training Pipeline: main (CLI) Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Execute the end-to-end training script via the command line. This script orchestrates configuration loading, data preparation, model training, checkpointing, and prediction export. ```bash # Install dependencies (requires uv) git clone https://github.com/your-repo/UGTS-DTI.git cd UGTS-DTI make install # Run with default configuration (DAVIS dataset, 100 epochs, CPU) uv run python -m src.main ``` -------------------------------- ### main (CLI entry point) Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt The main command-line interface entry point for the end-to-end training pipeline, orchestrating configuration loading, data preparation, model training, and prediction export. ```APIDOC ## Full Training Pipeline: `main` (CLI entry point) The end-to-end training script wires all components together: load config → seed → build data loaders → instantiate Student + Teacher + Fusion → train with early stopping → restore best checkpoint → export test CSV. ### Usage ```bash # Install dependencies (requires uv) git clone https://github.com/your-repo/UGTS-DTI.git cd UGTS-DTI make install # Run with default configuration (DAVIS dataset, 100 epochs, CPU) uv run python -m src.main ``` ``` -------------------------------- ### Prepare DataLoaders for Training Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Sets up the complete data pipeline, including loading, binarizing labels, undersampling negatives, splitting data, and applying DeepPurpose encoding. Returns PyTorch DataLoaders and graph construction metadata. ```python from src.data.processor import prepare_dataloaders # Supported datasets: "DAVIS", "KIBA", "BindingDB_Kd" ( train_loader, # DataLoader – MPNN-collated batches valid_loader, test_loader, nD, # int – number of unique drugs nP, # int – number of unique proteins dp_pairs, # np.ndarray (N, 2) – train drug-protein index pairs drug_id2local, # dict[str, int] prot_id2local, # dict[Any, int] ) = prepare_dataloaders("DAVIS", batch_size=32) # Each DataLoader yields batches of: # v_d – MPNN drug graph encoding (DeepPurpose format) # v_p – CNN protein embedding (np.ndarray, shape [L]) # y – float binary label (0 or 1) # d_idx – local drug integer index (for graph lookup) # p_idx – local protein integer index (for graph lookup) # Override to include validation/test pairs in graph construction (leakage warning): import os os.environ["UGTS_DTI_DP_PAIRS"] = "all" # default: "train" ``` -------------------------------- ### Initialize and Use UncertaintyGatedFusion Model Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Initializes the UncertaintyGatedFusion model, wrapping student and teacher models. Demonstrates a forward pass with MC-Dropout enabled for uncertainty estimation and calculates the knowledge distillation loss. ```python import torch import torch.nn as nn from src.models.fusion import UncertaintyGatedFusion from src.models.student.hdn import get_model from src.models.teacher.interaction_gnn import SimpleMIDTI nD, nP, dim = 50, 30, 256 device = torch.device("cpu") student = get_model().model.to(device) teacher = SimpleMIDTI(nD, nP, dim=dim, n_heads=8, dia_layers=2, dropout=0.1).to(device) fusion = UncertaintyGatedFusion( student_seq=student, teacher_midti=teacher, mc_samples=6, # Monte Carlo forward passes per branch temperature=2.0, # knowledge-distillation softening temperature gate_hidden=32, # PairGate hidden units ).to(device) # Forward (enable_mc=True activates MC-Dropout uncertainty estimation) logit_fused, logit_s, logit_t, w, u_s, u_t = fusion( v_d, v_p, # drug/protein sequence encodings (from DataLoader) d_idx, p_idx, # local graph indices graphs, # dict from build_midti_graphs() feat_drug, feat_prot, enable_mc=True, ) # logit_fused: (batch,) – uncertainty-gated blended prediction # w: (batch,) – gate weight toward student (0=all teacher, 1=all student) # u_s, u_t: (batch,) – MC-Dropout variance per branch probs = torch.sigmoid(logit_fused) # Knowledge distillation loss (Teacher → Student, temperature-scaled KL) kd = fusion.kd_loss(logit_s.view(-1), logit_t.view(-1)) ``` -------------------------------- ### Utilize Helper Functions: csv_record, to_device, check_dir Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt These low-level utilities support CSV logging for training batches, recursive tensor device transfer, and directory creation. `to_device` works with nested structures like lists and dictionaries. ```python from src.utils.engine import csv_record, to_device, check_dir import torch # Ensure output directory exists check_dir("output/experiment_1/logs") # Log a training batch record (auto-creates header on first call) csv_record( path="output/experiment_1/logs/loss.csv", data={ "epoch": 1, "batch": 42, "lr": 0.0005, "loss": 0.4231, "avg_loss": 0.4890, }, ) # Recursively move nested structures to device device = torch.device("cuda" if torch.cuda.is_available() else "cpu") nested = {"a": torch.randn(3), "b": [torch.randn(2), torch.randn(4)]} nested_gpu = to_device(nested, device) # Works with tensors, lists, tuples, and dicts at any nesting depth ``` -------------------------------- ### Initialize and Use PairGate Network Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Initializes the PairGate network, a 2-layer MLP that maps uncertainty estimates to a student mixing weight. Demonstrates its usage with simulated MC-Dropout uncertainty values. ```python import torch from src.models.fusion.uncertainty import PairGate gate = PairGate(hidden=32) # Simulate per-sample uncertainty estimates from MC-Dropout u_s = torch.tensor([0.05, 0.40, 0.01, 0.80]) # student variance u_t = torch.tensor([0.30, 0.02, 0.50, 0.10]) # teacher variance w = gate(u_s, u_t) print(w) # tensor of mixing weights in (0, 1) # When u_s >> u_t → w → 0 (trust Teacher more) # When u_t >> u_s → w → 1 (trust Student more) ``` -------------------------------- ### Utility Functions: csv_record, to_device, check_dir Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Provides low-level utility functions for CSV logging, recursive tensor device transfer, and directory creation, essential for the training loop. ```APIDOC ## Utility: `csv_record` / `to_device` / `check_dir` Low-level helpers used throughout the training loop: CSV logging, recursive tensor device transfer, and directory creation. ### Usage ```python from src.utils.engine import csv_record, to_device, check_dir import torch # Ensure output directory exists check_dir("output/experiment_1/logs") # Log a training batch record (auto-creates header on first call) csv_record( path="output/experiment_1/logs/loss.csv", data={ "epoch": 1, "batch": 42, "lr": 0.0005, "loss": 0.4231, "avg_loss": 0.4890, }, ) # Recursively move nested structures to device device = torch.device("cuda" if torch.cuda.is_available() else "cpu") nested = {"a": torch.randn(3), "b": [torch.randn(2), torch.randn(4)]} nested_gpu = to_device(nested, device) # Works with tensors, lists, tuples, and dicts at any nesting depth ``` ``` -------------------------------- ### Run Code Quality Checks Source: https://github.com/mysorf-9239/ugts-dti/blob/main/README.md Executes linting and type checking using ruff and mypy. Use 'make format' to automatically fix formatting issues. ```bash make check ``` ```bash make format ``` -------------------------------- ### Load Experiment Configuration Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Loads a YAML configuration file into a Config object for easy access. Supports nested dot-notation access for parameters. ```python from src.utils.config import load_config # Load the default experiment configuration cfg = load_config("configs/default.yaml") print(cfg.dataset) # "DAVIS" print(cfg.train.lr) # 0.0005 print(cfg.model.dim) # 256 print(cfg.model.teacher.n_heads) # 8 print(cfg.model.fusion.mc_samples) # 6 # Load a minimal smoke-test config cfg_smoke = load_config("configs/smoke.yaml") print(cfg_smoke.train.epochs) # 1 print(cfg_smoke.output.save_model) # False ``` -------------------------------- ### Build MIDTI Graphs Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Constructs normalized sparse adjacency matrices for drug-drug, protein-protein, drug-protein bipartite, and a combined DDPP graph from embeddings and known interactions. Requires numpy and torch. ```python import numpy as np import torch from src.models.teacher.builders import build_midti_graphs nD, nP, dim = 50, 30, 256 device = torch.device("cpu") # Random embeddings (in practice: feat_drug.detach().cpu().numpy()) drug_emb = np.random.randn(nD, dim).astype(np.float32) prot_emb = np.random.randn(nP, dim).astype(np.float32) # Example usage would follow to call build_midti_graphs with these embeddings ``` -------------------------------- ### Instantiate DeepPurpose Student Model Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Creates a DeepPurpose student model, configurable with different drug (MPNN) and protein (CNN) encoders. Accepts an HDNConfig object, a dictionary, or uses defaults. ```python from src.models.student.hdn import get_model, HDNConfig, forward_logits import torch # Using defaults (MPNN drug + CNN protein) dp_model = get_model() student = dp_model.model # the underlying nn.Module # Custom architecture via HDNConfig cfg = HDNConfig( drug_encoding="MPNN", target_encoding="CNN", cls_hidden_dims=(1024, 512, 256), mpnn_hidden_size=256, mpnn_depth=4, cnn_target_filters=(64, 128, 256), cnn_target_kernels=(4, 8, 12), ) dp_model_custom = get_model(cfg) student_custom = dp_model_custom.model # Or override from a YAML-loaded dict student_from_yaml = get_model({"drug_encoding": "MPNN", "target_encoding": "CNN"}).model # Inference (no-grad forward pass) # v_d, v_p are MPNN-collated drug graphs and protein embeddings # logits = forward_logits(student, v_d, v_p) # shape: (batch,) ``` -------------------------------- ### Manage Training Epochs with Trainer Class Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt The Trainer class encapsulates a full training epoch, validation, and test-set export. It handles device transfers, loss computation, learning-rate scheduling, and batch-level logging automatically. ```python import torch import torch.nn as nn from src.core.trainer import Trainer device = torch.device("cpu") optimizer = torch.optim.Adam( list(fusion.parameters()) + [feat_drug, feat_prot], lr=0.0005, weight_decay=0.0, ) scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1) trainer = Trainer( model=fusion, optimizer=optimizer, scheduler=scheduler, device=device, out_root="output/DAVIS/2024-01-01T00-00-00", # epoch logs saved here model_dir="output/models", # checkpoint dir ) # Train one epoch avg_loss, auroc_train = trainer.train_epoch( epoch=1, loader=train_loader, graphs=graphs, feat_drug=feat_drug, feat_prot=feat_prot, ) # Logs loss.csv per batch; returns mean loss and AUROC over the epoch # Validate val = trainer.evaluate(valid_loader, graphs, feat_drug, feat_prot) print(val.keys()) # dict_keys(['sensitivity','specificity','precision','recall','accuracy','f1', # 'mse','rmse','pearson','ci','auroc','auprc', # 'gate_mean','auroc_student','auprc_student','auroc_teacher','auprc_teacher']) print(f"Fusion AUPRC: {val['auprc']:.4f}, Gate mean: {val['gate_mean']:.3f}") # Export test predictions to CSV trainer.export_test_csv( test_loader, graphs, feat_drug, feat_prot, save_path="output/DAVIS/2024-01-01T00-00-00/test_predictions.csv", ) # CSV columns: Drug_ID, Target_ID, Label, Student, Teacher, Fusion ``` -------------------------------- ### Build MIDTI Graphs Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Builds interaction graphs for the MIDTI model. Requires drug and protein embeddings, and known interaction pairs. Specifies k-NN neighbors for drug-drug and protein-protein graphs. ```python dp_pairs = np.array([[0, 0], [1, 2], [5, 10], [20, 15]]) graphs = build_midti_graphs( drug_emb, prot_emb, dp_pairs, k_dd=10, # k-NN neighbours for drug–drug graph k_pp=10, # k-NN neighbours for protein–protein graph device=device, ) print(graphs.keys()) # dict_keys(['dd', 'pp', 'dp', 'ddpp']) print(graphs["dd"].shape) # sparse (50, 50) print(graphs["pp"].shape) # sparse (30, 30) print(graphs["dp"].shape) # sparse (80, 80) ← nD+nP joint print(graphs["ddpp"].shape)# sparse (80, 80) ``` -------------------------------- ### Data Preprocessing: Balance and Shuffle DataFrame Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Preprocesses a DataFrame by dropping NaN rows and optionally undersampling the majority class to balance positive and negative samples. Use `undersampling=False` to preserve the original imbalanced dataset. ```python from src.data.processor import df_data_preprocess import pandas as pd df = pd.DataFrame({ "Drug_ID": ["D1","D2","D3","D4","D5"], "Target_ID": ["T1","T1","T2","T2","T3"], "Drug": ["CC","CC","CC","CC","CC"], "Target": ["MA","MA","MA","MA","MA"], "Label": [1, 0, 0, 0, 1], }) # 2 positives, 3 negatives → undersamples to 2 neg df_balanced = df_data_preprocess(df, undersampling=True) print(df_balanced["Label"].value_counts()) # 0 2 # 1 2 # Preserve full imbalanced dataset df_full = df_data_preprocess(df, undersampling=False) print(len(df_full)) # 5 ``` -------------------------------- ### Code Quality Checks Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Run code quality checks including linting and type checking, or format code automatically. Use 'make clean' to remove cache directories. ```bash make check ``` ```bash make format ``` ```bash make clean ``` -------------------------------- ### Compute DTI Evaluation Metrics with all_dti_metrics Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Calculate a comprehensive suite of DTI evaluation metrics, including standard classification and regression-style scores. Requires true labels and predicted probabilities. ```python import numpy as np from src.utils.metrics import all_dti_metrics, concordance_index, pearson_correlation y_true = np.array([1, 0, 1, 1, 0, 0, 1, 0]) y_prob = np.array([0.9, 0.2, 0.8, 0.6, 0.3, 0.7, 0.75, 0.1]) metrics = all_dti_metrics(y_true, y_prob) print(metrics) # { # 'sensitivity': 1.0, 'specificity': 0.75, 'precision': 0.8, # 'recall': 1.0, 'accuracy': 0.875, 'f1': 0.888, # 'mse': 0.088, 'rmse': 0.297, # 'pearson': 0.763, 'ci': 0.875 # } # Individual metrics ci = concordance_index(y_true, y_prob) # proportion of concordant pairs pcc = pearson_correlation(y_true, y_prob) # Pearson r between labels and scores ``` -------------------------------- ### Trainer Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Encapsulates a full training epoch, validation evaluation, and test-set CSV export. It handles device transfers, multi-component loss computation, learning-rate scheduling, and batch-level CSV logging. ```APIDOC ## Trainer Encapsulates one full training epoch, validation evaluation, and test-set CSV export. Handles device transfers, multi-component loss computation, learning-rate scheduling, and batch-level CSV logging automatically. ### Usage ```python import torch import torch.nn as nn from src.core.trainer import Trainer device = torch.device("cpu") optimizer = torch.optim.Adam( list(fusion.parameters()) + [feat_drug, feat_prot], lr=0.0005, weight_decay=0.0, ) scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1) trainer = Trainer( model=fusion, optimizer=optimizer, scheduler=scheduler, device=device, out_root="output/DAVIS/2024-01-01T00-00-00", # epoch logs saved here model_dir="output/models", # checkpoint dir ) # Train one epoch avg_loss, auroc_train = trainer.train_epoch( epoch=1, loader=train_loader, graphs=graphs, feat_drug=feat_drug, feat_prot=feat_prot, ) # Logs loss.csv per batch; returns mean loss and AUROC over the epoch # Validate val = trainer.evaluate(valid_loader, graphs, feat_drug, feat_prot) print(val.keys()) # dict_keys(['sensitivity','specificity','precision','recall','accuracy','f1', # 'mse','rmse','pearson','ci','auroc','auprc', # 'gate_mean','auroc_student','auprc_student','auroc_teacher','auprc_teacher']) print(f"Fusion AUPRC: {val['auprc']:.4f}, Gate mean: {val['gate_mean']:.3f}") # Export test predictions to CSV trainer.export_test_csv( test_loader, graphs, feat_drug, feat_prot, save_path="output/DAVIS/2024-01-01T00-00-00/test_predictions.csv", ) # CSV columns: Drug_ID, Target_ID, Label, Student, Teacher, Fusion ``` ``` -------------------------------- ### Create Binary Labels for KIBA Score Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Converts raw KIBA scores into binary labels based on a threshold. Ensure the DataFrame contains 'KIBA' column before calling. ```python from DeepPurpose import make_binary_labels import pandas as pd df_kiba = pd.DataFrame({"Drug_ID":["D1"],"Target_ID":["T1"], "Drug":["CC"],"Target":["MA"],"Y":[15.0]}) df_kiba = make_binary_labels(df_kiba, "KIBA") print(df_kiba["Label"].values) # [1] ``` -------------------------------- ### Binarize Continuous Labels Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Converts continuous binding-affinity values to binary labels based on dataset-specific thresholds. Handles different units (e.g., nM) and calculates pKd or KIBA scores. ```python import pandas as pd from src.data.processor import make_binary_labels # DAVIS: Kd values in nM → pKd = -log10(Kd * 1e-9) df = pd.DataFrame({ "Drug_ID": ["D1", "D2", "D3"], "Target_ID": ["T1", "T1", "T2"], "Drug": ["CC(=O)Oc1ccccc1C(=O)O", "c1ccc2ccccc2c1", "CC1=CC=CC=C1"], "Target": ["MKTAYIAKQRQISFV", "MGGSSHHHHHHSSGL", "MAALSGGGGAAPAG"], "Y": [10.0, 45000.0, 800.0], # raw Kd in nM }) df = make_binary_labels(df, "DAVIS") print(df[["Drug_ID", "Y", "pY", "Label"]]) # Drug_ID Y pY Label # D1 10.0 10.9999 1 ← pKd > 7.0 → positive # D2 45000.0 4.3468 0 ← pKd < 7.0 → negative # D3 800.0 6.0969 0 ``` -------------------------------- ### all_dti_metrics Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Computes a comprehensive suite of Drug-Target Interaction (DTI) evaluation metrics from binary labels and predicted probabilities, including standard classification and regression-style scores. ```APIDOC ## Metrics: `all_dti_metrics` Computes the full suite of DTI evaluation metrics from binary labels and predicted probabilities, combining standard classification metrics with regression-style scores traditionally used in DTI benchmarks. ### Usage ```python import numpy as np from src.utils.metrics import all_dti_metrics, concordance_index, pearson_correlation y_true = np.array([1, 0, 1, 1, 0, 0, 1, 0]) y_prob = np.array([0.9, 0.2, 0.8, 0.6, 0.3, 0.7, 0.75, 0.1]) metrics = all_dti_metrics(y_true, y_prob) print(metrics) # { # 'sensitivity': 1.0, 'specificity': 0.75, 'precision': 0.8, # 'recall': 1.0, 'accuracy': 0.875, 'f1': 0.888, # 'mse': 0.088, 'rmse': 0.297, # 'pearson': 0.763, 'ci': 0.875 # } # Individual metrics ci = concordance_index(y_true, y_prob) # proportion of concordant pairs pcc = pearson_correlation(y_true, y_prob) # Pearson r between labels and scores ``` ``` -------------------------------- ### Data Splitting: Train, Validation, Test Sets Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Randomly shuffles and splits a DataFrame into training, validation, and testing sets. The default split is 70/10/20, but custom fractions can be provided. ```python from src.data.processor import df_data_split import pandas as pd, numpy as np df = pd.DataFrame({ "Drug_ID": [f"D{i}" for i in range(100)], "Target_ID": [f"T{i%10}" for i in range(100)], "Drug": ["CC"] * 100, "Target": ["MA"] * 100, "Label": np.random.randint(0, 2, 100), }) train_df, valid_df, test_df = df_data_split(df, frac=(0.7, 0.1, 0.2)) print(len(train_df), len(valid_df), len(test_df)) # 70 10 20 # Custom split: 80/10/10 train_df, valid_df, test_df = df_data_split(df, frac=(0.8, 0.1, 0.1)) ``` -------------------------------- ### DTI PyTorch Dataset and DataLoader Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Wraps an encoded DataFrame into a PyTorch Dataset for DTI tasks. It maps drug/protein IDs to local integer indices for graph lookups and requires a specific collate function for the DataLoader. ```python import torch from torch.utils import data from DeepPurpose import utils as dp_utils from src.data.dataset import DTI_Dataset # Assumes df is the output of dti_df_process() containing # 'drug_encoding', 'target_encoding', 'Seq_Label', 'Graph_Drug', 'Graph_Target' drug_id2local = {"D1": 0, "D2": 1} prot_id2local = {"T1": 0, "T2": 1} dataset = DTI_Dataset(encoded_df, drug_id2local, prot_id2local) loader = data.DataLoader( dataset, batch_size=32, shuffle=True, drop_last=True, collate_fn=dp_utils.mpnn_collate_func, ) for v_d, v_p, y, d_idx, p_idx in loader: print(type(v_d)) # list (MPNN graph objects) print(v_p.shape) # (batch, protein_embed_dim) print(y.shape) # (batch,) print(d_idx, p_idx) # local integer indices break ``` -------------------------------- ### GraphConvolution and GCNStack Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Implements single Graph Convolutional Network (GCN) layers and a stack of three GCN layers with ReLU activations for multi-scale representation. ```APIDOC ## GraphConvolution / GCNStack `GraphConvolution` implements a single GCN layer `A·(X·W) + b` using sparse-dense matrix multiplication. `GCNStack` chains three such layers with ReLU activations and returns all three intermediate feature maps for multi-scale representation. ### Usage ```python import torch from src.models.teacher.layers import GraphConvolution, GCNStack dim = 256 gcn_layer = GraphConvolution(in_features=dim, out_features=dim) gcn_stack = GCNStack(dim=dim) # adj: sparse_coo_tensor, shape (N, N), symmetric, row-normalized # feat: dense tensor, shape (N, dim) N = 50 adj = torch.eye(N).to_sparse() # identity as a trivial adjacency feat = torch.randn(N, dim) # Single layer h = gcn_layer(adj, feat) # shape: (50, 256) # Three-layer stack – returns h1, h2, h3 for multi-hop aggregation h1, h2, h3 = gcn_stack(adj, feat) print(h1.shape, h2.shape, h3.shape) # (50,256) (50,256) (50,256) ``` ``` -------------------------------- ### Implement GCN Layers: GraphConvolution and GCNStack Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Use GraphConvolution for a single GCN layer and GCNStack to chain multiple layers with ReLU activations. The stack returns intermediate feature maps for multi-scale representation. ```python import torch from src.models.teacher.layers import GraphConvolution, GCNStack dim = 256 gcn_layer = GraphConvolution(in_features=dim, out_features=dim) gcn_stack = GCNStack(dim=dim) # adj: sparse_coo_tensor, shape (N, N), symmetric, row-normalized # feat: dense tensor, shape (N, dim) N = 50 adj = torch.eye(N).to_sparse() # identity as a trivial adjacency feat = torch.randn(N, dim) # Single layer h = gcn_layer(adj, feat) # shape: (50, 256) # Three-layer stack – returns h1, h2, h3 for multi-hop aggregation h1, h2, h3 = gcn_stack(adj, feat) print(h1.shape, h2.shape, h3.shape) # (50,256) (50,256) (50,256) ``` -------------------------------- ### Set Reproducibility Seed Source: https://context7.com/mysorf-9239/ugts-dti/llms.txt Ensures reproducible results by setting seeds for PyTorch, NumPy, and Python's random module. Enforces deterministic cuDNN behavior. ```python from src.utils.engine import setup_seed setup_seed(42) # INFO: Reproducibility seed set to: 42 # All subsequent torch.randn / np.random calls are deterministic ``` -------------------------------- ### UGTS-DTI Citation Source: https://github.com/mysorf-9239/ugts-dti/blob/main/README.md BibTeX entry for citing the UGTS-DTI paper. ```bibtex @article{ugtsdti2026, title={UGTS-DTI: Uncertainty-Gated Teacher–Student Learning for Drug–Target Interaction Prediction}, author={UGTS-DTI Team}, year={2026}, journal={arXiv preprint} } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.