RNN Architecture › Stacked RNNs
Language AI HandbookAll chapters RNN Architecture › Stacked RNNsOne section · Sections in this chapter10 / 19 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Just as feedforward networks gain representational power by stacking multiple layers, RNNs can be stacked by feeding the output hidden states of one RNN layer as the input to the next.
In a stacked (deep) RNN with layers, the hidden state at layer is computed as:
where (the input) and is the hidden state from the layer below at the same time step. Each layer has its own independent set of parameters.
The motivation for stacking is hierarchy. The lower layers tend to learn local, surface-level patterns (bigrams, punctuation boundaries, character-level morphology). The higher layers can then learn more abstract, long-range patterns (topic, discourse structure, semantic relationships) on top of these local summaries. This hierarchy of representations mirrors how deep feedforward networks learn a hierarchy of features in computer vision.
In practice, 2-layer stacked RNNs are common. 3 or 4 layers are used in more demanding tasks like machine translation. Beyond 4 layers, training becomes difficult due to compounding gradient instability across both depth and time. Techniques like layer normalization (applied within each RNN step) can help stabilize deeper stacked RNNs.
PyTorch's nn.RNN(num_layers=2) implements a 2-layer stacked RNN. The output tensor has shape (batch, seq_len, hidden_size) (from the final layer), and the h_n output has shape (num_layers, batch, hidden_size) containing the final hidden state of each layer.
Dropout in Stacked RNNs
Dropout in recurrent networks requires care. Applying standard dropout to the hidden state at every time step disrupts the information flow through time, which can hurt performance. The standard approach (Gal & Ghahramani, 2016) is variational dropout: use the same dropout mask for all time steps within a sequence, applied only to non-recurrent connections. This drops out connections between layers (from to ) but not the recurrent connections ( to ). PyTorch implements this through nn.RNN(dropout=0.5, num_layers=2), which applies dropout between layers but not within the recurrent step.