πŸ€– GenAI from Scratch β€” Post 6 of 24 Β |Β  Module 1: NLP Foundations Β |Β  Class 06 (11 April)

← Post 5: Word2Vec and Embeddings Explained Post 7: Transformers and Attention β€” The SOTA Era β†’

In the last post you saw what Word2Vec does β€” it turns words into dense vectors where KING βˆ’ MAN + WOMAN β‰ˆ QUEEN. But we treated the model as a black box.

Today we open the box. By the end of this post you’ll understand word2vec CBOW and Skip-gram training from raw text all the way to the final embedding matrix β€” including the single most important insight in this whole module:

The embeddings ARE the hidden layer weights. Word2Vec is a neural network trained on a fake prediction task β€” and after training, we throw the prediction away and keep the weights.

What you’ll learn:

  • A 5-minute neural network crash course (perceptron β†’ MLP β†’ forward/backward propagation)
  • How vocabulary and window size turn raw text into training pairs
  • CBOW vs Skip-gram data preparation, step by step, with the exact class examples
  • The full Word2Vec architecture walkthrough: 5Γ—3 and 3Γ—5 weight matrices
  • Why BoW/TF-IDF dimension = vocab size, but Word2Vec dimension = hidden layer size
  • Training your own custom Word2Vec with gensim β€” validated in VS Code

πŸ“‹ Table of Contents

  1. The Story So Far β€” Encoding vs Embedding
  2. Neural Network Crash Course (Perceptron β†’ MLP)
  3. Forward Propagation, Loss, Backpropagation, Epochs
  4. Step 1: Build the Vocabulary
  5. Step 2: Window Size β€” The Context Hyperparameter
  6. Step 3: CBOW vs Skip-gram Data Preparation
  7. Step 4: Inside the Network β€” Where Embeddings Live
  8. Dimensions: Vocab Size vs Hidden Layer Size
  9. Hands-On: Train Your Own Word2Vec with gensim
  10. Word2Vec Pros and Cons (Interview Favourite)
  11. From Static to Dynamic β€” Why Transformers Won
  12. Common Errors and Fixes
  13. Key Takeaways

Prerequisites

Lab Environment

ComponentVersion/Details
Operating SystemWindows 11 / Ubuntu 22.04
Python3.11 (CPython, managed by uv)
gensim4.3.x
EditorVS Code

1. The Story So Far β€” Encoding vs Embedding

Quick recap of the four techniques we’ve covered, in one line each. This exact framing came up in class as an interview answer:

TechniqueAnswers the questionType
One-Hot Encoding“Is the word present or not?” (0 or 1)Encoding
Bag of Words“How many times does the word appear?” (count)Encoding
TF-IDF“How important is the word in this document?” (count + importance)Encoding
Embeddings (Word2Vec β†’)“What is the meaning of the text in context?”Embedding

πŸ“Œ Interview one-liner from class

OHE, BoW, TF-IDF and BM25 are encoding β€” direct calculations, no training. Embeddings come from a trained model (a neural network or transformer) and carry semantic meaning. Word2Vec (Google, 2013) is the bridge between the two worlds.

Remember the failure case that motivates everything today:

Sentence 1: "I like this movie"
Sentence 2: "I love this film"

OHE / BoW / TF-IDF:   "like" β‰  "love",  "movie" β‰  "film"   β†’ unrelated
Embeddings:           "like" β‰ˆ "love",  "movie" β‰ˆ "film"   β†’ model understands similarity

2. Neural Network Crash Course (Perceptron β†’ MLP)

Word2Vec is a neural network, so we need just enough NN theory to read its architecture diagram. Class 06 used a home-buying prediction example.

The Single Perceptron

Imagine predicting whether someone buys a home β€” a binary classification (Y/N) from three features:

F1 (Size)F2 (Location)F3 (Bedrooms)Output (Y/N)
1250 sq ftCity center3Y
1140 sq ftOutskirts2N

A single perceptron takes the inputs, multiplies each by a weight (w), adds a bias (b), sums everything (Ξ£), and passes the result through an activation function:

Output = Act( WΒ·x + b )

I/P ──w──▢ [ Ξ£ | Act ] ──▢ O/P
             β–²
             b (bias)

From Perceptron to Neural Network

Stack perceptrons into layers and you get a neural network. Every NN has exactly three kinds of layers:

  1. Input layer β€” receives your features
  2. Hidden layer(s) β€” learn intermediate representations
  3. Output layer β€” produces the prediction

A network with multiple hidden layers is a Multi-Layer Perceptron (MLP). Keep this in mind β€” because Word2Vec’s most surprising design choice is that it has just one hidden layer.

3. Forward Propagation, Loss, Backpropagation, Epochs

Training any neural network β€” including Word2Vec β€” is a loop of four ideas from the class whiteboard:

Forward Propagation (FP):   FP = Act(Wx + b), layer by layer β†’ prediction
Loss:                       Loss = Output(Prediction) βˆ’ Actual
Backward Propagation (BP):  BP β†’ Optimizer β†’ Gradient Descent β†’ adjust the weights
1 Epoch:                    FP + BP over the data = 1 epoch

Weights β†’ initialised with RANDOM values
Learning β†’ epoch after epoch β†’ Loss ↓↓↓↓ β†’ BEST POSSIBLE WEIGHTS

πŸ—„οΈ DBA Analogy β€” Training = Query Tuning Iterations

Random initial weights are like a fresh database with no statistics β€” the optimizer’s first execution plan is a guess. Each epoch is like gathering stats and re-running the workload: the plan (weights) gets adjusted until response time (loss) stops improving. “Best possible weights” = your stable, tuned execution plan.

Hold on to the phrase “best possible weights”. In Word2Vec, those final weights are not a means to an end β€” they are literally the product we ship.

4. Step 1: Build the Vocabulary

Word2Vec training is a 4-step data preparation pipeline. Step 1 is the same as OHE/BoW: extract the unique words (a set) from the data.

Data:  "I love AI and I love coding"

Vocab β†’ unique words (set of words)
Vocab = { "I", "love", "AI", "and", "coding" }     # 5 unique words

One subtle detail from class β€” vocabulary is case-sensitive by default:

Data:  "Sunny love AI sunny love coding"

Vocab = { "Sunny", "love", "AI", "sunny", "coding" }   # 5 words!
# "Sunny" (capital S) and "sunny" (small s) are DIFFERENT tokens
# Same for "Apple" vs "apple" β€” this is why lowercasing is a
# standard preprocessing step before training

5. Step 2: Window Size β€” The Context Hyperparameter

Window size = how many neighbours we consider around the word. It defines what “context” means for training.

Window Size = 1

Sentence: "I love deep learning" β€” each word looks 1 position left and 1 position right:

Context (Input)Target (Output)
loveI
I, deeplove
love, learningdeep
deeplearning

Window Size = 2

Same sentence, but now each word looks 2 positions in each direction β€” more context per pair:

Context (Input)Target (Output)
love, deepI
I, deep, learninglove
I, love, learningdeep
love, deeplearning

⚠️ Window size is a hyperparameter β€” experiment!

Typical values to try: 5, 10, 15, 20… But beware the trade-off from class: window size ↑↑↑ β†’ context ↑↑↑ β†’ but if it goes very, very high β†’ NOISE. Distant words stop being meaningful context and start polluting the training pairs.

6. Step 3: CBOW vs Skip-gram Data Preparation

Here’s the key reframe from Class 06: CBOW and Skip-gram are not two different models β€” they are two ways of preparing the training data for the same neural network.

                       Word2Vec
                (based on data preparation)
                    /              \
              CBOW                  Skip-gram
    (Continuous Bag of Words)
    Context β†’ predict TARGET      Target β†’ predict CONTEXT

Class example sentence: "Follow Sunny for Gen AI", window size = 1.

CBOW β€” Context In, Target Out

Input (Context)Output (Target)
SunnyFollow
Follow, forSunny
Sunny, Genfor
for, AIGen
GenAI

Skip-gram β€” Target In, Context Out

Input (Target)Output (Context)
FollowSunny
SunnyFollow, for
forSunny, Gen
Genfor, AI
AIGen

Notice the tables are mirror images β€” same pairs, flipped direction. This is supervised learning: we manufactured X (input) and Y (output) columns from raw, unstructured text. No human labelling required.

The Full 4-Step Data Preparation Pipeline

Data: "Follow Sunny for Gen AI"

Step 1 β†’ Vocab:        { AI, Follow, for, Gen, Sunny }        # sorted set
Step 2 β†’ One-Hot each word (5-dim vectors, one per vocab word):
           AI     β†’ [1 0 0 0 0]
           Follow β†’ [0 1 0 0 0]
           for    β†’ [0 0 1 0 0]
           Gen    β†’ [0 0 0 1 0]
           Sunny  β†’ [0 0 0 0 1]
Step 3 β†’ Window size = 1
Step 4 β†’ Build (X, Y) training pairs (CBOW or Skip-gram)

πŸ’‘ Full-circle moment: One-Hot Encoding β€” the “obsolete” technique from Post 3 β€” is exactly how words enter the Word2Vec network. OHE isn’t dead; it moved backstage.

7. Step 4: Inside the Network β€” Where Embeddings Live

Now the whiteboard diagram that ties everything together. Training pair (CBOW): context ["Follow", "for"] β†’ target "Sunny". Vocab size = 5, hidden layer = 3 neurons.

INPUT (OHE, 5-dim)        HIDDEN (3 neurons)        OUTPUT (5-dim, softmax)

Follow [0 1 0 0 0] ──┐
                     β”œβ”€β”€[ W1: 5Γ—3 ]──▢ (h1 h2 h3) ──[ W2: 3Γ—5 ]──▢ [p1 p2 p3 p4 p5]
for    [0 0 1 0 0] β”€β”€β”˜        β–²                            β”‚
                              β”‚                            β–Ό
                        EMBEDDING                 Predicted word vs
                      (weight matrix)             Expected word: "Sunny"
                                                          β”‚
   ◀──────────── Backpropagation: adjust weights ◀── Loss β”˜

FP + BP, epoch after epoch β†’ loss ↓ β†’ BEST POSSIBLE WEIGHTS
                                       = the EMBEDDING VECTORS

Walk through one forward pass:

  1. Each context word enters as a one-hot vector (1Γ—5)
  2. It’s multiplied by the input weight matrix W1 (5Γ—3) β€” pure matrix multiplication (vector Γ— matrix)
  3. The hidden layer holds a 3-dim representation
  4. Hidden output is multiplied by W2 (3Γ—5) to produce 5 scores β€” one per vocab word
  5. The predicted word is compared with the expected word (“Sunny”) β†’ loss
  6. Backpropagation adjusts both weight matrices; repeat until loss is minimised

πŸ”‘ THE key insight of Class 06

After training, we don’t care about the prediction at all. We keep W1, the input weight matrix. Because each word’s one-hot vector has a single 1, multiplying it by W1 simply selects one row of the matrix. That row is the word’s embedding. The 5Γ—3 weight matrix IS the embedding table: 5 words Γ— 3 dimensions. The prediction task was just a training excuse.

And this is why Word2Vec is fast: it’s a shallow model β€” one hidden layer, simple architecture. Google’s production model was exactly this, scaled up: 1 hidden layer with 300 neurons.

8. Dimensions: Vocab Size vs Hidden Layer Size

This comparison from the class notes clears up a confusion almost everyone has:

TechniqueVector dimension =Controlled by
BoW / TF-IDFVocabulary size (number of features)Your data β€” grows with vocab (10k, 50k, 100k…)
Word2VecHidden layer sizeYou β€” it’s a hyperparameter (3, 10, 100, 300, 500, 1000…)

Google’s pretrained Word2Vec chose 300 dimensions β€” every word becomes a 300-feature vector regardless of whether the vocabulary has 5 words or 3 million. That’s the escape from the high-dimensionality curse of BoW/TF-IDF: dense, compact, fixed-size vectors.

9. Hands-On: Train Your Own Word2Vec with gensim

Two practical routes from class: use Google’s pretrained model (Post 5) or do custom training on your own data. Today: custom training, where you control every hyperparameter we just learned.

Setup

# In your project folder (uv setup from Post 1)
uv init word2vec-lab
cd word2vec-lab
uv add gensim

[SCREENSHOT: VS Code terminal showing uv add gensim completing successfully]

File: train_word2vec.py

"""
Custom Word2Vec training β€” Class 06 concepts in code.
Every hyperparameter below maps to something from the whiteboard.
"""
from gensim.models import Word2Vec

# ── Step 1: Data (already tokenised, lowercased to avoid the
#            "Sunny" vs "sunny" case-sensitivity trap) ────────────
sentences = [
    ["follow", "sunny", "for", "gen", "ai"],
    ["i", "love", "ai", "and", "i", "love", "coding"],
    ["i", "love", "deep", "learning"],
    ["sunny", "teach", "ai"],
    ["people", "watch", "movie"],
    ["people", "like", "movie"],
    ["ai", "is", "the", "future"],
]

# ── Step 2: Train β€” the 4-step pipeline happens inside ────────────
model = Word2Vec(
    sentences   = sentences,
    vector_size = 3,      # HIDDEN LAYER SIZE = embedding dims (Google: 300)
    window      = 1,      # WINDOW SIZE from the class tables
    min_count   = 1,      # keep every word in the vocab
    sg          = 0,      # 0 = CBOW (context→target), 1 = Skip-gram
    epochs      = 200,    # FP + BP loops β€” loss ↓ each epoch
    seed        = 42,
)

# ── Step 3: Inspect the vocabulary (Step 1 of the pipeline) ──────
print("Vocab size:", len(model.wv.key_to_index))
print("Vocab:", sorted(model.wv.key_to_index))

# ── Step 4: THE EMBEDDING MATRIX = hidden layer weights ──────────
print("\nEmbedding matrix shape:", model.wv.vectors.shape)
# β†’ (vocab_size, 3)  β€” exactly the W1 matrix from the diagram!

# ── Step 5: One word = one ROW of that matrix ────────────────────
print("\nVector for 'ai':", model.wv["ai"].round(3))
print("Vector for 'sunny':", model.wv["sunny"].round(3))

# ── Step 6: Semantic neighbours ──────────────────────────────────
print("\nMost similar to 'ai':")
for word, score in model.wv.most_similar("ai", topn=3):
    print(f"  {word:10s}  {score:.3f}")

Run it

uv run train_word2vec.py

# Expected output (values vary β€” weights start RANDOM, remember?):
Vocab size: 20
Vocab: ['ai', 'and', 'coding', 'deep', 'follow', 'for', 'future', ...]

Embedding matrix shape: (20, 3)

Vector for 'ai': [ 0.217 -0.041  0.294]
Vector for 'sunny': [-0.166  0.089  0.312]

Most similar to 'ai':
  love        0.912
  sunny       0.847
  learning    0.803

[SCREENSHOT: VS Code output showing embedding matrix shape (20, 3) and similarity results]

Experiment Like the Class Told You To

# Try Skip-gram instead of CBOW:
sg = 1

# Try a bigger hidden layer (more expressive, needs more data):
vector_size = 100

# Try a wider window (more context β€” but remember: too high = noise):
window = 5

With a 7-sentence toy corpus, results are rough β€” that’s the honest lesson. Word2Vec’s quality comes from scale. Google trained on ~100 billion words of Google News to get its famous 300-dim vectors.

10. Word2Vec Pros and Cons (Interview Favourite)

βœ… Pros

  1. Efficient & fast training β€” shallow model, no deep layers (1 hidden layer!)
  2. Semantic understanding β€” similar meaning words β†’ close vectors (king β‰ˆ queen, car β‰ˆ vehicle). Captures similarity AND relationships
  3. Vector arithmetic β€” king βˆ’ man + woman = queen, demonstrable in code
  4. Pretrained embeddings available β€” Google News vectors (300d), easy to reuse
  5. General-purpose β€” usable in NLP pipelines, ML models, clustering, and search

❌ Cons

  1. Context-independent (static) β€” same word = same vector, always. bank (river) = bank (finance). The vector will not change according to the sentence context
  2. Fixed embeddings β€” trained once, frozen forever
  3. No OOV handling β€” a new word like “ChatGPT” (born after 2013) β†’ unknown to the Google model
  4. Cannot handle subwords β€” running, runner, runs are treated as three unrelated words; no morphology understanding
  5. Compared to BERT/GPT β€” no attention, no deep context, no dynamic embeddings

πŸ—„οΈ DBA Analogy β€” Static vs Dynamic Embeddings

A Word2Vec embedding is like a materialized view built once and never refreshed β€” great snapshot, but it can’t reflect what’s happening in the current query. Transformer embeddings are like a live view β€” recomputed per sentence, so “bank” gets a different vector next to “river” than next to “finance”.

11. From Static to Dynamic β€” Why Transformers Won

The Class 06 roadmap positions everything we’ve learned:

1. OHE          ─┐
2. BoW           β”œβ”€β”€ Encoding (no training, direct calculation)
3. TF-IDF       β”€β”˜
4. Word2Vec     ──── Classical embedding (Google 2013, shallow NN)
                     ↳ CBOW & Skip-gram = interview concept
                     ↳ Custom training  = practical skill (done today βœ…)
5. Transformers ──── SOTA (state of the art)
                     ↳ HF Sentence Transformers, OpenAI embeddings,
                       Gemini embeddings β€” the models behind RAG

Two more facts from class worth remembering:

  • Transformers still use embeddings internally β€” every token gets an embedding as the first step. Word2Vec’s core idea never died; it became layer zero of every LLM.
  • LLM vs MMLLM β€” LLMs like Llama are text-to-text; Multi-Modal LLMs handle image-to-text and text-to-image. All of them start by embedding their input.

Next post: the transformer era β€” attention, contextual embeddings, and calling real embedding models (Hugging Face free tier, OpenAI, Gemini) from Python.

12. Common Errors and Fixes

Error 1: gensim fails to install or import (NumPy conflict)

Symptom:

ImportError: numpy.core.multiarray failed to import
# or during install:
error: Failed to build `gensim`

Cause: gensim compiled against an older NumPy; very new Python versions (3.12/3.13) may lack prebuilt wheels.

Fix: pin Python 3.11 (as our lab does) and let uv resolve compatible versions:

uv python pin 3.11
uv add "gensim>=4.3" "numpy<2"
uv run train_word2vec.py

Error 2: KeyError when looking up a word

Symptom:

KeyError: "Key 'chatgpt' not present in vocabulary"

Cause: This is the OOV problem from the cons list, live in your terminal β€” the word never appeared in training data (or appeared fewer than min_count times, or with different casing: “AI” vs “ai”).

Fix: guard your lookups and normalise case:

word = "ChatGPT".lower()
if word in model.wv:
    print(model.wv[word])
else:
    print(f"'{word}' is OOV β€” not in the training vocabulary")

Error 3: Every training run gives different vectors

Symptom: You rerun the script and ‘ai’ has a completely different vector.

Cause: Not a bug β€” weights are initialised randomly (Section 3!), and gensim uses multiple worker threads, which adds nondeterminism.

Fix: for reproducible demos, set seed=42 and workers=1. The relative geometry (which words are near which) is what matters, not the raw numbers.

Key Takeaways

βœ… Word2Vec is a shallow neural network β€” one hidden layer β€” trained with the standard FP β†’ Loss β†’ BP β†’ epoch loop starting from random weights.

βœ… CBOW and Skip-gram are data-preparation strategies, not different models: CBOW predicts target from context; Skip-gram predicts context from target.

βœ… Window size is the context hyperparameter β€” bigger window = more context, but too big = noise.

βœ… The embeddings ARE the hidden layer weight matrix (W1) β€” the prediction task is thrown away after training; each word’s vector is one row of W1.

βœ… BoW/TF-IDF dimension = vocab size (grows with data); Word2Vec dimension = hidden layer size (you choose it β€” Google chose 300).

🧠 Test Your Knowledge

20 questions on Word2Vec training, CBOW vs Skip-gram, window size and embeddingsTake the Free Quiz β†’

Instant feedback Β· Detailed explanations Β· Free

What’s Next in the Series

#PostStatus
4Word2Vec and Embeddings Explained (KINGβˆ’MAN+WOMAN)βœ… Published
5Word2Vec in Practice β€” Pretrained Modelsβœ… Published
6Inside Word2Vec: CBOW, Skip-gram & Neural Network TrainingπŸ“ You are here
7Transformers and Attention β€” The SOTA Era⬜ Coming next week

πŸ‘‰ Next Post: Transformers and Attention β€” The SOTA Era β†’

References


Found this helpful? Share it with your team!
Questions? Drop them in the comments below.
Part of the GenAI from Scratch series β€” published every Friday at gradeupnow.in/genai-blog/

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top