Give it something to remember
Two names, an inside joke, the date that mattered. Whatever you type becomes the only input this exact reservoir has ever seen.
Example shown — try your own. Lowercase a–z, digits, space, and
. , ! ? & ' - are understood; anything else reads as a space.
Here's the shape it left
Every character nudges the network's hidden state a little further from where it started. The line on the left traces that path through space; the network on the right lights up the same way it actually did — teal for positive activation, rust for negative. Play it back to watch the memory form both ways at once.
Pick a look
Pick a Trace or a Fingerprint to download. That's your unique signature for the text that created it, drawn from the exact network configuration built just for you above.
How this actually works — reservoirs, spectral radius, and the node-link diagram underneath
The weights aren't trained — they're a seeded random reservoir (an echo state network, which is what this tool is named for), rescaled so the recurrent matrix hits a target spectral radius before any of this runs. It's the single biggest lever on how the network behaves, so it's worth playing with directly:
Below about 0.55 the state settles fast and forgets almost everything except the last couple of characters ("fixed point"). Above about 1.05 small differences compound instead of fading, so the trace can swing wildly and two similar inputs can end up looking unrelated ("saturating / chaotic"). The range in between is where a reservoir is actually useful — it remembers enough of what came before to make the trace mean something, without either collapsing to a point or blowing up.
At every character, the hidden state updates by:
xt is the current character as a 6-bit code (44 symbols — a–z, 0–9, space, and basic punctuation — rather than one-hot, which is most of why this stays small). Because there's no "correct" version being approximated, quantizing the weights to int8 for the QR code loses nothing that matters: the quantized weights are the model. Parameter count is fixed by H alone — H×(H+7) — 120 at the H=8 every new reservoir here uses — and never grows with the length of what you type.
Notice that formula only ever reaches back one step — each new state depends on the character just read and the state right before it, nothing further back than that. There's no backpropagation-through-time here, no training, no literal "unrolled" computation graph — it's a plain loop, computed forward once. What does get kept, purely for this page's own trace and playback, is every state along the way, not just the current one:
That's the whole picture of the trace and playback in step 02: states[t] is just this loop's own output, one snapshot per character, stored as it's computed rather than thrown away.
The trace itself is a projection, not the raw state — with 8 hidden units, the actual path lives in 8 dimensions, so what's plotted is the top 2 principal components of this run's own sequence of states (computed fresh for whatever you typed, not a fixed or precomputed projection).
That also means the whole network is small enough to draw honestly, node by node, connection by connection — not a stylized stand-in, the literal live weights of the reservoir above:
Input units sit on the left, feeding the six lines on the right through teal (positive) and rust (negative) connections — line opacity is weight magnitude. The hidden units sit in a ring, fully recurrent: every unit feeds every other unit, including itself, which is what makes it a loop instead of a straight pipeline. Node fill here follows the same convention, keyed to that unit's bias — this is the network's fixed wiring, unaffected by what you type. For how those same weights light up while actually reading your text, see the live diagram in step 02 above, or export it as its own print in step 03.