One-Hot Encoding for Tokens
The embedding layer is a lookup operation: a token ID selects a row of the weight matrix by position.
Try it: Text Vectorization: Tokens to Vectors
The text-to-tensor pipeline: standardize, split into tokens, build a frequency-ranked vocabulary with padding and [UNK], map tokens to integer ids, pad or truncate, then one-hot or multi-hot encode and look the ids up in an embedding table.
How it works
- Standardize: lowercase and delete punctuation.
- Split on whitespace into tokens.
- Build the vocabulary: 0 = padding, 1 = [UNK], then words by frequency (ties: first appearance), capped at max tokens.
- Map each token to its id (1 if it did not make the vocabulary), then pad with 0 or truncate to the sequence length.
- Encode: one-hot rows per position or one multi-hot row per text; embed: id k selects row k of the embedding table.
Default run (18 steps): Raw text (59 characters): "The movie was great. The plot was great, the acting wasn't!". A model cannot read strings, so it is turned into numbers step by step. … Embedding lookup: id k selects row k of a fixed 8 x 3 table, giving a (8, 3) dense matrix instead of (8, 8) sparse one-hots. Row 0 (padding) is looked up too; a trained Embedding layer would learn these rows.
Simplified: Bounded ASCII text (up to 200 characters, 40 tokens), whitespace splitting only, and a small FIXED embedding table (a real Embedding layer learns its rows). The multi-hot vector keeps the padding slot (always 0) so its positions line up with the ids.
Loading the simulation…
A Number That Only Labels a Token
Before a model learns anything, every token in a text has already been reduced to an integer. That integer is the token ID. It tells the model which entry of its vocabulary a token corresponds to, but it carries no information about meaning. The ID 3 is just a label, in the same way a locker number tells you which locker to open without telling you what is inside it.
An embedding layer is the part of the model that turns that bare label into a vector of numbers the model can actually compute with. The question this article answers is how it performs that conversion. The short answer is that it does not compute anything complicated. It looks up a row.
What do you think happens?
Given a token ID of 3, what does the embedding layer return: a freshly calculated vector, or something that already exists in the model?
Reveal answer
A vector that is identical to a row already stored in the embedding matrix.
The returned vector is not a fresh calculation. It is identical to a row that already exists in the embedding matrix, so the match is exact: the layer copies a stored row rather than approximating one.
Following Token ID 3 Through the Layer
Think of the embedding layer as holding a weight matrix with one row per vocabulary entry. The token ID is used as a position. The layer moves to that position in the weight matrix and reads the row it finds there. Rows at other positions are not touched for this lookup. Only one row is read, and the vector it contains is what comes back.
Notice the numbering in the diagram. Token ID 3 retrieves the row in position 3, which is the fourth row, because positions start counting at zero. The other rows are shown only to make clear that they are present in the matrix but are not read for this lookup.
Zero-Based Row Numbers and Verification
Token IDs are zero-based row indices. The first row is numbered 0, the second is numbered 1, and so on, up to the last row of the vocabulary. Token ID 3 therefore retrieves the fourth row, not the third. This is the most common source of confusion when reading embedding results, because people naturally count from one.
The returned embedding vector is identical to the stored row it came from. This gives you a simple verification procedure. Take the vector returned for a given token ID, find the row at that zero-based position in the embedding matrix, and compare the two. If they match exactly, the lookup worked as intended. If they do not match, the problem lies in the index that was used for the lookup, not in the stored values.
One-Hot Encoding as the Longer Route
Readers who already know one-hot encoding may recognize the lookup as a shortcut. One-hot encoding represents a token ID as a vector whose length equals the vocabulary size. That vector contains a single 1 at the position of the token and 0 everywhere else. The one-hot vector is then multiplied by a weight matrix in a fully connected layer.
In this expression, $\mathbf{x}$ is the one-hot vector for token ID 3, $W$ is the weight matrix, and $W_{3,:}$ is the row at zero-based position 3. Because every entry of $\mathbf{x}$ except the one at position 3 is zero, every other term in each sum is multiplied by zero and drops out. Only row 3 survives.
Five-token vocabulary, token ID 3
A vocabulary has five tokens with IDs 0 through 4. Token ID 3 arrives. Show that multiplying its one-hot vector by the weight matrix gives the same vector as reading row 3 directly.
- 1Write the one-hot vector
The vector has length 5, because the vocabulary size is 5. It has a 1 at position 3 and 0 at positions 0, 1, 2, and 4. The vector is 0, 0, 0, 1, 0.
- 2Multiply by the weight matrix
Each output entry is a sum of products of the one-hot entries with the matrix entries down a column. Four of the five products in each sum are zero, because the one-hot entries at those positions are zero.
- 3Identify the surviving term
Only the product with the 1 at position 3 remains in each sum. Those surviving terms reproduce the entries of row 3 exactly.
- 4Compare with the direct lookup
Reading row 3 directly from the embedding matrix returns the same vector. The two routes agree.
The one-hot vector times the weight matrix equals row 3 of the weight matrix, which is the same vector the embedding lookup returns for token ID 3.
The lookup is equivalent to one-hot encoding followed by matrix multiplication in a fully connected layer, and it is the more efficient implementation. The one-hot route performs a multiplication against a vector as long as the whole vocabulary, even though all but one of those products are zero. The lookup skips that work and reads the single row that the one-hot route would have kept. Because the two are equivalent, the embedding layer can be treated as a neural network layer. The weights of its matrix can be optimized through backpropagation during training, just like the weights of other layers.
A model with a large vocabulary has a weight matrix with a correspondingly large number of rows. Encoding each token as a full vocabulary-length vector and multiplying it through the matrix would mean doing arithmetic on many zeros for every token. Reading the single row directly gives the same vector with far less work, which is why the lookup form is the one used in practice.
Where an Unexpected Result Diverges
Suppose the vector printed for token ID 3 does not match the fourth row of the embedding matrix. The useful question is where in the path from token ID to returned vector the actual result stopped matching the row the lookup should return. The path has a small number of stages, and checking them in order narrows the problem quickly.
The returned vector is identical to the stored row, so a mismatch points to the index used for the lookup rather than to the stored values themselves. In practice, the first place to look is the index: was the token ID 3 read as a zero-based position, and was the fourth row the one actually read? If the index is correct and the vector still differs from the stored row, the comparison itself needs to be checked against the correct row.
Common mistake Counting rows from one instead of zero
What it looks likeToken ID 3 is matched against the third row of the matrix.
Why it failsToken IDs are zero-based row indices, so token ID 3 retrieves the fourth row.
Do this insteadCount the first row as 0, then match token ID 3 against the row in position 3.
Common mistake Expecting the returned vector to be a new calculation
Why it failsThe returned vector is identical to a row that already exists in the embedding matrix, so there is nothing to recompute.
Do this insteadCompare the returned vector directly against the stored row at the correct position.
Common mistake Treating the token ID as carrying meaning
Why it failsThe token ID is only a label that tells the model which vocabulary entry a token corresponds to. The meaning is in the vector the layer returns.
Do this insteadRead the ID as a position, then inspect the row found there.
Common mistake Reading the output for a formula instead of checking it against the matrix
Checking Your Understanding
A vocabulary has five tokens with IDs 0 through 4. The embedding layer receives token ID 2. Which row of the embedding matrix should be returned, and how would you verify the result?
Hints
- Token IDs are zero-based row indices, so count from the first row as position 0.
- The returned vector should be identical to the stored row at that position, with no new calculation involved.
- If the one-hot route were used, the one-hot vector would have a 1 at position 2 and zeros elsewhere.
An embedding result for token ID 3 matches the third row of the matrix but not the fourth. Explain which step in the lookup path is most likely wrong and what check would confirm it.
Hints
- Locate the step where the index is converted into a row position.
- Compare the index used against the zero-based rule for token ID 3.
What the Lookup Gives You
- 1The embedding layer is a lookup: a token ID selects a row of the weight matrix by its zero-based position.
- 2The returned embedding vector is identical to that stored row, so an exact comparison verifies the lookup.
- 3Token ID 3 retrieves the fourth row, because token IDs are zero-based row indices.
- 4One-hot encoding followed by matrix multiplication gives the same result, but the lookup is the more efficient implementation.
- 5When a result is unexpected, check the index first, because a mismatch points to the lookup position rather than the stored values.
Key Takeaways
- The embedding layer is a lookup: a token ID selects a row of the weight matrix by its zero-based position.
- The returned embedding vector is identical to that stored row, so an exact comparison verifies the lookup.
- Token ID 3 retrieves the fourth row, because token IDs are zero-based row indices.
- One-hot encoding followed by matrix multiplication gives the same result, but the lookup is the more efficient implementation.
- When a result is unexpected, check the index first, because a mismatch points to the lookup position rather than the stored values.