Download the original presentation (PDF)

1. From text to vectors

A familiar natural language processing task is sentiment classification: the model receives a piece of text as input and and outputs a predefined sentiment class (positive, negative, or neutral).

A text classifier mapping a movie review to positive, negative, or neutral sentiment
Fig. 1: Jay Alammar, 2019.1

Neural networks cannot operate directly on words. Text must first be mapped to vectors. A word embedding provides such a mapping, ideally in a space where useful semantic and syntactic relationships are reflected geometrically.

Words mapped to low-dimensional vector representations
Fig. 2: Jay Alammar, 2019.2

The simplest representation is one-hot encoding. Given a vocabulary of \(N\) words, one-hot encoding consists in assigning an integer index \(i \in \{1,\ldots,N\}\) to each word such that the word is represented as an \(N\)-dimensional sparse vector mostly composed of zeros, except for a single entry at the position corresponding to the word’s index in the vocabulary that takes the value 1. In addition to suffering from an obvious feature size downside, this approach does not take similarities between words into account.

One-hot vector representations for several words
Fig. 3: Jay Alammar, 2019.2

Distributional methods learn more useful spaces from the contexts in which words appear. As J. R. Firth summarized the idea: “You shall know a word by the company it keeps.” Well-known and largely used word embedding methods such as Word2Vec (Mikolov et al., 2013), GloVe (Pennington et al., 2014) and FastText (Bojanowski et al., 2016), all have a major weakness though: they create a fixed embedding for each word. Therefore, whatever the meaning of the word, it will always be mapped to the same vector.

Two-dimensional visualization of learned word embeddings
Fig. 4: Jay Alammar, 2019.2

The limitation of one fixed vector per word motivates contextual representations. The Transformer constructs them with self-attention.

2. Self-attention

As the model processes a certain word from the input sequence, self-attention allows the model to attend to all the other words from the sequence for clues to a good contextual representation of that word. In the example below, the model can associate it with animal rather than street.

Self-attention from the word it to the other words in a sentence
Fig. 5: Tensor2Tensor Google Colab.3

Self-attention is produced in six steps:

  • Step 1: Create a query, key, and value vector for each input word. These vectors are obtained by multiplying an initial word embedding vector (learned during training) by three distinct weight matrices \(\boldsymbol{W}^{Q}\), \(\boldsymbol{W}^{K}\), and \(\boldsymbol{W}^{V}\) (also learned during training).
Creation of query, key, and value vectors from input embeddings
Fig. 6: Jay Alammar, 2018.4
  • Step 2: Given a word of the input sequence, score its query vector with the key vectors of all other words. Scores are calculated by computing the dot product of the query-key vectors.
Dot-product scores between one query and all keys
Fig. 7: Jay Alammar, 2018.4
  • Step 3: Divide the scores by the square root of the key vector dimension. This division leads to more stable gradients.
Attention scores divided by the square root of the key dimension
Fig. 8: Jay Alammar, 2018.4
  • Step 4: Pass all the scores through a softmax operation. Softmax normalizes the scores so they are all positive and add up to 1.
Softmax-normalized attention scores
Fig. 9: Jay Alammar, 2018.4
  • Step 5: Multiply each value vector by its softmax score. The intuition here is to keep intact the value vectors of the word(s) the model decides to focus on, and drown out those of irrelevant words.
Value vectors multiplied by their softmax attention scores
Fig. 10: Jay Alammar, 2018.4
  • Step 6: Sum up all weighted value vectors. This produces the output vector of the self-attention calculation for a given word in the input sequence.
Summation of weighted value vectors into a self-attention output
Fig. 11: Jay Alammar, 2018.4

In practice, the tokens are processed together: packing the input embeddings into a matrix \(\boldsymbol{X}\) and multiplying it by the respective weight matrices \(\boldsymbol{W}^{Q}\), \(\boldsymbol{W}^{K}\), and \(\boldsymbol{W}^{V}\).

Query, key, and value matrices computed from an input matrix
Fig. 12: Jay Alammar, 2018.4

Steps 2 to 6 can be condensed in one formula.

Scaled dot-product self-attention in matrix form
Fig. 13: Jay Alammar, 2018.4

3. Multi-head attention

In the Transformer architecture, the self-attention computation is performed several times on each input word using different sets of Query/Key/Value weight matrices. Each of these sets is called an attention head and the whole mechanism is called multi-head attention. Separate \(\boldsymbol{W}^{Q}\), \(\boldsymbol{W}^{K}\), and \(\boldsymbol{W}^{V}\) matrices are maintained for each attention head.

Separate query, key, and value projections for two attention heads
Fig. 14: Jay Alammar, 2018.4

The Transformer uses 8 attention heads. The different self-attention calculations result in 8 different output matrices \(\boldsymbol{Z}_i\).

Eight output matrices produced by eight attention heads
Fig. 15: Jay Alammar, 2018.4

The final output from the self-attention layer is obtained by concatenating the different \(\boldsymbol{Z}_i\) matrices and multiplying them by a weight matrix \(\boldsymbol{W}^{O}\).

Concatenation and projection of multiple attention-head outputs
Fig. 16: Jay Alammar, 2018.4

The complete multi-head attention computation is illustrated below.

Complete multi-head attention computation
Fig. 17: Jay Alammar, 2018.4

4. Transformer

The Transformer5 architecture is composed of an encoder and a decoder.

Transformer architecture divided into an encoder and decoder
Fig. 18: Jay Alammar, 2018.4

Both the encoder and decoder are stacks of several encoding and decoding layers respectively, all identical in structure but not sharing the same weights.

Stacks of six encoder and six decoder layers
Fig. 19: Jay Alammar, 2018.4

Each encoder layer contains two types of sub-layers: (1) a self-attention layer that helps look at other words in the sequence when encoding a given word, and (2) a shallow feed-forward layer that is independently applied to each word vector, allowing the various paths to be executed in parallel.

Each decoder layer contains an extra sub-layer in-between: (3) an encoder-decoder attention layer, which helps focus on relevant parts of the initial input sequence.

Internal sublayers of Transformer encoder and decoder layers
Fig. 20: Jay Alammar, 2018.4

Every block in a Transformer has its own weights:

  1. the weight matrix used to create the queries, keys, and values (attn/c_attn/w);
  2. the weight matrix that projects the results of the attention heads into the output vector of the self-attention sub-layer (attn/c_proj/w);
  3. the weight matrix corresponding to the first layer of the Feed Forward Neural Network (mlp/c_fc/w);
  4. the weight matrix corresponding to the second layer of the Feed Forward Neural Network (mlp/c_proj/w).
Attention and feed-forward weight matrices in successive Transformer blocks
Fig. 21: Jay Alammar, 2019.6

Each sub-layer in an encoder/decoder layer has a residual connection around it, followed by a layer-normalization step.

Residual connections and normalization around Transformer sublayers
Fig. 22: Jay Alammar, 2018.4

After each sub-layer, the output matrix \(\boldsymbol{Z}\) is added to the input matrix \(\boldsymbol{X}\) and the result is normalized.

Addition and normalization of the input and sublayer output matrices
Fig. 23: Jay Alammar, 2018.4

Before being given to the encoder, each word must be converted to an input vector.

Input vectors flowing through the Transformer encoder stack
Fig. 24: Jay Alammar, 2018.4

The Transformer uses a data-driven tokenization method that creates a fixed-size vocabulary of individual characters, sub-words and words that best fits a given language corpus.

For example, the WordPiece tokenization model first checks if the full word is in the vocabulary. If not, it tries to break it down into the largest possible sub-words from the vocabulary. As a last resort, it decomposes the word into individual characters.

WordPiece-style decomposition of words into vocabulary tokens
Lookup of a learned embedding for each token
Fig. 25: Jay Alammar, 2018.4

To give the model a sense of order of the input words, positional encoding vectors are added to the token vectors. This results in the final input embedding that goes to the encoder.

Addition of token and positional embeddings
Sinusoidal positional encodings across dimensions and positions
Fig. 26: Jay Alammar, 2018.4

The output of the last encoder layer is transformed into a set of attention vectors \(\boldsymbol{K}\) and \(\boldsymbol{V}\), resulting from the multiplication of the FFN output matrix \(\boldsymbol{R}\) with the weight matrices \(\boldsymbol{W}^{K}\) and \(\boldsymbol{W}^{V}\).

Matrices \(\boldsymbol{K}\) and \(\boldsymbol{V}\) are used by each decoder layer in its encoder-decoder attention sub-layer, which works just like the self-attention sub-layer except it creates the query matrix \(\boldsymbol{Q}\) from the sub-layer below it and takes the key and value matrices from the output of the encoder stack. This sub-layer helps the decoder focus on appropriate positions from the initial input sequence.

Encoder outputs supplied as keys and values to each decoder layer
Fig. 27: Jay Alammar, 2018.4

The decoder output of each step is fed back to the decoder as input for the next time step. Note that the self-attention sub-layer in the decoder is only allowed to attend to earlier positions from the output sequence. This is done by masking future positions (setting them to \(-\infty\)) before the softmax step in the self-attention calculation.

Autoregressive decoder with masked self-attention
Fig. 28: Jay Alammar, 2018.4

The decoding process continues until a special symbol is reached indicating that the decoder has completed its output.

Successive decoder steps producing an output sentence
Fig. 29: Jay Alammar, 2018.4

The linear sub-layer is a simple fully connected neural network that projects the vector produced by the stack of decoders into a much larger vector of the size of the vocabulary (logits vector). Intuitively, each cell of the logits vector corresponds to the score given to the corresponding word. The softmax then turns those scores into probabilities. The cell with the highest probability is chosen and the word associated to it is the output for that time step.

Linear and softmax layers mapping a decoder state to a word probability
Fig. 30: Jay Alammar, 2018.4

5. BERT

BERT7 is a pre-trained Transformer encoder with 12 layers for its BASE model and 24 for its LARGE version (compared to 6 for the Transformer). BERT also has a larger hidden size (768 and 1024 for \(BERT_{BASE}\) and \(BERT_{LARGE}\) respectively, compared to 512 for the original Transformer), larger feed-forward sub-layers (3072 and 4096 units, compared to 2048), and more attention heads (12 and 16, compared to 8).

Comparison of Transformer, BERT-base, and BERT-large encoder stacks
Fig. 31: Jay Alammar, 2019.8

The first task BERT is pre-trained on is masked language modeling. Before feeding word sequences into BERT, 15% of the words in each sequence are replaced with a [MASK] token. The model then attempts to predict the original value of the masked words based on the context provided by the other, non-masked, words in the sequence.

BERT predicting a token hidden by a mask
Fig. 32: Jay Alammar, 2019.8

The second task BERT is pre-trained on is a two-sentence classification task. In BERT’s training process, the model receives pairs of sentences as input and learns to predict whether the second sentence in the pair follows the first one.

BERT predicting whether one sentence follows another
Fig. 33: Jay Alammar, 2019.8

Once pre-trained, BERT’s output can be used as contextualized word embeddings. One can choose among multiple options to get the embedding of a word: summing up, averaging, or concatenating all or some layers’ outputs.

Strategies for deriving contextual embeddings from BERT layers
Fig. 34: Jay Alammar, 2019.8

Which vector works best as a contextualized embedding depends on the task. The example below reports results for Named Entity Recognition (NER) on the CoNLL-2003 dataset.

Named-entity recognition scores for different BERT layer combinations
Fig. 35: Jay Alammar, 2019.8

BERT obtained new state-of-the-art results on 11 natural language processing tasks.

Fine-tuning BERT on eleven natural language processing tasks
Fig. 36: Devlin et al., 2018.7

The first input token is supplied with a special [CLS] token (standing for “classification”) and is used for classification tasks where only the output vector of this special token is sent to the classifier.

BERT sentence-classification pipeline using the CLS representation
Fig. 37: Jay Alammar, 2019.1

BERT uses a two-step fine-tuning approach:

BERT pre-training followed by task-specific fine-tuning
Fig. 38: Jay Alammar, 2019.1

References and credits

  1. Jay Alammar. A Visual Guide to Using BERT for the First Time. 2019.  2 3

  2. Jay Alammar. The Illustrated Word2Vec. 2019.  2 3

  3. Tensor2Tensor. Hello T2T notebook

  4. Jay Alammar. The Illustrated Transformer. 2018.  2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

  5. Vaswani et al. Attention Is All You Need. Advances in Neural Information Processing Systems, 2017. 

  6. Jay Alammar. The Illustrated GPT-2. 2019. 

  7. Devlin et al. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. Proceedings of NAACL-HLT, 2019.  2

  8. Jay Alammar. The Illustrated BERT, ELMo, and co.. 2019.  2 3 4 5