<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://joseph-rich.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://joseph-rich.com/" rel="alternate" type="text/html" /><updated>2026-07-13T17:32:55+00:00</updated><id>https://joseph-rich.com/feed.xml</id><title type="html">Joseph Rich</title><subtitle>Blog and writing by Joseph Rich on machine learning, bioinformatics, and radiology.</subtitle><author><name>Joseph Rich</name><email>josephrich98@gmail.com</email></author><entry><title type="html">Genomics Is Not NLP: A Field Guide for ML Scientists</title><link href="https://joseph-rich.com/posts/2026/06/genomics-vs-nlp/" rel="alternate" type="text/html" title="Genomics Is Not NLP: A Field Guide for ML Scientists" /><published>2026-06-03T00:00:00+00:00</published><updated>2026-06-03T00:00:00+00:00</updated><id>https://joseph-rich.com/posts/2026/06/genomics-vs-nlp</id><content type="html" xml:base="https://joseph-rich.com/posts/2026/06/genomics-vs-nlp/"><![CDATA[<!-- Generated from posts/2026-06-03-genomics-vs-nlp/main.md by scripts/sync_posts.py. Do not edit here; edit the source and re-commit. -->

<p>Before diving into a discussion of genomics and natural language processing (NLP), we should review a basic primer of molecular biology. For the biologists out there, forgive me for making some oversimplifications. This field is much richer than can be fit in one paragraph! And for the computer scientists out there, there really is more to biology than dissecting frogs and annotating oversaturated printouts of the endoplasmic reticulum.</p>

<h2 id="molecular-biology-primer">Molecular biology primer</h2>
<p>DNA is the “blueprint” of the human body that holds our genetic code. Every cell in a specific organism possesses identical DNA (barring mutations that accumulate over a person‘s life); it is regulation of this DNA that leads to differences between cell types (eg neuron vs. liver cell). DNA is a large molecule comprised of nucleotides — small chemical subunits that can be abstracted as “letters”. These four nucleotides are adenine (A), cytosine (C), guanine (G), and thymine (T). DNA is packaged into chromosomes. Humans have 46 chromosomes and are diploid — our chromosomes come in pairs, where we inherit half of our chromosomes from our mom and half from our dad. The chromosomes are numbered 1-22 (autosomes — descending order of length) and X/Y (sex chromosomes). The human genome contains ~3.2 billion nucleotides in total. The central dogma of molecular biology describes the fundamental role of DNA: DNA is transcribed into messenger RNA (mRNA), a form of ribonucleic acid (RNA), and mRNA is translated into protein. Only ~1–2% of DNA encodes mRNA; the rest of DNA is involved in regulation of gene expression, transcription into non-coding RNA, structural roles (such as centromeres and telomeres), has uncharacterized function, or may serve no function at all. mRNA is also comprised of nucleotides like DNA, and is grouped into triplets called codons during translation, where each codon encodes an amino acid. Amino acids are the subunit of proteins. There are 20 amino acids (the memorization of which is a rite of passage for every biochemistry student), each characterized by different chemical structures and properties (e.g., polarity, acidity, size, disulfide-bond potential, phosphorylation potential). As there are \(4^{3} = 64\) possible nucleotide combinations in a codon, the existence of only 20 amino acids implies that the genetic code is degenerate: 1-4 codons will encode the same amino acid. Proteins do the work of the cell — they catalyze reactions, communicate signals, transport molecules, build structures, and much more. Effectively, DNA is relevant only insofar that it encodes mRNA, which itself encodes protein — DNA molecules themselves serve essentially no role in the human body outside of this function.</p>

<h2 id="dna-and-nlp-similarities-and-differences">DNA and NLP similarities and differences</h2>
<p>At first glance, genomics looks like a direct analog to natural language processing. And in some respects, it is. Both the English language and the genetic code share a small finite alphabet — English has 26 letters, and DNA has four nucleotides (ACGT). Both have an exponentially large number of units that can be formed by unique permutations of this alphabet — English groups letters into words, and DNA groups nucleotides into genes. The two vocabulary sizes are comparable — there are ~20,000 words in the English language and ~20,000 genes encoded in the human body.</p>

<p>But there are also some crucial differences that must be addressed. For instance, English words are often within a narrow length range of 2 to 10 characters. Genes, however, range anywhere between 1,000 to 1,000,000 nucleotides. Changing an English sentence with even a single letter substitution is guaranteed to change the meaning of a sentence, as the similarity in meaning between words holds minimal correlation with similarity in structure. With DNA, some base substitutions are completely invisible, some have modest effects on outcome, and some are catastrophic. Mutations outside gene-coding regions nearly always have no effect. Mutations within gene-coding regions generally only have an effect if they cause a change in amino acid, and especially if they significantly change the chemical properties of the amino acid. Mutations are significant when they result in a change in protein folding structure, which can lead to protein instability or loss of ligand specificity.</p>

<p>DNA and English text also have different numbers of hierarchical groupings. As discussed earlier, nucleotides can be thought of as analogous to letters, and genes can be thought of as analogous to words. Carrying forward this analogy, each chromosome or entire human genome could be thought of as analogous to a document. However, there is no analogue to a “sentence” for DNA. Each “document” would simply read as a list of words used exactly one time, likely ordered based on their position in the genome — an order that has little functional significance. Or, perhaps, different conventions can be applied to DNA. For instance, an alternative representation would be to represent DNA codons as letters, rather than individual nucleotides, which would create a 64 character alphabet rather than a four character alphabet. This would pose its own challenges, however, such as the degeneracy of the DNA code (up to four codons can encode the same amino acid, with the last nucleotide often being flexible) and the questionable relevance of codon-tokenization in non-coding regions (where transcription does not occur). Or, alternatively yet again, if we stick with nucleotides as letters, then these codons or other k-mers (subsequences of length k) could represent words, and genes could represent sentences. But this still runs into the problem of high “sentence” similarity and “document” structure.</p>

<p>Any two English sentences or documents will contain vastly different structure. Some documents might be one sentence, while others might be hundreds of pages long. The lengths of sentences and vocabulary used can vary widely. For text classification, such as sentiment analysis, the entire body of text must be analyzed, as each portion can contribute to the meaning of the text as a whole. In contrast, DNA has a highly consistent structure between individuals. Any two individuals are ~99.9% identical. Of the ~3.2 billion nucleotides in the human genome, only ~10 million nucleotides have substantial (common) variation across the human population<sup><a href="#ref-auton2015" role="doc-biblioref">1</a></sup>. This shallow diversity is due to a population bottleneck approximately 50,000 years ago which restricted our genetic ancestors to approximately 10,000 individuals. Most of these variants have a most common form, which can be collected into what is called a reference genome<sup id="fnref:refgenome"><a href="#fn:refgenome" class="footnote" rel="footnote" role="doc-noteref">1</a></sup>. In addition to these ~10 million sites of possible variation, each person has ~70 <em>de novo</em> mutations that are specific to them<sup><a href="#ref-kong2012" role="doc-biblioref">3</a></sup>, and any given cell may accumulate up to several thousand somatic mutations over the person’s life<sup><a href="#ref-blokzijl2016" role="doc-biblioref">4</a></sup>. This means that any artificial intelligence (AI) model that ingests the entire 3.2 billion nucleotide sequence is exerting a lot of unnecessary energy, as most sites are essentially guaranteed to match the reference genome. There are benefits to working with raw DNA sequences as well. The simplicity of the input data, the direct analog to natural language, and the ability to maintain the full context of DNA that is especially relevant for tasks such as mutation effect prediction. But this trade-off is unique to genomics data and should be intentionally considered by the machine learning practitioner.</p>

<p><img src="/images/posts/2026-06-03-genomics-vs-nlp/corpus_redundancy_a.png" alt="**Figure 1**" /></p>

<p><strong>Figure 1</strong>: Two members of the human species are near-duplicates. The fraction of positions that differ between two sequences, on a log scale: two humans differ at only ~\(10^{-3}\) of positions and human versus chimpanzee at ~\(10^{-2}\), whereas two random DNA strings differ at \(0.75\) and two unrelated English documents at essentially every position. The within-species genomic “corpus” is roughly a thousandfold more redundant than text.</p>

<h2 id="sources-of-genomic-data">Sources of genomic data</h2>
<p>Genomics data can come from multiple sources. These include whole genome sequencing (WGS; sequencing the entire genome), whole exome sequencing (WES; sequencing only the gene-encoding regions of the genome), bulk RNA-sequencing (bulk RNA-seq; sequencing all expressed RNA), and single-cell RNA sequencing (scRNA-seq; sequencing RNA at single-cell resolution). These sequencing machines have ~99–99.9% per-base accuracy. When only mildly confident about the detected nucleotide, the machine may report a lowercase letter. When entirely unconfident, the machine may report an “N”. How to handle these additional characters is a design decision in any tokenizer.</p>

<p>The protocol to sequence genomic data depends on the assay and technology, but they all share the isolation of genetic material, decomposition into small regions generally between 75-150 nucleotides (reads), amplification by polymerase chain reaction (PCR), and sequence readout. The reads (FASTQ file) are usually mapped to the reference genome (FASTA file) to produce a genome alignment (BAM, or Binary Alignment Map, file). For DNA, the variants can be extracted in a VCF (Variant Call Format) file. For RNA data, the count of each gene can be stored in a count matrix, where each row represents a sample (bulk RNA-seq) or cell (single-cell RNA-seq), and each column represents a gene.</p>

<h2 id="dna-rna-and-protein">DNA, RNA, and protein</h2>
<p>I mentioned earlier that proteins are the real molecule of interest in the human body, so why do we measure RNA at all rather than measuring protein directly? One of the main reasons is that protein sequencing technology has simply lagged behind nucleotide sequencing technology in cost. The underlying assumption is that RNA levels correlate strongly with protein levels, so the former can be used as a proxy for the latter. However, this may be a stronger assumption than most would like to believe. Across many careful studies, the correlation between a gene’s mRNA level and its protein level is moderate at best — typically a Spearman \(\rho\) in the 0.4-0.6 range, and lower still when you look at changes over time rather than steady-state across genes. Schwanhäusser and colleagues found mRNA explained well under half the variance in protein abundance<sup><a href="#ref-schwanhausser2011" role="doc-biblioref">5</a></sup>; Vogel and Marcotte, Liu, Beyer and Aebersold, and Buccitelli and Selbach all converge on the same message — translation rates, protein half-lives, and post-translational regulation drive a large share of protein levels that mRNA simply does not see<sup><a href="#ref-vogel2012" role="doc-biblioref">6</a>–<a href="#ref-buccitelli2020" role="doc-biblioref">8</a></sup>. Edfors and colleagues showed the relationship is gene-specific<sup><a href="#ref-edfors2016" role="doc-biblioref">9</a></sup>: each gene has roughly its own mRNA-to-protein conversion factor, so a single global model is wrong per gene. Figure 2 shows the consequence in real data — even at the optimistic end of that range, knowing a gene’s mRNA leaves its protein level uncertain across a wide band.</p>

<p><img src="/images/posts/2026-06-03-genomics-vs-nlp/proxy_scatter.png" alt="**Figure 2**" /></p>

<p><strong>Figure 2</strong>: mRNA is a noisy proxy for protein. Real per-gene mRNA and protein copy numbers in mouse NIH3T3 fibroblasts (Schwanhäusser et al. 2011; \(n=4{,}309\) genes; Pearson \(r=0.62\) on log abundances). The red line is the best fit; even so, protein scatters across two to three orders of magnitude at any given mRNA level, because translation and degradation are not observed in the RNA.</p>

<h2 id="popular-datasets">Popular datasets</h2>
<p>Below is a set of some of the most popular public datasets in genomics. File sizes can be quite large — for WGS, FASTQ files are often around 100-200GB, BAM files are 30-100GB, and VCF files are 1-10GB. However, as described earlier, much of this information represents redundancy with the reference genome, and individuals are often the unit of interest when training AI models rather than nucleotides, so cohort sizes in the thousands-hundreds of thousands range is often fairly small for modern AI. Additionally, most data are collected on healthy individuals or individuals with cancer, so it is difficult to study other diseases because public datasets will be quite small (if available at all). And any data collected from a single institution or region will have batch effects, limiting generalizability to other populations.</p>

<table>
  <thead>
    <tr>
      <th>Resource</th>
      <th>What it is</th>
      <th>Assay</th>
      <th>Reported scale</th>
      <th>Ref.</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>1000 Genomes</strong></td>
      <td>Reference catalogue of human variation</td>
      <td>WGS, WES</td>
      <td>2,504 individuals, 26 populations; ~88M variants</td>
      <td><sup><a href="#ref-auton2015" role="doc-biblioref">1</a></sup></td>
    </tr>
    <tr>
      <td><strong>gnomAD</strong></td>
      <td>Aggregated exomes + genomes; constraint metrics</td>
      <td>WES, WGS</td>
      <td>125,748 exomes + 15,708 genomes (v2)</td>
      <td><sup><a href="#ref-karczewski2020" role="doc-biblioref">10</a></sup></td>
    </tr>
    <tr>
      <td><strong>UK Biobank</strong></td>
      <td>Population cohort, genotype + deep phenotype</td>
      <td>Array, WES, WGS</td>
      <td>~500,000 participants</td>
      <td><sup><a href="#ref-bycroft2018" role="doc-biblioref">11</a></sup></td>
    </tr>
    <tr>
      <td><strong>TCGA</strong></td>
      <td>Pan-cancer tumor/normal multi-omics</td>
      <td>WXS, WGS, bulk RNA-seq, WSI</td>
      <td>~11,000 tumors, 33 cancer types</td>
      <td><sup><a href="#ref-weinstein2013" role="doc-biblioref">12</a></sup></td>
    </tr>
    <tr>
      <td><strong>GTEx</strong></td>
      <td>Genetic regulation of expression across tissues</td>
      <td>bulk RNA-seq, WGS</td>
      <td>17,382 RNA-seq samples, 54 tissues, 948 donors</td>
      <td><sup><a href="#ref-gtex2020" role="doc-biblioref">13</a></sup></td>
    </tr>
    <tr>
      <td><strong>ENCODE</strong></td>
      <td>Functional/regulatory element annotation</td>
      <td>ChIP-seq, ATAC, DNase, RNA-seq</td>
      <td>Genome-wide assays across many cell types</td>
      <td><sup><a href="#ref-encode2012" role="doc-biblioref">14</a></sup></td>
    </tr>
    <tr>
      <td><strong>GENCODE</strong></td>
      <td>Reference gene/transcript annotation</td>
      <td>Annotation</td>
      <td>~20,000 coding genes; &gt;200,000 transcripts</td>
      <td><sup><a href="#ref-frankish2021" role="doc-biblioref">15</a></sup></td>
    </tr>
    <tr>
      <td><strong>Geuvadis</strong></td>
      <td>RNA-seq paired to 1000 Genomes genotypes</td>
      <td>bulk RNA-seq</td>
      <td>462 individuals, 5 populations</td>
      <td><sup><a href="#ref-lappalainen2013" role="doc-biblioref">16</a></sup></td>
    </tr>
    <tr>
      <td><strong>Tabula Sapiens</strong></td>
      <td>Multi-organ single-cell atlas</td>
      <td>scRNA-seq</td>
      <td>~500,000 cells, ~24 tissues</td>
      <td><sup><a href="#ref-tabulasapiens2022" role="doc-biblioref">17</a></sup></td>
    </tr>
    <tr>
      <td><strong>CZ CELLxGENE Discover</strong></td>
      <td>Aggregated, standardized single-cell expression atlas</td>
      <td>scRNA-seq</td>
      <td>&gt;90M cells across thousands of datasets</td>
      <td><sup><a href="#ref-cellxgene2023" role="doc-biblioref">18</a></sup></td>
    </tr>
    <tr>
      <td><strong>Human Cell Atlas</strong></td>
      <td>Cross-tissue single-cell reference of every cell type</td>
      <td>scRNA-seq</td>
      <td>Tens of millions of cells across many tissues</td>
      <td><sup><a href="#ref-regev2017" role="doc-biblioref">19</a></sup></td>
    </tr>
    <tr>
      <td><strong>10x Genomics Datasets</strong></td>
      <td>Vendor-released public single-cell/-nucleus datasets</td>
      <td>scRNA-seq</td>
      <td>Hundreds of datasets across tissues</td>
      <td><sup><a href="#ref-zheng2017" role="doc-biblioref">20</a></sup></td>
    </tr>
    <tr>
      <td><strong>T2T-CHM13</strong></td>
      <td>First complete (telomere-to-telomere) human genome</td>
      <td>WGS (long-read)</td>
      <td>1 gapless assembly</td>
      <td><sup><a href="#ref-nurk2022" role="doc-biblioref">21</a></sup></td>
    </tr>
  </tbody>
</table>

<p><em>Assay abbreviations: WGS = whole-genome sequencing; WES/WXS = whole-exome sequencing; bulk RNA-seq = bulk RNA sequencing; scRNA-seq = single-cell RNA sequencing; Array = genotyping microarray; WSI = whole-slide imaging; ChIP-seq = chromatin immunoprecipitation sequencing; ATAC = assay for transposase-accessible chromatin; DNase = DNase I hypersensitivity sequencing.</em></p>

<p>Two structural problems run underneath these numbers.</p>

<h2 id="how-real-models-approach-this">How real models approach this</h2>
<p>We’ve talked a lot about how genetic material can be represented as text for AI models. But what is actually done in practice? Here are a few notable examples.</p>
<ul>
  <li><strong>AlphaFold2</strong> (Jumper et al.<sup><a href="#ref-jumper2021" role="doc-biblioref">22</a></sup>) predicts protein three-dimensional (3D) structure from amino-acid sequence at near-experimental accuracy — arguably the field’s defining success. It takes a protein’s amino-acid sequence, together with a multiple-sequence alignment of evolutionarily related proteins and any available structural templates, and predicts the 3D coordinates of every atom. The sequence is treated as a string over the fixed 20-letter amino-acid alphabet — each residue is mapped to a learned embedding rather than an arbitrary text token — and much of the biological signal comes from the MSA, whose column-wise evolutionary covariation encodes which residues are likely to contact one another in 3D. Protein folding is a problem that possesses multiple attributes that make it an ideal candidate for AI. The 3D structure depends entirely on the discrete amino acid sequence itself, without dependencies from other parts of the genome or cell state broadly. There are over 200,000 experimentally determined protein structures with resolved amino-acid sequences across humans and model organisms<sup><a href="#ref-berman2000" role="doc-biblioref">23</a></sup>, representing a dataset that is large enough for supervised learning. And amino acids have biochemical properties that enable logical verification of predicted results to an extent.</li>
  <li><strong>Enformer</strong><sup><a href="#ref-avsec2021" role="doc-biblioref">24</a></sup> and <strong>AlphaGenome</strong><sup><a href="#ref-avsec2025" role="doc-biblioref">25</a></sup> attack the <em>cis</em>-regulatory problem head-on, predicting expression and chromatin readouts from sequence across ~200 kilobases and up to 1 megabase windows respectively. They are the state of the art on long-range <em>cis</em> effects — and structurally blind to <em>trans</em> regulation that acts through diffusible proteins or other chromosomes. Both take a one-hot-encoded DNA sequence — a long genomic window centered on the region of interest — and predict thousands of functional genomic and epigenomic tracks (expression, chromatin accessibility, histone marks, and more) along that window. Here the alphabet is simply the four DNA bases (A/C/G/T): each position becomes a 4-dimensional one-hot vector, so — unlike a text model with a learned subword vocabulary — there is no tokenization step at all, and biology enters through the fixed base alphabet and the reverse-complement symmetry the architectures are built to respect (a sequence and its complementary strand should give the same prediction).</li>
  <li><strong>DNABERT</strong><sup><a href="#ref-ji2021" role="doc-biblioref">26</a></sup>, the <strong>Nucleotide Transformer</strong><sup><a href="#ref-dallatorre2024" role="doc-biblioref">27</a></sup>, and <strong>Evo</strong><sup><a href="#ref-nguyen2024" role="doc-biblioref">28</a></sup> are DNA “language models” — masked or autoregressive pre-training over genomic sequence, transferred to downstream tasks. Each tokenizes raw nucleotide sequence — overlapping k-mers for DNABERT, fixed non-overlapping k-mer tokens for the Nucleotide Transformer, and single-nucleotide (byte-level) tokens for Evo — and learns representations by predicting masked or next tokens over large genomic corpora. The vocabulary is built from the four nucleotides rather than natural-language words, and the differing tokenizations are attempts to package that four-letter alphabet into biologically meaningful units: k-mers approximate short motifs or codon-like chunks, while single-base tokens keep every nucleotide addressable at the cost of longer sequences.</li>
  <li><strong>scGPT</strong><sup><a href="#ref-cui2024" role="doc-biblioref">29</a></sup> and <strong>Geneformer</strong><sup><a href="#ref-theodoris2023" role="doc-biblioref">30</a></sup> bring the foundation-model recipe to single-cell transcriptomics, learning representations of cell state from large RNA-expression atlases. These approaches do not take in raw sequencing reads as input, but rather the processed count matrices. Consequently the “alphabet” is not sequence at all but the roughly 20,000 genes — each gene is a token, and its expression level is encoded either by binning the count into discrete value tokens (scGPT) or by ranking genes from most to least expressed within a cell (Geneformer), so the biology is carried by which genes are on and their relative levels rather than by any letter sequence.</li>
</ul>

<h2 id="conclusion">Conclusion</h2>
<p>There have been exciting developments in genomics AI, and there is much to be done moving forward. ~40% of variants in cancer cases are still classified as variants of unknown significance<sup><a href="#ref-mellgard2024" role="doc-biblioref">31</a></sup>. When analyzing a cancer patient’s mutations, it is still often impossible to distinguish the driver mutation from passenger mutations. The role of genomics outside of cancer and well-characterized genes characterized by single mutation/gene events is minimal in clinical practice. A single human scRNA-seq experiment often has thousands of cells, and tens of thousands of genes. In an atlas comprised of dozens or hundreds of datasets, there can be millions of cells, with various sources of batch effects. Continuing to develop models that can make sense of these data will be critical for advancing genomics research.</p>

<h2 id="references">References</h2>

<div id="refs" class="references csl-bib-body" role="list">
<div id="ref-auton2015" class="csl-entry" role="listitem">
<div class="csl-left-margin">1. </div><div class="csl-right-inline"><span class="nocase">Auton A, Brooks LD, Durbin RM, et al.</span> A global reference for human genetic variation. <em>Nature</em>. 2015;526(7571):68-74. doi:<a href="https://doi.org/10.1038/nature15393">10.1038/nature15393</a></div>
</div>
<div id="ref-liao2023" class="csl-entry" role="listitem">
<div class="csl-left-margin">2. </div><div class="csl-right-inline"><span class="nocase">Liao W-W, Asri M, Ebler J, et al.</span> A draft human pangenome reference. <em>Nature</em>. 2023;617(7960):312-324. doi:<a href="https://doi.org/10.1038/s41586-023-05896-x">10.1038/s41586-023-05896-x</a></div>
</div>
<div id="ref-kong2012" class="csl-entry" role="listitem">
<div class="csl-left-margin">3. </div><div class="csl-right-inline"><span class="nocase">Kong A, Frigge ML, Masson G, et al.</span> Rate of de novo mutations and the importance of father’s age to disease risk. <em>Nature</em>. 2012;488(7412):471-475. doi:<a href="https://doi.org/10.1038/nature11396">10.1038/nature11396</a></div>
</div>
<div id="ref-blokzijl2016" class="csl-entry" role="listitem">
<div class="csl-left-margin">4. </div><div class="csl-right-inline"><span class="nocase">Blokzijl F, Ligt J de, Jager M, et al.</span> Tissue-specific mutation accumulation in human adult stem cells during life. <em>Nature</em>. 2016;538(7624):260-264. doi:<a href="https://doi.org/10.1038/nature19768">10.1038/nature19768</a></div>
</div>
<div id="ref-schwanhausser2011" class="csl-entry" role="listitem">
<div class="csl-left-margin">5. </div><div class="csl-right-inline"><span class="nocase">Schwanhäusser B, Busse D, Li N, et al.</span> Global quantification of mammalian gene expression control. <em>Nature</em>. 2011;473(7347):337-342. doi:<a href="https://doi.org/10.1038/nature10098">10.1038/nature10098</a></div>
</div>
<div id="ref-vogel2012" class="csl-entry" role="listitem">
<div class="csl-left-margin">6. </div><div class="csl-right-inline">Vogel C, Marcotte EM. Insights into the regulation of protein abundance from proteomic and transcriptomic analyses. <em>Nature Reviews Genetics</em>. 2012;13(4):227-232. doi:<a href="https://doi.org/10.1038/nrg3185">10.1038/nrg3185</a></div>
</div>
<div id="ref-liu2016" class="csl-entry" role="listitem">
<div class="csl-left-margin">7. </div><div class="csl-right-inline">Liu Y, Beyer A, Aebersold R. On the dependency of cellular protein levels on <span class="nocase">mRNA</span> abundance. <em>Cell</em>. 2016;165(3):535-550. doi:<a href="https://doi.org/10.1016/j.cell.2016.03.014">10.1016/j.cell.2016.03.014</a></div>
</div>
<div id="ref-buccitelli2020" class="csl-entry" role="listitem">
<div class="csl-left-margin">8. </div><div class="csl-right-inline">Buccitelli C, Selbach M. <span class="nocase">mRNAs</span>, proteins and the emerging principles of gene expression control. <em>Nature Reviews Genetics</em>. 2020;21(10):630-644. doi:<a href="https://doi.org/10.1038/s41576-020-0258-4">10.1038/s41576-020-0258-4</a></div>
</div>
<div id="ref-edfors2016" class="csl-entry" role="listitem">
<div class="csl-left-margin">9. </div><div class="csl-right-inline"><span class="nocase">Edfors F, Danielsson F, Hallström BM, et al.</span> Gene-specific correlation of <span>RNA</span> and protein levels in human cells and tissues. <em>Molecular Systems Biology</em>. 2016;12(10):883. doi:<a href="https://doi.org/10.15252/msb.20167144">10.15252/msb.20167144</a></div>
</div>
<div id="ref-karczewski2020" class="csl-entry" role="listitem">
<div class="csl-left-margin">10. </div><div class="csl-right-inline"><span class="nocase">Karczewski KJ, Francioli LC, Tiao G, et al.</span> The mutational constraint spectrum quantified from variation in 141,456 humans. <em>Nature</em>. 2020;581(7809):434-443. doi:<a href="https://doi.org/10.1038/s41586-020-2308-7">10.1038/s41586-020-2308-7</a></div>
</div>
<div id="ref-bycroft2018" class="csl-entry" role="listitem">
<div class="csl-left-margin">11. </div><div class="csl-right-inline"><span class="nocase">Bycroft C, Freeman C, Petkova D, et al.</span> The <span>UK</span> <span>Biobank</span> resource with deep phenotyping and genomic data. <em>Nature</em>. 2018;562(7726):203-209. doi:<a href="https://doi.org/10.1038/s41586-018-0579-z">10.1038/s41586-018-0579-z</a></div>
</div>
<div id="ref-weinstein2013" class="csl-entry" role="listitem">
<div class="csl-left-margin">12. </div><div class="csl-right-inline"><span class="nocase">Weinstein JN, Collisson EA, Mills GB, et al.</span> The <span>Cancer</span> <span>Genome</span> <span>Atlas</span> <span>Pan-Cancer</span> analysis project. <em>Nature Genetics</em>. 2013;45(10):1113-1120. doi:<a href="https://doi.org/10.1038/ng.2764">10.1038/ng.2764</a></div>
</div>
<div id="ref-gtex2020" class="csl-entry" role="listitem">
<div class="csl-left-margin">13. </div><div class="csl-right-inline">GTEx Consortium. The <span>GTEx</span> <span>Consortium</span> atlas of genetic regulatory effects across human tissues. <em>Science</em>. 2020;369(6509):1318-1330. doi:<a href="https://doi.org/10.1126/science.aaz1776">10.1126/science.aaz1776</a></div>
</div>
<div id="ref-encode2012" class="csl-entry" role="listitem">
<div class="csl-left-margin">14. </div><div class="csl-right-inline">ENCODE Project Consortium. An integrated encyclopedia of <span>DNA</span> elements in the human genome. <em>Nature</em>. 2012;489(7414):57-74. doi:<a href="https://doi.org/10.1038/nature11247">10.1038/nature11247</a></div>
</div>
<div id="ref-frankish2021" class="csl-entry" role="listitem">
<div class="csl-left-margin">15. </div><div class="csl-right-inline"><span class="nocase">Frankish A, Diekhans M, Jungreis I, et al.</span> <span>GENCODE</span> 2021. <em>Nucleic Acids Research</em>. 2021;49(D1):D916-D923. doi:<a href="https://doi.org/10.1093/nar/gkaa1087">10.1093/nar/gkaa1087</a></div>
</div>
<div id="ref-lappalainen2013" class="csl-entry" role="listitem">
<div class="csl-left-margin">16. </div><div class="csl-right-inline"><span class="nocase">Lappalainen T, Sammeth M, Friedländer MR, et al.</span> Transcriptome and genome sequencing uncovers functional variation in humans. <em>Nature</em>. 2013;501(7468):506-511. doi:<a href="https://doi.org/10.1038/nature12531">10.1038/nature12531</a></div>
</div>
<div id="ref-tabulasapiens2022" class="csl-entry" role="listitem">
<div class="csl-left-margin">17. </div><div class="csl-right-inline">Tabula Sapiens Consortium. The <span>Tabula</span> <span>Sapiens</span>: A multiple-organ, single-cell transcriptomic atlas of humans. <em>Science</em>. 2022;376(6594):eabl4896. doi:<a href="https://doi.org/10.1126/science.abl4896">10.1126/science.abl4896</a></div>
</div>
<div id="ref-cellxgene2023" class="csl-entry" role="listitem">
<div class="csl-left-margin">18. </div><div class="csl-right-inline"><span class="nocase">Abdulla S, Aevermann B, Assis P, et al.</span> <span>CZ</span> <span>CELLxGENE</span> <span>Discover</span>: A single-cell data platform for scalable exploration, analysis and modeling of aggregated data. <em>bioRxiv</em>. Published online 2023. doi:<a href="https://doi.org/10.1101/2023.10.30.563174">10.1101/2023.10.30.563174</a></div>
</div>
<div id="ref-regev2017" class="csl-entry" role="listitem">
<div class="csl-left-margin">19. </div><div class="csl-right-inline"><span class="nocase">Regev A, Teichmann SA, Lander ES, et al.</span> The <span>Human</span> <span>Cell</span> <span>Atlas</span>. <em>eLife</em>. 2017;6:e27041. doi:<a href="https://doi.org/10.7554/eLife.27041">10.7554/eLife.27041</a></div>
</div>
<div id="ref-zheng2017" class="csl-entry" role="listitem">
<div class="csl-left-margin">20. </div><div class="csl-right-inline"><span class="nocase">Zheng GXY, Terry JM, Belgrader P, et al.</span> Massively parallel digital transcriptional profiling of single cells. <em>Nature Communications</em>. 2017;8:14049. doi:<a href="https://doi.org/10.1038/ncomms14049">10.1038/ncomms14049</a></div>
</div>
<div id="ref-nurk2022" class="csl-entry" role="listitem">
<div class="csl-left-margin">21. </div><div class="csl-right-inline"><span class="nocase">Nurk S, Koren S, Rhie A, et al.</span> The complete sequence of a human genome. <em>Science</em>. 2022;376(6588):44-53. doi:<a href="https://doi.org/10.1126/science.abj6987">10.1126/science.abj6987</a></div>
</div>
<div id="ref-jumper2021" class="csl-entry" role="listitem">
<div class="csl-left-margin">22. </div><div class="csl-right-inline"><span class="nocase">Jumper J, Evans R, Pritzel A, et al.</span> Highly accurate protein structure prediction with <span>AlphaFold</span>. <em>Nature</em>. 2021;596(7873):583-589. doi:<a href="https://doi.org/10.1038/s41586-021-03819-2">10.1038/s41586-021-03819-2</a></div>
</div>
<div id="ref-berman2000" class="csl-entry" role="listitem">
<div class="csl-left-margin">23. </div><div class="csl-right-inline"><span class="nocase">Berman HM, Westbrook J, Feng Z, et al.</span> The <span>Protein</span> <span>Data</span> <span>Bank</span>. <em>Nucleic Acids Research</em>. 2000;28(1):235-242. doi:<a href="https://doi.org/10.1093/nar/28.1.235">10.1093/nar/28.1.235</a></div>
</div>
<div id="ref-avsec2021" class="csl-entry" role="listitem">
<div class="csl-left-margin">24. </div><div class="csl-right-inline"><span class="nocase">Avsec Ž, Agarwal V, Visentin D, et al.</span> Effective gene expression prediction from sequence by integrating long-range interactions. <em>Nature Methods</em>. 2021;18(10):1196-1203. doi:<a href="https://doi.org/10.1038/s41592-021-01252-x">10.1038/s41592-021-01252-x</a></div>
</div>
<div id="ref-avsec2025" class="csl-entry" role="listitem">
<div class="csl-left-margin">25. </div><div class="csl-right-inline"><span class="nocase">Avsec Ž, Latysheva N, Cheng J, et al.</span> <span>AlphaGenome</span>: Advancing regulatory variant effect prediction with a unified <span>DNA</span> sequence model. <em>bioRxiv</em>. Published online 2025. doi:<a href="https://doi.org/10.1101/2025.06.25.661532">10.1101/2025.06.25.661532</a></div>
</div>
<div id="ref-ji2021" class="csl-entry" role="listitem">
<div class="csl-left-margin">26. </div><div class="csl-right-inline">Ji Y, Zhou Z, Liu H, Davuluri RV. <span>DNABERT</span>: Pre-trained <span>Bidirectional</span> <span>Encoder</span> <span>Representations</span> from <span>Transformers</span> model for <span class="nocase">DNA-language</span> in genome. <em>Bioinformatics</em>. 2021;37(15):2112-2120. doi:<a href="https://doi.org/10.1093/bioinformatics/btab083">10.1093/bioinformatics/btab083</a></div>
</div>
<div id="ref-dallatorre2024" class="csl-entry" role="listitem">
<div class="csl-left-margin">27. </div><div class="csl-right-inline"><span class="nocase">Dalla-Torre H, Gonzalez L, Mendoza-Revilla J, et al.</span> Nucleotide <span>Transformer</span>: Building and evaluating robust foundation models for human genomics. <em>Nature Methods</em>. 2024;22(2):287-297. doi:<a href="https://doi.org/10.1038/s41592-024-02523-z">10.1038/s41592-024-02523-z</a></div>
</div>
<div id="ref-nguyen2024" class="csl-entry" role="listitem">
<div class="csl-left-margin">28. </div><div class="csl-right-inline"><span class="nocase">Nguyen E, Poli M, Durrant MG, et al.</span> Sequence modeling and design from molecular to genome scale with <span>Evo</span>. <em>Science</em>. 2024;386(6723):eado9336. doi:<a href="https://doi.org/10.1126/science.ado9336">10.1126/science.ado9336</a></div>
</div>
<div id="ref-cui2024" class="csl-entry" role="listitem">
<div class="csl-left-margin">29. </div><div class="csl-right-inline"><span class="nocase">Cui H, Wang C, Maan H, et al.</span> <span class="nocase">scGPT</span>: Toward building a foundation model for single-cell multi-omics using generative <span>AI</span>. <em>Nature Methods</em>. 2024;21(8):1470-1480. doi:<a href="https://doi.org/10.1038/s41592-024-02201-0">10.1038/s41592-024-02201-0</a></div>
</div>
<div id="ref-theodoris2023" class="csl-entry" role="listitem">
<div class="csl-left-margin">30. </div><div class="csl-right-inline"><span class="nocase">Theodoris CV, Xiao L, Chopra A, et al.</span> Transfer learning enables predictions in network biology. <em>Nature</em>. 2023;618(7965):616-624. doi:<a href="https://doi.org/10.1038/s41586-023-06139-9">10.1038/s41586-023-06139-9</a></div>
</div>
<div id="ref-mellgard2024" class="csl-entry" role="listitem">
<div class="csl-left-margin">31. </div><div class="csl-right-inline"><span class="nocase">Mellgard GS, Atabek Z, LaRose M, et al.</span> Variants of uncertain significance in precision oncology: Nuance or nuisance? <em>The Oncologist</em>. 2024;29(8):641-644. doi:<a href="https://doi.org/10.1093/oncolo/oyae135">10.1093/oncolo/oyae135</a></div>
</div>
</div>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:refgenome">
      <p>The human reference genome disproportionately represents individuals of European ancestry, as these are the most widely available genomic data. Recent efforts have been made to create pan-genomes that better represent global diversity, most notably the Human Pangenome Reference Consortium’s draft reference assembled from 47 genetically diverse individuals<sup><a href="#ref-liao2023" role="doc-biblioref">2</a></sup>. <a href="#fnref:refgenome" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Joseph Rich</name><email>josephrich98@gmail.com</email></author><category term="machine learning" /><category term="genomics" /><category term="transcriptomics" /><category term="natural language processing" /><category term="computational biology" /><category term="bioinformatics" /><summary type="html"><![CDATA[A field guide for ML scientists working in genomics. How is genomics similar to NLP, and how is it different? This post covers a molecular biology primer, some biological context that makes genomics data different from text, some widely-used genomics datasets, and some popular genomics AI models.]]></summary></entry><entry><title type="html">Radiology AI Is Not Computer Vision: A Field Guide for ML Scientists</title><link href="https://joseph-rich.com/posts/2026/06/radiology-ai-vs-computer-vision/" rel="alternate" type="text/html" title="Radiology AI Is Not Computer Vision: A Field Guide for ML Scientists" /><published>2026-06-02T00:00:00+00:00</published><updated>2026-06-02T00:00:00+00:00</updated><id>https://joseph-rich.com/posts/2026/06/radiology-ai-vs-computer-vision</id><content type="html" xml:base="https://joseph-rich.com/posts/2026/06/radiology-ai-vs-computer-vision/"><![CDATA[<!-- Generated from posts/2026-06-02-radiology-ai-vs-computer-vision/main.md by scripts/sync_posts.py. Do not edit here; edit the source and re-commit. -->

<h1 id="why-a-computer-vision-experts-intuitions-misfire">Why a computer-vision expert’s intuitions misfire</h1>

<p>If you have trained a model on ImageNet, COCO, or a few hundred million
Instagram photos, you have excellent instincts for natural-image vision. Most of
those instincts are wrong — or at least dangerously incomplete — the moment you
point them at a chest CT or a screening mammogram.</p>

<p>This post is a field guide for machine-learning scientists moving into
radiology. It is not a survey of architectures; the architectures are mostly the
ones you already know (CNNs, U-Nets, vision transformers, increasingly
foundation models). What changes is everything <em>around</em> the architecture: the
statistics of the signal, the cost and meaning of a label, the data you can
actually get, and — the part that quietly sinks most projects —
<strong>generalization across the bewildering heterogeneity of how medical images are
produced.</strong> I will end with the two things ML scientists most often discover too
late: how the FDA actually regulates these models, and why the model in the
paper is rarely the model that ships.</p>

<p>A running theme: medical imaging is in some ways <em>easier</em> than natural-image
vision, and leaning on those advantages is the difference between a model that
demos well and one that survives contact with a second hospital.</p>

<h1 id="what-is-genuinely-easier-than-natural-images">What is genuinely easier than natural images</h1>

<p>Start with the good news, because it is real and underexploited.</p>

<p><strong>Canonical pose and framing.</strong> A street scene can contain a cat at any scale,
any orientation, anywhere in the frame, against any background. A PA chest
radiograph is, by protocol, a patient standing upright, facing the detector,
arms positioned to rotate the scapulae off the lung fields. The heart is on the
left.<sup id="fnref:situs"><a href="#fn:situs" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> The aortic knob is where the aortic knob goes. This is a strong
spatial prior that natural-image models simply do not get for free — and it is
why registration, atlas-based priors, and even fixed positional encodings work
far better here than they would on web images.</p>

<p><strong>One channel, calibrated.</strong> Most modalities are grayscale, and — crucially —
the gray values often <em>mean something physical</em>. CT is quantitative: each voxel
is a Hounsfield unit, a linear transform of the X-ray attenuation coefficient
\(\mu\) relative to water,</p>

\[\mathrm{HU} = 1000 \times \frac{\mu - \mu_{\text{water}}}{\mu_{\text{water}} - \mu_{\text{air}}},\]

<p>so water is \(0\), air is \(-1000\), fat is around \(-100\), and cortical bone is
\(+1000\) or more. Fat is fat in every CT scanner on Earth. Nothing in RGB is
calibrated like this; “how blue is the sky” is not a physical constant. You can
and should exploit it — windowing, HU-based preprocessing, and physically
motivated augmentations all follow from it.</p>

<p><strong>The suspected disease localizes attention.</strong> Clinical imaging arrives with a
<em>reason for exam</em>. “Rule out pneumothorax” tells you to look at the pleural line;
“rule out stroke” sends you to the brain parenchyma and vessels. The organ of
interest is usually known, which is a luxury object detection never has.</p>

<p>But each of these advantages has a barb:</p>

<ul>
  <li>The canonical pose breaks for portable/supine films, pediatric patients, body
habitus, and post-surgical anatomy.</li>
  <li>HU calibration drifts with scanner, kVp, and contrast timing (more on this
below), and MRI intensities are <em>not</em> standardized at all — a T1 value is only
meaningful relative to the rest of that one acquisition.</li>
  <li>“The organ of interest is known” is a trap: incidental findings in the
<em>other</em> organs are often what matter most clinically. The lung-nodule model
that ignores the adrenal mass at the edge of the field has failed the patient
even if its AUC is perfect.</li>
</ul>

<p>So: use the priors, but treat every one of them as a covariate that can shift.</p>

<h1 id="the-needle-in-the-haystack-subtlety-and-extreme-imbalance">The needle in the haystack: subtlety and extreme imbalance</h1>

<p>Here is the single biggest statistical difference from natural images. In
COCO, the object you care about typically occupies a meaningful fraction of the
frame. In radiology, the finding is often a handful of voxels in a sea of normal
tissue, and the difference between <em>malignant</em> and <em>benign</em> — between <em>call the
patient back</em> and <em>see you in two years</em> — can come down to a few millimeters of
spiculation or a subtle change in density.</p>

<p>Make it concrete with geometry. A chest CT of roughly \(512 \times 512 \times 320\)
voxels at \(0.7 \times 0.7 \times 1.0\,\text{mm}\) contains about \(8.4 \times 10^7\)
voxels. A clinically important \(5\,\text{mm}\) pulmonary nodule is a sphere of
volume \(\tfrac{4}{3}\pi r^3 \approx 65\,\text{mm}^3\), or about \(134\) voxels. The
lesion is therefore</p>

\[\frac{134}{8.4\times 10^7} \approx 1.6 \times 10^{-6}\]

<p>of the volume — roughly <strong>one in six hundred thousand voxels</strong>. Shrink it to a
\(3\,\text{mm}\) nodule and you are at one in <em>three million</em>. Figure 1 puts
several findings on the same axis as natural-image objects; note the five-to-six
order-of-magnitude gap.</p>

<p><img src="figures/needle_in_haystack.png" alt="**Figure 1.** The fraction of an image that actually belongs to the finding,
on a log scale. Natural-image objects (blue) occupy $$10^{-3}$$ to $$10^{0}$$ of the
frame. Clinically critical lesions (red/navy) sit at $$10^{-7}$$ to $$10^{-5}$$.
This five-to-six order-of-magnitude difference is why naive pixel-wise losses
and patch samplers fail in radiology." /></p>

<p>The consequences for an ML scientist are direct:</p>

<ul>
  <li><strong>Accuracy is meaningless and pixel-wise loss is treacherous.</strong> A segmentation
model that predicts “no lesion” everywhere achieves \(1 - 1.6\times10^{-6}
\approx 99.9998\%\) voxel accuracy. Use overlap and detection metrics built for
imbalance — Dice / \(F_1\), where for prediction \(P\) and ground truth \(G\),
\(\mathrm{Dice} = \frac{2|P \cap G|}{|P| + |G|},\)
free-response ROC (FROC) for detection, and class-balanced or region-based
losses (Dice loss, Tversky, focal). The focal loss down-weights the easy
negatives that otherwise dominate the gradient:
\(\mathrm{FL}(p_t) = -(1-p_t)^{\gamma}\log p_t\).</li>
  <li><strong>Most of the volume is uninteresting, and uninteresting in a structured
way.</strong> Hard-negative mining, lesion-aware patch sampling, and two-stage
candidate-then-classify pipelines exist because uniformly sampling voxels
wastes almost all of your compute on obvious lung parenchyma.</li>
  <li><strong>Resolution is not negotiable.</strong> Downsampling a natural image to \(224^2\)
loses a cat’s whiskers; downsampling a CT slice can erase the lesion entirely.
The signal you are hunting may be at the Nyquist limit of the acquisition.</li>
</ul>

<h1 id="annotation-is-the-bottleneck-not-the-model">Annotation is the bottleneck, not the model</h1>

<p>In natural-image land, labels are cheap: crowdworkers draw boxes, and “is this a
dog” needs no credential. Radiology inverts this completely, and it reshapes
what is feasible.</p>

<p><strong>A bounding box is the wrong primitive, and often impossible.</strong> Many findings
have no crisp boundary. Where exactly does a ground-glass opacity end and normal
lung begin? What is the bounding box of diffuse interstitial disease, or of
“the lungs look hyperinflated”? The pathology is frequently a texture or a
<em>global</em> property, not a localizable object. Even when a lesion is discrete, it
lives in 3D — a box becomes a volume, and a radiologist scrolling 320 slices to
contour a tumour is spending clinical time that costs orders of magnitude more
than a crowdworker.</p>

<p><strong>Ground truth is noisy and sometimes unobtainable from the image alone.</strong> The
honest label often is not in the pixels. Is that lung nodule malignant? The
image cannot say; you need the biopsy, or two years of follow-up showing growth.
This is why so many “labels” in public datasets are actually <em>NLP-extracted from
the radiology report</em> (MIMIC-CXR, CheXpert, ChestX-ray14, PadChest all do this)
— which means your labels inherit both the radiologist’s error rate <em>and</em> the
text-mining model’s error rate.</p>

<p><strong>Inter-reader variability is a hard ceiling.</strong> Radiologists disagree. The
LIDC-IDRI lung-nodule database was annotated by four thoracic radiologists
precisely because no single read is ground truth; of 2,669 lesions marked as
nodules \(\geq 3\,\text{mm}\) by at least one reader, only about 35% were marked
by all four. If your “ground truth” is one radiologist, your evaluation noise
floor may be larger than the improvement you are claiming. Model the labels as
noisy: capture annotator agreement (e.g. Cohen’s / Fleiss’ \(\kappa\)), train
against multi-reader consensus where you can, and report performance relative to
the inter-reader band, not to an imagined perfect oracle.</p>

<p><strong>You cannot read the data without domain knowledge.</strong> A computer-vision
engineer can sanity-check an ImageNet pipeline by eye. Almost no ML scientist
can look at a FLAIR hyperintensity and tell whether the label is right. This has
a practical implication that teams underestimate: <em>you need a radiologist in the
loop continuously</em>, not just at the start, because data-cleaning decisions
(which views to keep, how to handle priors, what counts as positive) are
clinical judgments in disguise.</p>

<h1 id="the-data-scarcity-problem">The data scarcity problem</h1>

<p>Natural-image research rides on ImageNet (\(1.4\)M images), and webscale sets in
the billions. Radiology has nothing remotely comparable that is <em>public</em>, and
the reasons are structural: images are protected health information, they must
be de-identified (including burned-in pixel annotations and faces
reconstructable from head CT/MRI), and the expert labels are expensive. What we
do have is a handful of landmark public collections, summarized in Table 1.</p>

<p>Table: Major public medical-imaging datasets. “Images” counts vary by modality
(a CT/MRI “study” is a 3D volume of many slices). Sizes are as reported by the
source publications.</p>

<table>
  <thead>
    <tr>
      <th>Dataset</th>
      <th>Modality</th>
      <th>Scale</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>TCIA</strong> (The Cancer Imaging Archive) <sup><a href="#ref-clark2013" role="doc-biblioref">1</a></sup></td>
      <td>CT/MR/PET, many</td>
      <td>Umbrella of 100+ collections</td>
      <td>The host for most public oncology imaging, incl. LIDC-IDRI, BraTS sources</td>
    </tr>
    <tr>
      <td><strong>MIMIC-CXR</strong> <sup><a href="#ref-johnson2019" role="doc-biblioref">2</a></sup></td>
      <td>Chest X-ray</td>
      <td>377,110 images / 227,835 studies / 65,379 patients</td>
      <td>Single US center; paired free-text reports</td>
    </tr>
    <tr>
      <td><strong>CheXpert</strong> <sup><a href="#ref-irvin2019" role="doc-biblioref">3</a></sup></td>
      <td>Chest X-ray</td>
      <td>224,316 images / 65,240 patients</td>
      <td>Stanford; 14 NLP-mined labels with uncertainty</td>
    </tr>
    <tr>
      <td><strong>ChestX-ray14</strong> (NIH) <sup><a href="#ref-wang2017" role="doc-biblioref">4</a></sup></td>
      <td>Chest X-ray</td>
      <td>112,120 images / 30,805 patients</td>
      <td>14 labels mined from reports</td>
    </tr>
    <tr>
      <td><strong>PadChest</strong> <sup><a href="#ref-bustos2020" role="doc-biblioref">5</a></sup></td>
      <td>Chest X-ray</td>
      <td>160,868 images / ~67,000 patients</td>
      <td>Spanish; 174 findings, multi-view</td>
    </tr>
    <tr>
      <td><strong>LIDC-IDRI</strong> <sup><a href="#ref-armato2011" role="doc-biblioref">6</a></sup></td>
      <td>Chest CT</td>
      <td>1,018 scans</td>
      <td>4-radiologist nodule annotations</td>
    </tr>
    <tr>
      <td><strong>BraTS / TCGA glioma</strong> <sup><a href="#ref-bakas2017" role="doc-biblioref">7</a>,<a href="#ref-menze2015" role="doc-biblioref">8</a></sup></td>
      <td>Brain MRI (4 sequences)</td>
      <td>hundreds of cases</td>
      <td>Expert tumor segmentations; the benchmark for glioma</td>
    </tr>
    <tr>
      <td><strong>RSNA ICH</strong></td>
      <td>Head CT</td>
      <td>&gt;25,000 exams</td>
      <td>Intracranial hemorrhage, 60+ radiologist labelers</td>
    </tr>
    <tr>
      <td><strong>EMBED</strong> <sup><a href="#ref-jeong2023" role="doc-biblioref">9</a></sup></td>
      <td>Mammography (2D/DBT)</td>
      <td>3.4M images / ~110,000 patients</td>
      <td>Racially balanced; 20% public via AWS</td>
    </tr>
    <tr>
      <td><strong>fastMRI</strong> <sup><a href="#ref-knoll2020" role="doc-biblioref">10</a></sup></td>
      <td>Knee/brain MRI</td>
      <td>&gt;1,500 knee + ~7,000 brain raw studies</td>
      <td>Raw <em>k</em>-space — for reconstruction research</td>
    </tr>
    <tr>
      <td><strong>UK Biobank imaging</strong> <sup><a href="#ref-littlejohns2020" role="doc-biblioref">11</a></sup></td>
      <td>Whole-body MRI/DXA</td>
      <td>100,000 participants</td>
      <td>Population cohort, healthy-skewed; access-controlled</td>
    </tr>
  </tbody>
</table>

<p>Two things to internalize. First, the largest <em>labeled</em> sets are 2D chest
radiographs, because they are the cheapest to acquire and the easiest to label
from reports; 3D, multi-sequence, and rarer-modality data are one to three
orders of magnitude smaller. Second — and this is the setup for the rest of the
post — <strong>a big total \(N\) is not the same as a big \(N\) where it counts.</strong> EMBED
has 3.4M images, but if you want to evaluate performance for, say,
architectural distortion in dense breasts of women under 40 scanned on one
vendor’s tomosynthesis unit, you are suddenly working with a few dozen cases.</p>

<h1 id="heterogeneity-and-generalization-the-part-everyone-underestimates">Heterogeneity and generalization: the part everyone underestimates</h1>

<p>Everyone says medical-imaging AI “doesn’t generalize.” Fewer people say <em>why</em>,
mechanistically. The reason is that a medical image is the output of a long
physical and human pipeline, and <strong>every stage of that pipeline is a covariate
that differs across hospitals.</strong> A natural image has confounders too (lighting,
camera), but nothing like this stack.</p>

<p>Formally, the trouble is distribution shift. Your model learns
\(P_{\text{train}}(Y \mid X)\) over inputs drawn from \(P_{\text{train}}(X)\), and is
deployed where both can differ:</p>

\[P_{\text{train}}(X, Y) \;\neq\; P_{\text{test}}(X, Y).\]

<p>Decompose it. <strong>Covariate shift</strong> is \(P(X)\) changing while \(P(Y\mid X)\) holds —
a different scanner renders the <em>same</em> pathology with different texture.
<strong>Label shift</strong> is \(P(Y)\) changing — disease prevalence differs across a
referral center and a screening clinic, which (via Bayes) moves every predicted
probability and every PPV even if the imaging is identical. <strong>Concept shift</strong> is
the genuinely dangerous one, \(P(Y\mid X)\) itself changing — the imaging
appearance of a disease differs by population, or the label definition differs
by institution. Here is the catalogue of what actually shifts:</p>

<ul>
  <li><strong>Scanner vendor and model.</strong> GE, Siemens, Philips, Canon detectors and
reconstruction software impose vendor-specific texture and noise signatures.
Models readily learn the <em>scanner</em>, not the disease.</li>
  <li><strong>Acquisition physics.</strong> CT: tube voltage (kVp), tube current (mAs), pitch,
slice thickness, and especially the <strong>reconstruction kernel</strong> (sharp vs.
smooth) dramatically change texture — reconstruction kernel alone can render
the majority of radiomic features non-reproducible across settings. MRI: field
strength (1.5T vs 3T), pulse sequence and vendor implementation, TR/TE, and
the fact that intensities are not standardized at all.</li>
  <li><strong>Contrast and timing.</strong> With vs. without IV contrast, and <em>when</em> in the
contrast bolus the scan was captured, can change a structure’s appearance
more than disease does.</li>
  <li><strong>Imaging noise and dose.</strong> Low-dose protocols (and the shift toward them)
raise quantum noise; denoising and dose vary by site and by patient size.</li>
  <li><strong>Patient demographics and disease spectrum.</strong> Age, sex, body habitus,
ancestry, comorbidity mix, and <em>disease prevalence and severity</em> all vary by
catchment. A model tuned where pneumothoraces are large and obvious degrades
where they are small and subtle.</li>
  <li><strong>Protocol and positioning.</strong> Portable vs. fixed units, supine vs. upright,
inspiration depth, pediatric protocols, post-surgical hardware.</li>
</ul>

<p>The canonical demonstration is Zech et al.<sup><a href="#ref-zech2018" role="doc-biblioref">12</a></sup>: CNNs trained to detect
pneumonia on chest radiographs generalized <em>worse</em> to outside hospitals than
internal test performance suggested, and the models had learned to detect the
<em>hospital system and even the department</em> — exploiting that a portable scanner
marker or a prevalence difference correlated with disease. The same pattern
shows up in segmentation: AlBadawy et al.<sup><a href="#ref-albadawy2018" role="doc-biblioref">13</a></sup> found glioma-segmentation
performance dropped measurably when training and test institutions differed.
This is shortcut learning, and it is rampant precisely because the spurious
features (scanner, view, burned-in markers) are <em>so</em> predictable.</p>

<p>What this means for your workflow:</p>

<ul>
  <li><strong>Internal test performance is an upper bound, not an estimate.</strong> The only
trustworthy evaluation is external — a held-out <em>site</em>, ideally a held-out
<em>vendor</em> and <em>time period</em>. Split by hospital, not by image.</li>
  <li><strong>Audit for shortcuts.</strong> Saliency maps that point at the corner marker, an
AUC that survives when you black out the anatomy, a model that can classify
scanner from the image — all are red flags.</li>
  <li><strong>Harmonize deliberately.</strong> Intensity normalization, resampling to common
spacing, vendor-aware augmentation, and even learned kernel/stain-style
conversion exist to fight covariate shift; use them, but verify they did not
erase the signal.</li>
</ul>

<h1 id="the-statistical-power-trap-in-numbers">The statistical-power trap, in numbers</h1>

<p>Now combine the previous two sections — heterogeneity <em>and</em> scarcity — and you
get the quietest failure mode in the field. To <em>prove</em> a model generalizes, you
must evaluate it in each clinically relevant subgroup. But every stratification
you add slices your sample, and because disease is rare, it is the <strong>positive
cases</strong> that vanish first.</p>

<p>Walk it down for a chest-radiograph model, anchored to MIMIC-CXR’s 377,110
images (Figure 2). Keep frontal views only (\(\times 0.65\)). Keep the positives
for your target finding — pneumothorax, prevalence \(\approx 3\%\) (\(\times 0.03\));
already you are at ~7,000 positive cases, not 377,110. Now ask the
generalization questions clinicians will ask: how does it do in <strong>women</strong>
(\(\times 0.47\)), specifically those <strong>aged 18–40</strong> (\(\times 0.16\)), specifically
scanned on <strong>vendor B</strong> (\(\times 0.30\)), specifically with the
<strong>moderate-to-large, actionable</strong> subtype (\(\times 0.40\))? You land on about
<strong>66 positive cases</strong>. From 377,110 to 66 — and 66 is the number that actually
governs what you can conclude about that subgroup.</p>

<p><img src="figures/stratification_waterfall.png" alt="**Figure 2.** The stratification waterfall. Each clinically reasonable filter
multiplies the count down. The binding constraint is the number of *positive*
(diseased) cases, which collapses fastest because disease is
rare." /></p>

<p>Why 66 is a problem is pure sampling theory. Estimate a subgroup sensitivity
(true positive rate) \(\hat{p}\) from \(n\) positive cases; its standard error is
\(\sqrt{p(1-p)/n}\), so the 95% confidence half-width is about</p>

\[1.96\sqrt{\frac{p(1-p)}{n}}.\]

<p>At a true sensitivity of \(0.85\) and \(n = 66\), that half-width is \(\pm 0.086\):
your estimate is “somewhere between \(0.76\) and \(0.94\).” You cannot distinguish a
clinically excellent \(0.90\) from a borderline \(0.78\). (For small \(n\) use the
Wilson interval rather than this normal approximation — the qualitative story is
the same, and at these counts it matters.) Figure 3a shows the half-width
shrinking only as \(1/\sqrt{n}\); the subgroup strata are marked.</p>

<p>Worse, suppose you want to <em>detect</em> a real subgroup gap — say sensitivity drops
from \(0.85\) overall to \(0.75\) in young women on vendor B. The number of positives
per group needed for a two-sided test at \(\alpha = 0.05\) with power \(1-\beta\) is</p>

\[n = \frac{\left(z_{1-\alpha/2}\sqrt{2\bar{p}(1-\bar{p})} +
z_{1-\beta}\sqrt{p_1(1-p_1)+p_2(1-p_2)}\right)^2}{(p_1 - p_2)^2},\]

<p>which for \(p_1=0.85,\, p_2=0.75\) works out to about <strong>250 positive cases per
group</strong> for 80% power. Your subgroup has 66, which buys roughly <strong>30% power</strong>
(Figure 3b): a two-in-three chance of <em>missing</em> a real, clinically meaningful
degradation. And if you honestly test across, say, ten subgroups, a Bonferroni
correction to \(\alpha = 0.005\) pushes the requirement to ~425 per group — while
simultaneously, <em>not</em> correcting means some of your “significant” subgroup
findings are noise. You are squeezed from both sides.</p>

<p><img src="figures/power_and_precision.png" alt="**Figure 3.** What those counts buy. **(a)** The 95% CI half-width on a
subgroup sensitivity estimate shrinks only as $$1/\sqrt{n}$$; at $$n=66$$ positives
you have $$\pm 0.09$$ precision. **(b)** Power to detect a $$0.85 \to 0.75$$
sensitivity drop: you need ~250 positives per group for 80% power, but the
deepest subgroup has 66, giving ~30% power." /></p>

<p>The lesson is not “give up.” It is to <strong>plan evaluation as a power calculation
from day one</strong>: decide which subgroups are non-negotiable, estimate the positive
counts you will actually have, and either acquire enough cases (often via
multi-site collaboration) or state honestly which subgroups you are <em>not</em>
powered to certify. Silent truncation — reporting one headline AUC computed over
a population you never stratified — is how models that look published-ready fail
in deployment.</p>

<h1 id="how-these-models-are-actually-regulated">How these models are actually regulated</h1>

<p>If your model will touch patient care in the US, it is almost certainly a
<em>medical device</em>, and the FDA’s framework shapes your engineering. A few facts
ML scientists are routinely surprised by:</p>

<ul>
  <li><strong>Radiology dominates.</strong> From the 1990s through the mid-2020s, roughly
<strong>three-quarters of all FDA-authorized AI/ML-enabled devices are in
radiology</strong> — by far the largest category. This is your field.</li>
  <li><strong>Almost everything clears via 510(k), not clinical trials.</strong> The dominant
path is the <strong>510(k)</strong>, which establishes “substantial equivalence” to a
legally marketed <em>predicate</em> device — <em>not</em> a randomized trial. (Genuinely
novel devices use the <strong>De Novo</strong> path; the highest-risk ones need full
premarket approval, <strong>PMA</strong>, which is rare for imaging AI.) A consequence:
fewer than a third of FDA-authorized radiology AI devices have published
prospective clinical testing. Substantial equivalence is a regulatory claim,
not evidence your model helps patients — keep those separate in your head.</li>
  <li><strong>Models had to be “locked.”</strong> Historically the FDA cleared <strong>locked</strong>
algorithms — same input, same output, no learning in the field — because a
continuously adapting model breaks the entire premarket paradigm.</li>
</ul>

<p>What changed recently is worth knowing, because it directly affects how you can
plan model updates. In December 2024 the FDA finalized guidance on the
<strong>Predetermined Change Control Plan (PCCP)</strong>. The idea: in your original
submission, you pre-specify <em>what</em> you will be allowed to change (e.g. retrain on
new sites, recalibrate a threshold), the <em>methodology</em> you will use to develop
and validate each change, and an <em>impact assessment</em> — and then you can ship
those pre-authorized modifications without a new marketing submission. For an ML
scientist this is the bridge from “frozen forever” toward “responsibly
updatable,” and it explicitly asks you to think up front about intended-use
populations (ethnicity, sex, disease severity) and deployment environments. In
practice it means your <em>monitoring and revalidation plan is part of the product</em>,
not an afterthought.</p>

<h1 id="the-academic-model-is-not-the-deployed-model">The academic model is not the deployed model</h1>

<p>Finally, the gap that ends the most promising projects. The model in the paper
and the model in the hospital are different artifacts, optimized against
different objectives.</p>

<table>
  <thead>
    <tr>
      <th>Dimension</th>
      <th>Academic / benchmark model</th>
      <th>Deployed clinical model</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Objective</strong></td>
      <td>Maximize AUC/Dice on a fixed test set</td>
      <td>Improve a clinical workflow at a fixed, safe operating point</td>
    </tr>
    <tr>
      <td><strong>Metric that matters</strong></td>
      <td>Discrimination (AUROC)</td>
      <td>Sensitivity/specificity at a <em>chosen</em> threshold; calibration; PPV at local prevalence</td>
    </tr>
    <tr>
      <td><strong>Data</strong></td>
      <td>Curated, deduplicated, clean labels</td>
      <td>Messy PACS feed: priors, wrong views, artifacts, truncation</td>
    </tr>
    <tr>
      <td><strong>Generalization</strong></td>
      <td>Random split, often single site</td>
      <td>Must hold across vendors, sites, time, demographics</td>
    </tr>
    <tr>
      <td><strong>Failure cost</strong></td>
      <td>A lower number in a table</td>
      <td>A missed cancer or a false alarm that fatigues the radiologist</td>
    </tr>
    <tr>
      <td><strong>Lifecycle</strong></td>
      <td>Frozen at publication</td>
      <td>Monitored, drifts, must be revalidated and re-cleared</td>
    </tr>
    <tr>
      <td><strong>Integration</strong></td>
      <td>A <code class="language-plaintext highlighter-rouge">.ipynb</code> and a checkpoint</td>
      <td>DICOM in/out, PACS + reporting integration, latency budget, audit trail</td>
    </tr>
  </tbody>
</table>

<p>Concretely, what bites teams crossing this gap:</p>

<ul>
  <li><strong>Operating point, not the whole curve.</strong> A clinician runs your model at <em>one</em>
threshold. A great ROC curve with no defensible, <em>calibrated</em> operating point
is not deployable. And because prevalence differs by site (label shift), the
threshold that gives the right PPV in your lab is wrong in the clinic; plan to
recalibrate, e.g. with Platt scaling or isotonic regression, per site.</li>
  <li><strong>The long tail is the job.</strong> Benchmarks delete the ambiguous and corrupted
cases that dominate a real PACS queue. In deployment those <em>are</em> the workload:
the lateral mistakenly sent as frontal, the patient with prior surgery, the
motion-degraded study. Your model needs a calibrated “I don’t know.”</li>
  <li><strong>Prospective \(\neq\) retrospective.</strong> Retrospective AUC routinely overstates
prospective performance; the few prospective and randomized radiology-AI
studies have repeatedly come in below their retrospective hype.</li>
  <li><strong>Automation bias and workflow effects.</strong> A deployed model changes radiologist
behavior — sometimes it catches misses, sometimes it anchors the reader to a
wrong call. The endpoint that matters is <em>reader + model</em>, not the model in
isolation.</li>
  <li><strong>Drift and monitoring.</strong> Scanners get replaced, protocols change, populations
shift. A model that was validated in 2024 is not automatically valid in 2027.
The PCCP framework above exists precisely because this drift is inevitable.</li>
</ul>

<h1 id="takeaways">Takeaways</h1>

<p>If you remember five things moving from natural images to radiology:</p>

<ol>
  <li><strong>Exploit the priors, distrust them.</strong> Canonical pose, calibrated intensities,
and a known organ of interest are real gifts — but each is a covariate that
shifts, and the finding may be in the organ you weren’t told to look at.</li>
  <li><strong>Your signal is a needle.</strong> Lesions are \(10^{-7}\)–\(10^{-5}\) of the image.
Abandon accuracy and pixel-wise loss; use detection/overlap metrics,
imbalance-aware losses, and lesion-aware sampling, and don’t downsample away
the disease.</li>
  <li><strong>Labels are the bottleneck.</strong> They are expensive, noisy, NLP-mined, and
bounded by inter-reader disagreement. Keep a radiologist in the loop and
model the label noise explicitly.</li>
  <li><strong>Generalization is the whole game.</strong> Split by site/vendor/time, hunt for
shortcuts, and treat internal test numbers as upper bounds.</li>
  <li><strong>Power your evaluation before you train.</strong> Stratification destroys positive
counts; decide which subgroups you can certify, and say so honestly. Then
remember the deployed model lives at one calibrated operating point, under FDA
rules, drifting over time — design for that from the start.</li>
</ol>

<p>See the accompanying <code class="language-plaintext highlighter-rouge">notebook.ipynb</code> for the geometry, the stratification
waterfall, the power calculations behind Figures 1–3, and an automated check
that every citation below resolves.</p>

<h2 id="references">References</h2>

<div id="refs" class="references csl-bib-body" role="list">
<div id="ref-clark2013" class="csl-entry" role="listitem">
<div class="csl-left-margin">1. </div><div class="csl-right-inline"><span class="nocase">Clark K, Vendt B, Smith K, et al.</span> The <span>Cancer</span> <span>Imaging</span> <span>Archive</span> (<span>TCIA</span>): Maintaining and operating a public information repository. <em>Journal of Digital Imaging</em>. 2013;26(6):1045-1057. doi:<a href="https://doi.org/10.1007/s10278-013-9622-7">10.1007/s10278-013-9622-7</a></div>
</div>
<div id="ref-johnson2019" class="csl-entry" role="listitem">
<div class="csl-left-margin">2. </div><div class="csl-right-inline"><span class="nocase">Johnson AEW, Pollard TJ, Berkowitz SJ, et al.</span> <span>MIMIC-CXR</span>, a de-identified publicly available database of chest radiographs with free-text reports. <em>Scientific Data</em>. 2019;6:317. doi:<a href="https://doi.org/10.1038/s41597-019-0322-0">10.1038/s41597-019-0322-0</a></div>
</div>
<div id="ref-irvin2019" class="csl-entry" role="listitem">
<div class="csl-left-margin">3. </div><div class="csl-right-inline"><span class="nocase">Irvin J, Rajpurkar P, Ko M, et al.</span> <span>CheXpert</span>: A large chest radiograph dataset with uncertainty labels and expert comparison. <em>Proceedings of the AAAI Conference on Artificial Intelligence</em>. 2019;33(1):590-597. doi:<a href="https://doi.org/10.1609/aaai.v33i01.3301590">10.1609/aaai.v33i01.3301590</a></div>
</div>
<div id="ref-wang2017" class="csl-entry" role="listitem">
<div class="csl-left-margin">4. </div><div class="csl-right-inline"><span class="nocase">Wang X, Peng Y, Lu L, et al.</span> <span class="nocase">ChestX-ray8</span>: Hospital-scale chest <span class="nocase">X-ray</span> database and benchmarks on weakly-supervised classification and localization of common thorax diseases. <em>IEEE Conference on Computer Vision and Pattern Recognition (CVPR)</em>. Published online 2017:3462-3471. doi:<a href="https://doi.org/10.1109/CVPR.2017.369">10.1109/CVPR.2017.369</a></div>
</div>
<div id="ref-bustos2020" class="csl-entry" role="listitem">
<div class="csl-left-margin">5. </div><div class="csl-right-inline">Bustos A, Pertusa A, Salinas J-M, Iglesia-Vayá M de la. <span>PadChest</span>: A large chest x-ray image dataset with multi-label annotated reports. <em>Medical Image Analysis</em>. 2020;66:101797. doi:<a href="https://doi.org/10.1016/j.media.2020.101797">10.1016/j.media.2020.101797</a></div>
</div>
<div id="ref-armato2011" class="csl-entry" role="listitem">
<div class="csl-left-margin">6. </div><div class="csl-right-inline"><span class="nocase">Armato III SG, McLennan G, Bidaut L, et al.</span> The <span>Lung</span> <span>Image</span> <span>Database</span> <span>Consortium</span> (<span>LIDC</span>) and <span>Image</span> <span>Database</span> <span>Resource</span> <span>Initiative</span> (<span>IDRI</span>): A completed reference database of lung nodules on <span>CT</span> scans. <em>Medical Physics</em>. 2011;38(2):915-931. doi:<a href="https://doi.org/10.1118/1.3528204">10.1118/1.3528204</a></div>
</div>
<div id="ref-bakas2017" class="csl-entry" role="listitem">
<div class="csl-left-margin">7. </div><div class="csl-right-inline"><span class="nocase">Bakas S, Akbari H, Sotiras A, et al.</span> Advancing <span>The</span> <span>Cancer</span> <span>Genome</span> <span>Atlas</span> glioma <span>MRI</span> collections with expert segmentation labels and radiomic features. <em>Scientific Data</em>. 2017;4:170117. doi:<a href="https://doi.org/10.1038/sdata.2017.117">10.1038/sdata.2017.117</a></div>
</div>
<div id="ref-menze2015" class="csl-entry" role="listitem">
<div class="csl-left-margin">8. </div><div class="csl-right-inline"><span class="nocase">Menze BH, Jakab A, Bauer S, et al.</span> The <span>Multimodal</span> <span>Brain</span> <span>Tumor</span> <span>Image</span> <span>Segmentation</span> <span>Benchmark</span> (<span>BRATS</span>). <em>IEEE Transactions on Medical Imaging</em>. 2015;34(10):1993-2024. doi:<a href="https://doi.org/10.1109/TMI.2014.2377694">10.1109/TMI.2014.2377694</a></div>
</div>
<div id="ref-jeong2023" class="csl-entry" role="listitem">
<div class="csl-left-margin">9. </div><div class="csl-right-inline"><span class="nocase">Jeong JJ, Vey BL, Bhimireddy A, et al.</span> The <span>EMory</span> <span>BrEast</span> imaging <span>Dataset</span> (<span>EMBED</span>): A racially diverse, granular dataset of 3.4 million screening and diagnostic mammographic images. <em>Radiology: Artificial Intelligence</em>. 2023;5(1):e220047. doi:<a href="https://doi.org/10.1148/ryai.220047">10.1148/ryai.220047</a></div>
</div>
<div id="ref-knoll2020" class="csl-entry" role="listitem">
<div class="csl-left-margin">10. </div><div class="csl-right-inline"><span class="nocase">Knoll F, Zbontar J, Sriram A, et al.</span> <span class="nocase">fastMRI</span>: A publicly available raw k-space and <span>DICOM</span> dataset of knee images for accelerated <span>MR</span> image reconstruction using machine learning. <em>Radiology: Artificial Intelligence</em>. 2020;2(1):e190007. doi:<a href="https://doi.org/10.1148/ryai.2020190007">10.1148/ryai.2020190007</a></div>
</div>
<div id="ref-littlejohns2020" class="csl-entry" role="listitem">
<div class="csl-left-margin">11. </div><div class="csl-right-inline"><span class="nocase">Littlejohns TJ, Holliday J, Gibson LM, et al.</span> The <span>UK</span> <span>Biobank</span> imaging enhancement of 100,000 participants: Rationale, data collection, management and future directions. <em>Nature Communications</em>. 2020;11:2624. doi:<a href="https://doi.org/10.1038/s41467-020-15948-9">10.1038/s41467-020-15948-9</a></div>
</div>
<div id="ref-zech2018" class="csl-entry" role="listitem">
<div class="csl-left-margin">12. </div><div class="csl-right-inline"><span class="nocase">Zech JR, Badgeley MA, Liu M, et al.</span> Variable generalization performance of a deep learning model to detect pneumonia in chest radiographs: A cross-sectional study. <em>PLoS Medicine</em>. 2018;15(11):e1002683. doi:<a href="https://doi.org/10.1371/journal.pmed.1002683">10.1371/journal.pmed.1002683</a></div>
</div>
<div id="ref-albadawy2018" class="csl-entry" role="listitem">
<div class="csl-left-margin">13. </div><div class="csl-right-inline">AlBadawy EA, Saha A, Mazurowski MA. Deep learning for segmentation of brain tumors: Impact of cross-institutional training and testing. <em>Medical Physics</em>. 2018;45(3):1150-1158. doi:<a href="https://doi.org/10.1002/mp.12752">10.1002/mp.12752</a></div>
</div>
</div>
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:situs">
      <p>Except in <em>situs inversus</em> (~1 in 10,000), which is exactly the kind of
rare but catastrophic edge case a model trained on the canonical prior will get
confidently wrong. Hold that thought; it returns under heterogeneity. <a href="#fnref:situs" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Joseph Rich</name><email>josephrich98@gmail.com</email></author><category term="machine learning" /><category term="radiology" /><category term="computer vision" /><category term="medical imaging" /><summary type="html"><![CDATA[A field guide for ML scientists moving into radiology: what is genuinely easier than natural images, where computer-vision intuitions misfire, the data and labels you can actually get, how the FDA regulates these models, and why the model in the paper is rarely the one that ships.]]></summary></entry><entry><title type="html">How This Blog Is Built: A Reproducible Pipeline for Scientific Writing</title><link href="https://joseph-rich.com/posts/2026/06/how-this-blog-is-built/" rel="alternate" type="text/html" title="How This Blog Is Built: A Reproducible Pipeline for Scientific Writing" /><published>2026-06-01T00:00:00+00:00</published><updated>2026-06-01T00:00:00+00:00</updated><id>https://joseph-rich.com/posts/2026/06/how-this-blog-is-built</id><content type="html" xml:base="https://joseph-rich.com/posts/2026/06/how-this-blog-is-built/"><![CDATA[<!-- Generated from posts/2026-06-01-how-this-blog-is-built/main.md by scripts/sync_posts.py. Do not edit here; edit the source and re-commit. -->

<p>I’ve decided to make my first post on my blog a bit of a meta-post. The purpose of this post is to describe how I built my personal website, including the decisions that went into various design components. This post serves as a reference for anyone looking to design a similar website.</p>

<p><img src="/images/posts/2026-06-01-how-this-blog-is-built/pipeline.png" alt="**Figure 1.**" /></p>

<p>Blog writing workflow. Blue = manual; black = automatic.</p>

<h2 id="hosting-vercel">Hosting: Vercel</h2>
<p>I host my website on <a href="https://vercel.com/">Vercel</a>. The benefits of this include DDoS protection, analytics, and easy deployment. My site consists primarily of text and small images, so a static site made the most sense.</p>

<p>I opted for Vercel over graphical website design tools, such as WordPress and Wix, for a number of reasons, but the main reason being easy programmatic updates with just a markdown file and a single git commit+push rather. No need for logging into websites and interacting with GUIs for each update. GitHub Pages is a valid alternative to Vercel. I opted for Vercel primarily because of my familiarity with the service from other projects, but GitHub Pages offers many of the same benefits.</p>

<p>I use a pre-commit hook to convert blog post markdown files into pages on the site with each commit. Specifically, this hook converts each entry in <code class="language-plaintext highlighter-rouge">posts/&lt;title&gt;/main.md</code> into a Jekyll post under <code class="language-plaintext highlighter-rouge">site/_posts/&lt;title&gt;.md</code> and copies the associated images into <code class="language-plaintext highlighter-rouge">site/images/posts/&lt;title&gt;</code>. That keeps the rendered site in sync with the source posts on every commit, with no manual publish step.</p>

<h2 id="site-generation-jekyll">Site generation: Jekyll</h2>
<p>For static page generation, I use <a href="https://jekyllrb.com/">Jekyll</a>. Jekyll converts the pages of my website, including blog posts and selected publications, from Markdown to HTML. It also combines each page with reusable templates, stylesheets, and configuration files to generate the complete website. I use the theme <a href="https://github.com/academicpages/academicpages.github.io"><strong>academicpages</strong></a>, a fork of <a href="https://github.com/mmistakes/minimal-mistakes">Minimal Mistakes</a>, because I like the appearance (nothing deep here). The resulting site consists entirely of static files, making it fast to load and requiring virtually no server-side infrastructure.</p>

<h2 id="file-system">File system</h2>
<p>All website content lives in the GitHub repository <a href="https://github.com/josephrich98/joseph_rich_blog">josephrich98/joseph_rich_blog</a>. Each blog post contains its own directory, named after the post title.</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>posts/&lt;slug&gt;/
  main.md            # the article: Markdown + YAML text + LaTeX math
  references.bib     # the references: Generated from Zotero with Better BibTex
  notebook.ipynb     # the analysis that runs analysis and generates figures
  scripts/           # plotting / analysis code, runnable standalone
  figures/           # generated plots (git-ignored)
  data/              # datasets + a README describing each source (git-ignored)
  requirements.txt   # the pinned pip packages for this post
  environment.yml    # thin conda wrapper: Python + pip + requirements.txt
  Dockerfile         # a container that reproduces this post
</code></pre></div></div>

<p>Each post is just a Markdown file <code class="language-plaintext highlighter-rouge">main.md</code>. Markdown struck a good balance between simplicity and expressiveness. It enables basic features such as text blocks, headings, equations, images, hyperlinks, and code blocks. I write most of my academic manuscripts in LaTeX and considered using the same for this page, but it felt a bit overkill in the absence of customized post layouts, extended mathematical proof derivations, and detailed figure specifications.</p>

<p>Accompanying each post is a Jupyter notebook <code class="language-plaintext highlighter-rouge">notebook.ipynb</code>. This notebook contains code to reproduce all analyses from the post. Scripts with longer runtimes, called by the notebook, are included in the <code class="language-plaintext highlighter-rouge">scripts/</code> directory. Data files are stored in <code class="language-plaintext highlighter-rouge">data/</code>, which is git-ignored because files might be large and unnecessary for site generation. Code for data download will always be present in the notebook or as a script when publicly available to ensure full reproducibility. Figures are written into <code class="language-plaintext highlighter-rouge">figures/</code>, also git-ignored as these are a copy of the figures stored in the <code class="language-plaintext highlighter-rouge">site</code> directory.</p>

<p>For reproducibility, each post also includes a <code class="language-plaintext highlighter-rouge">requirements.txt</code> file, <code class="language-plaintext highlighter-rouge">environment.yml</code> file, and <code class="language-plaintext highlighter-rouge">Dockerfile</code>. While perhaps a bit overkill, it represents a trade-off between ease of use and reproducibility. The <code class="language-plaintext highlighter-rouge">requirements.txt</code> file is the simplest option and requires only a Python installation, but it does not specify the Python version or non-Python system dependencies. The <code class="language-plaintext highlighter-rouge">environment.yml</code> file additionally specifies the Python version and many system libraries available through Conda, providing a more reproducible software environment. However, it still relies on the host operating system. Finally, the <code class="language-plaintext highlighter-rouge">Dockerfile</code> packages nearly the entire runtime environment into an isolated container, providing the highest level of reproducibility, although it requires Docker to be installed and permission to run containers. For readers who don’t want to install anything, each notebook also opens directly in <a href="https://colab.research.google.com/"><strong>Google Colab</strong></a> from a badge at the top.</p>

<p>When making changes to the website, including the addition of a new blog post, I always work in a branch to avoid pushing incomplete changes to the main site. Every branch automatically receives its own preview deployment, allowing me to review changes before merging them into <code class="language-plaintext highlighter-rouge">main</code> by visiting <code class="language-plaintext highlighter-rouge">https://joseph-rich-blog-git-BRANCH-josephrich98s-projects.vercel.app</code>. I then merge the branch into <code class="language-plaintext highlighter-rouge">main</code> once the changes are ready.</p>

<h2 id="domain-hosting-cloudflare">Domain hosting: Cloudflare</h2>
<p>I manage my domain through <a href="https://www.cloudflare.com/">Cloudflare</a>. It is one of the most popular domain registrars, offers competitive pricing (around $11 per year at the time of writing), and provides reliable DNS management with seamless integration into services such as Vercel.</p>

<h2 id="comments-giscus">Comments: giscus</h2>
<p>As mentioned earlier, the entire site is hosted on GitHub. This enables benefits such as version control, programmatic updates, and familiarity with tools in the ecosystem such as branches and GitHub Actions. However, natively, GitHub does not support comments. This is where <a href="https://giscus.app/"><strong>giscus</strong></a> comes into play. giscus provides a comment section interface for each post, with data stored as a GitHub Discussion. Unlike hosted comment widgets, giscus serves no advertising and sells no data. giscus requires that each user has a GitHub account, which could be seen as a drawback since it is an extra barrier to commenting for those without an account. However, it is also a feature in the sense that it ensures user verification and identity, enabling discussions to be more intentional.</p>

<h2 id="testing-and-cicd-pytest-github-actions">Testing and CI/CD: Pytest, GitHub Actions</h2>
<p>In order to ensure that all notebooks associated with blog posts run correctly, I run a pytest for each notebook using NBVal in both strict and lax mode. This two-level design allows me to distinguish between code errors and logic errors. Lax mode only runs if strict mode fails, preventing redundant checks.</p>

<p>A test for a post only runs when a file associated with that post (outside of <code class="language-plaintext highlighter-rouge">main.md</code> or any file in <code class="language-plaintext highlighter-rouge">figures</code>) changes in a commit. This prevents unnecessary checks. While environment reproducibility files generally pin python dependency versions, there is also a GitHub Action to rerun pytests for each notebook every six months to ensure that notebooks remain working.</p>

<h2 id="writing">Writing</h2>
<p>While not part of the technical stack of the website, there were a few notes I wanted to make about my habits around writing blog posts.</p>

<p>I use Zotero for citation management. This tool enables directory structures for project management, BibTex export, web browser extensions for citation addition with a single click, and integration with Google Docs and Overleaf for automatics citation updating (not used in this blog, but useful for many of my other projects). Citations are automatically updated in each post through the pandoc referencing of entries in the <code class="language-plaintext highlighter-rouge">references.bib</code> file. There is another pre-commit hook to verify that each reference in <code class="language-plaintext highlighter-rouge">references.bib</code> contains a valid DOI, verified against <a href="https://doi2bib.org/">doi2bib</a>
(<code class="language-plaintext highlighter-rouge">https://doi2bib.org/bib/&lt;DOI&gt;</code>)</p>

<p>All posts are written entirely by me — no AI writing. I sometimes use AI during brainstorming, citation retrieval, code assistance, and spelling/grammer checks. But all ideas and words come from me. If you wanted to read from ChatGPT, you could visit ChatGPT yourself. The purpose of my blog is to share thoughts that come from me directly. Plus, the writing part is fun. It’s a fun blend of academic and creative thinking that gets the juices flowing in some of the dusty parts of my right brain. So you won’t be seeing things such as “it’s not A, but B,” “this is the right place to pause,” or “the bottom line, summarized honestly.” But for the record, I liked em-dashes before they were cool.</p>

<h2 id="conclusion">Conclusion</h2>
<p>This setup allows maintaining the blog to be effortless from a technical standpoint. To add a new blog post, I simply make a directory in the <code class="language-plaintext highlighter-rouge">posts</code> directory containing a <code class="language-plaintext highlighter-rouge">main.md</code> file (and the associated Jupyter notebook and environment reproducibility files for best practice) and push my changes to GitHub. To add a publication, I simply add a file in <code class="language-plaintext highlighter-rouge">site/_publications/&lt;date-name&gt;md</code>. That’s it.</p>

<p>Behind the scenes, the notebook is verified to run, the Markdown is converted to HTML, and the site is deployed. The setup is completely free besides the minimal domain hosting cost (which can also be eliminated by using the free Vercel or GitHub Pages subdomain). There is site protection, analytics, version control, and automated testing and deployment. And everything can be fully controlled from the command line.</p>

<p>You know what they say: “If you want to change the world, start off by streamlining your website.”</p>]]></content><author><name>Joseph Rich</name><email>josephrich98@gmail.com</email></author><category term="blogging" /><category term="open-source software" /><category term="reproducibility" /><category term="science writing" /><summary type="html"><![CDATA[A description of the tech stack behind joseph-rich.com. Writing blog posts is as simple as writing a markdown file and pushing to GitHub. Everything else is automated: site generation and deployment, notebook testing, and CI/CD.]]></summary></entry></feed>