GATED MEMORY · ONE STEP · INTERACTIVE

LSTM · GRU · KDA

The same token "journey" (x₁ = [0.55, 0.87, 0.66]) meets the same yesterday
(s₀ = [0.80, 0.50, 0.30], the memory left after "your") — only the memory update rule changes.
Gates act per dimension: every gate below is 3 numbers, one for each dimension of the memory state.
Parameters — move any slider, every number below recomputes
LSTM — what the dials mean
f — forget: how much of yesterday each dim keeps
i — input: how much of the candidate gets written
a₁ — candidate: the new content itself (tanh, can be negative)
o — output: how much of the memory is exposed as h₁
f and i are independent: keeping and adding are separate decisions.
GRU — what the dials mean
f — the single keep dial (shared with LSTM above)
1 − f — the write dial: adding is forced to be what's left of keeping
r — reset: how much of yesterday the candidate may see
ã₁ — candidate built from r ⊙ s₀ (r₃ = 0 → dim 3 is blind to yesterday)
No output gate, no tanh: h₁ = s₁, the raw state is exposed.
KDA — what the dials mean
α — per-channel keep rate: each memory column has its own clock
β — write strength: how hard this key–value pair updates memory
k — key: which slot to erase and write to
v — value: what gets written
q — query: which slot to read. Memory is a dictionary, not a dial.
x₁ = [0.55, 0.87, 0.66]  ("journey")
s₀ =  (yesterday, after "your")
gates = assumed sigmoid outputs ∈ (0, 1)
candidates = assumed tanh outputs ∈ (−1, 1)
Same skeleton · three update rules
LSTM
s₁ = f ⊙ s₀ + i ⊙ a₁
h₁ = o ⊙ tanh(s₁)
→
GRU
s₁ = f ⊙ s₀ + (1 − f) ⊙ ã₁
ã₁ = tanh(W·[r ⊙ s₀ ; x₁])   h₁ = s₁
→
KDA
S₂ = S₁ · ( Diag(α) − β·k·(α⊙k)′ ) + β·v·k′
o₂ = S₂ · q
Same skeleton, three dialects — memory: s₀ ↔ S  ·  forget: f ↔ Diag(α)  ·  input: i ⊙ a₁ ↔ β·v·k′  ·  readout: h₁ ↔ S·q
Step by step · keep → add → read

Same step, three behaviors — focus on dim 3

s₀₃ = yesterday. What each model keeps of it, what it adds, and what it shows:
ModelKept of old (dim 3)Added of new (dim 3)WhyReadout (dim 3)