RNN: What is the difference between LSTM and GRU?

Published

This is a series where I answer the questions my tutoring students really ask – the ones textbooks tend to skip. I teach machine learning, deep learning, statistics, and math to graduate students and working engineers.


The question. After we worked through an LSTM by hand, a student asked: “Everyone says a GRU is just a simplified LSTM. Simplified how, exactly? What did they throw out, and what does it cost?”

The fairest way to answer is to run the same prediction through both cells with the same weights and watch where the numbers diverge. So here is one day of temperature forecasting, computed twice.

The setup: predicting tomorrow’s temperature

The task, taken straight from our teaching notebook: predict tomorrow’s air temperature from today’s humidity, today’s sea-level pressure, and yesterday’s prediction. The output is a temperature index where 0.0 is freezing, 0.50 is mild, 0.77 is warm, and 1.25 is extreme heat.

Both cells share the same small weight collection, so any difference in behavior comes from the architecture, not the parameters:

Input weights (on humidity and pressure):
  candidate  W = [0.45, 0.25],  b = 0.20
  gate 1     W = [0.95, 0.80],  b = 0.65   (LSTM input gate  / GRU update gate)
  gate 2     W = [0.70, 0.45],  b = 0.15   (LSTM forget gate / GRU reset gate)
  gate 3     W = [0.60, 0.40],  b = 0.10   (LSTM output gate only)

Recurrent weights (on yesterday's output): 0.15, 0.80, 0.10, 0.25

Day 0’s input is humidity 1.0 and pressure 2.0, and yesterday’s output and memory start at zero. The actual temperature index on day 0 is 0.50.

The LSTM step: three gates, two memories

An LSTM carries two separate memories: the cell state (long-term) and the output (short-term). Three sigmoid gates decide what to keep, what to record, and what to reveal:

LSTM cell diagram with forget input and output gates

Here is the day-0 computation. I write sig() for the sigmoid function:

a_0 = tanh(0.45*1 + 0.25*2 + 0.15*0 + 0.20) = tanh(1.15) = 0.818   candidate
i_0 = sig (0.95*1 + 0.80*2 + 0.80*0 + 0.65) = sig(3.20)  = 0.961   input gate
f_0 = sig (0.70*1 + 0.45*2 + 0.10*0 + 0.15) = sig(1.75)  = 0.852   forget gate
o_0 = sig (0.60*1 + 0.40*2 + 0.25*0 + 0.10) = sig(1.50)  = 0.818   output gate

state_0 = f_0 * 0 + i_0 * a_0 = 0.852*0 + 0.961*0.818 = 0.786   long-term memory
out_0   = o_0 * tanh(state_0) = 0.818 * 0.656         = 0.536   prediction

The prediction 0.536 lands close to the actual 0.50. Notice the two-step reveal: the cell state first absorbs 96% of the candidate into long-term memory, and then the output gate decides that only 82% of that memory, squashed through tanh, becomes the visible prediction.

LSTM forward pass at day zero with the temperature arithmetic

The GRU step: same numbers, two gates, one memory

A GRU keeps only one memory, the hidden state, which is both the long-term memory and the output. It merges the input and forget gates into a single update gate z, and adds a reset gate r that controls how much of the past the new candidate is allowed to see. There is no output gate at all:

GRU cell diagram with update and reset gates

Same day, same weights:

z_0 = sig (0.95*1 + 0.80*2 + 0.80*0 + 0.65) = sig(3.20)  = 0.961   update gate
r_0 = sig (0.70*1 + 0.45*2 + 0.10*0 + 0.15) = sig(1.75)  = 0.852   reset gate
h~_0 = tanh(0.45*1 + 0.25*2 + 0.15*(r_0*0) + 0.20) = tanh(1.15) = 0.818   candidate

h_0 = (1 - z_0)*0 + z_0 * h~_0 = 0.961 * 0.818 = 0.786   prediction and memory in one

Look at that last line carefully. The GRU’s output, 0.786, is exactly the LSTM’s cell state – the number the LSTM kept hidden inside. The GRU simply publishes its whole memory as the prediction, with no tanh squash and no output gate deciding how much to reveal. That single observation is most of the answer to my student’s question.

Day 1: where the difference starts to matter

On day 1 the input is humidity 0.5, pressure 3.0, and yesterday’s output. The actual temperature index is 1.25, extreme heat. Running both cells:

LSTM:  state_1 = 0.870*0.786 + 0.981*0.851 = 1.518
       out_1   = 0.850 * tanh(1.518) = 0.772

GRU:   z_1 = 0.985,  r_1 = 0.873
       h~_1 = tanh(0.45*0.5 + 0.25*3 + 0.15*(0.873*0.786) + 0.20) = tanh(1.278) = 0.856
       h_1  = (1 - 0.985)*0.786 + 0.985*0.856 = 0.855

Both underestimate the heat, but the GRU is bolder: 0.855 against the LSTM’s 0.772. The LSTM’s output gate acts like a cautious editor between memory and prediction, while the GRU’s update gate writes 98.5% of the new candidate straight into the state it shows the world. Neither is wrong; they make different trade-offs.

So what is the actual difference?

LSTM GRU
Gates 3 (input, forget, output) 2 (update, reset)
Memories 2 (cell state + hidden output) 1 (hidden state)
What is revealed o * tanh(cell state) the whole state
Parameter sets 4 3

The parameter difference is real and you can measure it in two lines:

import torch.nn as nn
sum(p.numel() for p in nn.LSTM(2, 8, batch_first=True).parameters())  # 384
sum(p.numel() for p in nn.GRU(2, 8, batch_first=True).parameters())   # 288

A GRU carries 25% fewer parameters at any hidden size, which means less memory, faster training, and less data needed before it stops underfitting. The LSTM’s extra output gate buys finer control over what the memory reveals, and its protected cell state – an express lane that gradients can flow through almost untouched – is still the safer default when sequences get long and the important events are far apart. In practice the honest answer is boring: on most medium-sized problems they perform almost identically, so start with the GRU for speed and switch to the LSTM if you suspect the output gating matters.

One thing to try

Take the day-1 GRU arithmetic and force r_1 = 0. The candidate becomes tanh(0.45*0.5 + 0.25*3 + 0.20) = tanh(1.175) = 0.826, and yesterday’s 0.786 survives only through the tiny (1 - z_1) channel. Now force z_1 = 1 and watch the state get completely overwritten every day. These two knobs – how much of the past the candidate may see, and how much of the past the state may keep – are the entire GRU. Compare that with the LSTM, where f and i control the past and the present independently. That independence is what the GRU gave up for its 25% discount.


The arithmetic in this article is adapted from the teaching notebooks I use with my students, where every gate value is computed by hand before any library is allowed.

References

  1. Hochreiter, S., & Schmidhuber, J. (1997). “Long Short-Term Memory.” Neural Computation 9(8).
  2. Cho, K., et al. (2014). “Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation.” arXiv:1406.1078.
  3. Chung, J., et al. (2014). “Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling.” arXiv:1412.3555.
  4. Olah, C. (2015). “Understanding LSTM Networks.” colah’s blog.

I tutor machine learning, deep learning, statistics, and math. If recurrent networks – or anything else – are not clicking for you, you can find me on Wyzant.