{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# ๐Ÿงฌ Fine-Tuning a Pre-trained Model on Genome Annotation Tracks Prediction\n", "\n", "This notebook demonstrates a **simplified fine-tuning setup** that enables training of a **pre-trained Nucleotide Transformer v3 (NTv3) model** to predict genome annotation tracks directly from DNA sequences. The streamlined approach leverages a pre-trained NTv3 backbone as a feature extractor and adds a custom prediction head that outputs single-nucleotide resolution signal values for four annotation tracks from the NTv3 benchmark dataset (exon, intron, splice_acceptor & start_codon).\n", "\n", "๐Ÿ“Š We provide access to the NTv3-benchmark data that we released on our Hugging Face dataset: `InstaDeepAI/NTv3_benchmark_dataset`. In this repository, you will find ready-to-use genome FASTA files, genome annotation data, metadata, but also the splits that were used for the benchmark.\n", "\n", "**๐Ÿ”ง Main Simplifications**: Compared to the full supervised tracks pipeline used in the paper, this notebook simplifies several aspects to enable faster experimentation with limited resources for users:\n", "- **Constant learning rate**: Uses a fixed learning rate throughout training without learning rate scheduling\n", "- **No gradient accumulation**: Implements simple step-based training without gradient accumulation, making the training loop more straightforward but changing the effective batch size compared with the full pipeline\n", "\n", "**๐ŸŽฏ Notebook purpose:**\n", "This notebook is configured to train the `NTv3_8M_pre` model on the `human` species from the NTv3 benchmark dataset. It is a lightweight, simplified setup that can be run on a T4 GPU on Colab." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ๐Ÿ’ป A note on hardware\n", "\n", "While this pipeline is designed to run on limited resources (e.g., Google Colab with a T4 GPU and 2CPUs), the mentioned training time or displayed performances (see **Test evaluation** section) was obtained on a more powerful setup and is shown just as a reference. If you want to reach similar performance levels or the ones reported in the paper, you should be aware that you'll need **significant hardware resources** (high-end GPUs with substantial memory and multiple data loading workers). Training times will vary significantly based on your hardware configuration.\n", "\n", "๐Ÿ“ Note for Google Colab users: This notebook is compatible with Colab and designed to work with limited resources! For faster training, make sure to enable GPU: Runtime โ†’ Change runtime type โ†’ GPU (T4 or better recommended)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 0. ๐Ÿ“ฆ Imports dependencies" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Login to HuggingFace (required for gated models)\n", "from huggingface_hub import login\n", "login()" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting pyfaidx\n", " Downloading pyfaidx-0.9.0.3-py3-none-any.whl.metadata (25 kB)\n", "Requirement already satisfied: pyBigWig in ./.venv/lib/python3.11/site-packages (0.3.24)\n", "Collecting torchmetrics\n", " Downloading torchmetrics-1.8.2-py3-none-any.whl.metadata (22 kB)\n", "Requirement already satisfied: transformers in ./.venv/lib/python3.11/site-packages (4.57.1)\n", "Requirement already satisfied: packaging in ./.venv/lib/python3.11/site-packages (from pyfaidx) (25.0)\n", "Requirement already satisfied: numpy>1.20.0 in ./.venv/lib/python3.11/site-packages (from torchmetrics) (2.1.3)\n", "Requirement already satisfied: torch>=2.0.0 in ./.venv/lib/python3.11/site-packages (from torchmetrics) (2.5.1+cu121)\n", "Collecting lightning-utilities>=0.8.0 (from torchmetrics)\n", " Downloading lightning_utilities-0.15.2-py3-none-any.whl.metadata (5.7 kB)\n", "Requirement already satisfied: filelock in ./.venv/lib/python3.11/site-packages (from transformers) (3.17.0)\n", "Requirement already satisfied: huggingface-hub<1.0,>=0.34.0 in ./.venv/lib/python3.11/site-packages (from transformers) (0.36.0)\n", "Requirement already satisfied: pyyaml>=5.1 in ./.venv/lib/python3.11/site-packages (from transformers) (6.0.2)\n", "Requirement already satisfied: regex!=2019.12.17 in ./.venv/lib/python3.11/site-packages (from transformers) (2024.11.6)\n", "Requirement already satisfied: requests in ./.venv/lib/python3.11/site-packages (from transformers) (2.32.3)\n", "Requirement already satisfied: tokenizers<=0.23.0,>=0.22.0 in ./.venv/lib/python3.11/site-packages (from transformers) (0.22.1)\n", "Requirement already satisfied: safetensors>=0.4.3 in ./.venv/lib/python3.11/site-packages (from transformers) (0.7.0)\n", "Requirement already satisfied: tqdm>=4.27 in ./.venv/lib/python3.11/site-packages (from transformers) (4.67.1)\n", "Requirement already satisfied: fsspec>=2023.5.0 in ./.venv/lib/python3.11/site-packages (from huggingface-hub<1.0,>=0.34.0->transformers) (2025.3.0)\n", "Requirement already satisfied: typing-extensions>=3.7.4.3 in ./.venv/lib/python3.11/site-packages (from huggingface-hub<1.0,>=0.34.0->transformers) (4.12.2)\n", "Requirement already satisfied: hf-xet<2.0.0,>=1.1.3 in ./.venv/lib/python3.11/site-packages (from huggingface-hub<1.0,>=0.34.0->transformers) (1.2.0)\n", "Requirement already satisfied: setuptools in ./.venv/lib/python3.11/site-packages (from lightning-utilities>=0.8.0->torchmetrics) (80.9.0)\n", "Requirement already satisfied: networkx in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (3.6.1)\n", "Requirement already satisfied: jinja2 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (3.1.6)\n", "Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.1.105 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (12.1.105)\n", "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.1.105 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (12.1.105)\n", "Requirement already satisfied: nvidia-cuda-cupti-cu12==12.1.105 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (12.1.105)\n", "Requirement already satisfied: nvidia-cudnn-cu12==9.1.0.70 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (9.1.0.70)\n", "Requirement already satisfied: nvidia-cublas-cu12==12.1.3.1 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (12.1.3.1)\n", "Requirement already satisfied: nvidia-cufft-cu12==11.0.2.54 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (11.0.2.54)\n", "Requirement already satisfied: nvidia-curand-cu12==10.3.2.106 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (10.3.2.106)\n", "Requirement already satisfied: nvidia-cusolver-cu12==11.4.5.107 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (11.4.5.107)\n", "Requirement already satisfied: nvidia-cusparse-cu12==12.1.0.106 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (12.1.0.106)\n", "Requirement already satisfied: nvidia-nccl-cu12==2.21.5 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (2.21.5)\n", "Requirement already satisfied: nvidia-nvtx-cu12==12.1.105 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (12.1.105)\n", "Requirement already satisfied: triton==3.1.0 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (3.1.0)\n", "Requirement already satisfied: sympy==1.13.1 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (1.13.1)\n", "Requirement already satisfied: nvidia-nvjitlink-cu12 in ./.venv/lib/python3.11/site-packages (from nvidia-cusolver-cu12==11.4.5.107->torch>=2.0.0->torchmetrics) (12.9.86)\n", "Requirement already satisfied: mpmath<1.4,>=1.1.0 in ./.venv/lib/python3.11/site-packages (from sympy==1.13.1->torch>=2.0.0->torchmetrics) (1.3.0)\n", "Requirement already satisfied: MarkupSafe>=2.0 in ./.venv/lib/python3.11/site-packages (from jinja2->torch>=2.0.0->torchmetrics) (3.0.2)\n", "Requirement already satisfied: charset-normalizer<4,>=2 in ./.venv/lib/python3.11/site-packages (from requests->transformers) (3.4.1)\n", "Requirement already satisfied: idna<4,>=2.5 in ./.venv/lib/python3.11/site-packages (from requests->transformers) (3.10)\n", "Requirement already satisfied: urllib3<3,>=1.21.1 in ./.venv/lib/python3.11/site-packages (from requests->transformers) (2.3.0)\n", "Requirement already satisfied: certifi>=2017.4.17 in ./.venv/lib/python3.11/site-packages (from requests->transformers) (2025.1.31)\n", "Downloading pyfaidx-0.9.0.3-py3-none-any.whl (29 kB)\n", "Downloading torchmetrics-1.8.2-py3-none-any.whl (983 kB)\n", "\u001b[2K \u001b[90mโ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”\u001b[0m \u001b[32m983.2/983.2 kB\u001b[0m \u001b[31m38.7 MB/s\u001b[0m \u001b[33m0:00:00\u001b[0m\n", "\u001b[?25hDownloading lightning_utilities-0.15.2-py3-none-any.whl (29 kB)\n", "Installing collected packages: pyfaidx, lightning-utilities, torchmetrics\n", "\u001b[2K \u001b[90mโ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”\u001b[0m \u001b[32m3/3\u001b[0m [torchmetrics][0m [torchmetrics]\n", "\u001b[1A\u001b[2KSuccessfully installed lightning-utilities-0.15.2 pyfaidx-0.9.0.3 torchmetrics-1.8.2\n" ] } ], "source": [ "# Install dependencies\n", "!pip install pyfaidx pyBigWig torchmetrics transformers" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import random\n", "import functools\n", "from typing import List, Dict, Callable\n", "import os\n", "from pathlib import Path\n", "from huggingface_hub import HfApi, snapshot_download\n", "\n", "import torch\n", "import torch.nn as nn\n", "import torch.nn.functional as F\n", "from torch.utils.data import Dataset, DataLoader\n", "from torch.optim import AdamW\n", "from transformers import AutoConfig, AutoModelForMaskedLM, AutoTokenizer\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from pyfaidx import Fasta\n", "from torchmetrics.classification import MulticlassMatthewsCorrCoef\n", "from tqdm import tqdm" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. โš™๏ธ Configuration\n", "\n", "## Configuration Parameters\n", "\n", "### Model\n", "- **`model_name`**: HuggingFace model name/identifier for the pretrained backbone model\n", "\n", "### Data\n", "- **`hf_repo_id`**: HuggingFace dataset repository ID containing the benchmark data\n", "- **`species`**: Species name (e.g., \"human\") to select data from the benchmark dataset\n", "- **`data_cache_dir`**: Directory where downloaded data files (FASTA, bigWig) will be stored\n", "- **`sequence_length`**: Length of input sequences in base pairs (bp)\n", "- **`keep_target_center_fraction`**: Fraction of center sequence to keep for target prediction (crops edges to focus on center)\n", "\n", "### Training\n", "- **`batch_size`**: Number of samples per batch\n", "- **`learning_rate`**: Constant learning rate for optimizer\n", "- **`weight_decay`**: L2 regularization coefficient for optimizer\n", "- **`num_steps_training`**: Total number of training steps\n", "- **`log_every_n_steps`**: Log training metrics every N steps\n", "\n", "### Validation\n", "- **`validate_every_n_steps`**: Run validation every N steps\n", "- **`num_validation_samples`**: Number of samples to use for validation set\n", "\n", "### Test\n", "- **`num_test_samples`**: Number of samples to use for test set evaluation\n", "\n", "### General\n", "- **`seed`**: Random seed for reproducibility\n", "- **`device`**: Device to run training on (\"cuda\" or \"cpu\")\n", "- **`num_workers`**: Number of worker processes for DataLoader (0 = single-threaded)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using device: cuda\n" ] } ], "source": [ "config = {\n", " # Model\n", " \"model_name\": \"InstaDeepAI/NTv3_8M_pre\",\n", " \n", " # Data\n", " \"hf_repo_id\": \"InstaDeepAI/NTv3_benchmark_dataset\",\n", " \"species_name\": \"human\",\n", " \"data_cache_dir\": \"./data\",\n", " \"sequence_length\": 32_768,\n", " \"keep_target_center_fraction\": 0.375,\n", " \n", " # Training\n", " \"batch_size\": 4,\n", " \"num_steps_training\": 5000, \n", " \"log_every_n_steps\": 40,\n", " \"learning_rate\": 1e-5,\n", " \"weight_decay\": 0.01,\n", " \n", " # Validation\n", " \"validate_every_n_steps\": 400, \n", " \"num_validation_samples\": 1000,\n", "\n", " # Test\n", " \"num_test_samples\": 10000,\n", " \n", " # General\n", " \"seed\": 0,\n", " \"device\": \"cuda\" if torch.cuda.is_available() else \"cpu\",\n", " \"num_workers\": 0, # NOTE: currently only supports num_workers=0\n", "}\n", "\n", "# Set random seed\n", "torch.manual_seed(config[\"seed\"])\n", "np.random.seed(config[\"seed\"])\n", "\n", "# Set device\n", "device = torch.device(config[\"device\"])\n", "print(f\"Using device: {device}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. ๐Ÿ“ฅ Genome & Tracks Data Download\n", "\n", "Download the reference genome FASTA file and annotation tracks that are used to train the model." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "def prepare_genomics_inputs(\n", " species: str,\n", " data_cache_dir: str | Path = \"data\",\n", " hf_repo_id: str = \"InstaDeepAI/NTv3_benchmark_dataset\",\n", ") -> tuple[str, list[str], list[str], pd.DataFrame]:\n", " \"\"\"\n", " Downloads:\n", " 1) FASTA from HF dataset under: /genome.fasta\n", " 2) Bed files from HF dataset under: /genome_annotation/**\n", " 3) Splits from HF dataset under: /splits.bed\n", " 4) Metadata from HF dataset under: benchmark_metadata.tsv\n", " \n", " Args:\n", " species: Species name (e.g., \"human\", \"arabidopsis\")\n", " data_cache_dir: Directory where downloaded data files will be stored\n", " hf_repo_id: HuggingFace dataset repository ID\n", " \n", " Returns:\n", " (fasta_path, bed_path_list, bed_elements, splits_df)\n", " \"\"\"\n", " cache = Path(data_cache_dir).expanduser().resolve()\n", " cache.mkdir(parents=True, exist_ok=True)\n", " \n", " # --- Download metadata + files (FASTA, BigWigs, Splits) ---\n", " download_patterns = [f\"{species}/genome.fasta\", f\"{species}/splits.bed\"]\n", " \n", " # Download all BigWig files\n", " download_patterns.append(f\"{species}/genome_annotation/*.bed\")\n", " local_dir = Path(\n", " snapshot_download(\n", " repo_id=hf_repo_id,\n", " repo_type=\"dataset\",\n", " allow_patterns=download_patterns,\n", " local_dir=str(cache),\n", " )\n", " )\n", " local_dir = Path(\"data/\")\n", " \n", " # --- Organize outputs ---\n", " # FASTA file\n", " fasta_path_repo = f\"{species}/genome.fasta\"\n", " fasta_path = str(local_dir / fasta_path_repo)\n", " \n", " # Bed files - use downloaded files directly\n", " bed_dir = local_dir / species / \"genome_annotation\"\n", "\n", " # Find all downloaded BigWig files\n", " bed_paths = [str(bigwig_file) for bigwig_file in bed_dir.glob(\"*.bed\")]\n", " bed_elements = [bigwig_file.stem for bigwig_file in bed_dir.glob(\"*.bed\")] \n", " \n", " # Splits file\n", " splits_path_repo = f\"{species}/splits.bed\"\n", " splits_path = local_dir / splits_path_repo\n", "\n", " splits_df = pd.read_csv(\n", " splits_path, \n", " sep=\"\\t\", \n", " header=None, \n", " names=[\"chr_name\", \"start\", \"end\", \"split\"],\n", " dtype={\"chr_name\": str, \"start\": int, \"end\": int, \"split\": str},\n", " )\n", " \n", "\n", " return fasta_path, bed_paths, bed_elements, splits_df" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "1d21653f04d1445cb8e9601b3e851bb3", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Fetching 6 files: 0%| | 0/6 [00:00 np.ndarray:\n", " \"\"\"Crop the central sequence-length fraction for arrays of size (..., seq_len, num_tracks)\"\"\"\n", " seq_len = x.shape[-2]\n", " target_offset = int(seq_len * (1 - keep_target_center_fraction) // 2)\n", " target_length = seq_len - 2 * target_offset\n", " return x[..., target_offset:target_offset + target_length, :]\n", "\n", "\n", "class ClassificationHead(nn.Module):\n", " \"\"\"A linear head that predicts one scalar value per track.\"\"\"\n", " def __init__(self, embed_dim: int, num_elements: int):\n", " super().__init__()\n", " self.num_elements = num_elements\n", " self.layer_norm = nn.LayerNorm(embed_dim)\n", " self.head = nn.Linear(embed_dim, num_elements*2)\n", " \n", " def forward(self, x: torch.Tensor) -> torch.Tensor:\n", " x = self.layer_norm(x)\n", " x = self.head(x)\n", " batch_size, sequence_length, _ = x.shape\n", " x = x.reshape(batch_size, sequence_length, self.num_elements, 2)\n", " return x\n", "\n", "\n", "class HFModelForBedElements(nn.Module):\n", " \"\"\"Simple model wrapper: HF backbone with species conditioning and bed element slicing\"\"\"\n", " \n", " def __init__(\n", " self,\n", " model_name: str,\n", " bed_elements: int,\n", " keep_target_center_fraction: float = 0.375,\n", " ):\n", " super().__init__()\n", " \n", " # Load config and model\n", " self.config = AutoConfig.from_pretrained(model_name, trust_remote_code=True)\n", " backbone = AutoModelForMaskedLM.from_pretrained(\n", " model_name, \n", " trust_remote_code=True,\n", " )\n", " self.backbone = torch.compile(backbone)\n", "\n", " self.keep_target_center_fraction = keep_target_center_fraction\n", " \n", " # Annotation head (NTv3 outputs at single-nucleotide resolution)\n", " self.bed_head = ClassificationHead(self.config.embed_dim, len(bed_elements))\n", " self.model_name = model_name\n", " \n", " def forward(self, tokens: torch.Tensor, **kwargs) -> Dict[str, torch.Tensor]:\n", " # Forward through backbone\n", " outputs = self.backbone(input_ids=tokens, output_hidden_states=True)\n", " embedding = outputs.hidden_states[-1] # Last hidden state\n", " \n", " # Crop to center fraction\n", " if self.keep_target_center_fraction < 1.0:\n", " embedding = crop_center(embedding, self.keep_target_center_fraction)\n", " \n", " # Predict bigwig tracks\n", " bed_logits = self.bed_head(embedding)\n", " \n", " return {\"bed_tracks_logits\": bed_logits}" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "3f514e0345fa464e9b95d19710b10c74", "version_major": 2, "version_minor": 0 }, "text/plain": [ "tokenizer_config.json: 0%| | 0.00/1.48k [00:00 Fasta handle\n", "_bed_cache = {} # Maps (process_id, file_path) -> pyBigWig handle\n", "\n", "\n", "def _get_fasta_handle(fasta_path: str) -> Fasta:\n", " \"\"\"Get or create a FASTA file handle for the current process.\"\"\"\n", " process_id = os.getpid()\n", " abs_path = str(Path(fasta_path).resolve())\n", " cache_key = (process_id, abs_path)\n", " \n", " if cache_key not in _fasta_cache:\n", " _fasta_cache[cache_key] = Fasta(abs_path, as_raw=True, sequence_always_upper=True)\n", " \n", " return _fasta_cache[cache_key]\n", "\n", "def _get_bed_handle(bed_path: str) -> pd.DataFrame:\n", " \"\"\"Get or create a Bed file handle for the current process.\"\"\"\n", " process_id = os.getpid()\n", " abs_path = str(Path(bed_path).resolve())\n", " cache_key = (process_id, abs_path)\n", " \n", " if cache_key not in _bed_cache:\n", " # Check if file exists before trying to open\n", " if not Path(abs_path).exists():\n", " raise FileNotFoundError(f\"Bed file not found: {abs_path}\")\n", " \n", " try:\n", " _bed_cache[cache_key] = pd.read_csv(abs_path, sep=\"\\t\", header=None)\n", " _bed_cache[cache_key].columns = [\"chr\", \"start\", \"end\", \"\", \"\", \"strand\", \"element\"]\n", " except Exception as e:\n", " raise RuntimeError(f\"Failed to open Bed file: {abs_path} with error: {str(e)}\") from e\n", " \n", " return _bed_cache[cache_key]\n", "\n", "\n", "\n", "class GenomeBedDataset(Dataset):\n", " \"\"\"\n", " A PyTorch dataset to access a reference genome and bigwig tracks. The dataset is \n", " compatible with multi-worker DataLoaders (using process-local file handles and lazy \n", " loading). For each sample, a random genomic region is picked from the specified split,\n", " and a random window of length `sequence_length` within that region is returned.\n", " \"\"\"\n", "\n", " def __init__(\n", " self,\n", " fasta_path: str,\n", " bed_path_list: list[str],\n", " chrom_regions: pd.DataFrame,\n", " split: str,\n", " sequence_length: int,\n", " num_samples: int,\n", " tokenizer: AutoTokenizer,\n", " keep_target_center_fraction: float = 1.0,\n", " ):\n", " super().__init__()\n", "\n", " # Store paths instead of opening files immediately (for multi-worker compatibility)\n", " self.fasta_path = fasta_path\n", " self.bed_path_list = bed_path_list\n", " self.sequence_length = sequence_length\n", " self.num_samples = num_samples\n", " self.tokenizer = tokenizer\n", " self.keep_target_center_fraction = keep_target_center_fraction\n", " self.chrom_regions = chrom_regions\n", "\n", " # Filter regions by split\n", " split_regions = self.chrom_regions[self.chrom_regions[\"split\"] == split].copy()\n", "\n", " # Filter valid regions (must be large enough for sequence_length)\n", " self.valid_regions = [\n", " (r.chr_name, r.start, r.end) \n", " for r in split_regions.itertuples() \n", " if r.end - r.start >= self.sequence_length\n", " ]\n", "\n", " def __len__(self):\n", " return self.num_samples\n", "\n", " def __getitem__(self, idx):\n", " # Sample a random region from the valid regions\n", " chrom, region_start, region_end = random.choice(self.valid_regions)\n", " \n", " # Sample a random window within this region\n", " max_start = region_end - self.sequence_length\n", " start = random.randint(region_start, max_start)\n", " end = start + self.sequence_length\n", "\n", " # Sequence - get FASTA handle lazily (cached per worker process)\n", " fasta = _get_fasta_handle(self.fasta_path)\n", " seq = fasta[chrom][start:end] # string slice\n", " # Tokenize with padding and truncation to ensure consistent lengths for batching\n", " tokenized = self.tokenizer(\n", " seq,\n", " padding=\"max_length\",\n", " truncation=True,\n", " max_length=self.sequence_length,\n", " return_tensors=\"pt\",\n", " )\n", " tokens = tokenized[\"input_ids\"][0] # Shape: (max_length,)\n", "\n", " # Get bed targets\n", " bed_sequence_length = self.sequence_length * self.keep_target_center_fraction\n", " bed_start = int(start + (self.sequence_length - bed_sequence_length) // 2)\n", " bed_end = int(bed_start + bed_sequence_length)\n", " bed_targets = np.zeros((int(bed_sequence_length), len(self.bed_path_list)), dtype=np.int32)\n", " for bed_idx, bed_path in enumerate(self.bed_path_list):\n", " bed_df = _get_bed_handle(bed_path)\n", " regions = bed_df[(bed_df[\"chr\"] == chrom) & (bed_df[\"start\"] >= bed_start) & (bed_df[\"end\"] <= bed_end)]\n", " for _, row in regions.iterrows():\n", " bed_targets[row[\"start\"] - bed_start:row[\"end\"] - bed_start, bed_idx] = 1\n", "\n", " # pyBigWig returns NaN where no data; turn NaN into 0\n", " bed_targets = torch.tensor(bed_targets, dtype=torch.int64)\n", "\n", " sample = {\n", " \"tokens\": tokens,\n", " \"bed_targets\": bed_targets,\n", " \"chrom\": chrom,\n", " \"start\": start,\n", " \"end\": end,\n", " }\n", " return sample" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Train samples: 20000\n", "Val samples: 1000\n", "Test samples: 10000\n" ] } ], "source": [ "# Create datasets & dataloaders\n", "create_dataset_fn = functools.partial(\n", " GenomeBedDataset,\n", " fasta_path=fasta_path,\n", " bed_path_list=bed_paths,\n", " chrom_regions=species_splits_df,\n", " sequence_length=config[\"sequence_length\"],\n", " tokenizer=tokenizer,\n", " keep_target_center_fraction=config[\"keep_target_center_fraction\"],\n", ")\n", "\n", "train_dataset = create_dataset_fn(\n", " split=\"train\",\n", " num_samples=config[\"num_steps_training\"] * config[\"batch_size\"],\n", ")\n", "\n", "val_dataset = create_dataset_fn(\n", " split=\"val\",\n", " num_samples=config[\"num_validation_samples\"],\n", ")\n", "\n", "test_dataset = create_dataset_fn(\n", " split=\"test\",\n", " num_samples=config[\"num_test_samples\"],\n", ")\n", "\n", "# Create dataloaders\n", "train_loader = DataLoader(\n", " train_dataset,\n", " batch_size=config[\"batch_size\"],\n", " shuffle=True,\n", " num_workers=config[\"num_workers\"],\n", ")\n", "\n", "val_loader = DataLoader(\n", " val_dataset,\n", " batch_size=config[\"batch_size\"],\n", " shuffle=False,\n", " num_workers=config[\"num_workers\"],\n", ")\n", "\n", "test_loader = DataLoader(\n", " test_dataset,\n", " batch_size=config[\"batch_size\"],\n", " shuffle=False,\n", " num_workers=config[\"num_workers\"],\n", ")\n", "\n", "print(f\"\\nTrain samples: {len(train_dataset)}\")\n", "print(f\"Val samples: {len(val_dataset)}\")\n", "print(f\"Test samples: {len(test_dataset)}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 5. โš™๏ธ Optimizer setup\n", "\n", "Configure the AdamW optimizer with learning rate and weight decay hyperparameters. This optimizer will update the model parameters during training to minimize the loss function.\n", "\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Training configuration:\n", " Batch size: 4\n", " Total training steps: 5000\n", " Log metrics every: 40 steps\n", " Validate every: 400 steps\n", "\n", "Optimizer setup:\n", " Learning rate: 1e-05\n" ] } ], "source": [ "# Training setup\n", "print(f\"Training configuration:\")\n", "print(f\" Batch size: {config['batch_size']}\")\n", "print(f\" Total training steps: {config['num_steps_training']}\")\n", "print(f\" Log metrics every: {config['log_every_n_steps']} steps\")\n", "print(f\" Validate every: {config['validate_every_n_steps']} steps\")\n", "\n", "# Setup optimizer\n", "optimizer = AdamW(\n", " model.parameters(),\n", " lr=config[\"learning_rate\"],\n", " weight_decay=config[\"weight_decay\"],\n", ")\n", "\n", "print(f\"\\nOptimizer setup:\")\n", "print(f\" Learning rate: {config['learning_rate']}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 6. ๐Ÿ“Š Metrics setup\n", "\n", "Set up evaluation metrics to track model performance during training and validation. We use Matthews Correlation Coefficient (MCC) to measure how well the predicted annotation tracks match the ground truth signals." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "\n", "class TracksMetrics:\n", " \"\"\"Metrics to handle multi-track MCC correlations and losses\"\"\"\n", " \n", " def __init__(self, track_names: List[str], split: str):\n", " self.track_names = track_names\n", " self.num_tracks = len(track_names)\n", " self.split = split\n", "\n", " # Initialise metrics \n", " self.mccs = [\n", " MulticlassMatthewsCorrCoef(num_classes=2).to(device) \n", " for _ in range(len(track_names))\n", " ]\n", " self.losses = []\n", "\n", " # Record mean metrics per logging interval\n", " self.step_idxs = []\n", " self.mean_mcc = []\n", " self.mean_losses = []\n", " \n", " def reset(self):\n", " for mcc in self.mccs:\n", " mcc.reset()\n", " self.losses = []\n", " \n", " def update(\n", " self, \n", " logits: torch.Tensor, \n", " labels: torch.Tensor,\n", " loss: float\n", " ):\n", " \"\"\"\n", " Update the metrics with logits and labels of shape (..., num_tracks) and a scalar loss.\n", " \"\"\"\n", " # Flatten batch and sequence dimensions\n", " pred_flat = logits.detach().reshape(-1, self.num_tracks, 2) # (N, num_tracks)\n", " target_flat = labels.detach().reshape(-1, self.num_tracks) # (N, num_tracks)\n", " \n", " # Update metrics\n", " for i, mcc in enumerate(self.mccs):\n", " mcc.update(pred_flat[:, i, :], target_flat[:, i])\n", " self.losses.append(loss)\n", " \n", " def compute(self) -> Dict[str, float]:\n", " \"\"\"Compute the MCC correlations and loss and return a dictionary of metrics.\"\"\"\n", " # Per-track MCC correlations\n", " metrics_dict = {}\n", " for i, mcc in enumerate(self.mccs):\n", " metrics_dict[f\"{self.track_names[i]}/mcc\"] = mcc.compute().cpu().item()\n", " metrics_dict[\"mean/mcc\"] = np.mean(list(metrics_dict.values()))\n", " \n", " # Mean loss\n", " metrics_dict[\"loss\"] = np.mean(self.losses)\n", " \n", " return metrics_dict\n", "\n", " def update_mean_metrics(self, step_idx: int):\n", " \"\"\"Update the mean metrics over the logging interval and save to a csv file.\"\"\"\n", " # Update mean metrics with the mean mcc & average loss\n", " metrics_dict = self.compute()\n", " self.step_idxs.append(step_idx)\n", " self.mean_mcc.append(metrics_dict[\"mean/mcc\"])\n", " self.mean_losses.append(metrics_dict[\"loss\"])\n", "\n", " # Save metrics to a csv for plotting\n", " data = {\n", " \"step\": self.step_idxs,\n", " \"mean_loss\": self.mean_losses,\n", " \"mean_mcc\": self.mean_mcc,\n", " }\n", " df = pd.DataFrame(data)\n", " df.to_csv(f\"metrics_{self.split}.csv\", index=False)\n", " \n", " def print_metrics(self, print_per_track: bool = False):\n", " \"\"\"Print a summary of the metrics.\"\"\"\n", " print(\n", " f\"Step {self.step_idxs[-1]}/{config['num_steps_training']} | \"\n", " f\"Loss: {self.mean_losses[-1]:.4f} | \"\n", " f\"Mean MCC: {self.mean_mcc[-1]:.4f}\"\n", " )\n", " metrics_dict = self.compute()\n", " if print_per_track:\n", " for metric_key, metric_value in metrics_dict.items():\n", " print(f\" {metric_key}: {metric_value:.4f}\")\n", " " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "train_metrics = TracksMetrics(bed_elements, \"train\")\n", "val_metrics = TracksMetrics(bed_elements, \"val\")\n", "test_metrics = TracksMetrics(bed_elements, \"test\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 7. ๐Ÿ“‰ Loss functions\n", "\n", "Use the focal loss to focus the model on learning the difficult to classify examples." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "\n", "def focal_loss(\n", " logits: torch.Tensor,\n", " targets: torch.Tensor,\n", " gamma: float = 2.0,\n", " epsilon: float = 1e-7,\n", ") -> torch.Tensor:\n", " \"\"\"\n", " Computes focal loss for nucleotide-level classification tasks from logits.\n", " It handles masking of invalid positions. Includes optional class weights.\n", "\n", " \"\"\"\n", " # Compute probabilities\n", " log_probs = F.log_softmax(logits, dim=-1)\n", " probabilities = torch.exp(log_probs)\n", "\n", " # Reshape for loss computation\n", " # num_classes: scalar\n", " num_classes = probabilities.shape[-1]\n", " probabilities = torch.reshape(probabilities, (-1, num_classes))\n", " log_probs = torch.reshape(log_probs, (-1, num_classes))\n", " targets = torch.reshape(targets, (-1,))\n", "\n", "\n", " # Compute focal loss per position\n", " loss = -torch.sum(\n", " torch.gather(\n", " (1 - probabilities) ** gamma * log_probs,\n", " dim=-1,\n", " index=targets[..., None],\n", " ),\n", " dim=-1,\n", " ) # shape: (total_positions,)\n", "\n", " # Average loss over valid positions only\n", " loss = loss.sum() / (loss.numel() + epsilon) # type: ignore\n", "\n", " return loss\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 8. ๐Ÿƒ Training loop\n", "\n", "Run the main training loop that iterates through batches, computes gradients, and updates model parameters. The loop includes periodic validation checks and real-time metric visualization to monitor training progress." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "def train_step(\n", " model: nn.Module,\n", " optimizer: torch.optim.Optimizer,\n", " batch: Dict[str, torch.Tensor],\n", " train_metrics: TracksMetrics,\n", ") -> None:\n", " \"\"\"Single training step.\"\"\"\n", " tokens = batch[\"tokens\"].to(device)\n", " bed_targets = batch[\"bed_targets\"].to(device)\n", " \n", " # Forward pass\n", " outputs = model(tokens=tokens)\n", " bed_logits = outputs[\"bed_tracks_logits\"]\n", " \n", " # Compute loss\n", " loss = focal_loss(\n", " logits=bed_logits,\n", " targets=bed_targets,\n", " )\n", "\n", " # Backward pass\n", " optimizer.zero_grad()\n", " loss.backward()\n", " optimizer.step()\n", "\n", " # Update metrics\n", " train_metrics.update(\n", " logits=bed_logits,\n", " labels=bed_targets,\n", " loss=loss.item()\n", " )\n", " \n", "\n", "\n", "def validation_step(\n", " model: nn.Module,\n", " batch: Dict[str, torch.Tensor],\n", " metrics: TracksMetrics,\n", ") -> None:\n", " \"\"\"Single validation step.\"\"\"\n", " tokens = batch[\"tokens\"].to(device)\n", " bed_targets = batch[\"bed_targets\"].to(device)\n", " \n", " with torch.no_grad():\n", " # Forward pass\n", " outputs = model(tokens=tokens)\n", " bed_logits = outputs[\"bed_tracks_logits\"]\n", " \n", " # Compute loss\n", " loss = focal_loss(\n", " logits=bed_logits,\n", " targets=bed_targets,\n", " )\n", " \n", " # Update metrics\n", " metrics.update(\n", " logits=bed_logits,\n", " labels=bed_targets,\n", " loss=loss.item()\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Run Training Loop" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Starting training for 5000 steps\n", "\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/app/.venv/lib/python3.11/site-packages/torch/_inductor/compile_fx.py:167: UserWarning: TensorFloat32 tensor cores for float32 matrix multiplication available but not enabled. Consider setting `torch.set_float32_matmul_precision('high')` for better performance.\n", " warnings.warn(\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Step 40/5000 | Loss: 0.2218 | Mean MCC: 0.0032\n", "Step 80/5000 | Loss: 0.0547 | Mean MCC: 0.0031\n", "Step 120/5000 | Loss: 0.0405 | Mean MCC: 0.0065\n", "Step 160/5000 | Loss: 0.0391 | Mean MCC: 0.0111\n", "Step 200/5000 | Loss: 0.0391 | Mean MCC: 0.0098\n", "Step 240/5000 | Loss: 0.0381 | Mean MCC: 0.0492\n", "Step 280/5000 | Loss: 0.0342 | Mean MCC: 0.0149\n", "Step 320/5000 | Loss: 0.0357 | Mean MCC: 0.0468\n", "Step 360/5000 | Loss: 0.0396 | Mean MCC: 0.0194\n", "Step 400/5000 | Loss: 0.0388 | Mean MCC: 0.0353\n", "\n", "Running validation at step 400...\n", "Step 400/5000 | Loss: 0.0369 | Mean MCC: 0.0381\n", " start_codon/mcc: 0.0506\n", " exon/mcc: 0.0876\n", " intron/mcc: 0.0146\n", " splice_acceptor/mcc: -0.0003\n", " mean/mcc: 0.0381\n", " loss: 0.0369\n", "\n", "----------------------------------------------------------------------------------------------------\n", "Training metrics:\n", "Step 440/5000 | Loss: 0.0315 | Mean MCC: 0.0215\n", "Step 480/5000 | Loss: 0.0388 | Mean MCC: 0.0094\n", "Step 520/5000 | Loss: 0.0336 | Mean MCC: 0.0464\n", "Step 560/5000 | Loss: 0.0348 | Mean MCC: 0.0321\n", "Step 600/5000 | Loss: 0.0382 | Mean MCC: 0.0223\n", "Step 640/5000 | Loss: 0.0302 | Mean MCC: 0.0643\n", "Step 680/5000 | Loss: 0.0349 | Mean MCC: 0.0498\n", "Step 720/5000 | Loss: 0.0306 | Mean MCC: 0.0547\n", "Step 760/5000 | Loss: 0.0297 | Mean MCC: 0.0488\n", "Step 800/5000 | Loss: 0.0328 | Mean MCC: 0.0613\n", "\n", "Running validation at step 800...\n", "Step 800/5000 | Loss: 0.0347 | Mean MCC: 0.0299\n", " start_codon/mcc: 0.0000\n", " exon/mcc: 0.0851\n", " intron/mcc: 0.0352\n", " splice_acceptor/mcc: -0.0005\n", " mean/mcc: 0.0299\n", " loss: 0.0347\n", "\n", "----------------------------------------------------------------------------------------------------\n", "Training metrics:\n", "Step 840/5000 | Loss: 0.0320 | Mean MCC: 0.0560\n", "Step 880/5000 | Loss: 0.0352 | Mean MCC: 0.0184\n", "Step 920/5000 | Loss: 0.0274 | Mean MCC: 0.0665\n", "Step 960/5000 | Loss: 0.0333 | Mean MCC: 0.0319\n", "Step 1000/5000 | Loss: 0.0388 | Mean MCC: 0.0501\n", "Step 1040/5000 | Loss: 0.0301 | Mean MCC: 0.0942\n", "Step 1080/5000 | Loss: 0.0353 | Mean MCC: 0.0731\n", "Step 1120/5000 | Loss: 0.0340 | Mean MCC: 0.0865\n", "Step 1160/5000 | Loss: 0.0364 | Mean MCC: 0.1012\n", "Step 1200/5000 | Loss: 0.0296 | Mean MCC: 0.1745\n", "\n", "Running validation at step 1200...\n", "Step 1200/5000 | Loss: 0.0299 | Mean MCC: 0.1300\n", " start_codon/mcc: 0.0000\n", " exon/mcc: 0.2830\n", " intron/mcc: 0.2371\n", " splice_acceptor/mcc: 0.0000\n", " mean/mcc: 0.1300\n", " loss: 0.0299\n", "\n", "----------------------------------------------------------------------------------------------------\n", "Training metrics:\n", "Step 1240/5000 | Loss: 0.0322 | Mean MCC: 0.1402\n", "Step 1280/5000 | Loss: 0.0254 | Mean MCC: 0.1792\n", "Step 1320/5000 | Loss: 0.0330 | Mean MCC: 0.2094\n", "Step 1360/5000 | Loss: 0.0272 | Mean MCC: 0.1255\n", "Step 1400/5000 | Loss: 0.0289 | Mean MCC: 0.1414\n", "Step 1440/5000 | Loss: 0.0220 | Mean MCC: 0.2283\n", "Step 1480/5000 | Loss: 0.0271 | Mean MCC: 0.2110\n", "Step 1520/5000 | Loss: 0.0294 | Mean MCC: 0.2254\n", "Step 1560/5000 | Loss: 0.0243 | Mean MCC: 0.2215\n", "Step 1600/5000 | Loss: 0.0237 | Mean MCC: 0.1931\n", "\n", "Running validation at step 1600...\n", "Step 1600/5000 | Loss: 0.0285 | Mean MCC: 0.1651\n", " start_codon/mcc: 0.0506\n", " exon/mcc: 0.3448\n", " intron/mcc: 0.2649\n", " splice_acceptor/mcc: 0.0000\n", " mean/mcc: 0.1651\n", " loss: 0.0285\n", "\n", "----------------------------------------------------------------------------------------------------\n", "Training metrics:\n", "Step 1640/5000 | Loss: 0.0230 | Mean MCC: 0.2508\n", "Step 1680/5000 | Loss: 0.0245 | Mean MCC: 0.2233\n", "Step 1720/5000 | Loss: 0.0287 | Mean MCC: 0.1908\n", "Step 1760/5000 | Loss: 0.0244 | Mean MCC: 0.2006\n", "Step 1800/5000 | Loss: 0.0271 | Mean MCC: 0.2052\n", "Step 1840/5000 | Loss: 0.0271 | Mean MCC: 0.2295\n", "Step 1880/5000 | Loss: 0.0232 | Mean MCC: 0.2136\n", "Step 1920/5000 | Loss: 0.0224 | Mean MCC: 0.2423\n", "Step 1960/5000 | Loss: 0.0232 | Mean MCC: 0.2989\n", "Step 2000/5000 | Loss: 0.0193 | Mean MCC: 0.2383\n", "\n", "Running validation at step 2000...\n", "Step 2000/5000 | Loss: 0.0252 | Mean MCC: 0.2248\n", " start_codon/mcc: 0.0000\n", " exon/mcc: 0.4335\n", " intron/mcc: 0.4652\n", " splice_acceptor/mcc: 0.0005\n", " mean/mcc: 0.2248\n", " loss: 0.0252\n", "\n", "----------------------------------------------------------------------------------------------------\n", "Training metrics:\n", "Step 2040/5000 | Loss: 0.0218 | Mean MCC: 0.1973\n", "Step 2080/5000 | Loss: 0.0264 | Mean MCC: 0.2163\n", "Step 2120/5000 | Loss: 0.0219 | Mean MCC: 0.2114\n", "Step 2160/5000 | Loss: 0.0277 | Mean MCC: 0.1805\n", "Step 2200/5000 | Loss: 0.0275 | Mean MCC: 0.1896\n", "Step 2240/5000 | Loss: 0.0240 | Mean MCC: 0.2577\n", "Step 2280/5000 | Loss: 0.0277 | Mean MCC: 0.2725\n", "Step 2320/5000 | Loss: 0.0217 | Mean MCC: 0.2318\n", "Step 2360/5000 | Loss: 0.0290 | Mean MCC: 0.2289\n", "Step 2400/5000 | Loss: 0.0233 | Mean MCC: 0.2429\n", "\n", "Running validation at step 2400...\n", "Step 2400/5000 | Loss: 0.0277 | Mean MCC: 0.1997\n", " start_codon/mcc: 0.0493\n", " exon/mcc: 0.3561\n", " intron/mcc: 0.3934\n", " splice_acceptor/mcc: 0.0000\n", " mean/mcc: 0.1997\n", " loss: 0.0277\n", "\n", "----------------------------------------------------------------------------------------------------\n", "Training metrics:\n", "Step 2440/5000 | Loss: 0.0210 | Mean MCC: 0.2887\n", "Step 2480/5000 | Loss: 0.0267 | Mean MCC: 0.2501\n", "Step 2520/5000 | Loss: 0.0258 | Mean MCC: 0.2599\n", "Step 2560/5000 | Loss: 0.0298 | Mean MCC: 0.2299\n", "Step 2600/5000 | Loss: 0.0221 | Mean MCC: 0.2404\n", "Step 2640/5000 | Loss: 0.0234 | Mean MCC: 0.2633\n", "Step 2680/5000 | Loss: 0.0238 | Mean MCC: 0.2584\n", "Step 2720/5000 | Loss: 0.0263 | Mean MCC: 0.2445\n", "Step 2760/5000 | Loss: 0.0204 | Mean MCC: 0.2888\n", "Step 2800/5000 | Loss: 0.0205 | Mean MCC: 0.2162\n", "\n", "Running validation at step 2800...\n", "Step 2800/5000 | Loss: 0.0267 | Mean MCC: 0.2122\n", " start_codon/mcc: 0.0000\n", " exon/mcc: 0.4210\n", " intron/mcc: 0.4279\n", " splice_acceptor/mcc: 0.0000\n", " mean/mcc: 0.2122\n", " loss: 0.0267\n", "\n", "----------------------------------------------------------------------------------------------------\n", "Training metrics:\n", "Step 2840/5000 | Loss: 0.0243 | Mean MCC: 0.2412\n", "Step 2880/5000 | Loss: 0.0177 | Mean MCC: 0.2594\n", "Step 2920/5000 | Loss: 0.0194 | Mean MCC: 0.1863\n", "Step 2960/5000 | Loss: 0.0251 | Mean MCC: 0.2636\n", "Step 3000/5000 | Loss: 0.0288 | Mean MCC: 0.2346\n", "Step 3040/5000 | Loss: 0.0271 | Mean MCC: 0.1957\n", "Step 3080/5000 | Loss: 0.0233 | Mean MCC: 0.2755\n", "Step 3120/5000 | Loss: 0.0252 | Mean MCC: 0.2669\n", "Step 3160/5000 | Loss: 0.0258 | Mean MCC: 0.2408\n", "Step 3200/5000 | Loss: 0.0241 | Mean MCC: 0.2430\n", "\n", "Running validation at step 3200...\n", "Step 3200/5000 | Loss: 0.0274 | Mean MCC: 0.2360\n", " start_codon/mcc: 0.0490\n", " exon/mcc: 0.4073\n", " intron/mcc: 0.4878\n", " splice_acceptor/mcc: 0.0000\n", " mean/mcc: 0.2360\n", " loss: 0.0274\n", "\n", "----------------------------------------------------------------------------------------------------\n", "Training metrics:\n", "Step 3240/5000 | Loss: 0.0204 | Mean MCC: 0.2803\n", "Step 3280/5000 | Loss: 0.0261 | Mean MCC: 0.2555\n", "Step 3320/5000 | Loss: 0.0238 | Mean MCC: 0.2637\n", "Step 3360/5000 | Loss: 0.0220 | Mean MCC: 0.2562\n", "Step 3400/5000 | Loss: 0.0239 | Mean MCC: 0.2776\n", "Step 3440/5000 | Loss: 0.0274 | Mean MCC: 0.2685\n", "Step 3480/5000 | Loss: 0.0263 | Mean MCC: 0.2586\n", "Step 3520/5000 | Loss: 0.0234 | Mean MCC: 0.2768\n", "Step 3560/5000 | Loss: 0.0222 | Mean MCC: 0.2892\n", "Step 3600/5000 | Loss: 0.0267 | Mean MCC: 0.2421\n", "\n", "Running validation at step 3600...\n", "Step 3600/5000 | Loss: 0.0256 | Mean MCC: 0.2280\n", " start_codon/mcc: 0.0501\n", " exon/mcc: 0.4380\n", " intron/mcc: 0.4242\n", " splice_acceptor/mcc: 0.0000\n", " mean/mcc: 0.2280\n", " loss: 0.0256\n", "\n", "----------------------------------------------------------------------------------------------------\n", "Training metrics:\n", "Step 3640/5000 | Loss: 0.0237 | Mean MCC: 0.2400\n", "Step 3680/5000 | Loss: 0.0276 | Mean MCC: 0.2614\n", "Step 3720/5000 | Loss: 0.0257 | Mean MCC: 0.3063\n", "Step 3760/5000 | Loss: 0.0212 | Mean MCC: 0.2614\n", "Step 3800/5000 | Loss: 0.0205 | Mean MCC: 0.2899\n", "Step 3840/5000 | Loss: 0.0218 | Mean MCC: 0.2880\n", "Step 3880/5000 | Loss: 0.0227 | Mean MCC: 0.2528\n", "Step 3920/5000 | Loss: 0.0241 | Mean MCC: 0.2407\n", "Step 3960/5000 | Loss: 0.0212 | Mean MCC: 0.2855\n", "Step 4000/5000 | Loss: 0.0205 | Mean MCC: 0.2798\n", "\n", "Running validation at step 4000...\n", "Step 4000/5000 | Loss: 0.0260 | Mean MCC: 0.2303\n", " start_codon/mcc: 0.0521\n", " exon/mcc: 0.4383\n", " intron/mcc: 0.4306\n", " splice_acceptor/mcc: 0.0000\n", " mean/mcc: 0.2303\n", " loss: 0.0260\n", "\n", "----------------------------------------------------------------------------------------------------\n", "Training metrics:\n", "Step 4040/5000 | Loss: 0.0252 | Mean MCC: 0.2623\n", "Step 4080/5000 | Loss: 0.0238 | Mean MCC: 0.2784\n", "Step 4120/5000 | Loss: 0.0231 | Mean MCC: 0.2999\n", "Step 4160/5000 | Loss: 0.0233 | Mean MCC: 0.3056\n", "Step 4200/5000 | Loss: 0.0273 | Mean MCC: 0.2512\n", "Step 4240/5000 | Loss: 0.0204 | Mean MCC: 0.2305\n", "Step 4280/5000 | Loss: 0.0214 | Mean MCC: 0.3093\n", "Step 4320/5000 | Loss: 0.0200 | Mean MCC: 0.2867\n", "Step 4360/5000 | Loss: 0.0211 | Mean MCC: 0.3121\n", "Step 4400/5000 | Loss: 0.0252 | Mean MCC: 0.2565\n", "\n", "Running validation at step 4400...\n", "Step 4400/5000 | Loss: 0.0251 | Mean MCC: 0.2467\n", " start_codon/mcc: 0.0526\n", " exon/mcc: 0.4339\n", " intron/mcc: 0.5002\n", " splice_acceptor/mcc: 0.0000\n", " mean/mcc: 0.2467\n", " loss: 0.0251\n", "\n", "----------------------------------------------------------------------------------------------------\n", "Training metrics:\n", "Step 4440/5000 | Loss: 0.0342 | Mean MCC: 0.2754\n", "Step 4480/5000 | Loss: 0.0234 | Mean MCC: 0.2421\n", "Step 4520/5000 | Loss: 0.0286 | Mean MCC: 0.2575\n", "Step 4560/5000 | Loss: 0.0284 | Mean MCC: 0.2739\n", "Step 4600/5000 | Loss: 0.0266 | Mean MCC: 0.2727\n", "Step 4640/5000 | Loss: 0.0189 | Mean MCC: 0.3080\n", "Step 4680/5000 | Loss: 0.0244 | Mean MCC: 0.2475\n", "Step 4720/5000 | Loss: 0.0184 | Mean MCC: 0.2889\n", "Step 4760/5000 | Loss: 0.0192 | Mean MCC: 0.2923\n", "Step 4800/5000 | Loss: 0.0202 | Mean MCC: 0.3148\n", "\n", "Running validation at step 4800...\n", "Step 4800/5000 | Loss: 0.0258 | Mean MCC: 0.2494\n", " start_codon/mcc: 0.0518\n", " exon/mcc: 0.4250\n", " intron/mcc: 0.5185\n", " splice_acceptor/mcc: 0.0023\n", " mean/mcc: 0.2494\n", " loss: 0.0258\n", "\n", "----------------------------------------------------------------------------------------------------\n", "Training metrics:\n", "Step 4840/5000 | Loss: 0.0199 | Mean MCC: 0.2911\n", "Step 4880/5000 | Loss: 0.0263 | Mean MCC: 0.2619\n", "Step 4920/5000 | Loss: 0.0213 | Mean MCC: 0.2649\n", "Step 4960/5000 | Loss: 0.0276 | Mean MCC: 0.2586\n", "Step 5000/5000 | Loss: 0.0225 | Mean MCC: 0.2812\n", "\n", "Training completed after 5000 steps.\n" ] } ], "source": [ "# Training loop\n", "print(f\"Starting training for {config['num_steps_training']} steps\\n\")\n", "\n", "# Create iterator for training data (will cycle if needed)\n", "train_iter = iter(train_loader)\n", "model.train()\n", "\n", "# Main training loop\n", "for step_idx in range(config[\"num_steps_training\"]):\n", " try:\n", " batch = next(train_iter)\n", " except StopIteration:\n", " # Restart iterator if we run out of data\n", " train_iter = iter(train_loader)\n", " batch = next(train_iter)\n", " \n", " # Take a training step\n", " train_step(model, optimizer, batch, train_metrics)\n", "\n", " # Logging\n", " if (step_idx + 1) % config[\"log_every_n_steps\"] == 0:\n", " train_metrics.update_mean_metrics(step_idx + 1)\n", " train_metrics.print_metrics()\n", " train_metrics.reset()\n", " \n", " # Validation\n", " if (step_idx + 1) % config[\"validate_every_n_steps\"] == 0:\n", " print(f\"\\nRunning validation at step {step_idx + 1}...\")\n", " model.eval()\n", " \n", " for val_batch in val_loader:\n", " validation_step(model, val_batch, val_metrics)\n", " \n", " val_metrics.update_mean_metrics(step_idx + 1)\n", " val_metrics.print_metrics(print_per_track=True)\n", " val_metrics.reset()\n", "\n", " # Back to training mode\n", " print(\"\\n\" + \"-\"*100 + \"\\nTraining metrics:\")\n", " model.train() \n", "\n", "print(f\"\\nTraining completed after {config['num_steps_training']} steps.\")\n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA/oAAAHWCAYAAADHF/LFAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzsnXd8FGX+x9+76b0XegAJBIWAoIgN1AjYJUEUVAR7wYb+LKcS2h2oqJyK4umJeicqSix3KhYULIeiYBAhFOktnfSyye78/hhmsjXZTTbJAt/367Wv7LRnnnlmJ7uf59sMiqIoCIIgCIIgCIIgCIJwXGDs7A4IgiAIgiAIgiAIguA9ROgLgiAIgiAIgiAIwnGECH1BEARBEARBEARBOI4QoS8IgiAIgiAIgiAIxxEi9AVBEARBEARBEAThOEKEviAIgiAIgiAIgiAcR4jQFwRBEARBEARBEITjCBH6giAIgiAIgiAIgnAcIUJfEARBEARBEARBEI4jROgLgiAIgiAIgiC4YPXq1RgMBlavXu3Vdg0GA7NmzfJqm4KgIUJfEIQ28cYbb2AwGPj11187uyuCIAiC4BHad5jBYOCHH35w2K4oCj169MBgMHDppZd2Qg/dJyUlBYPBQEZGhtPtr776qn6tzr6zc3Nzue666+jRowdBQUHExsaSkZHB0qVLMZvNNvvW1dXx3HPPMWLECKKioggODiY1NZXp06ezfft2t/pbUFDAgw8+yIABAwgNDSUsLIxhw4Yxb948ysrKPL5+X+Wzzz4TMS90Cv6d3QFBEARBEARB6EyCg4NZtmwZZ599ts36NWvWcODAAYKCgjqpZ54RHBzMt99+S35+PsnJyTbb3n77bYKDg6mrq3M47rXXXuP2228nKSmJ66+/nn79+lFZWcmqVau46aabOHz4MH/5y18AKC4uZty4caxfv55LL72UyZMnEx4ezrZt23j33Xf5xz/+gclkarafv/zyCxdffDFVVVVcd911DBs2DIBff/2VBQsW8N133/Hll196aVQ6l88++4zFixc7Ffu1tbX4+4scE9oH+WQJgiAIgiAIJzQXX3wx77//Ps8//7yN8Fq2bBnDhg2juLi4E3vnPmeddRa//PIL7733Hvfee6++/sCBA3z//feMHz+eFStW2Bzz008/cfvttzNy5Eg+++wzIiIi9G333Xcfv/76K3/88Ye+burUqfz222988MEHZGVl2bQ1d+5cHnvssWb7WFZWxvjx4/Hz8+O3335jwIABNtv/+te/8uqrr3p87c6oqakhNDTUYX1jYyMWi4XAwECvnKe1BAcHd+r5heMbcd0XBKHd+e2337jooouIjIwkPDycCy64gJ9++slmn4aGBmbPnk2/fv0IDg4mLi6Os88+m6+++krfJz8/n2nTptG9e3eCgoLo0qULV1xxBXv27OngKxIEQRCOJyZNmkRJSYnNd47JZOKDDz5g8uTJTo+xWCwsWrSIk08+meDgYJKSkrjttts4cuSIzX4ff/wxl1xyCV27diUoKIi+ffsyd+5cB3f40aNHc8opp7BlyxbOO+88QkND6datG0899ZTb1xEcHExmZibLli2zWf/OO+8QExPD2LFjHY6ZPXs2BoOBt99+20bkawwfPpypU6cC8PPPP/Ppp59y0003OYh8gKCgIBYuXNhsH1955RUOHjzIs88+6yDyAZKSknj88cdt1r300kucfPLJBAUF0bVrV+666y4H935t/NavX8+5555LaGgof/nLX9izZw8Gg4GFCxeyaNEi+vbtS1BQEFu2bAFg69atTJgwgdjYWIKDgxk+fDiffPJJs9cA8P3333PVVVfRs2dPgoKC6NGjB/fffz+1tbX6PlOnTmXx4sUAetiEwWDQtzuL0XfnN5MWcvLjjz8yY8YMEhISCAsLY/z48RQVFbXYd+HEQCz6giC0K5s3b+acc84hMjKShx56iICAAF555RVGjx7NmjVrGDFiBACzZs1i/vz53HzzzZx++ulUVFTw66+/smHDBi688EIAsrKy2Lx5M3fffTcpKSkUFhby1VdfsW/fPlJSUjrxKgVBEIRjmZSUFEaOHMk777zDRRddBMDnn39OeXk511xzDc8//7zDMbfddhtvvPEG06ZN45577mH37t28+OKL/Pbbb/z4448EBAQAqigLDw9nxowZhIeH88033zBz5kwqKip4+umnbdo8cuQI48aNIzMzk4kTJ/LBBx/w8MMPM2jQIL1fLTF58mTGjBnDzp076du3L6B6JkyYMEHvk0ZNTQ2rVq3i3HPPpWfPni22rQng66+/3q2+uGojJCSECRMmuLX/rFmzmD17NhkZGdxxxx1s27aNl19+mV9++cVmnAFKSkq46KKLuOaaa7juuutISkrSty1dupS6ujpuvfVWPQfB5s2bOeuss+jWrRuPPPIIYWFhLF++nCuvvJIVK1Ywfvx4l/16//33qamp4Y477iAuLo5169bxwgsvcODAAd5//31A/YwcOnSIr776in/9618tXqu7v5k07r77bmJiYsjOzmbPnj0sWrSI6dOn895777k1tsJxjiIIgtAGli5dqgDKL7/84nT7lVdeqQQGBio7d+7U1x06dEiJiIhQzj33XH1denq6cskll7g8z5EjRxRAefrpp73XeUEQBOGExvo77MUXX1QiIiKUmpoaRVEU5aqrrlLOO+88RVEUpVevXjbfUd9//70CKG+//bZNeytXrnRYr7VnzW233aaEhoYqdXV1+rpRo0YpgPLWW2/p6+rr65Xk5GQlKyurxWvR+tjY2KgkJycrc+fOVRRFUbZs2aIAypo1axy+szdu3KgAyr333tti+4qiKOPHj1cA5ciRI27t74yYmBglPT3drX0LCwuVwMBAZcyYMYrZbNbXv/jiiwqgvP766/o6bfyWLFli08bu3bsVQImMjFQKCwtttl1wwQXKoEGDbO6DxWJRzjzzTKVfv376um+//VYBlG+//VZf5+y+zp8/XzEYDMrevXv1dXfddZfiSnIBSnZ2tr7s7m8m7T5mZGQoFotFX3///fcrfn5+SllZmdPzCScW4rovCEK7YTab+fLLL7nyyivp06ePvr5Lly5MnjyZH374gYqKCgCio6PZvHkzO3bscNpWSEgIgYGBrF692sEtUhAEQRDaysSJE6mtreW///0vlZWV/Pe//3Xptv/+++8TFRXFhRdeSHFxsf4aNmwY4eHhfPvtt/q+ISEh+vvKykqKi4s555xzqKmpYevWrTbthoeHc9111+nLgYGBnH766ezatcvt6/Dz82PixIm88847gJqEr0ePHpxzzjkO+2rfwc5c9p3h6f6u2nD3+K+//hqTycR9992H0dgkW2655RYiIyP59NNPbfYPCgpi2rRpTtvKysoiISFBXy4tLeWbb75h4sSJ+n0pLi6mpKSEsWPHsmPHDg4ePOiyb9b3tbq6muLiYs4880wUReG3335z6/qs8eQ3k8att95qEwpwzjnnYDab2bt3r8fnF44/ROgLgtBuFBUVUVNTQ//+/R22paWlYbFY2L9/PwBz5syhrKyM1NRUBg0axP/93//x+++/6/sHBQXx5JNP8vnnn5OUlMS5557LU089RX5+foddjyAIgnD8kpCQQEZGBsuWLSMnJwez2ezSvXzHjh2Ul5eTmJhIQkKCzauqqorCwkJ9382bNzN+/HiioqKIjIwkISFBF/Pl5eU27Xbv3t1GuAHExMR4PME9efJktmzZwsaNG1m2bBnXXHONQ7sAkZGRgDoB4Q6e7u+qDXeP1wSr/e+IwMBA+vTp4yBou3Xr5jLBXu/evW2W//zzTxRF4YknnnC4h9nZ2QA299Geffv2MXXqVGJjYwkPDychIYFRo0YBjvfVHTz5zaRhH24RExMDIAYRAZAYfUEQfIRzzz2XnTt38vHHH/Pll1/y2muv8dxzz7FkyRJuvvlmQM3+e9lll/HRRx/xxRdf8MQTTzB//ny++eYbhg4d2slXIAiCIBzrTJ48mVtuuYX8/HwuuugioqOjne5nsVhITEzk7bffdrpdsxyXlZUxatQoIiMjmTNnDn379iU4OJgNGzbw8MMPY7FYbI7z8/Nz2p6iKB5dx4gRI+jbty/33Xcfu3fvdumZcNJJJ+Hv78+mTZvcaldLnrdp0yanHgLutpGbm4vJZPJ61ntrK3tL27Sxf/DBB50mKQR1fJxhNpu58MILKS0t5eGHH2bAgAGEhYVx8OBBpk6d6nBf2wtvfV6E4xMR+oIgtBsJCQmEhoaybds2h21bt27FaDTSo0cPfV1sbCzTpk1j2rRpVFVVce655zJr1ixd6AP07duXBx54gAceeIAdO3YwZMgQnnnmGf797393yDUJgiAIxy/jx4/ntttu46effmo2oVnfvn35+uuvOeuss5oVl6tXr6akpIScnBzOPfdcff3u3bu92m9nTJo0iXnz5pGWlsaQIUOc7hMaGsr555/PN998w/79+22+k51x2WWXMX/+fP7973+3WuhfdtllrF27lhUrVjBp0qRm9+3VqxcA27Zts3FnN5lM7N69m4yMjFb1AdDbCwgI8LidTZs2sX37dt58802mTJmir7eu2qDhzJPCGZ7+ZhKElhDXfUEQ2g0/Pz/GjBnDxx9/bFMCr6CggGXLlnH22WfrboAlJSU2x4aHh3PSSSdRX18PqJmB6+rqbPbp27cvERER+j6CIAiC0BbCw8N5+eWXmTVrFpdddpnL/SZOnIjZbGbu3LkO2xobG/XSb5rF1drCajKZeOmll7zbcSfcfPPNZGdn88wzzzS7X3Z2NoqicP3111NVVeWwff369bz55psAjBw5knHjxvHaa6/x0UcfOexrMpl48MEHmz3f7bffTpcuXXjggQfYvn27w/bCwkLmzZsHQEZGBoGBgTz//PM2Y/jPf/6T8vJyLrnkkmbP1RyJiYmMHj2aV155hcOHDztsb65MnbP7qigKf//73x32DQsLA3AoB+isTXd/MwmCO4hFXxAEr/D666+zcuVKh/WzZs3iq6++4uyzz+bOO+/E39+fV155hfr6epvawAMHDmT06NEMGzaM2NhYfv31Vz744AOmT58OwPbt27nggguYOHEiAwcOxN/fnw8//JCCggKuueaaDrtOQRAE4fjmhhtuaHGfUaNGcdtttzF//nxyc3MZM2YMAQEB7Nixg/fff5+///3vTJgwgTPPPJOYmBhuuOEG7rnnHgwGA//61786xLW6V69eDjXanXHmmWeyePFi7rzzTgYMGMD1119Pv379qKysZPXq1XzyySe68AZ46623GDNmDJmZmVx22WVccMEFhIWFsWPHDt59910OHz7MwoULXZ4vJiaGDz/8kIsvvpghQ4Zw3XXXMWzYMAA2bNjAO++8w8iRIwHVyv3oo48ye/Zsxo0bx+WXX862bdt46aWXOO2002wSF7aGxYsXc/bZZzNo0CBuueUW+vTpQ0FBAWvXruXAgQNs3LjR6XEDBgygb9++PPjggxw8eJDIyEhWrFjhNDZeu7Z77rmHsWPH4ufn5/J3y7x589z6zSQIbtFZ6f4FQTg+0Eq8uHrt379f2bBhgzJ27FglPDxcCQ0NVc477zzlf//7n0078+bNU04//XQlOjpaCQkJUQYMGKD89a9/VUwmk6IoilJcXKzcddddyoABA5SwsDAlKipKGTFihLJ8+fLOuGxBEAThOKClErEa9uX1NP7xj38ow4YNU0JCQpSIiAhl0KBBykMPPaQcOnRI3+fHH39UzjjjDCUkJETp2rWr8tBDDylffPGFQ7m2UaNGKSeffLLDOW644QalV69eLV6Lqz5a09z1rl+/Xpk8ebLStWtXJSAgQImJiVEuuOAC5c0337Qpbacoamm5hQsXKqeddpoSHh6uBAYGKv369VPuvvtu5c8//2yxr4qilo27//77ldTUVCU4OFgJDQ1Vhg0bpvz1r39VysvLbfZ98cUXlQEDBigBAQFKUlKScscd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/vttYvA7gl27/FEU2+RLigLbtnVoNwRBOEGoqYHw8NYdaz0hCXDttc72MgDOY82rqiAsrHXntueRRx5h4cKF9OnTh5iYGPbv38/FF1/MX//6V4KCgnjrrbe47LLL2LZtm01JVXtmz57NU089xdNPP80LL7zAtddey969e5ut4uKK9evXM3HiRGbNmsXVV1/N//73P+68807i4uKYOnUqv/76K/fccw//+te/OPPMMyktLeX7778HVCvr5MmTeeqppxg/fjyVlZV8//33UrngGKSmoYbw+Z4/ZNY/IAGuzXH6gLmk6tEqwgK984B15vMVGBjItddey9KlSxkxYgQAb7zxBk899ZSN235ubi6bN29m2bJlTsNVtCpL77//PiaTiYceesjp+eyrMQmC4Fvk5OUwe81sthdvJzU+lexR2WSmZXZoH7YXb9f/N2soKGwr8X3B1ulCH2D69OlMnz7d6bbVq1fbLLuKoddISUlp8cfRqaeeyk8//eRJF9uFPn0a2brVVuwbDNC/fyd2ShAEwceZM2cOF154ob4cGxtLenq6vjx37lw+/PBDPvnkE5ffLQBTp05l0qRJAPztb3/j+eefZ926dYwbN87jPj377LNccMEFPPHEEwCkpqayZcsWnn76aaZOncq+ffsICwvj0ksvJSIigl69ejF06FAURSE/P5/GxkYyMzPp1asXAIMGDfK4D4LgDTr7+brxxhs555xzeOaZZ9i4cSPl5eVceumlNkJ/x44dAAwYMKDZtnbs2EFkZKSD278gCL6P5jKvWdM1j6cVE1d0qNhPjU9lU8EmG7FvwED/ON8XbD4h9E9UHnigiptvbgoVMBhUa1l2did2ShCE45bQUNWy7glnnAGbN9u63hsMcMopsHat7b5aTK+/v7+eYM763N7CPjdLVVUVs2bN4tNPP+Xw4cM0NjZSW1vLvn37mm3HOpFrWFgYkZGRFBYWtqpPeXl5XHHFFTbrzjrrLBYtWoTZbObCCy+kV69e9OnTh3HjxjFu3DjGjx9PSEgIgwcP5oILLmDQoEGMHTuWMWPGMGHChA4NJRO8Q2hAKFWPNj1kzT0TAGf88ww2F252+AF5SuIprL1prcP+zZ3XW3T285Wenk6/fv1YsWIF33//Pddff71D5RB3vV0URXE67oIg+D7Nucx3pNDPHpVN1vIsfVnrU/Yo3xdsnR6j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H/4HVOZCYDQMmtm2YwkhhAsk0PcSlsH4pEZfCCFEZ/Dqq68yb948rrrqKgoLC6198kNDQ1m6dKlnMye6neS4ZN5Oftv6OrJHpHXKOLs1+r56jb6jwfgsNf4uMddBxvP687gHwODn+rGEEMJFHg/0ly1bRkxMDCaTicTERLZu3eow7Y8//khKSgoxMTFommb3h8TixYs555xz6NmzJ3369GHatGlkZmbapLn44ovRNM1mueuuu9x9ak6RpvtCCCE6k5deeom///3vPProo/hYLmLAhAkT2L17twdzJrqry4dcbn0+c9RM67zwztTou6Xp/s8fQulB8O8NZ93u+nGEEKINPBrov//++8ybN4/U1FS2bdtGQkICSUlJ5Obm2k1fXl7OkCFDePrpp4mKirKbZtOmTdx77718++23rF+/npqaGq644grKysps0s2ZM4eTJ09al2effdbt5+cMCfSFEEJ0JocPH2bs2LFN1huNxibXXCE6QsPa+bzyPOvzgooCwH6g7/bB+JSCvc/oz4fPBd8erh1HCCHayKXB+I4dO4amaQwYMACArVu38s477zBy5EjuvPPOVh9nyZIlzJkzh9mzZwOwfPlyPv30U1asWMHDDz/cJP0555zDOefoc5Da2w6wdu1am9dvvfUWffr0IT09nYsuusi6PjAw0OHNAk+QQF8IIURnMnjwYHbs2NFkgL61a9cSFxfnoVyJ7qy8ptz6PL883/q8pcH4lFJoZwbLcynQL8uCqjPvV/A9nPoBDP4wYJorpyGEEG7hUqB/8803c+edd/LLX/6S7OxsLr/8ckaNGsXbb79NdnY2CxYsaPEY1dXVpKenM3/+fOs6g8HAlClT2LJliyvZsquoqAiA3r1726x/++23+de//kVUVBTXXnstjz/+OIGBgQ6PU1VVRVVVlfV1cXExAGazGbMLI+iZzWaUUo32NWA2K8zm5ucn7q7sl5loiZSb86TMXCPl5jx3l1lHlv28efO49957qazUA6WtW7fy7rvvsnjxYl5//fUOy4cQFg0D/YY1+pZAPywgzLrOEsgrFNV11dZp96yBvk8rA/2yLPgkFsy2XQAwV8Pn58G1mdAj2ulzEUKItnIp0N+zZw8TJ04EYOXKlYwePZpvvvmGzz//nLvuuqtVgX5+fj51dXVERkbarI+MjGTfvn2uZKsJs9nM73//e84/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9lv11VdfqaFDh6pZs2ZZtxcVFanIyEh1yy23qD179qh3331XBQQEqL/97W8ddZpulZSUpN588021Z88etWPHDnXVVVep6OhoVVpaak1z1113qYEDB6oNGzaoH374QZ177rnqvPPOs26vra1Vo0ePVlOmTFHbt29Xn332mQoPD1fz58+3pjl06JAKDAxU8+bNU3v37lUvvfSS8vHxUWvXru3Q83WXjz/+WH366adq//79KjMzUz3yyCPKz89P7dmzRyklZdaSrVu3qpiYGBUfH6/uu+8+63opt6ZSU1PVqFGj1MmTJ61LXl6edbuUWfck13u53jtLrvfOk2t928i1vvU647VeAv0ONnHiRHXvvfdaX9fV1al+/fqpxYsXezBXntH4wm82m1VUVJR67rnnrOsKCwuV0WhU7777rlJKqb179ypAff/999Y0//nPf5Smaer48eNKKaVeeeUV1atXL1VVVWVN88c//lHFxsa28xl1jNzcXAWoTZs2KaX0MvLz81OrVq2ypsnIyFCA2rJli1JK/8FlMBhUdna2Nc2rr76qgoODreX00EMPqVGjRtm814033qiSkpLa+5Q6TK9evdTrr78uZdaCkpISNWzYMLV+/Xo1efJk68Vfys2+1NRUlZCQYHeblFn3Jdf7enK9d41c710j1/rWkWu9czrjtV6a7neg6upq0tPTmTJlinWdwWBgypQpbNmyxYM58w6HDx8mOzvbpnxCQkJITEy0ls+WLVsIDQ1lwoQJ1jRTpkzBYDDw3XffWdNcdNFF+Pv7W9MkJSWRmZnJ6dOnO+hs2k9RUREAvXv3BiA9PZ2amhqbchsxYgTR0dE25Xb22WcTGRlpTZOUlERxcTE//vijNU3DY1jSdIXvZl1dHe+99x5lZWVMmjRJyqwF9957L1dffXWTc5Nyc+ynn36iX79+DBkyhFtuuYWsrCxAyqy7kut98+R63zpyvXeOXOudI9d653W2a70E+h0oPz+furo6mw8YIDIykuzsbA/lyntYyqC58snOzqZPnz422319fendu7dNGnvHaPgenZXZbOb3v/89559/PqNHjwb0c/L39yc0NNQmbeNya6lMHKUpLi6moqKiPU6n3e3evZugoCCMRiN33XUXH374ISNHjpQya8Z7773Htm3bWLx4cZNtUm72JSYm8tZbb7F27VpeffVVDh8+zIUXXkhJSYmUWTcl1/vmyfW+ZXK9bz251jtPrvXO64zXel+n9xBCeMy9997Lnj17+Prrrz2dlU4hNjaWHTt2UFRUxAcffMBtt93Gpk2bPJ0tr3Xs2DHuu+8+1q9fj8lk8nR2Oo0rr7zS+jw+Pp7ExEQGDRrEypUrCQgI8GDOhBCdlVzvW0+u9c6Ra71rOuO1Xmr0O1B4eDg+Pj5NRmDMyckhKirKQ7nyHpYyaK58oqKiyM3NtdleW1vLqVOnbNLYO0bD9+iM5s6dy7///W++/PJLBgwYYF0fFRVFdXU1hYWFNukbl1tLZeIoTXBwsNf+A2uJv78/Q4cOZfz48SxevJiEhARefPFFKTMH0tPTyc3NZdy4cfj6+uLr68umTZv461//iq+vL5GRkVJurRAaGsrw4cM5cOCAfNe6KbneN0+u982T671z5FrvHLnWu0dnuNZLoN+B/P39GT9+PBs2bLCuM5vNbNiwgUmTJnkwZ95h8ODBREVF2ZRPcXEx3333nbV8Jk2aRGFhIenp6dY0X3zxBWazmcTERGua//3vf9TU1FjTrF+/ntjYWHr16tVBZ+M+Sinmzp3Lhx9+yBdffMHgwYNtto8fPx4/Pz+bcsvMzCQrK8um3Hbv3m3zo2n9+vUEBwczcuRIa5qGx7Ck6UrfTbPZTFVVlZSZA5dddhm7d+9mx44d1mXChAnccsst1udSbi0rLS3l4MGD9O3bV75r3ZRc75sn13v75HrvHnKtb55c692jU1zrXRrCT7jsvffeU0ajUb311ltq79696s4771ShoaE2IzB2ZSUlJWr79u1q+/btClBLlixR27dvV0ePHlVK6dPthIaGqo8++kjt2rVLXX/99Xan2xk7dqz67rvv1Ndff62GDRtmM91OYWGhioyMVL/85S/Vnj171HvvvacCAwM77XQ7d999twoJCVEbN260mdKjvLzcmuauu+5S0dHR6osvvlA//PCDmjRpkpo0aZJ1u2VKjyuuuELt2LFDrV27VkVERNid0uPBBx9UGRkZatmyZZ16GpSHH35Ybdq0SR0+fFjt2rVLPfzww0rTNPX5558rpaTMWqvhSLxKSbnZ88ADD6iNGzeqw4cPq2+++UZNmTJFhYeHq9zcXKWUlFl3Jdd7ud47S673zpNrvXvItb5lnfFaL4G+B7z00ksqOjpa+fv7q4kTJ6pvv/3W01nqMF9++aUCmiy33XabUkqfcufxxx9XkZGRymg0qssuu0xlZmbaHKOgoEDNmjVLBQUFqeDgYDV79mxVUlJik2bnzp3qggsuUEajUfXv3189/fTTHXWKbmevvAD15ptvWtNUVFSoe+65R/Xq1UsFBgaq6dOnq5MnT9oc58iRI+rKK69UAQEBKjw8XD3wwAOqpqbGJs2XX36pxowZo/z9/dWQIUNs3qOz+fWvf60GDRqk/P39VUREhLrsssusF36lpMxaq/HFX8qtqRtvvFH17dtX+fv7q/79+6sbb7xRHThwwLpdyqz7kuu9XO+dIdd758m13j3kWt+yznit15RSyrW2AEIIIYQQQgghhPA20kdfCCGEEEIIIYToQiTQF0IIIYQQQgghuhAJ9IUQQgghhBBCiC5EAn0hhBBCCCGEEKILkUBfCCGEEEIIIYToQiTQF0IIIYQQQgghuhAJ9IUQQgghhBBCiC5EAn0hhBBCCCGEEKILkUBfCCGEEEIIIYToQiTQF0K4TV5eHnfffTfR0dEYjUaioqJISkrim2++AUDTNNasWePZTAohhBDCZXKtF6Jz8PV0BoQQXUdKSgrV1dX84x//YMiQIeTk5LBhwwYKCgo8nTUhhBBCuIFc64XoHDSllPJ0JoQQnV9hYSG9evVi48aNTJ48ucn2mJgYjh49an09aNAgjhw5AsBHH33EwoUL2bt3L/369eO2227j0UcfxddXvxepaRqvvPIKH3/8MRs3bqRv3748++yz3HDDDR1ybkIIIYSQa70QnYk03RdCuEVQUBBBQUGsWbOGqqqqJtu///57AN58801Onjxpff3VV19x6623ct9997F3717+9re/8dZbb/GnP/3JZv/HH3+clJQUdu7cyS233MJNN91ERkZG+5+YEEIIIQC51gvRmUiNvhDCbVavXs2cOXOoqKhg3LhxTJ48mZtuuon4+HhAv1v/4YcfMm3aNOs+U6ZM4bLLLmP+/PnWdf/617946KGHOHHihHW/u+66i1dffdWa5txzz2XcuHG88sorHXNyQgghhJBrvRCdhNToCyHcJiUlhRMnTvDxxx8zdepUNm7cyLhx43jrrbcc7rNz504WLVpkrSUICgpizpw5nDx5kvLycmu6SZMm2ew3adIkucsvhBBCdDC51gvROchgfEIItzKZTFx++eVcfvnlPP7449xxxx2kpqbyq1/9ym760tJSFi5cSHJyst1jCSGEEMK7yLVeCO8nNfpCiHY1cuRIysrKAPDz86Ours5m+7hx48jMzGTo0KFNFoOh/l/Ut99+a7Pft99+S1xcXPufgBBCCCGaJdd6IbyP1OgLIdyioKCAGTNm8Otf/5r4+Hh69uzJDz/8wLPPPsv1118P6KPxbtiwgfPPPx+j0UivXr1YsGAB11xzDdHR0dxwww0YDAZ27tzJnj17eOqpp6zHX7VqFRMmTOCCCy7g7bffZuvWrbzxxhueOl0hhBCi25FrvRCdhwzGJ4Rwi6qqKp544gk+//xzDh48SE1NDQMHDmTGjBk88sgjBAQE8MknnzBv3jyOHDlC//79rVPurFu3jkWLFrF9+3b8/PwYMWIEd9xxB3PmzAH0AXqWLVvGmjVr+N///kffvn155plnmDlzpgfPWAghhOhe5FovROchgb4QwuvZG8FXCCGEEF2HXOvF/7dvxzQAADAMw/izLolekc0iWseXH30AAAAIEfoAAAAQYroPAAAAIS76AAAAECL0AQAAIEToAwAAQIjQBwAAgBChDwAAACFCHwAAAEKEPgAAAIQIfQAAAAgZIffiAp/rJeQAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Plot training results\n", "fig, axes = plt.subplots(1, 2, figsize=(12, 5))\n", "\n", "df_train = pd.read_csv(\"metrics_train.csv\")\n", "df_val = pd.read_csv(\"metrics_val.csv\")\n", "\n", "# Plot Loss\n", "axes[0].plot(df_train[\"step\"], df_train[\"mean_loss\"], 'b-o', label='Train Loss', markersize=4, linewidth=1.5)\n", "axes[0].plot(df_val[\"step\"], df_val[\"mean_loss\"], 'r-s', label='Val Loss', markersize=4, linewidth=1.5)\n", "axes[0].set_xlabel('Step')\n", "axes[0].set_ylabel('Loss')\n", "axes[0].set_title('Loss')\n", "axes[0].legend()\n", "axes[0].grid(True, alpha=0.3)\n", "\n", "# Plot MCC Correlation\n", "axes[1].plot(df_train[\"step\"], df_train[\"mean_mcc\"], 'g-o', label='Train MCC', markersize=4, linewidth=1.5)\n", "axes[1].plot(df_val[\"step\"], df_val[\"mean_mcc\"], 'orange', marker='s', label='Val MCC', markersize=4, linewidth=1.5)\n", "axes[1].set_xlabel('Step')\n", "axes[1].set_ylabel('MCC Correlation')\n", "axes[1].set_title('Mean MCC Correlation')\n", "axes[1].legend()\n", "axes[1].grid(True, alpha=0.3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 9. ๐Ÿงช Test evaluation\n", "\n", "Evaluate the fine-tuned model on the held-out test set to assess final performance. This provides an unbiased estimate of how well the model generalizes to unseen genomic regions." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Running test evaluation with 2500 steps (10000 samples)\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Test evaluation: 100%|โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| 2500/2500 [13:34<00:00, 3.07it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "==================================================\n", "Test Set Results\n", "==================================================\n", "\n", "Metrics:\n", " Mean MCC: 0.2215\n", " start_codon/mcc: 0.0177\n", " exon/mcc: 0.4044\n", " intron/mcc: 0.4597\n", " splice_acceptor/mcc: 0.0044\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "# Calculate number of test steps (based on deepspeed pipeline)\n", "num_test_samples = len(test_dataset)\n", "num_test_steps = num_test_samples // config[\"batch_size\"]\n", "print(f\"Running test evaluation with {num_test_steps} steps ({num_test_samples} samples)\")\n", "\n", "# Set model to eval mode\n", "model.eval()\n", "\n", "# Run test evaluation with progress bar\n", "for test_batch in tqdm(test_loader, desc=\"Test evaluation\", total=num_test_steps): \n", " validation_step( \n", " model, \n", " test_batch, \n", " test_metrics,\n", " )\n", " \n", "# Compute final test metrics\n", "test_metrics_dict = test_metrics.compute()\n", "print(\"\\n\" + \"=\"*50)\n", "print(\"Test Set Results\")\n", "print(\"=\"*50)\n", "print(f\"\\nMetrics:\")\n", "print(f\" Mean MCC: {test_metrics_dict['mean/mcc']:.4f}\")\n", "for track_name in bed_elements: \n", " print(f\" {track_name}/mcc: {test_metrics_dict[f'{track_name}/mcc']:.4f}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " ## Test set results\n", "\n", "Mean MCC: 0.2215\n", "\n", "- start_codon/mcc: 0.0177\n", "- exon/mcc: 0.4044\n", "- intron/mcc: 0.4597\n", "- splice_acceptor/mcc: 0.0044" ] } ], "metadata": { "kernelspec": { "display_name": ".venv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.14" } }, "nbformat": 4, "nbformat_minor": 2 }