Embeddings · Next-token prediction
Neural Language Models
What the model learns about one word can help it predict related words, instead of treating every context as unrelated.
Evidence & limits
- What the further reading establishes
- Distributed word representations help models go beyond the exact n-grams they saw during training.
- What this lab runs
- You'll train a small context-embedding model and compare it with a count-based baseline on held-out examples.
- What it does not prove
- The lab leaves out the paper's deeper hidden network, large dataset, and full vocabulary-softmax cost.
Dataset
Roles and Actions
- Source
- Course-authored synthetic corpus
- License
- Not separately licensed
- Size
- 20 sentences · fixed example-by-example modulo split
Further reading
- A Neural Probabilistic Language Model
Primary · Yoshua Bengio et al. · 2003
Shows how a neural language model can learn useful word embeddings while it trains.
- Efficient Estimation of Word Representations in Vector Space
Paper · Tomas Mikolov et al. · 2013
Shows how simpler training goals make strong word embeddings practical at scale.
- Distributed Representations of Words and Phrases
Paper · Tomas Mikolov et al. · 2013
Adds negative sampling, subsampling, and phrase embeddings to the approach.
Lesson progressRestoring progress…
- CodeRestoring
- ExperimentRestoring
- CheckRestoring
Summary
How an n-gram counts. An n-gram model guesses the next word from an exact window of earlier words. A trigram estimate for “the researcher reads” depends on how often that exact three-word sequence showed up. If the model never saw “the researcher,” that count gives it no direct help—even if it saw “the analyst reads” many times.
Look up the embeddings. Give every word in the vocabulary an integer id, then use that id to pick a row from a trainable embedding table. Each row is a short vector of continuous values. For a two-word context, this lab looks up both rows and averages them coordinate by coordinate to make one context vector.
Score every possible next word. A learned projection turns the context vector into one logit—a raw score—for every possible next word. Softmax exponentiates the score differences and divides by their total. Subtracting the largest logit first doesn't change the probabilities, but it does prevent numerical overflow.
Score the real next word. Training scores the real next word with −log p(target). With 30 vocabulary items, a uniform model gives each one probability 1/30 and gets a loss of ln(30) ≈ 3.40. A validation loss of 2.53 means a perplexity of exp(2.53) ≈ 12.6. In effect, the model has cut its next-word uncertainty from 30 equally likely choices to about 12.6.
Learn both parts together. Backpropagation updates the output projection and the chosen embedding rows together. Words end up with nearby vectors only when similar coordinates help predict what follows them. The nearest-neighbor list after training shows the shape the model learned; it isn't a dictionary of meanings someone entered by hand.
“the researcher” unseen → no direct trigram estimateLearned vectorssimilar predictive use → nearby embeddings- 1Context ids
the analyst → [4, 17] - 2Embedding lookup
[.6, −.2], [.2, .8] - 3Mean context
c = [.4, .3] - 4Vocabulary logits
z = [1.2, .1, −.4] - 5Stable softmax
p = [.65, .22, .13] - 6Target loss
−log .65 = .43
A big vocabulary costs more. This lab has 30 output words, but a production vocabulary can have tens of thousands of tokens. Creating and normalizing one logit for every item makes the output layer expensive. Modern models use different context encoders, but embedding lookup, logits, stable softmax, and negative log-likelihood are still basic building blocks.
Knowledge check
Implementation
Turn vocabulary logits into probabilities without exponent overflow.
- Signature
def stable_softmax(logits):- Inputs
- logits [vocab]
- Returns
- list[float] with shape [vocab], summing to 1
- Rule
p_i = exp(z_i − max(z)) / Σ_j exp(z_j − max(z))- Example
[1001, 1000, 999] → [0.665, 0.245, 0.090]
Reference solution
Approach Turn vocabulary logits into probabilities without exponent overflow.
import numpy as np def stable_softmax(logits): values = np.asarray(logits, dtype=float) if values.size == 0: return [] shifted = values - np.max(values) weights = np.exp(shifted) return (weights / weights.sum()).tolist()Implement stable softmax, average the context embeddings, and compute the target loss. Run each function independently before training.
Saved results
Results created after your saved code passes its checks
Saved results
Results created after your saved code passes its checks
The replay is course data. The validation result is tied to the code you saved and checked.
Loading…