Neural Networks
RNN vs LSTM Memory
Why information dies as it is passed forward through time: the gradient reaching an early step is a product of one factor per step, and only a gate can hold those factors near 1.
Stage 1 of 5: One cell, one loop
A single RNN cell, before it is unrolled. Its own output returns as an input on the next step.
A recurrent cell is a dense layer whose own output comes back as an input on the next step. Here is the loop before we unroll it.
Check your understanding
The gradient reaching the first token is a product of one factor per step. This lab plots that product, and shows why turning the recurrent weight up cannot fix it while a forget gate can.
What you are looking at
The upper panel is a recurrent cell unrolled along time: one circle per timestep, all of them the same cell reusing the same weights. Under each one are up to three bars — the hidden state on the left, the cell state in the middle, and the forget gate on the right, as the stages introduce them. The Input Tokens row beneath the controls is the sequence being fed in, and every value in it is editable.
The lower panel, which arrives at the third stage, is the point of the lab. It plots how much the final state still depends on each earlier step. The axis is , so exponential decay is a straight line and a twelve-decade collapse still fits on screen. The dashed horizontal line is one part in a thousand — below it, the earliest input has no influence an optimiser could act on.
Where the number in the lower panel comes from
Backpropagation through time is the chain rule applied along the sequence. The gradient arriving at step has been multiplied by one Jacobian per step between and the end, and for a single-unit cell that Jacobian is a single number.
For the RNN:
Two factors, and they fail in opposite directions. is at most 1 and heads to 0 as the unit saturates, so it can only ever shrink the signal. is unbounded, so it is the one that could grow it.
Which suggests an obvious fix, and the obvious fix does not work.
Why a bigger recurrent weight does not help
Move Recurrent Weight up from its default of 0.8 and watch Earliest Influence over a ten-step sequence:
| Earliest influence | Memory horizon | |
|---|---|---|
| 0.2 | 5.1e-7 | 5 of 10 |
| 0.5 | 1.8e-3 | 10 of 10 |
| 0.8 | 9.6e-2 | 10 of 10 |
| 1.0 | 2.8e-1 | 10 of 10 |
| 1.2 | 9.1e-2 | 10 of 10 |
| 1.5 | 2.0e-3 | 10 of 10 |
| 2.0 | 1.7e-6 | 4 of 10 |
It peaks at and falls away on both sides. The reason is in the formula: a larger weight drives toward , and at the factor is 0.02. You have bought a bigger by destroying . The two halves of the product fight, and 0.283 is the best this architecture manages over ten steps at any setting.
A bucket chain with leaky buckets
Passing water down a line of people, each one spills a fraction. Ten people in, most of the water is gone, and there is no arrangement of spilling that gets it all the way.
You could try throwing harder — that is . But throw hard enough and the buckets overflow, and an overflowing bucket does not pass on more, it passes on whatever it can hold and loses the rest. That ceiling is , and it is why throwing harder stops helping.
What actually works is not throwing at all. Put the water on a conveyor belt and let each person decide whether to take some off or add some. Nobody has to pass it on, so nobody spills it. That is the cell state.
The gate
Switch to the LSTM at the fourth stage and both curves stay on screen, so you are reading a comparison rather than remembering one.
The LSTM keeps a second channel, the cell state, and updates it by addition:
Differentiate that with respect to and you get the whole reason the architecture exists:
The forget gate, and nothing else. No activation derivative, so nothing capped at 1 by a squashing function and nothing that shrinks because the unit happens to be saturated. And is learned — the network can decide to hold this path open, which is not a decision an RNN gets to make.
This lab holds the input and output gates at with zero weights so the scene isolates the forget gate; both values are printed in the metrics rather than left silent.
An LSTM does not preserve memory by existing
The forget gate bias defaults to 1, which is the standard initialisation and looks like it ought to be enough. It is not. , so the per-step factor is 0.731 and over nine steps that is — measured in this lab as slightly worse than the RNN at its own default of 9.6e-2.
Push Forget Gate Bias to 3 and the gate sits at 0.953, giving 0.646 over the same ten steps. That is the LSTM winning, and it wins because the gate is nearly open, not because it is an LSTM.
The positive bias initialisation is a head start, not a solution: it puts the gate on the open side of 0.5 so that gradient can flow at all in the first few epochs, which is what lets training discover where the gate should actually be. Read the reference card's memory-horizon row and then compare bias 1 against bias 3 — the architecture is the same in both, and one of them remembers.
When it fails, and what it fails into
Drag Forget Gate Bias to −3. The gate closes to 0.047, the forget-gate bars shrink to almost nothing, and the memory horizon collapses to 3 of 10 steps — the earliest token's influence on the final state is 1.2e-12, twelve orders of magnitude down.
It is worth being precise about what has happened, because the intuitive description is wrong. With the update becomes : the cell state depends on the current input only, with no term carrying the past at all. That is not an LSTM behaving like an RNN — an RNN still routes the past through and manages 9.6e-2 over those same ten steps. A shut forget gate is worse than having no gate, because it actively erases what it is holding.
Reference
- RNN update
- h_t = tanh(W_h·h_{t-1} + W_x·x_t + b) — one weight, reused at every step
- RNN backward
- ∂h_t/∂h_{t-1} = (1 − h_t²)·W_h — the activation derivative times the recurrent weight
- Why it vanishes
- the gradient reaching step k is the product of those factors over every later step. tanh′ ≤ 1, so the product can only shrink unless W_h > 1
- Why W_h > 1 does not help
- a larger weight saturates the unit, and tanh′ collapses toward 0. The two factors fight; the best this lab reaches over ten steps is 0.283, at W_h = 1
- Forget gate
- f_t = σ(W_f·[h_{t-1}, x_t] + b_f). Decides what of the past to keep
- Input gate
- i_t = σ(W_i·[h_{t-1}, x_t] + b_i). Decides what of the present to write
- Output gate
- o_t = σ(W_o·[h_{t-1}, x_t] + b_o). Decides what of the cell state to expose as h_t
- Cell state
- c_t = f_t·c_{t-1} + i_t·g_t. Addition, not a fresh matrix product
- LSTM backward
- ∂c_t/∂c_{t-1} = f_t exactly — no activation derivative in it at all, which is the entire trick
- Memory horizon
- how many steps back the final state still depends on, before the sensitivity falls under 1e-3
- Input/output gates fixed here
- i and o are held at σ(10) ≈ 0.99995 with zero weights, so the scene isolates the forget gate. Both are shown as readouts rather than left silent
Break it on purpose
Drag Forget Gate Bias to −3. The gate closes to 0.047, so every step multiplies the cell state by that and the memory horizon collapses to 3 of 10 steps — the earliest token’s influence on the final state is 1.2e-12. That is not "an LSTM behaving like an RNN": an RNN still has recurrence through its weight and manages 9.6e-2 over the same ten steps. A shut forget gate is worse than no gate at all, because it actively erases what it is holding.