Background
Sections
IntroductionModule 01 β€” Tensors 🧊01 Β· Creating Tensors 🧊02 Β· Indexing & Reshaping πŸ”ͺ03 Β· Tensor Math βž—04 Β· Device Placement πŸ–₯️⚑Module 02 β€” Autograd βš™οΈ01 Β· The Computational Graph πŸ•ΈοΈ02 Β· Backward Pass & Gradients ⬅️03 Β· Turning Autograd Off πŸ›‘04 Β· Gradient Gotchas πŸͺ€Module 03 β€” Neural Networks01 Β· The `nn.Module` Basics 🧱02 Β· Common Layers 🧩03 Β· Building a Network πŸ—οΈ04 Β· Inspecting Models πŸ”Module 04 β€” Data Handling πŸ—‚οΈ01 Β· Dataset Basics πŸ“‡02 Β· The DataLoader 🚚03 Β· Transforms 🎨04 Β· Splits & Built-in Datasets βœ‚οΈModule 05 β€” The Training Loop πŸ”01 Β· Loss Functions 🎯02 Β· Optimizers βš™οΈ03 Β· The Training Loop πŸ”04 Β· Evaluation & Metrics πŸ“ŠModule 06 β€” Saving & Loading πŸ’Ύ01 Β· `state_dict` Basics πŸ’Ύ02 Β· Checkpoints & Resuming ⏸️03 Β· Loading for Inference πŸš€04 Β· Best Model & Early Stopping πŸ…Module 07 β€” Computer Vision πŸ‘οΈ01 Β· Convolutions πŸ”²02 Β· CNN Architecture πŸ›οΈ03 Β· Transfer Learning πŸ”04 Β· Image Classification Project πŸ§ͺModule 08 β€” NLP & Transformers πŸ’¬01 Β· Text Data & Tokenization πŸ”€02 Β· Embeddings 🧭03 Β· Recurrent Layers & LSTMs πŸ”„04 Β· Intro to Transformers ⚑Module 09 β€” Ecosystem: PyTorch Lightning ⚑01 Β· Why Lightning? πŸ€”02 Β· The LightningModule 🧩03 Β· The Trainer πŸŽ›οΈ04 Β· DataModules & Callbacks 🧰Module 10 β€” Deployment & Optimization πŸš€01 Β· Exporting Models πŸ“¦02 Β· `torch.compile` ⚑03 Β· Inference Optimization πŸͺΆ04 Β· Serving & Next Steps πŸŽ“

02 · Embeddings 🧭

4 min read

A word's integer ID is just a name tag β€” it carries no meaning. Embeddings turn those IDs into rich vectors where similar words live near each other.


1. The 'Why'

After tokenization (sub-module 01) you have integer IDs like cat β†’ 3, dog β†’ 4. But those numbers are arbitrary labels: the fact that dog is 4 and cat is 3 doesn't mean dog is "one more than" cat in any meaningful sense. Feeding raw IDs to a network implies false numeric relationships. The obvious fix β€” one-hot encoding, a vector that's all zeros except a single 1 at the word's index β€” removes the false ordering, but it's disastrous in its own way: with a 50,000-word vocabulary, every word becomes a 50,000-dimensional vector that's 99.998% zeros, and crucially, every word is equally distant from every other. One-hot vectors know that "cat" and "dog" are different, but not that they're both animals and more alike than "cat" and "democracy."

Embeddings solve this elegantly. Instead of a sparse one-hot, each token maps to a short, dense vector of learnable numbers β€” say 100 or 300 dimensions. These vectors start random and are trained along with the rest of the model, so the network learns to place words with similar meanings or uses near each other in the vector space. The famous result is that embeddings capture semantic structure: related words cluster, and directions in the space can encode relationships. nn.Embedding implements this as a simple, efficient lookup table, and it's the standard first layer of virtually every NLP model β€” the piece that finally turns symbols into something a network can reason about.


2. Core Concepts

nn.Embedding(num_embeddings, embedding_dim). A learnable lookup table with one row per vocabulary token. num_embeddings = vocabulary size; embedding_dim = the length of each vector. Given integer IDs, it returns the corresponding rows.

It's a lookup, not a matmul. Conceptually an embedding is a one-hot times a weight matrix, but PyTorch implements it as a direct row lookup β€” far faster and more memory-efficient. You pass integer IDs, not one-hot vectors.

Learnable by default. The embedding table is a parameter (requires_grad=True), so it's trained by backprop like any weight. The network shapes the vector space to serve the task.

padding_idx. Tell the layer which ID is <pad> so its embedding stays all-zeros and receives no gradient β€” keeping padding truly inert.

Pretrained embeddings. You can initialize the table with pretrained vectors (GloVe, word2vec) instead of random β€” a form of transfer learning (Module 07) for text.


3. Code in Action

The embedding lookup

import torch
import torch.nn as nn

vocab_size, dim = 20, 8
embedding = nn.Embedding(num_embeddings=vocab_size, embedding_dim=dim)

ids = torch.tensor([[3, 4, 6, 0],      # a padded batch of token IDs
                    [7, 5, 2, 0]])      # (batch=2, seq_len=4)
vectors = embedding(ids)                # look up each ID's row
print(vectors.shape)                    # torch.Size([2, 4, 8]) -> (batch, seq, dim)

Keeping padding inert with padding_idx

import torch
import torch.nn as nn

emb = nn.Embedding(20, 8, padding_idx=0)   # ID 0 (<pad>) -> fixed zero vector
print(emb(torch.tensor([0]))[0][:4])       # tensor([0., 0., 0., 0.]) -> all zeros
# Its row won't be updated during training, so padding never influences learning.

Embedding as the first layer of a text model

import torch
import torch.nn as nn

class TextClassifier(nn.Module):
    def __init__(self, vocab_size, dim, num_classes):
        super().__init__()
        self.embed = nn.Embedding(vocab_size, dim, padding_idx=0)  # IDs -> vectors
        self.fc = nn.Linear(dim, num_classes)                     # simple classifier head

    def forward(self, ids):
        vecs = self.embed(ids)          # (batch, seq, dim)
        pooled = vecs.mean(dim=1)       # average word vectors -> (batch, dim)
        return self.fc(pooled)          # -> logits

model = TextClassifier(vocab_size=20, dim=8, num_classes=2)
print(model(torch.tensor([[3, 4, 6, 0]])).shape)   # torch.Size([1, 2])

4. Common Pitfalls

Pitfall 1 β€” Passing one-hot vectors instead of IDs. nn.Embedding expects a LongTensor of integer indices, not one-hot floats. Handing it one-hots (or float IDs) throws a type/shape error. Feed raw integer token IDs straight from numericalization.

Pitfall 2 β€” Vocabulary/embedding size mismatch. num_embeddings must be at least as large as your largest token ID + 1. If an ID exceeds the table size, you get an index-out-of-range error at runtime. Size the embedding to the full vocabulary (including specials).

Pitfall 3 β€” Ignoring padding_idx. Without it, the <pad> token gets a trainable, non-zero embedding that leaks into pooled representations and wastes capacity. Set padding_idx so padding contributes nothing.


5. Further Reading & Watch List


⬅️ Prev: 01 Β· Text Data & Tokenization Β· ➑️ Next: 03 Β· Recurrent Layers & LSTMs