Recurrent Layers
RNN layers in Deeplearning4j — LSTM, GRU, Bidirectional wrapper, masking, TBPTT, and sequence data handling
Overview
Deeplearning4j provides a complete set of recurrent neural network (RNN) layers for processing sequential and time-series data. The framework supports variable-length sequences via masking, truncated backpropagation through time (TBPTT) for long sequences, and step-by-step inference for online/streaming use cases.
This page assumes familiarity with RNN concepts (LSTM gates, backpropagation through time, sequence labelling). For an introduction to RNNs see the deep learning conceptual overview.
Data Format
All RNN layers in DL4J use the format:
[minibatch, features, timeSteps]Dimension 0: minibatch size
Dimension 1: number of features per time step
Dimension 2: sequence length (number of time steps)
This is the "channels-first" or NCL (batch, channels, length) layout. This applies to both input and output activations.
Example: a minibatch of 32 sequences, each with 10 features over 100 time steps would have shape [32, 10, 100].
For RnnOutputLayer labels used in classification, the shape is [minibatch, numClasses, timeSteps].
Available Layers
LSTM
Class: org.deeplearning4j.nn.conf.layers.LSTM Source: LSTM.java
Long Short-Term Memory layer without peephole connections. This is the preferred LSTM implementation in M2.1 — it supports CuDNN acceleration on NVIDIA GPUs automatically.
Builder Parameters
nIn
int
required
Input feature size
nOut
int
required
Hidden state (cell) size
activation
Activation
TANH
Activation for cell state
gateActivationFunction
Activation
SIGMOID
Gate activation (should be bounded 0-1)
forgetGateBiasInit
double
1.0
Initial forget gate bias; values 1-5 help retain longer dependencies
weightInit
WeightInit
global
Weight initializer
l1 / l2
double
global
Regularization
dropOut
double
global
Input dropout
Example
GravesLSTM
Class: org.deeplearning4j.nn.conf.layers.GravesLSTM Source: GravesLSTM.java
LSTM with peephole connections as described in Graves (2013) "Supervised Sequence Labelling with Recurrent Neural Networks". Peephole connections give gate computations direct access to the cell state.
Note: GravesLSTM does not support CuDNN acceleration. Use LSTM for GPU-optimized training unless you specifically need peephole connections.
Builder Parameters
Same as LSTM, plus:
forgetGateBiasInit
double
Forget gate bias initialization
gateActivationFunction
Activation
Bounded gate activation
Example
SimpleRnn
Class: org.deeplearning4j.nn.conf.layers.recurrent.SimpleRnn Source: SimpleRnn.java
Vanilla Elman recurrent network. Computes:
Very fast to compute but struggles with long-term dependencies. Recommended only when temporal dependencies span a few steps.
Example
Bidirectional (Wrapper)
Class: org.deeplearning4j.nn.conf.layers.recurrent.Bidirectional Source: Bidirectional.java
Wraps any unidirectional RNN layer to make it bidirectional. The layer runs two independent copies of the wrapped layer — one forward, one backward — and combines their outputs.
Combination Modes
ADD
nOut
Element-wise addition of forward and backward activations
MUL
nOut
Element-wise multiplication
AVERAGE
nOut
0.5 * (forward + backward)
CONCAT
2 * nOut
Concatenation along feature dimension
Example
In a MultiLayerNetwork
LastTimeStep (Wrapper)
Class: org.deeplearning4j.nn.conf.layers.recurrent.LastTimeStep Source: LastTimeStep.java
Wraps any RNN (or Conv1D) layer and extracts only the output at the last valid time step, returning a 2D array [minibatch, nOut] instead of the full 3D sequence [minibatch, nOut, timeSteps]. Mask-aware: if masking arrays are present, it returns the last non-masked time step for each example independently.
Use LastTimeStep when you want sequence-to-vector encoding (many-to-one).
Example — Sequence Classification
RnnOutputLayer
Class: org.deeplearning4j.nn.conf.layers.RnnOutputLayer Source: RnnOutputLayer.java
The RNN counterpart of OutputLayer. Handles time-distributed loss computation. Input and label shapes are both [minibatch, size, timeSteps].
Supports mask arrays for variable-length sequence training.
Also works for Conv1D output (same shape convention).
Example
RnnLossLayer
Class: org.deeplearning4j.nn.conf.layers.RnnLossLayer
Time-distributed loss layer without learnable parameters. Use when the previous layer already outputs the correct number of features and you only need a loss function applied across time.
Truncated Backpropagation Through Time (TBPTT)
Standard backpropagation through time (BPTT) for long sequences (>500 steps) is computationally expensive and can suffer from vanishing gradients. TBPTT breaks sequences into shorter segments and performs a forward-backward pass on each segment, giving more frequent parameter updates.
Configuration
BackpropType.Standard
Full BPTT (default)
BackpropType.TruncatedBPTT
TBPTT with segments of .tBPTTLength(n) steps
.tBPTTLength(int)
Number of time steps per TBPTT segment (default: 20)
Guidelines:
Use TBPTT when sequences are longer than ~200 time steps.
tBPTTLengthshould be a fraction of the total sequence length (e.g., 100-200 for 1000-step sequences).Variable-length sequences in the same minibatch work correctly with TBPTT.
TBPTT can learn shorter dependencies than full BPTT because gradients don't flow beyond the segment boundary.
Masking: Variable-Length Sequences
DL4J supports one-to-many, many-to-one, and variable-length many-to-many training via padding and mask arrays.
Padding and Mask Arrays
When sequences in a minibatch have different lengths, shorter sequences are padded with zeros to match the longest. Mask arrays (shape [minibatch, timeSteps] with values 0 or 1) record which time steps are real data vs. padding.
The mask array is stored in the DataSet object:
When a DataSet contains mask arrays, MultiLayerNetwork.fit() and evaluation methods automatically use them.
Many-to-One (Sequence Classification)
For classifying an entire sequence with a single label, use a labels mask with a single 1 at the last valid time step:
Or with RnnOutputLayer and an output mask:
Evaluation with Masks
Loading Variable-Length Data
Alignment modes:
ALIGN_END
Align the end of sequences (many-to-one: label at the last step)
ALIGN_START
Align the start of sequences (one-to-many: label at the first step)
Combining RNN with Other Layer Types
RNN + Dense (Many-to-One Classification)
CNN + RNN (Video Classification)
Convolutional layers process each frame independently; the RNN processes the sequence of frame features. DL4J automatically inserts the required CnnToRnnPreProcessor:
Manual Pre-Processor Insertion
If automatic pre-processor detection doesn't work for a custom topology:
Step-by-Step Inference (rnnTimeStep)
Use rnnTimeStep() for real-time or online inference where preserving RNN hidden state between calls is important.
Multi-step input is also supported:
Managing state manually (e.g., for serialization):
Complete Example: Sequence Classification with LSTM
Key API Summary
fit(DataSetIterator)
Train with full sequence data
output(INDArray)
Forward pass, returns full output sequence [mb, nOut, T]
rnnTimeStep(INDArray)
Step-by-step inference with state retention
rnnClearPreviousState()
Reset hidden state for all RNN layers
rnnGetPreviousState(int)
Get hidden state for a specific layer
rnnSetPreviousState(int, Map)
Restore hidden state for a specific layer
evaluate(DataSetIterator)
Classification evaluation
Evaluation.evalTimeSeries(...)
Evaluation with mask arrays for variable-length sequences
Last updated
Was this helpful?