Can you trust what a tiny model tells you about Pluto?
The short version. Train this tiny model once and it tells you, with confidence, whether Pluto is a planet. Train it again on a fresh draw of the same data and the answer can flip. This page is about that gap: how a single run hands you a clean result that is really a coin flip, why a four-times-larger model grows more confident without growing more right, and why the model ends up deciding Pluto's fate from the word it heard most often rather than from anything about Pluto itself. If you read only this paragraph, that is the conclusion.
In August 2006, the International Astronomical Union voted Pluto out of the planets. The case had been building for years: astronomers had been finding objects out beyond Neptune since the 1990s, and in 2005 they found Eris, larger than Pluto and well outside the planet category. The category was fraying.
There is an old line of Juliet's: a rose by any other name would smell as sweet. The name is idle; the features, the smell, are what is real. Pluto is a good place to test that. In 2006 we did not move Pluto or remeasure it, we only renamed it, and the question this page keeps circling is whether the name should have mattered at all, or only the features. Our tiny model, it turns out, has an uncomfortable opinion.
This page walks through a small experiment that began with a sharper version of that history: given only the kind of evidence Pluto-era astronomers had, can a tiny language model notice that the planet category is under strain? Along the way the question changed. The interesting problem turned out not to be whether the model notices the strain. It is whether you can trust what it tells you when you ask. Train this toy once and it answers with confidence. Train it again, on a fresh draw of the same world, and the answer can flip.
The walkthrough is interactive, and you do not need a machine-learning background. The headline section lets you train the model yourself, one run at a time, and watch the answer refuse to settle down.
1. The toy world
To study category strain in something we can fully control, we do not use real astronomy. We invent a synthetic world. Each "celestial body" is described by exactly three integer features:
- Mass: tiny, small, medium, large, huge (0–4)
- Diameter: tiny, small, medium, large, huge (0–4)
- Orbit: near, inner, middle, outer, distant (0–4)
The world has four canonical categories, planet, asteroid, comet, and moon, each with a prototypical feature combination. P1 through P9 are nine generic planets sampled near the planet prototype. P10 is our Pluto-analog: it carries the planet label, but its features sit at the small-mass, distant-orbit edge of the category, shown as the pink marker in the plot below.
It is worth pausing on what we have done to P10, because the whole experiment turns on it. P10 is pinned down two ways at once: by a label (the canon says "planet") and by its features (small, distant, on the category's edge). Most planets agree with themselves, label and features pointing the same way. P10 is built so that new evidence can pull them apart, and the question becomes: when the label says one thing and the features say another, which does the model follow? It is the same fork the real Pluto debate turned on.
Then we add six new entities, E1 through E6, the Eris-analogs, each labeled dwarf. The experimental knob is where in feature space we place those six dwarfs. There are two places they can go:
- The overlap region: the same features as P10. A dwarf placed here looks just like Pluto.
- The disjoint corner: the opposite end of feature space (huge mass, tiny diameter, near orbit). A dwarf placed here looks nothing like Pluto.
So the question is: of the six dwarfs, how many go in the disjoint corner? We call that knob the corner-mix. Click the buttons to run the world with four values of it and see where the six dwarfs land.
Aside: what "rote" means here
"Rote" is the everyday word: learning by memorizing flat pairings, without integrating them into anything else. A child who memorizes "8×7=56" as a free-standing fact, rather than working it out from 8×8 minus 8, has learned it by rote.
At corner-mix 6/6 the six dwarfs sit where no other category lives, so the model can only learn "dwarf" by rote: by memorizing that things-with-these-features are called dwarf, with no overlap or conflict against what it already knows about planets. There is no room for category strain, because the feature evidence and the label structure never compete. That makes 6/6 our control. If the model still attaches "dwarf" to P10 at 6/6, it cannot be because the features support it, since the dwarfs share none of P10's features. It would have to be something else: a frequency effect, the word dwarf simply becoming common. Hold onto that distinction. It is the hinge of the whole experiment, and we return to it in section 7.
2. Three ways of training
The model trains in two phases. Phase 1 is the canon: 28 entities (P1 through P10, plus asteroids, comets, moons), each described and labeled. Phase 2 is the new evidence: six dwarfs, described and labeled. How those phases get combined matters a great deal, so we compare three schedules.
The toy uses a 50,000-parameter transformer, roughly four million times smaller than ChatGPT-class models. We also test a 300,000-parameter version, still tiny, to ask whether more capacity changes the story.
3. The dual-label probe
Once the model is trained, we ask what it thinks P10 is. We give it the prompt
P10 has mass small diameter large orbit distant . P10 is a ___
and read the probability it puts on each next word. (The model produces a number for every word in its vocabulary, and the softmax turns those into probabilities that sum to 1.) A forced-choice probe would ask only whether planet beat dwarf. That throws away exactly what we care about: if the model is genuinely conflicted, holding both labels, forced-choice cannot say so.
The dual-label probe reads P(planet) and P(dwarf) independently. Each reading lands in a 2×2 grid:
| P(planet) high | P(planet) low | |
|---|---|---|
| P(dwarf) high | TENSION both labels in play |
swap label flipped |
| P(dwarf) low | canon still a planet |
nothing some third word wins |
"High" means a label clears an absolute floor of 10% of the probability. So a reading of (P_planet=0.45, P_dwarf=0.50) is TENSION; (0.01, 0.99) is a swap; (0.99, 0.01) is canon. Tension is structural conflict, the model holding two categorizations of the same features at once. A swap is just relabeling. Forced-choice sees both as "dwarf wins," but they are different states of the model, and only one of them is what a category-strain story would point to.
4. Train it once. Now train it again.
Here is the natural thing to do, and what our earlier write-ups did: train the model once, on the overlapping condition under the curriculum schedule, run the probe, and report the answer. Do that and P10 comes back as a canon planet, P(planet) near 0.87. Clean. You would write it down.
But that was one run, and a training run has randomness baked into it: which corpus we happen to generate from the world, and which random starting weights the model happens to get. So let us not train once. Click the button and train a model. Then train another. Then twenty. Each dot is one trained model's verdict on P10, placed by its P(planet) and P(dwarf) and colored by the 2×2 cell it lands in. The black star is the single run you would have done.
At the small model, the dots scatter across the whole plot. The single run you would have done, the star, says canon: P10 stays a planet. But that outcome is a minority. Most runs swap P10 to dwarf; a few land in genuine tension; one or two keep canon. The verdict is not a number. It is a distribution, and the one run we happened to do sat in its tail. Had we trained once and published, we would have reported a roughly one-in-twenty outcome as the finding.
So the honest read of "is P10 under strain?" is not a cell. It is the shape of this cloud. And that immediately raises a question: where does all that scatter come from?
5. What the wobble is made of
The cloud has two independent sources of randomness, and telling them apart is the whole methodological point. One is which corpus we drew from the world: a different sample of feature values and sentence orderings. The other is which starting weights the model got, the random seed of the optimizer. We can measure each on its own. Hold the starting weights fixed and vary only the corpus, and the spread you get is epistemic, the part driven by the data draw. Hold the corpus fixed and vary only the weights, and the spread is the optimizer's own noise.
Training many models this way, then measuring the spread, is called bootstrap-and-retrain. The bar below splits the wobble in P10's tension reading into its two parts, for the contested overlap condition and the rote-control.
Here is why this matters beyond the toy. The standard, cheap way to put error bars on a result like this is to retrain a handful of times with different seeds and report the spread. But that holds the data fixed: it measures only the grey bar. The corpus luck, often the larger share, is invisible to it. A single fixed corpus with a few seeds will hand you tight, confident error bars that hide most of the real uncertainty. You have to pay for the red bar by actually redrawing the data and retraining, and until you do, you do not know how much of your finding was the draw.
6. Does a bigger model fix it?
A natural hope is that the wobble is just a symptom of the model being too small, and that more capacity would settle it down. So flip the size toggle in section 4 to the large (300K) model and watch the cloud.
It does tighten. But look where it tightens: onto swap. At the larger size, run after run drives P(planet) for P10 to near zero, and the bootstrap is nearly unanimous. The bigger model is not more uncertain than the small one, and it is not more discerning either. It is more decisive: it calls P10 a dwarf, hard, every time.
Decisive on what grounds, though? In this overlapping condition we cannot yet say, because the features and the sheer frequency of "dwarf" in phase 2 both point the same way. Section 7 pulls them apart, and the answer is not flattering. What is clear already is the trap: more capacity buys confidence, not correctness. A crisp, repeatable verdict feels like the evidence has spoken, when it may only be the training schedule speaking louder. Low variance is necessary for a finding to be real. It is not sufficient. You can be tightly, repeatably, confidently wrong about a question that had no single right answer to begin with.
7. The control that backfired
Recall the control from section 1. At corner-mix 6/6 the six dwarfs sit in the disjoint corner, sharing none of P10's features. We built it precisely so that tension could not come from feature overlap: if P10 still picks up "dwarf" there, it can only be the frequency effect, the word becoming common, and not a real conflict over P10's features.
So we ran it, across a sweep of how prototype-edge P10 is (lower means more dwarf-like), at both model sizes. The plot is the fraction of trained models that classify P10 as TENSION, for the overlap condition and for the rote-control.
The red line should sit on the floor. It does not. Across every prototype edge and at both model sizes, the rote-control shows as much "tension" as the contested overlap condition, and usually more. P10 is picking up "dwarf" even though no dwarf shares any of its features. That is the frequency effect, exactly the thing the control was built to expose, and it means the probe's "tension" is not measuring feature conflict. It is catching a common label leaking onto P10. The control we designed to rule out the confound caught the confound instead.
Set this against the overlapping condition, because the contrast is the whole point. There, calling P10 a dwarf at least went along with its features. Here it goes along with nothing about P10: the features say planet, the canon says planet, the classifiers say planet, and the model leans dwarf regardless. The pull toward "dwarf" was never really about what P10 is like. It was about how often the word turned up.
To be fair, there is a faint signal in the intended direction at the far planet end of the sweep. But it is buried under the run-to-run scatter, and it does not survive at either size. The honest conclusion is a boundary, drawn cleanly: at this scale, this toy cannot separate genuine category tension from a frequent label leaking. That is a real limit, and it is better to know it than to have reported the clean-looking single run.
8. What the data alone says
One more check keeps us honest. The trained model is wobbling, but maybe the data is genuinely ambiguous, and the model is just faithfully reflecting that. So set the transformer aside and ask: given P10's three features, what does a plain statistical classifier say? Below are four shallow classifiers, each fit on the same labeled features the transformer trains on.
P(planet | P10's features). Dashed: P(dwarf | P10's features). Baselines are deterministic given the corpus; transformer error bars are one standard error across seeds.Every baseline tells the same clean story. At full overlap the data implies P10 is a dwarf; at full rote-control it implies P10 is a planet; in between the answer slides smoothly from one to the other. And no baseline ever lands in tension. At every corner-mix the data has one decisive answer. The data does not contain category strain; it contains a shifting single-label majority.
That is the punchline of this section. The model's instability is not the data being ambiguous, because the data is clear. It is the training process being a coin flip, plus the curriculum schedule's bias toward the frequent phase-2 label. The gap between the clean baseline and the wobbling model is variance and schedule, not insight.
9. What we learned
The toy set out to show that a small model could detect category strain. It ended up teaching something more useful, and more cautionary.
Start with what actually happened across the two schedules, because it is not what we first reported. The cells below are P10's probabilities on the two label words, next to what a plain classifier infers from P10's features alone.
| where the dwarfs sit → | on P10 0 of 6 | 2 of 6 | 4 of 6 | far corner 6 of 6 |
|---|---|---|---|---|
| the features imply | 0.13 / 0.73 | 0.31 / 0.45 | 0.49 / 0.17 | 0.67 / 0.00 |
| mixed says | 0.99 / 0.01 | 0.99 / 0.01 | 0.99 / 0.00 | 1.00 / 0.00 |
| curriculum (50K) says | 0.28 / 0.68 | 0.28 / 0.65 | 0.24 / 0.70 | 0.38 / 0.56 |
| curriculum (300K) says | 0.10 / 0.89 | 0.12 / 0.87 | 0.11 / 0.87 | 0.42 / 0.50 |
P(planet) / P(dwarf). The three model rows are label-tracking: the probability the model puts on the words "planet" and "dwarf." The top row is feature-tracking: what a classifier infers from P10's features alone, with no labels in sight. Green is planet-leaning, orange dwarf-leaning. Read across each row: only the features move. Mixed sits on "planet" everywhere, the canon label, even at 0 of 6 where the features say dwarf. Curriculum sits on "dwarf" everywhere, the frequent phase-2 word, even at 6 of 6 where the features put zero mass on dwarf.So neither schedule does the rational thing, which would be to read P10's category off its features. Mixed rehearses phase 1 throughout, so the canon label survives and P10 stays a planet, no matter what the new evidence shows. Curriculum fine-tunes on the new evidence without rehearsal, so the planet label erodes, but it slides toward the word that was frequent, not toward what the features support. Same data, opposite verdicts, and in both the feature evidence is a bystander.
- One run is one sample. A single training run gives a confident verdict, but the verdict is a draw from a distribution. Our one run said canon; the distribution said swap. The single run was not just uncertain, it was unrepresentative.
- Cheap error bars hide the bigger half. Retraining with a few seeds on a fixed corpus measures the optimizer's noise and misses the data-draw uncertainty, which is often larger. You have to redraw the data and retrain to see it.
- Scale buys confidence, not discernment. The larger model is more decisive, not more correct: it commits harder to "dwarf" without committing any harder to the features. A tighter answer is not a truer one.
- The control failed informatively. What the probe reads as "tension" is, at this scale, largely a frequent label leaking onto P10, not feature-driven conflict. The toy cannot, at 50K or 300K parameters, separate the two.
So the toy is best understood two ways at once. It is a clean, runnable demonstration of a method: when you ask whether a model has "noticed" something, retrain it many times, separate the data luck from the seed luck, and report the distribution rather than the run. And it is a cautionary tale: a single training run will hand you a clean result, a bigger model will hand you a confident one, and neither is the same as a true one.
This is a miniature of the question the parent project asks at full scale: what would it have taken for a model trained only on pre-2006 astronomy to recognize that the planet category was already strained? The toy's answer is modest and honest. There is no single "recognized" state to find. There is a distribution of things a model might do with the evidence, and the discipline that tells a real finding from an artifact is to retrain and look at the spread.
Underneath all of this is a genuine question, and the toy is a good place to feel its edges. A label invites inferences about what a thing is like, and later evidence can make those inferences misleading: a sky full of Eris-sized neighbors, sharing Pluto's features. When the label and the updated features finally disagree, which one fixes the thing's real kind? The toy does not settle it. What it shows is sharper, and a little deflating: the model's answer is not discovered from the features at all, it is decided by how we chose to train it. So was Juliet right, that a rose by any other name smells as sweet, the name idle and the features all that matter? For our model, no. The name was very nearly everything, and the smell, the features, barely registered.
10. Under the hood
This section is for readers who want the exact settings. The rest of the page can be read without it.
Architecture
Both sizes are minimal decoder-only transformers (the GPT-2 family, much smaller), in under 200 lines of PyTorch: pre-LayerNorm blocks, multi-head causal attention, a 4× MLP per block, tied input and output embeddings.
| small | large | |
|---|---|---|
| n_embd (width) | 32 | 64 |
| n_layer (blocks) | 4 | 6 |
| n_head | 4 | 4 |
| parameters | 54,464 | 306,688 |
The ensemble
The draw-a-run scatter, the variance split, and the edge sweep all come from bootstrap-and-retrain: for each condition we train B = 20 models from scratch. To separate the two sources of randomness we run three ensembles. Parametric: regenerate the corpus from a fresh random seed each time, holding the starting weights fixed. Bootstrap: resample the realized corpus with replacement (keeping each description glued to its label), again with fixed weights. Optimization: hold the corpus fixed and vary only the starting weights. The first two estimate the corpus (epistemic) uncertainty by different means and agree; the third is the seed-luck term that the older single-corpus sweeps measured on their own.
Corpus and training
The tokenizer is word-level, 64 tokens, fit on the union of both phases. Optimizer AdamW with a cosine learning-rate schedule; phase 1 runs 1,500 steps, the curriculum phase 2 a further 300 at a low-rate floor; mixed runs 1,500 steps on the joint corpus. All runs use a single Apple M-series GPU via PyTorch MPS; a small-model run takes about 30 seconds, a large-model run about 40. The full set of ensembles behind this page is a few hours of wall time.
The code is at github.com/bertybaums/pluto-toy. ensemble_tension.py runs the three ensembles; generate_corpus.py, train.py, and tension_probe.py are the world, the training loop, and the dual-label probe.