What Attention is Really Doing: Weighted Memory Retrieval from Scratch
Building attention from first principles — the fixed-length bottleneck that broke RNN encoder–decoders on long sentences, the weighted-sum solution introduced by Bahdanau, Cho, and Bengio (2015), alignment score derivation, softmax normalization, and a complete 3-word numerical walkthrough — all derived step by step
Before the Transformer, before Q/K/V, before any of the modern terminology, there was a concrete failure mode: sequence-to-sequence models fell apart on long sentences. The fix that Bahdanau, Cho, and Bengio proposed in 2015 is what we now call attention. We will derive it from first principles, starting from the failure and arriving at the mechanism.
We will keep the entire post anchored to one tiny running example and compute the full mechanism by hand.
If you haven’t read Mathematical Prerequisites for the Attention Series, start there — we will use tanh, exponentials, and a few basic algebraic identities throughout this post.
1. Before Attention: The Fixed-Length Bottleneck
1.1 The Encoder–Decoder Framework
A sequence-to-sequence model maps a source sequence
to a target sequence
with potentially different lengths.
Before attention, the standard design had two pieces: an encoder that reads the full source sequence and compresses it into one vector , and a decoder that generates each target token from that same vector . The conditional probability at target step is written as
where is the previous target token, is the decoder hidden state at step , and is a nonlinear function that uses the decoder’s current state and source context to assign probabilities to possible next target words.
The important point is not the exact form of — the important point is that the same appears in every conditional.
1.2 The Bottleneck
The encoder is a recurrent neural network:
Here is the -th source word, and is the encoder hidden state after reading up to that position. You can think of as the encoder’s running summary of the source sequence so far.
The simplest context choice is just the last hidden state:
So the whole source sequence must be compressed into one vector before decoding even starts. That means the decoder uses , then , then , and so on. The previous target token changes, the decoder hidden state changes, and the target step changes — but the source summary does not. This is the problem. The entire source sentence has to survive inside one fixed-size summary, and the decoder has no way to go back and look at particular source positions later.
1.3 Why one vector is too rigid
Suppose the source sentence is long and the decoder is currently generating target word 17. The information needed for word 17 might live near source word 3, but a few steps later, when generating target word 18, the useful information might live near source word 11. With a fixed context vector, the decoder cannot ask for different source information at different times — it gets one precomputed summary and has to reuse it for every target position. This is the fixed-length context vector bottleneck. Bahdanau et al. showed empirically that translation quality degrades as source sentence length grows. The model is not failing because recurrent networks are impossible. It is failing because the decoder is forced to read the whole source through one frozen summary.
2. The Running Example
We will use one tiny source sequence throughout the post so that every derivation stays concrete.
After encoding three source words with a bidirectional RNN, suppose we obtain the scalar annotations
These are deliberately one-dimensional so every arithmetic step stays visible.
We also assume the decoder state just before generating the first target word is
Our goal is to compute the context vector used for generating the first target word.
If we used the old fixed-vector design and took only the last encoder state, then the context would be
for every target word. Attention replaces that fixed choice with a learned weighted sum.
3. The Fix: A Position-Dependent Context Vector
Instead of one context vector for the whole sentence, Bahdanau et al. define one context vector per target position:
The new objects are the weights .
An attention weight tells us how much target position should use source position . For example, means “how much should the second target word attend to the third source word?“
3.1 The two properties the weights must satisfy
If the context vector is supposed to behave like a soft selection over source positions, the weights have to satisfy two basic constraints: they must be nonnegative, for all , and they must sum to one, , for each fixed target position . These two conditions make a convex combination of the encoder states.
3.2 What a convex combination means here
A convex combination is a weighted average where the weights are nonnegative and sum to 1.
In our scalar running example, that means must lie between the smallest and largest source annotations.
The source values are:
So any valid context vector must satisfy
Why? Because weighted averages cannot leave the interval spanned by the values being averaged.
3.3 Numerical checks
If all weight goes to the second source word:
then
If the model splits evenly between the first two source words:
then
If the weights are uniform:
then
All three results lie inside , as they must.
3.4 Why the weighted sum must be soft
A natural question is why we do not simply pick one source position and stop there. That would mean using a hard argmax and then setting . The problem is that the argmax is discrete — gradients do not flow cleanly through it during ordinary backpropagation. The weighted sum is differentiable, so the decoder can learn where to look by gradient descent rather than by a separate combinatorial procedure. That is the key engineering reason for soft attention.
4. Alignment Scores: How the Model Decides Where to Look
To get attention weights, we first need unnormalized alignment scores:
The function is the alignment model. It measures how compatible the decoder state is with encoder state .
4.1 Bahdanau’s alignment model
Bahdanau et al. use a one-hidden-layer feedforward network:
This looks dense, so let us unpack it. We first project the decoder state with and the encoder state with , add those projected vectors, apply , and finally take a dot product with to produce one scalar score. A useful implementation detail from the paper is that the term depends only on the encoder side, not on the decoder step , so it can be precomputed once for every source position.
4.2 The scalar version of the running example
To keep the arithmetic transparent, take the one-dimensional case
Then the alignment model simplifies to
This is not the full expressive model used in practice. It is a toy scalar version that lets us trace every number by hand without hiding the arithmetic.
4.3 Numerical check: compute the three scores
For the first target word we use .
Source word 1
Use the definition of the hyperbolic tangent:
So
Source word 2
Source word 3
So the score vector is
4.4 What the ordering means
In our toy scalar setup, , so source word 2 receives the highest score. That is consistent with the source values: is the largest annotation, and the scalar function
is monotone increasing in because
This derivative formula is the derivative identity for hyperbolic tangent.
So in this toy setup, larger gives larger . The ranking is not mysterious. It is coming directly from monotonicity.
5. From Scores to Weights: Softmax
The alignment scores are arbitrary real numbers. We still need to turn them into proper attention weights.
Bahdanau et al. apply the softmax function:
5.1 Why softmax gives valid weights
We need two things: nonnegative weights, and weights that sum to 1. The exponential gives the first immediately, since for every real , which means for every . Now sum over all :
The denominator is the same in every term, so factor it out by the common-denominator rule:
The numerator and denominator are the same sum, just with different dummy indices and , so:
Exactly what we need.
5.2 A useful identity: score differences turn into weight ratios
Take two source positions and at the same target step . Their weight ratio is . The shared denominator cancels:
Now apply the exponential quotient identity:
to get
This tells us something important: softmax cares about score differences, not absolute score levels.
5.3 Numerical check: compute the weights
We start from
Exponentiate each score:
Add them:
Now divide:
So
Verification:
5.4 Numerical check of the ratio identity
Take the ratio of the two largest attention weights:
Now compute the exponential of the score difference:
Both sides match.
This identity is useful because it tells us exactly how much a score advantage translates into a weight advantage.
5.5 Another useful identity: adding the same constant changes nothing
Softmax has a second property that matters constantly in implementations. If we add the same constant to every score in one row, the attention weights do not change.
Start from
Use the exponential product rule
in both numerator and denominator:
The factor is common to every term in the denominator, so factor it out:
Now cancel the common factor:
So we have the softmax shift-invariance identity:
5.6 Numerical check of shift invariance
Take our score vector
and add 5 to every entry:
Exponentiate:
Add them:
Normalize:
Exactly the same weights as before.
This is why practical implementations subtract the row maximum before exponentiating. It changes nothing mathematically, but it prevents large exponentials from blowing up numerically.
6. The Context Vector
Now we finally have everything needed for the actual context vector:
Expand the sum:
Substitute the numbers:
6.1 Numerical check
Work through the three terms separately:
Add them:
So the first context vector is
6.2 Interpretation
The value is not equal to any one source annotation, and that is the whole point. The decoder is not copying one source state — it is retrieving a weighted mixture. Source word 2 pulls the context upward because it received the largest weight, while source words 1 and 3 pull it back down because their annotations are smaller. The result sits between the source values:
as predicted by the convex-combination argument earlier.
6.3 Compare with the no-attention baseline
Without attention, we said the simplest old context would be . With attention, the decoder instead receives . The difference is not a small tweak — it is a different access pattern. In the old model, every target word receives the same source summary. In the attention model, each target word performs its own retrieval from the full source memory bank.
6.4 Rewriting the context to see what matters most
Because the weights sum to 1, we can eliminate one of them. Write
and substitute this into the context formula:
Distribute by the distributive law:
Group the and terms:
Now substitute our source annotations:
So
This form is easier to read. It tells us immediately which source positions matter most. Increasing moves the context up only slightly, because sits just above . Increasing moves it much more strongly, because sits above .
6.5 Numerical check of the rewritten form
Substitute the attention weights:
Compute each term:
Add them:
which matches the earlier result up to rounding:
This rewritten form makes the dominant contribution of source word 2 completely explicit.
7. Why the Mechanism Is Trainable End to End
The weighted-sum formulation is not only expressive. It is differentiable from end to end.
7.1 Gradient with respect to the attention weights
Treat the encoder annotations as fixed for a moment. The context vector is , so differentiating with respect to one weight gives . By the linearity of differentiation, every term with differentiates to zero because it does not depend on , and only the term remains:
So the gradient flowing into is directly modulated by the encoder annotation .
7.2 Numerical check
In our running example,
so
and likewise
This makes the derivative formula concrete. A small change in changes the context more strongly than the same-sized change in or , because source position 2 carries the largest annotation in this toy example.
7.3 Why this matters
This means the loss can push on the attention weights smoothly. Those weights are smooth functions of the alignment scores through softmax, and the alignment scores are smooth functions of the encoder and decoder states through the feedforward alignment model. So gradients flow from the loss through , then through the attention weights , then through the alignment scores , and finally into the encoder and decoder states . That is why the whole system can be trained end to end with backpropagation.
8. Where the Encoder Annotations Come From
So far we have treated as given. In the actual model, they come from a bidirectional encoder.
Bahdanau et al. obtain them from a Bidirectional Recurrent Neural Network.
8.1 Forward and backward states
The forward encoder reads the source left to right, computing , while the backward encoder reads right to left, computing . The annotation at source position is the concatenation of both directions:
So each annotation contains both left context and right context. If the source word is “bank,” its meaning may depend on both the word before it and the word after it, and a bidirectional annotation can encode that local context before attention ever begins. That is why the encoder states are a good memory bank — each is not a raw word embedding but already a contextual summary centered on source position .
8.2 Numerical check
Our scalar running example hid this structure by collapsing each annotation to one number. In an actual bidirectional encoder, each annotation would contain one part from the left-to-right pass and one part from the right-to-left pass.
For example, suppose that at source position 2 the forward encoder produces
and the backward encoder produces
Then the bidirectional annotation at that position is
The important point is not the specific numbers. The important point is that one source position now carries information from both directions at once. Attention does not read from raw source words. It reads from contextualized source annotations.
9. The Full Decoder Objective
The decoder does not stop at computing . At target step , it computes the attention-based context vector, updates the decoder state, and then predicts the next word.
A standard attention-based decoder step can be written abstractly as
followed by
The first equation says that the new decoder state is built from three things: the old decoder state, the previous target token, and the source information retrieved for the current step. The second says that this updated state and retrieved context are then used to predict the next target word. So attention does not replace the decoder. It gives the decoder a better source-dependent input at each step.
The full translation probability factorizes by the chain rule of probability:
Taking logs and using the logarithm product rule
gives
9.1 Numerical check
Suppose a target sentence has two words, and the model assigns
Then the full sentence probability is
Taking logs gives
Now compute the sum of the two token-level log-probabilities:
The two results match exactly, which is why training can be written as a sum over target positions rather than as one monolithic sentence-level quantity.
This is the training objective the model maximizes. The alignment model receives no direct supervision. It learns useful alignments only because better alignments improve the translation log-likelihood.
10. The Alignment Matrix and the Memory-Retrieval View
If we stack the attention weights over all target positions, we get the alignment matrix:
Each row is a probability distribution over source positions for one target token. This makes the memory interpretation explicit: the encoder annotations are the memory slots, the decoder state is the query, the scores measure compatibility between that query and each slot, softmax turns those compatibilities into a distribution, and the weighted sum returns the retrieved content.
This is already most of the modern query-key-value story, just without the names. In Bahdanau attention, the query is the decoder state, the key is the encoder annotation, and the value is the encoder annotation as well. The Transformer will keep the same memory-retrieval pattern but separate keys and values into different learned projections.
11. Common Confusions
11.1 Attention is not hard selection
Attention does not pick one source token and ignore the rest. Even when one weight is large, the output is still a weighted average. In our running example, source word 2 has the largest weight at , but it does not get all the mass — the other two source words still contribute.
11.2 Attention weights are not explanations by default
The attention weights tell us where the model routed information for this mechanism. They do not automatically tell us why the translation is correct or whether the model “understood” the sentence in a human sense. They are routing coefficients, not magical semantic certificates.
11.3 The toy scalar model is less expressive than the real one
This is the part that usually feels wrong on a first pass through a tiny example. In our scalar toy model,
and is increasing. So if , then source word 2 will always receive the highest score for any fixed decoder state added equally to all three.
That might make it seem like attention cannot change its ranking across target positions.
That conclusion would be wrong. The full model is
where and are vectors and , , are learned. Different decoder states can interact with different encoder annotations in different directions, so the ranking can change from one target position to the next.
To see that change explicitly, leave the scalar toy for a moment and take a tiny 2-dimensional example with two source positions:
Now compare two decoder states.
For the first target step, let
Then
while
So at the first target step, source position 2 receives the higher score.
For the second target step, let
Then the same computation gives
Now source position 1 receives the higher score. The ranking has flipped.
If we softmax each pair of scores, the first step gives attention weights approximately
while the second step gives
So the decoder really can look in different places at different target positions. Our scalar example is useful because it makes the arithmetic transparent, while the full vector model is useful because it restores expressive power.
Summary
Attention solves the fixed-length bottleneck by replacing one global source summary with a target-specific weighted sum of encoder annotations. Bahdanau’s alignment model produces scores , softmax turns them into valid weights , and the context vector becomes a differentiable soft retrieval from the source memory bank.
In our running example, the mechanism turns source annotations and decoder state into attention weights and the context value . The next post keeps this retrieval view intact but asks a new question: why use this feedforward alignment function at all, and how do we arrive at queries, keys, and values?
Previous: Mathematical Prerequisites for the Attention Series
Next: From Soft Alignment to Queries, Keys, and Values
Enjoyed this post?
Subscribe to get notified when I publish new posts. No spam, unsubscribe anytime.