How to add attention layer to a Bi-LSTM
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
A Bi-LSTM already captures context from both directions, but it still compresses sequence information in a fixed way unless you add another mechanism on top. Attention improves that by letting the model learn which timesteps matter most for the final prediction instead of treating every hidden state equally.
The Core Idea
A Bi-LSTM produces one hidden representation per timestep when return_sequences=True. Attention then assigns a learned weight to each timestep and builds a weighted summary vector.
So the workflow is:
- encode the sequence with a Bi-LSTM
- compute attention scores over timesteps
- normalize those scores into weights
- take the weighted sum of hidden states
- send the resulting context vector to the output layer
That is the simplest mental model for sentence classification, sequence labeling, and many other sequence tasks.
A Minimal Keras Example
Here is a compact TensorFlow and Keras model that adds a custom attention layer on top of a Bi-LSTM.
This is a good baseline for sequence classification.
Why return_sequences=True Matters
Attention needs access to the whole sequence of hidden states. If the Bi-LSTM returns only its final output, there is no sequence left to score.
That means this is correct:
and this is not sufficient for sequence-level attention:
The second form collapses the time dimension before attention ever gets a chance to use it.
What the Attention Layer Is Learning
The custom layer above learns a scalar score for each timestep. After softmax, those scores become weights that sum to 1 across the sequence.
That means important timesteps receive more influence in the final context vector. In text classification, those may be sentiment-bearing words. In time series, those may be spikes or regime changes.
This is why attention is often easier to interpret than using only the final hidden state.
Built-In Attention Versus Custom Pooling
Keras also has built-in attention layers such as Attention and AdditiveAttention, but those are most natural when you have separate query and value tensors, such as encoder-decoder models.
For a simple Bi-LSTM classifier, a lightweight attention-pooling layer is often easier to understand and debug.
If you move into sequence-to-sequence tasks, decoder attention becomes a better fit than this pooling-style summary.
Masking Is Not Optional
If sequences are padded, the attention mechanism must ignore padded positions. In the example above, the layer uses the incoming mask and applies a large negative value to padded logits before softmax.
Without masking, the model can waste probability mass on padding timesteps, which weakens both accuracy and interpretability.
That is why mask_zero=True on the embedding layer and mask-aware attention logic work well together.
A Small Training Example
The model compiles like any other Keras model.
This is only synthetic data, but it shows that the architecture is runnable end to end.
When Attention Helps Most
Attention is especially useful when:
- not all positions in the sequence are equally informative
- the important evidence may appear anywhere in the sequence
- you want the model to produce a learned weighted summary rather than relying on the last state only
For very short sequences or simple tasks, a plain Bi-LSTM may already be enough. Attention helps most when the sequence contains distractors or dispersed signal.
Common Pitfalls
A common mistake is forgetting return_sequences=True, which removes the time dimension attention needs.
Another issue is applying attention without masking padded tokens. That often leads to weaker and less interpretable weights.
Developers also sometimes use built-in Keras attention layers without understanding whether they need query-key-value style attention or simple sequence pooling. Those are related but not identical.
Finally, do not expect attention to rescue a poor encoder automatically. If the Bi-LSTM representations are weak, the attention layer has little useful signal to weight.
Summary
- Add attention after a Bi-LSTM that returns the full sequence.
- Use
return_sequences=Trueso attention can score each timestep. - Mask padding positions before softmax.
- A simple attention-pooling layer is often enough for sequence classification.
- Attention helps the model focus on the most informative parts of the sequence.
Related reading
- How to add attention layer to a Bi-LSTM
- How to add Dropout in Keras functional model?
- How to add regularizations in TensorFlow?
- how to add text preprocessing tokenization step into Tensorflow model
- How to add basic authentication for Tensorflow serving
- How to add if condition in a TensorFlow graph?
- How to apply data augmentation in TensorFlow 2.0 after tfds.load
- How to apply gradient clipping in TensorFlow?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.