Long Short-Term Memory (LSTM): Explained Visually
Long Short-Term Memory (LSTM) is a special kind of recurrent neural network (RNN) that can remember information for a long time. A normal RNN forgets after about 10 to 20 words. An LSTM adds a separate memory line and three gates that decide what to forget, what to save and what to show. It was introduced by Hochreiter and Schmidhuber in 1997 and powered Google Translate, Siri and most speech and text systems until Transformers arrived.
- Why plain RNNs forget, and how LSTM fixes it
- What the cell state, hidden state and the three gates do
- The six LSTM equations, with a worked example
- How the forget gate keeps gradients alive
- Bidirectional and stacked LSTMs, and LSTM vs GRU vs Transformer
- LSTM in NumPy (from scratch) and in PyTorch
Contents
Why do we need LSTM?
Read this sentence: "I grew up in France, moved to Bangalore for work, learned to cook dosa, and after all these years I still speak fluent ____."
You know the answer is French, because you remembered the word France from the start of the sentence. To predict the blank, a model must carry one piece of information across almost 20 words. This is called a long-term dependency.
A plain RNN struggles with this. During training, the error signal has to travel backwards through every word. At every step it is multiplied by a number. If that number is smaller than 1, the signal shrinks again and again until it disappears. This is the vanishing gradient problem. If the number is larger than 1, it grows until training breaks. That is the exploding gradient problem.
Play with the visual below. The pink bars show how much of the signal from word 1 is still alive in a plain RNN. The mint bars show an LSTM with a forget gate close to 1.
0.8 multiplied by itself 40 times is about 0.0001. In other words, after 40 words only 0.01% of the learning signal reaches the first word. With 1.2 instead of 0.8, it becomes about 1,470. Small changes in the factor make a huge difference.
The big idea: a memory highway
The LSTM solves this with a simple design trick. It keeps two kinds of memory:
| Memory | Symbol | Think of it as | Changes how? |
|---|---|---|---|
| Cell state | ct | Long-term memory, a notebook carried through the whole sentence | Only by a multiply (forget) and an add (write) |
| Hidden state | ht | Short-term memory, what the cell says out loud at this step | Recomputed fully at every step |
The cell state runs like a straight highway through time. Information can ride along it for many steps almost untouched. Three gates stand beside the highway and control traffic.
Imagine a bank clerk handling your loan file. Each day a new document arrives (the input). The clerk decides which old notes to tear out (forget gate), which new facts to add (input gate) and what to tell you today (output gate). The file itself (the cell state) travels from day to day and keeps the important history.
LSTM architecture
Every LSTM cell takes three inputs and produces two outputs:
- Inputs: the current word xt, the previous hidden state ht-1 and the previous cell state ct-1.
- Outputs: the new hidden state ht and the new cell state ct.
Inside the cell there are four small neural network layers: three gates that use the sigmoid function (output between 0 and 1) and one candidate layer that uses tanh (output between -1 and 1). A gate value of 0 means "let nothing through" and 1 means "let everything through".
Use the interactive cell below. Move the sliders to change the inputs, try the three scenarios, then press Play to watch the data flow one gate at a time. Every number is computed live.
How an LSTM works, step by step
Step 1: Forget gate, what should we erase?
The forget gate looks at the previous hidden state and the current word, and outputs a number between 0 and 1 for every value in the cell state.
- f = 1 means keep this memory completely.
- f = 0 means erase it completely.
Example: in "Ravi is a doctor. Priya is a teacher. She…", when the model reads the new subject Priya, the forget gate can erase "the subject is male" so that she makes sense.
Step 2: Input gate and candidate, what new information should we save?
This step has two parts that work together:
- The candidate gt is the new information itself (for example, "the subject is now female").
- The input gate it decides how much of that candidate to actually write. Not every word is worth remembering. Words like the or is usually get a small input gate value.
Step 3: Update the cell state
Now the old memory and the new information are combined:
Here ⊙ means element-wise multiplication. The first part is "what we kept", the second part is "what we added". This single line is the heart of the LSTM.
Step 4: Output gate, what should we show?
The cell does not reveal its whole memory at every step. The output gate decides which parts are useful right now:
The new hidden state ht goes to the next time step and to the next layer (for example, a classifier that predicts the next word).
Forget what is old, input what is new, output what is needed. Three gates use sigmoid because they are "how much" decisions. The candidate uses tanh because it is the actual content, which can be positive or negative.
A worked example with real numbers
Let us run one LSTM step with a single memory unit so you can follow every number. Suppose the gates have already been computed from xt and ht-1:
| Quantity | Value | Meaning |
|---|---|---|
| Old memory ct-1 | 0.80 | The cell strongly remembers something |
| Forget gate ft | 0.90 | Keep 90% of it |
| Input gate it | 0.30 | Write only 30% of the new info |
| Candidate gt | -0.50 | New info points the other way |
| Output gate ot | 0.60 | Show 60% of the memory |
Now compute:
- Kept memory = f × ct-1 = 0.90 × 0.80 = 0.72
- New information = i × g = 0.30 × (-0.50) = -0.15
- New cell state ct = 0.72 + (-0.15) = 0.57
- tanh(0.57) = 0.515
- New hidden state ht = 0.60 × 0.515 = 0.31
The memory went down a little (from 0.80 to 0.57) because the new word disagreed, but most of it survived. Set the sliders in the visual above to see the same behaviour.
How LSTM solves the vanishing gradient problem
In a plain RNN, the gradient from one step to the previous step is multiplied by the recurrent weights and the tanh derivative every time. In an LSTM, look at how the cell state is updated: ct = ft ⊙ ct-1 + it ⊙ gt. If we take the derivative of ct with respect to ct-1 along the highway, we get:
So the gradient is multiplied only by the forget gate. The network can learn to keep f close to 1 for information that matters, so the gradient survives for 100+ steps. This additive path is the same idea later used in ResNet's skip connections.
LSTMs reduce the vanishing gradient problem, they do not remove it. For very long documents (thousands of tokens), LSTMs still forget, and they cannot be trained in parallel across time steps. These two limits are why Transformers replaced them for large language models.
LSTM in Python
LSTM from scratch in NumPy
This code implements exactly the four equations above. Read it next to the formulas.
import numpy as np
np.random.seed(42)
sigmoid = lambda z: 1 / (1 + np.exp(-z))
input_size, hidden_size = 3, 2
# one weight matrix and bias per gate: forget, input, candidate, output
W = {g: np.random.randn(hidden_size, hidden_size + input_size) * 0.5 for g in "figo"}
b = {g: np.zeros(hidden_size) for g in "figo"}
b["f"] += 1.0 # common trick: start by remembering
def lstm_step(x_t, h_prev, c_prev):
z = np.concatenate([h_prev, x_t]) # [h_{t-1}, x_t]
f = sigmoid(W["f"] @ z + b["f"]) # forget gate
i = sigmoid(W["i"] @ z + b["i"]) # input gate
g = np.tanh(W["g"] @ z + b["g"]) # candidate memory
o = sigmoid(W["o"] @ z + b["o"]) # output gate
c_t = f * c_prev + i * g # new cell state
h_t = o * np.tanh(c_t) # new hidden state
return h_t, c_t, f
sequence = np.random.randn(4, input_size) # 4 time steps
h, c = np.zeros(hidden_size), np.zeros(hidden_size)
for t, x_t in enumerate(sequence, 1):
h, c, f = lstm_step(x_t, h, c)
print(f"t={t} forget={f.round(2)} cell={c.round(3)} hidden={h.round(3)}")
t=1 forget=[0.8 0.77] cell=[-0.033 0.055] hidden=[-0.015 0.016] t=2 forget=[0.46 0.74] cell=[0.726 0.379] hidden=[0.387 0.279] t=3 forget=[0.84 0.7 ] cell=[0.515 0.127] hidden=[0.205 0.05 ] t=4 forget=[0.68 0.54] cell=[ 0.334 -0.096] hidden=[ 0.134 -0.076]
Notice two things in the output. First, the forget values start high (about 0.8) because we added 1.0 to the forget bias. This "remember by default" trick is used in real libraries too. Second, the cell state carries value from step 2 into steps 3 and 4 even as new words arrive.
LSTM for sentiment analysis in PyTorch
In practice you use a library. This model reads a review of 50 word IDs and predicts positive or negative.
import torch
import torch.nn as nn
class SentimentLSTM(nn.Module):
def __init__(self, vocab_size=10_000, embed_dim=100, hidden=128):
super().__init__()
self.embed = nn.Embedding(vocab_size, embed_dim)
self.lstm = nn.LSTM(embed_dim, hidden, batch_first=True)
self.fc = nn.Linear(hidden, 1)
def forward(self, x):
out, (h_n, c_n) = self.lstm(self.embed(x)) # h_n: final hidden state
return torch.sigmoid(self.fc(h_n[-1])) # probability of "positive"
model = SentimentLSTM()
batch = torch.randint(0, 10_000, (32, 50)) # 32 reviews, 50 words each
print(model(batch).shape)
print(sum(p.numel() for p in model.lstm.parameters()))
torch.Size([32, 1]) 117760
Where does 117,760 come from? An LSTM layer has 4 weight blocks (one per gate and candidate). Each block has input weights (128 × 100), recurrent weights (128 × 128) and, in PyTorch, two bias vectors of 128. So the total is 4 × (128×100 + 128×128 + 128 + 128) = 4 × 29,440 = 117,760. That is 4 times more than a plain RNN of the same size.
Types of LSTM
Runs one LSTM left to right and another right to left, then joins their outputs. Each word sees both its past and its future context. Great for tasks where the full sentence is available, such as named entity recognition and sentiment analysis. Not usable for real-time next-word prediction, because the future is not known yet.
In PyTorch: nn.LSTM(100, 128, bidirectional=True) gives an output size of 256 (128 from each direction).
Puts several LSTM layers on top of each other. The hidden states of layer 1 become the inputs of layer 2. Lower layers learn simple patterns (word endings, short phrases), higher layers learn more abstract ones (sentence meaning). Two to four layers is common. In PyTorch: nn.LSTM(100, 128, num_layers=2, dropout=0.2).
The Gated Recurrent Unit (2014) merges the cell state and hidden state into one, and uses only two gates: an update gate (forget and input combined) and a reset gate. It has about 25% fewer parameters than an LSTM, trains faster, and often performs just as well on small and medium datasets.
LSTM vs RNN vs GRU vs Transformer
| Feature | Plain RNN | LSTM | GRU | Transformer |
|---|---|---|---|---|
| Memory | Hidden state only | Cell state + hidden state | Hidden state with gates | Attention over all tokens |
| Gates | None | 3 (forget, input, output) | 2 (update, reset) | None (uses attention) |
| Long-range memory | Poor (~10–20 steps) | Good (~100s of steps) | Good | Excellent (whole context window) |
| Parameters (same size) | 1× | 4× | 3× | Much larger in practice |
| Parallel training over time | No | No | No | Yes |
| Typical use today | Teaching, tiny models | Time series, speech, on-device text | Same as LSTM, when speed matters | LLMs, translation, almost all NLP |
Applications of LSTM
- Time-series forecasting: stock prices, electricity demand, sales and sensor readings.
- Speech recognition: converting audio frames to text (used in early Siri and Google Voice).
- Machine translation: the original Google Neural Machine Translation (2016) used stacked LSTMs.
- Text generation and next-word prediction: mobile keyboards.
- Anomaly detection: fraud in card transactions, faults in machines.
- Healthcare: reading patient vital signs over time.
Advantages and limitations
Remembers long-range patterns much better than a plain RNN. Handles variable-length sequences. Works well with small and medium data. Cheap to run on devices with little memory.
Slow to train because steps run one after another. Four times more parameters than an RNN. Still forgets over very long sequences. Usually beaten by Transformers when lots of data and GPUs are available.
- An LSTM is an RNN with a cell state (long-term memory) and three gates.
- Forget gate erases, input gate writes, output gate reveals. Gates use sigmoid (0 to 1); the candidate uses tanh (-1 to 1).
- The core update is ct = f ⊙ ct-1 + i ⊙ g. Because it is mostly addition, gradients survive many steps.
- An LSTM has 4 times the parameters of a plain RNN: 4 × (h·x + h·h + h).
- GRU is a lighter alternative; Transformers replaced LSTMs for large-scale NLP because they train in parallel and attend to the whole context.
Test yourself
Score: 0 / 51. Which part of an LSTM acts as the long-term memory?
2. The forget gate outputs 0.02 for a memory value. What happens to that memory?
3. Why do the gates use the sigmoid function?
4. How many parameters does nn.LSTM(input_size=10, hidden_size=20) have in PyTorch?
5. What is the main reason Transformers replaced LSTMs for large language models?
Frequently asked questions
What is the difference between the cell state and the hidden state in an LSTM?
The cell state is the long-term memory that flows through time with only small, controlled changes. The hidden state is the short-term output at each step, computed as the output gate times tanh of the cell state. The hidden state is what the next layer sees.
Is LSTM still used in 2026?
Yes, but mostly for time-series forecasting, speech, sensor data and small on-device models. For large-scale text tasks, Transformers and LLMs are the standard. LSTM is still a very common interview topic because it explains the vanishing gradient problem and gating clearly.
Why is the forget gate bias often initialised to 1?
With a bias of 1, the forget gate starts around 0.73, so the cell remembers by default at the start of training. This helps gradients flow early on and usually speeds up learning.
What is the difference between LSTM and GRU?
A GRU merges the cell and hidden states and uses two gates (update and reset) instead of three. It has fewer parameters and trains faster. LSTM can be slightly better on very long or complex sequences. In practice, try both.
Can an LSTM have an exploding gradient?
Yes. The cell state path is protected, but other paths through the gates can still explode. That is why gradient clipping (for example, clip_grad_norm_ in PyTorch) is standard when training LSTMs.
Real interview walkthroughs and AI explained simply on our YouTube channel.