diff --git a/paper/pnas/body.tex b/paper/pnas/body.tex index 68fdbb8..27c5fcd 100644 --- a/paper/pnas/body.tex +++ b/paper/pnas/body.tex @@ -21,7 +21,7 @@ An operator of a model population faces recurring decisions for which there is n \begin{figure*}[p]\centering % fig1 \includegraphics[width=\textwidth]{figs/fig1a.pdf}\\[6pt] \includegraphics[width=\textwidth]{figs/fig1b.pdf} -\caption{(A) The experimental programme. Each population-genetic abstraction (Table 1) is tested at up to three tiers, ordered left to right by increasing realism: a biological model (a Wright--Fisher simulator over knowledge distributions; closed forms, bitwise-reproducible), trained neural networks measured against exact oracles (recurrent, feedforward, and variational-autoencoder generators on a synthetic mode universe, and a convolutional VAE on MNIST), and language models (LoRA specialists on Qwen bases at 0.5B and 7B, scored by an exact-match verifier). Colour separates the two categories: the biological model in blue, the two AI-model tiers in oranges. The same abstractions are carried across all three. Rows are the framework's mechanisms, each defined at the left margin; filled cells name the experiments run at each tier, and each carries, in its corner, the figure or table where that result is reported, so this figure doubles as a map of the paper. Each claim is tested at the cheapest tier that can falsify it, and a costlier tier is entered only where it adds a discriminating test rather than a replication: grounding at language-model scale is established in prior work (21, 30) and is not re-run; epistasis and the society skip the middle tier, whose distinctive value (exact oracles) does not bear on those operator-level questions; and the society at language-model scale is the integrative experiment this paper specifies but does not run --- its stated gap. (B) The conceptual basis of the transfer. A population of models is usually pictured as a society in space: contemporaries exchanging messages. The couplings this paper studies run instead between generations --- training on model output (inheritance), weight-space merging (recombination), verified real data entering each generation (immigration from reality) --- a society in time, the object population genetics was built to describe. Dots mark capabilities: the rare one (gold) is lost under single-parent inheritance, reassembled by merging complementary parents, and re-supplied by grounding.}\label{fig1} +\caption{(A) The experimental programme. Each population-genetic abstraction (Table 1) is tested at up to three tiers, ordered left to right by increasing realism: a biological model (a Wright--Fisher simulator over knowledge distributions; closed forms, bitwise-reproducible), trained neural networks measured against exact oracles (recurrent, feedforward, and variational-autoencoder generators on a synthetic mode universe, and a convolutional VAE on MNIST), and language models (LoRA specialists on Qwen bases at 0.5B and 7B, scored by an exact-match verifier). Colour separates the two categories: the biological model in green, the two AI-model tiers in blues. The same abstractions are carried across all three. Rows are the framework's mechanisms, each defined at the left margin; filled cells name the experiments run at each tier, and each carries, in its corner, the figure or table where that result is reported, so this figure doubles as a map of the paper. Each claim is tested at the cheapest tier that can falsify it, and a costlier tier is entered only where it adds a discriminating test rather than a replication: grounding at language-model scale is established in prior work (21, 30) and is not re-run; epistasis and the society skip the middle tier, whose distinctive value (exact oracles) does not bear on those operator-level questions; and the society at language-model scale is the integrative experiment this paper specifies but does not run --- its stated gap. (B) The conceptual basis of the transfer. A population of models is usually pictured as a society in space: contemporaries exchanging messages. The couplings this paper studies run instead between generations --- training on model output (inheritance), weight-space merging (recombination), verified real data entering each generation (immigration from reality) --- a society in time, the object population genetics was built to describe. Dots mark capabilities: the rare one (gold) is lost under single-parent inheritance, reassembled by merging complementary parents, and re-supplied by grounding.}\label{fig1} \end{figure*} \section*{The biological model, and where trained learners depart from it} diff --git a/paper/pnas/build.py b/paper/pnas/build.py index 68a0a14..9d6ac8d 100644 --- a/paper/pnas/build.py +++ b/paper/pnas/build.py @@ -28,8 +28,8 @@ FIGURES: dict[str, tuple[list[str], str]] = { "trained neural networks measured against exact oracles (recurrent, feedforward, and " "variational-autoencoder generators on a synthetic mode universe, and a convolutional VAE on " "MNIST), and language models (LoRA specialists on Qwen bases at 0.5B and 7B, scored by an " - "exact-match verifier). Colour separates the two categories: the biological model in blue, " - "the two AI-model tiers in oranges. The same abstractions are carried across " + "exact-match verifier). Colour separates the two categories: the biological model in green, " + "the two AI-model tiers in blues. The same abstractions are carried across " "all three. Rows are the framework's mechanisms, each defined at the left margin; filled " "cells name the experiments run at each tier, and each carries, in its corner, the figure " "or table where that result is reported, so this figure doubles as a map of the paper. Each claim is tested at the cheapest tier that " diff --git a/paper/pnas/figs/fig1a.pdf b/paper/pnas/figs/fig1a.pdf index 2ce40f0..a668b95 100644 Binary files a/paper/pnas/figs/fig1a.pdf and b/paper/pnas/figs/fig1a.pdf differ diff --git a/paper/pnas/figs/icons/pea.png b/paper/pnas/figs/icons/pea.png new file mode 100644 index 0000000..5a4f788 Binary files /dev/null and b/paper/pnas/figs/icons/pea.png differ diff --git a/paper/pnas/figs/icons/robot.png b/paper/pnas/figs/icons/robot.png new file mode 100644 index 0000000..d4fe920 Binary files /dev/null and b/paper/pnas/figs/icons/robot.png differ diff --git a/paper/pnas/main.pdf b/paper/pnas/main.pdf index 24bfb3b..c96b4f8 100644 Binary files a/paper/pnas/main.pdf and b/paper/pnas/main.pdf differ diff --git a/paper/pnas/make_figs.py b/paper/pnas/make_figs.py index f11966a..65e7a27 100644 --- a/paper/pnas/make_figs.py +++ b/paper/pnas/make_figs.py @@ -46,13 +46,17 @@ def save(fig, name): def fig1a(): from matplotlib.patches import FancyBboxPatch + # (name, architecture, guarantee, edge, cell face, header fill, header text colour, icon) + # Icons: Flaticon #2347052 (green pea, for Mendel) and #10479785 (robot), used under GG's + # paid Flaticon licence. TIERS = [ ("Biological model", "Wright\u2013Fisher simulator (NumPy)", "closed forms \u00b7 bitwise-reproducible", - "#3d7eb8", "#eaf2fa"), + "#4e8d4e", "#eef6ec", "#c5e0bd", "#2d5b2d", "icons/pea.png"), ("Trained networks", "RNN \u00b7 MLP \u00b7 VAE on a synthetic oracle;\nconvolutional VAE on MNIST", - "sign-level tests \u00b7 exact oracles", "#e97313", "#fdefe1"), + "sign-level tests \u00b7 exact oracles", "#5b9bc9", "#eff6fb", "#c9e2f2", "#1f4e79", + "icons/robot.png"), ("Language models", "LoRA specialists on Qwen 0.5B & 7B;\nexact-match verifier", - "seed-replicated signs", "#b04e0c", "#fbe6d4"), + "seed-replicated signs", "#3c6ea5", "#e7eef8", "#adc8e8", "#1d3f66", "icons/robot.png"), ] ROWS = [ ("Grounding = immigration", @@ -98,16 +102,22 @@ def fig1a(): xs = [x0, x0 + cw + sep, x0 + 2 * cw + sep] row_h, row_top = 0.157, 0.805 - for j2, (name, arch, guarantee, edge, face) in enumerate(TIERS): + from matplotlib.offsetbox import AnnotationBbox, OffsetImage + + for j2, (name, arch, guarantee, edge, face, headfill, textcol, icon) in enumerate(TIERS): x = xs[j2] + xc = x + cw / 2 - 0.02 # text centred left of the icon slot ax.add_patch(FancyBboxPatch((x + gap, 0.825), cw - 2 * gap, 0.155, - boxstyle="round,pad=0.004", fc=edge, ec=edge, lw=1.4)) - ax.text(x + cw / 2, 0.966, name, ha="center", va="top", fontsize=9.5, - fontweight="bold", color="white") - ax.text(x + cw / 2, 0.922, arch, ha="center", va="top", fontsize=6.8, - linespacing=1.3, color="white") - ax.text(x + cw / 2, 0.833, guarantee, ha="center", va="bottom", fontsize=6.4, - style="italic", color="white", alpha=0.92) + boxstyle="round,pad=0.004", fc=headfill, ec=edge, lw=1.6)) + ax.text(xc, 0.966, name, ha="center", va="top", fontsize=9.5, + fontweight="bold", color=textcol) + ax.text(x + cw / 2 - 0.026, 0.922, arch, ha="center", va="top", fontsize=6.6, + linespacing=1.3, color=textcol) + ax.text(xc, 0.833, guarantee, ha="center", va="bottom", fontsize=6.4, + style="italic", color=textcol, alpha=0.85) + img = plt.imread(str(OUT / icon)) + ax.add_artist(AnnotationBbox(OffsetImage(img, zoom=0.055), + (x + cw - gap - 0.024, 0.902), frameon=False)) for i2, (label, definition, cells) in enumerate(ROWS): tags = TAGS[i2] @@ -119,7 +129,8 @@ def fig1a(): style="italic", color="#555", linespacing=1.35) for j2, cell in enumerate(cells): x = xs[j2] - edge, face = TIERS[j2][3], TIERS[j2][4] + edge = TIERS[j2][3] + face = TIERS[j2][4] if cell is None: ax.add_patch(FancyBboxPatch((x + gap, y0), cw - 2 * gap, y1 - y0, boxstyle="round,pad=0.004", fc="white", ec="#bbbbbb",