Back to Data Science Notes
Topic #81

LSTMs & GRUs

Understand how Long Short-Term Memory (LSTM) and Gated Recurrent Unit (GRU) networks solve the vanishing gradient problem in sequential data, enabling models to learn long-range dependencies.

What it is

Standard Recurrent Neural Networks (RNNs) struggle with long sequences because gradients vanish or explode during backpropagation. LSTMs and GRUs are specialized RNN architectures that introduce gating mechanisms. These gates act as valves, regulating the flow of information into and out of a memory cell. This allows the network to retain relevant context over many time steps while discarding irrelevant noise.

An LSTM uses three gates: forget, input, and output. A GRU simplifies this to two gates: update and reset, merging the cell state and hidden state. Both are "gated units" designed for sequence modeling tasks like text generation, speech recognition, and time-series forecasting.

Why it matters

  • Solves Vanishing Gradients: Gates allow error signals to propagate backward through time without decaying to zero.
  • Long-Range Dependencies: Essential for tasks where early inputs influence later outputs (e.g., subject-verb agreement in long sentences).
  • Selective Memory: The model learns what to remember and what to forget, improving efficiency on noisy data.
  • Versatility: Applicable to any sequential data type, including audio, video frames, and financial ticks.

Syntax or steps

The core logic involves updating the cell state ($C_t$) and hidden state ($h_t$) at each time step $t$. For an LSTM:

  1. Forget Gate: Decides what information to discard from the previous cell state.
  2. Input Gate: Decides which new values to update in the cell state.
  3. Candidate Values: Creates a vector of new candidate values.
  4. Update Cell State: Combines old state (scaled by forget gate) and new candidates (scaled by input gate).
  5. Output Gate: Determines what part of the cell state becomes the hidden output.

Example

Below is a minimal implementation using PyTorch. It defines a simple LSTM layer processing a batch of sequences.

import torch
import torch.nn as nn

class SimpleLSTM(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers=1):
        super(SimpleLSTM, self).__init__()
        # Define the LSTM layer
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        # Linear layer to map hidden states to output classes
        self.fc = nn.Linear(hidden_size, 1) 

    def forward(self, x):
        # x shape: (batch_size, seq_length, input_size)
        # Initialize hidden and cell states to zeros
        h0 = torch.zeros(1, x.size(0), self.lstm.hidden_size).to(x.device)
        c0 = torch.zeros(1, x.size(0), self.lstm.hidden_size).to(x.device)
        
        # Pass through LSTM
        # out shape: (batch_size, seq_length, hidden_size)
        # hn/cn are final hidden/cell states
        out, (hn, cn) = self.lstm(x, (h0, c0))
        
        # Take only the last time step's output for classification/regression
        last_out = out[:, -1, :] 
        prediction = self.fc(last_out)
        return prediction

# Usage
model = SimpleLSTM(input_size=10, hidden_size=20)
dummy_input = torch.randn(32, 5, 10) # Batch=32, SeqLen=5, Features=10
output = model(dummy_input)
print(output.shape) # Expected: torch.Size([32, 1])

Explanation: The nn.LSTM handles the complex gating math internally. We initialize hidden (h0) and cell (c0) states. The forward pass returns all intermediate outputs; we select the last one (out[:, -1, :] ) because it contains the accumulated context of the entire sequence, which is then passed to a fully connected layer for prediction.

Common mistakes

  • Forgetting Initialization: Not passing initial hidden/cell states can lead to errors if the batch size changes between training and inference. Always ensure shapes match.
  • Using All Outputs Incorrectly: If you need a single prediction per sequence, use the last hidden state. If you need predictions per time step (e.g., language modeling), use all outputs but reshape carefully.
  • Ignoring Sequence Length Variance: Real-world data has variable lengths. You must pad sequences and use pack_padded_sequence in PyTorch to prevent the model from learning from padding tokens.
  • Overfitting Small Data: LSTMs have many parameters. On small datasets, they often memorize noise. Use dropout or simpler architectures (like GRUs) if performance suffers.

When to use it

Feature LSTM GRU
Gates 3 (Forget, Input, Output) 2 (Update, Reset)
Complexity Higher parameter count Fewer parameters, faster training
Performance Often better on very long/complex dependencies Comparable on shorter sequences; easier to tune
Use Case High-stakes accuracy, large datasets Resource-constrained environments, quick prototyping

Choose GRU first for speed and simplicity. Switch to LSTM if you observe underfitting on long-range dependencies.

Practice

Guided Exercise: Modify the code above to accept a num_layers argument greater than 1. Observe how the shape of hn and cn changes (the first dimension should equal num_layers).

Challenge: Implement a GRU version of the same model using nn.GRU. Note that GRU does not require a separate cell state initialization (c0). Compare the number of parameters in both models using sum(p.numel() for p in model.parameters()).

Quick check

Q: Why do we typically use the last hidden state of an LSTM for sequence classification rather than averaging all hidden states?

A: The last hidden state theoretically contains the compressed representation of the entire sequence history due to the recurrent nature of the gates. Averaging dilutes this specific end-of-sequence context, though attention mechanisms can mitigate this.

Summary

LSTMs and GRUs extend standard RNNs with gating mechanisms to preserve long-term dependencies and stabilize gradient flow. While LSTMs offer more granular control via three gates, GRUs provide a computationally efficient alternative with comparable performance on many tasks. Selecting between them depends on your dataset size, latency requirements, and the complexity of temporal patterns.

Want to go beyond the notes?

Join Coding Now Tech Institute's Data Science course — live mentorship, real projects, and 100% placement support.

Enroll Now — Free Demo Available

LSTMs & GRUs – FAQs

Quick answers about learning LSTMs & GRUs in Data Science.

This free note from Coding Now Tech Institute explains LSTMs & GRUs in Data Science — concept, syntax and worked code examples you can copy, run and revise before interviews.
Yes. Every Data Science topic on Coding Now Tech Institute, including LSTMs & GRUs, is 100% free with no signup required.
With focused practice, most students grasp LSTMs & GRUs in 1–3 days from these notes; pairing it with Coding Now Tech Institute's mentor-led course takes you to job-ready depth faster.
Use the code examples in this note, then ask doubts for free on the Coding Now Tech Institute Community (/community) — expert instructors answer within 24 hours.
Call NowEnroll Now