🎉 75% of content is free forever — Unlock Premium from $10/mo →
CW
💼 Servicesℹ️ About✉️ ContactView Pricing Plansfrom $10

AI for Genomic Medicine

Healthcare AIAI for Genomic Medicine🟢 Free Lesson

Advertisement

AI for Genomic Medicine

AI in Genomic Medicine: From Sequence to DiagnosisDNASequencingBAMAlignmentAIVariant CallPRSRisk ScoreDxDiagnosisRxPrecision Tx4B base pairsReference mapDeep learningPopulation scaleClinical actionTargeted therapyWGS / WESDeepVariantPRS / LDpredClinical Genomics

What is Genomic Medicine?

Genomic medicine uses an individual's genetic information to guide diagnosis, treatment, and disease prevention. AI has revolutionized this field by enabling the analysis of massive genomic datasets that would take human researchers decades to process manually.

Core Concepts

  • Genome: Complete set of DNA (3.2 billion base pairs) in a human cell
  • Variant: A difference from the reference genome at a specific position
  • SNP: Single Nucleotide Polymorphism — the most common type of genetic variation
  • GWAS: Genome-Wide Association Study — links genetic variants to traits/diseases
  • PRS: Polygenic Risk Score — aggregates effects of many variants into one risk number

The Human Genome: Scale and Complexity

Human Genome Scale3.2 Billion Base Pairs~20,000 protein-coding genes | ~1% of genome~4-5 Million VariantsPer individual vs reference~10,000 Disease-CausingKnown pathogenic variantsWGS Cost$100K (2007)$200 (2024)Sequencing Time3 years (2003)~24 hours (2024)AI AccuracyGATK (traditional)DeepVariant (99.7%)

Why AI is Essential

The human genome contains 3.2 billion base pairs. A single Whole Genome Sequencing (WGS) run produces ~90GB of raw data. Traditional variant calling tools (GATK) require:

  • 6+ hours of processing time
  • 40+ parameters to tune
  • Expert bioinformatician oversight

DeepVariant (Google) uses a CNN to classify variants with 99.7% accuracy — outperforming all traditional methods.

Key Mathematical Foundations

Hardy-Weinberg Equilibrium

where and are allele frequencies. This equation tests whether a population is in genetic equilibrium — deviations suggest selection, migration, or non-random mating.

Polygenic Risk Score (PRS)

where is the effect size from GWAS and is the genotype dosage (0, 1, or 2 copies of the risk allele). PRS aggregates thousands of small-effect variants into a single risk predictor.

Phred-Scaled Quality Score

A Phred score of 30 means 1 in 1000 probability of error. Most clinical pipelines require Q ≥ 20 for variant confidence.

Linkage Disequilibrium (LD)

LD measures non-random association between alleles at different loci. High LD means variants are inherited together — critical for PRS calculation and imputation.

Genomic AI Applications

ApplicationMethodAccuracyClinical Utility
Variant CallingDeepVariant99.7%Diagnostic
PRS CalculationLDpred2AUC 0.72Risk stratification
Gene ExpressionEnformerr=0.85Functional annotation
Splice PredictionSpliceAI0.95Pathogenicity
Regulatory EffectsBasset0.82Variant interpretation

Deep Variant Calling with DeepVariant

DeepVariant: CNN Architecture for Variant CallingBAM FileAligned reads+ ReferencePileup ImageRGB tensor100 x 221 x 6Inception-v3Transfer learningPre-trained on ImageNetSoftmaxHET / HOM_REFHOM_ALTVCF OutputGenotype callsQuality scoresHow DeepVariant Works1. Pileup Generation: Reads are piled up at each position. Each base is encoded as RGB channels (read bases, mapping quality, base quality).2. Image Classification: The pileup is treated as an image and classified by a CNN (Inception-v3 pretrained on ImageNet).3. Genotype Call: CNN outputs probabilities for HOM_REF, HET, or HOM_ALT. Phred-scaled confidence scores are computed.

DeepVariant Architecture

DeepVariant converts the variant calling problem into an image classification task:

  1. Pileup Image: Reads are stacked at each genomic position, creating a "pileup image" with RGB-like channels
  2. CNN Classification: An Inception-v3 network (pretrained on ImageNet) classifies the pileup into genotype classes
  3. Genotype Output: Three classes — HOM_REF (homozygous reference), HET (heterozygous), HOM_ALT (homozygous alternate)

Why CNN for Genomics?

CNNs excel at detecting local patterns — just as they find edges in natural images, they find allele frequency patterns in pileup images. The convolutional filters learn to detect:

  • Consistent alternate alleles across reads
  • Strand bias (alleles appearing only on one strand)
  • Base quality gradients
  • Mapping quality distributions
import torch
import torch.nn as nn
import numpy as np

class DeepVariantCNN(nn.Module):
    def __init__(self, num_classes=3):
        super().__init__()
        self.features = nn.Sequential(
            nn.Conv2d(6, 32, kernel_size=5, padding=2),
            nn.BatchNorm2d(32),
            nn.ReLU(),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, kernel_size=3, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.MaxPool2d(2),
            nn.Conv2d(64, 128, kernel_size=3, padding=1),
            nn.BatchNorm2d(128),
            nn.ReLU(),
            nn.AdaptiveAvgPool2d((1, 1))
        )
        self.classifier = nn.Sequential(
            nn.Linear(128, 64),
            nn.ReLU(),
            nn.Dropout(0.3),
            nn.Linear(64, num_classes)
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        return self.classifier(x)

def create_pileup_image(reads, ref_seq, position, window=100):
    """Create a pileup image tensor from aligned reads."""
    channels = 6  # A, C, G, T, mapping_qual, base_qual
    image = np.zeros((channels, window * 2, 3))

    for i, read in enumerate(reads):
        start = max(0, position - window)
        end = min(len(read.query_sequence), position + window)
        for j in range(start, end):
            base = read.query_sequence[j]
            base_idx = {'A': 0, 'C': 1, 'G': 2, 'T': 3}.get(base, -1)
            if base_idx >= 0:
                image[base_idx, j - start, 0] = 1.0
            image[4, j - start, 0] = read.mapping_quality / 60.0
            image[5, j - start, 0] = read.query_qualities[j] / 40.0

    return torch.tensor(image, dtype=torch.float32).unsqueeze(0)

model = DeepVariantCNN(num_classes=3)
dummy_input = torch.randn(1, 6, 200, 3)
output = model(dummy_input)
print(f'DeepVariant output: {output.shape}')  # [1, 3] logits

Polygenic Risk Scores (PRS)

Polygenic Risk Score PipelineGWAS SummaryEffect sizes (β)LD Pred2Bayesian shrinkageGenotype DataIndividual SNPsPRS CalculationWeighted sumRiskScorePRS Methods ComparisonLDpred2:Bayesian method that accounts for LD. Most accurate for European populations (AUC 0.72 for CAD).PRS-CS:Continuous shrinkage prior. Better cross-ancestry performance. Requires individual-level LD reference.SBayesR:Deterministic EM algorithm. Fast computation. Works well with large GWAS summary statistics.Key limitation:PRS accuracy drops significantly in non-European populations due to LD structure differences.

How PRS Works

  1. GWAS Discovery: Large GWAS studies identify thousands of SNPs associated with a disease
  2. Effect Size Estimation: Each SNP's effect size (β) is estimated from the GWAS
  3. LD Adjustment: LDpred2 adjusts for linkage disequilibrium between SNPs using Bayesian shrinkage
  4. Score Computation: PRS = Σ(βᵢ × Gᵢ) for all SNPs in the individual

Clinical Applications of PRS

DiseasePRS AUCTop SNPs UsedClinical Action
Coronary Artery Disease0.72~6.6MStatin eligibility at age 40
Breast Cancer0.68~300KMammography screening age
Type 2 Diabetes0.65~1.2MLifestyle intervention
Alzheimer's Disease0.78~800KEarly cognitive screening
Schizophrenia0.70~100KAntipsychotic selection
import numpy as np

class PRSCalculator:
    def __init__(self, effect_sizes, ld_matrix=None):
        self.effect_sizes = effect_sizes
        self.ld_matrix = ld_matrix

    def compute_prs(self, genotypes):
        """Compute polygenic risk score."""
        if self.ld_matrix is not None:
            ld_inv = np.linalg.inv(self.ld_matrix + 0.01 * np.eye(len(self.ld_matrix)))
            adjusted_effects = ld_inv @ self.effect_sizes
        else:
            adjusted_effects = self.effect_sizes
        return np.sum(adjusted_effects * genotypes)

    def stratify_risk(self, prs_score, population_mean, population_std):
        """Stratify individual into risk categories."""
        z_score = (prs_score - population_mean) / population_std
        percentile = 0.5 * (1 + np.tanh(0.7 * z_score))

        if percentile > 0.95:
            return "Very High Risk", percentile, "Immediate specialist referral"
        elif percentile > 0.80:
            return "High Risk", percentile, "Enhanced screening"
        elif percentile > 0.20:
            return "Average Risk", percentile, "Population-level screening"
        else:
            return "Low Risk", percentile, "Standard screening"

# Example: Coronary Artery Disease PRS
np.random.seed(42)
n_snps = 6600000
effect_sizes = np.random.exponential(0.01, n_snps) * np.random.choice([-1, 1], n_snps)
genotypes = np.random.choice([0, 1, 2], n_snps, p=[0.25, 0.50, 0.25])

calculator = PRSCalculator(effect_sizes)
prs_score = calculator.compute_prs(genotypes)
risk_category, percentile, action = calculator.stratify_risk(prs_score, 0, 1)
print(f'PRS Score: {prs_score:.2f}')
print(f'Risk Category: {risk_category}')
print(f'Percentile: {percentile:.1%}')
print(f'Clinical Action: {action}')

SpliceAI: Predicting Splice Variants

SpliceAI: Deep Learning for Splice Site PredictionDNA SequenceResNet (32 layers)Donor/AcceptorPathogenicitySpliceAI Performance• Accuracy: 0.95 for splice variant classification• Context: Uses 10,000 nucleotides on each side of variant• Impact: ~35% of pathogenic variants affect splicing• Clinical use: Recommended by ACMG for variant interpretation

What is Splicing?

Splicing removes introns (non-coding regions) from pre-mRNA to create mature mRNA. SpliceAI predicts whether a genetic variant disrupts this process.

SpliceAI Architecture

  • Input: 10,000 nucleotides centered on the variant
  • Network: 32-layer ResNet with residual connections
  • Output: Probability of variant affecting donor or acceptor splice sites
  • Accuracy: 0.95 for pathogenicity classification
import torch
import torch.nn as nn

class SpliceAIBlock(nn.Module):
    def __init__(self, channels):
        super().__init__()
        self.conv1 = nn.Conv1d(channels, channels, kernel_size=11, padding=5)
        self.bn1 = nn.BatchNorm1d(channels)
        self.conv2 = nn.Conv1d(channels, channels, kernel_size=11, padding=5)
        self.bn2 = nn.BatchNorm1d(channels)
        self.relu = nn.ReLU()

    def forward(self, x):
        residual = x
        out = self.relu(self.bn1(self.conv1(x)))
        out = self.bn2(self.conv2(out))
        out = self.relu(out + residual)
        return out

class SpliceAI(nn.Module):
    def __init__(self, input_channels=4, num_classes=3):
        super().__init__()
        self.input_conv = nn.Conv1d(input_channels, 32, kernel_size=1)
        self.blocks = nn.Sequential(*[SpliceAIBlock(32) for _ in range(32)])
        self.classifier = nn.Conv1d(32, num_classes, kernel_size=1)

    def forward(self, x):
        x = self.input_conv(x)
        x = self.blocks(x)
        return self.classifier(x)

def one_hot_dna(sequence):
    mapping = {'A': [1,0,0,0], 'C': [0,1,0,0], 'G': [0,0,1,0], 'T': [0,0,0,1]}
    encoded = np.zeros((4, len(sequence)))
    for i, base in enumerate(sequence):
        if base in mapping:
            encoded[:, i] = mapping[base]
    return torch.tensor(encoded, dtype=torch.float32).unsqueeze(0)

# Example: SpliceAI prediction
model = SpliceAI(input_channels=4, num_classes=3)
sequence = "ACGTACGTACGT" * 833  # ~10,000 nucleotides
encoded = one_hot_dna(sequence)
output = model(encoded)
prediction = torch.softmax(output, dim=1)
print(f'SpliceAI output shape: {output.shape}')
print(f'Donor site probability: {prediction[0, 0, 5000]:.3f}')

Enformer: Gene Expression Prediction

Enformer: From Sequence to Gene ExpressionDNA SequenceTransformer200K ContextExpression• Input: 200,000 base pairs (128kb on each side)• Output: Gene expression predictions for 5,000+ genes• Architecture: Transformer with 16 attention heads• Correlation: r=0.85 with experimental gene expression

Enformer is a transformer model that predicts gene expression from DNA sequence. Unlike SpliceAI (which looks at local splice sites), Enformer captures long-range regulatory interactions up to 200kb away.

Why Enformer Matters

  • Regulatory variants: Many disease-causing variants don't change protein structure — they alter gene expression
  • Long-range effects: Enhancers can be 100kb+ away from the gene they regulate
  • Functional annotation: Enformer predictions help prioritize variants for clinical interpretation

Common Clinical Challenges

ChallengeProblemSolution
Variant Interpretation~40% of variants are "Variants of Unknown Significance" (VUS)AI-powered functional prediction (SpliceAI, Enformer)
Population BiasPRS trained on European populations perform poorly in other ancestriesMulti-ancestry GWAS and transfer learning
Data PrivacyGenomic data is uniquely identifiableFederated learning and differential privacy
Clinical ActionabilityMost PRS effects are smallCombine PRS with clinical risk factors

Summary

Key Takeaways

  1. DeepVariant achieves 99.7% accuracy by treating variant calling as image classification
  2. Polygenic Risk Scores aggregate thousands of small-effect variants into clinically actionable risk predictors
  3. SpliceAI predicts whether variants disrupt splicing with 0.95 accuracy
  4. Enformer captures long-range regulatory interactions to predict gene expression from DNA sequence
  5. Population bias remains a critical challenge — PRS must be validated across diverse ancestries

Need Expert Healthcare AI Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement