{ "cells": [ { "cell_type": "markdown", "id": "765d15f2", "metadata": {}, "source": [ "# Topic 3: A deeper text model: a Bengio-style MLP\n", "\n", "The bigram model only looks at **one** previous character, which is why its names were so-so.\n", "Here we use the **three** previous characters to predict the next one, with a small neural network in the style of Bengio et al. (2003), *A Neural Probabilistic Language Model*.\n", "Along the way we meet `nn.Module`, `nn.Embedding`, minibatch training and train/validation splits." ] }, { "cell_type": "markdown", "id": "2d91ece0", "metadata": {}, "source": [ "## 1. Setup, seed and device\n", "Same imports as Topic 2, plus matplotlib for plots. We fix the seed and pick the GPU if one is available." ] }, { "cell_type": "code", "execution_count": 1, "id": "40198429", "metadata": { "execution": { "iopub.execute_input": "2026-10-01T17:12:47.731747Z", "iopub.status.busy": "2026-10-01T17:12:47.731577Z", "iopub.status.idle": "2026-10-01T17:12:50.773651Z", "shell.execute_reply": "2026-10-01T17:12:50.773193Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "device: cpu\n" ] } ], "source": [ "import torch\n", "import torch.nn as nn\n", "import torch.nn.functional as F\n", "import matplotlib.pyplot as plt\n", "\n", "torch.manual_seed(1337)\n", "g = torch.Generator().manual_seed(1337) # our own generator for shuffling and batch sampling\n", "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", "print(\"device:\", device)" ] }, { "cell_type": "markdown", "id": "5c1f0ea2", "metadata": {}, "source": [ "## 2. Load the names and build the vocabulary\n", "Exactly as in Topics 1 and 2: 27 tokens, with `.` (index 0) marking the start and end of a name." ] }, { "cell_type": "code", "execution_count": 2, "id": "37774e1a", "metadata": { "execution": { "iopub.execute_input": "2026-10-01T17:12:50.775644Z", "iopub.status.busy": "2026-10-01T17:12:50.775415Z", "iopub.status.idle": "2026-10-01T17:12:50.782959Z", "shell.execute_reply": "2026-10-01T17:12:50.782590Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "32033 names, 27 tokens\n" ] } ], "source": [ "words = open(\"names.txt\").read().splitlines()\n", "chars = sorted(set(\"\".join(words)))\n", "stoi = {ch: i + 1 for i, ch in enumerate(chars)}\n", "stoi[\".\"] = 0\n", "itos = {i: ch for ch, i in stoi.items()}\n", "vocab_size = len(stoi)\n", "print(len(words), \"names,\", vocab_size, \"tokens\")" ] }, { "cell_type": "markdown", "id": "967dd78d", "metadata": {}, "source": [ "## 3. Context windows and a train/val/test split\n", "Each training example is now a **context** of the `block_size = 3` previous characters (padded with `.` at the start of a name) and the character that follows it.\n", "Here is what the examples for `emma` look like." ] }, { "cell_type": "code", "execution_count": 3, "id": "f019c7b3", "metadata": { "execution": { "iopub.execute_input": "2026-10-01T17:12:50.784712Z", "iopub.status.busy": "2026-10-01T17:12:50.784543Z", "iopub.status.idle": "2026-10-01T17:12:50.789050Z", "shell.execute_reply": "2026-10-01T17:12:50.788666Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "... -> e\n", "..e -> m\n", ".em -> m\n", "emm -> a\n", "mma -> .\n" ] } ], "source": [ "block_size = 3\n", "\n", "def build_dataset(words):\n", " X, Y = [], []\n", " for w in words:\n", " context = [0] * block_size # start with '...'\n", " for ch in w + \".\":\n", " ix = stoi[ch]\n", " X.append(context)\n", " Y.append(ix)\n", " context = context[1:] + [ix] # slide the window\n", " return torch.tensor(X), torch.tensor(Y)\n", "\n", "X, Y = build_dataset([\"emma\"])\n", "for x, y in zip(X, Y):\n", " print(\"\".join(itos[i] for i in x.tolist()), \"->\", itos[y.item()])" ] }, { "cell_type": "markdown", "id": "f7343ac3", "metadata": {}, "source": [ "To judge whether the model has learned something general, and not just memorized, we hold out names it never trains on.\n", "We shuffle the names and split them 80/10/10 into **train** (to fit the weights), **val** (to compare models and settings) and **test** (touched only once, at the very end)." ] }, { "cell_type": "code", "execution_count": 4, "id": "46a74a05", "metadata": { "execution": { "iopub.execute_input": "2026-10-01T17:12:50.790797Z", "iopub.status.busy": "2026-10-01T17:12:50.790628Z", "iopub.status.idle": "2026-10-01T17:12:51.158386Z", "shell.execute_reply": "2026-10-01T17:12:51.157893Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "train (182508, 3) val (22860, 3) test (22778, 3)\n" ] } ], "source": [ "perm = torch.randperm(len(words), generator=g).tolist()\n", "words = [words[i] for i in perm]\n", "n1, n2 = int(0.8 * len(words)), int(0.9 * len(words))\n", "\n", "Xtr, Ytr = build_dataset(words[:n1])\n", "Xva, Yva = build_dataset(words[n1:n2])\n", "Xte, Yte = build_dataset(words[n2:])\n", "print(\"train\", tuple(Xtr.shape), \" val\", tuple(Xva.shape), \" test\", tuple(Xte.shape))" ] }, { "cell_type": "markdown", "id": "3ae974f3", "metadata": {}, "source": [ "## 4. The scaling problem\n", "The obvious extension of the bigram is a lookup table with one row of next-character scores per possible context.\n", "With 3 characters of context that is already 27^4 ≈ 531k numbers, and every extra character of context multiplies it by 27; most rows would also never be seen in training." ] }, { "cell_type": "code", "execution_count": 5, "id": "e6fb94da", "metadata": { "execution": { "iopub.execute_input": "2026-10-01T17:12:51.160220Z", "iopub.status.busy": "2026-10-01T17:12:51.160057Z", "iopub.status.idle": "2026-10-01T17:12:51.163052Z", "shell.execute_reply": "2026-10-01T17:12:51.162603Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "context 1: table with 729 entries\n", "context 2: table with 19,683 entries\n", "context 3: table with 531,441 entries\n", "context 4: table with 14,348,907 entries\n", "context 5: table with 387,420,489 entries\n", "context 6: table with 10,460,353,203 entries\n" ] } ], "source": [ "for n in range(1, 7):\n", " print(f\"context {n}: table with {vocab_size ** (n + 1):>13,} entries\")" ] }, { "cell_type": "markdown", "id": "1cd5ae0f", "metadata": {}, "source": [ "Bengio's idea: give every character a short learned vector (an **embedding**) from one small shared table `C`, concatenate the vectors of the 3 context characters, and let a small neural network map them to next-character scores.\n", "Characters that behave similarly (e.g. vowels) can end up with similar vectors, so what is learned about one context transfers to similar contexts." ] }, { "cell_type": "markdown", "id": "8b5b703d", "metadata": {}, "source": [ "## 5. The model as an `nn.Module`\n", "Real models are written as a class that subclasses `nn.Module`: layers are created in `__init__` (PyTorch then tracks their parameters automatically) and `forward` says how to compute the output.\n", "`nn.Embedding(27, 10)` is just a learnable 27x10 table `C`: indexing it with a character id returns that character's row, which is equivalent to (but cheaper than) one-hot times a weight matrix." ] }, { "cell_type": "code", "execution_count": 6, "id": "c0c118a8", "metadata": { "execution": { "iopub.execute_input": "2026-10-01T17:12:51.164974Z", "iopub.status.busy": "2026-10-01T17:12:51.164732Z", "iopub.status.idle": "2026-10-01T17:12:51.181807Z", "shell.execute_reply": "2026-10-01T17:12:51.181450Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "MLP(\n", " (C): Embedding(27, 10)\n", " (hidden): Linear(in_features=30, out_features=200, bias=True)\n", " (out): Linear(in_features=200, out_features=27, bias=True)\n", ")\n" ] } ], "source": [ "class MLP(nn.Module):\n", " def __init__(self, vocab_size, block_size, n_embd=10, n_hidden=200):\n", " super().__init__()\n", " self.C = nn.Embedding(vocab_size, n_embd)\n", " self.hidden = nn.Linear(block_size * n_embd, n_hidden)\n", " self.out = nn.Linear(n_hidden, vocab_size)\n", "\n", " def forward(self, x): # x: (B, block_size) integer ids\n", " emb = self.C(x) # (B, block_size, n_embd)\n", " emb = emb.view(x.shape[0], -1) # (B, block_size * n_embd): concatenate the 3 vectors\n", " h = torch.tanh(self.hidden(emb)) # (B, n_hidden)\n", " return self.out(h) # (B, vocab_size) logits\n", "\n", "model = MLP(vocab_size, block_size).to(device)\n", "print(model)" ] }, { "cell_type": "markdown", "id": "00dfd7f5", "metadata": {}, "source": [ "`model.parameters()` lists every learnable tensor; counting them shows how much smaller this is than the 4-gram table." ] }, { "cell_type": "code", "execution_count": 7, "id": "7127ea89", "metadata": { "execution": { "iopub.execute_input": "2026-10-01T17:12:51.183457Z", "iopub.status.busy": "2026-10-01T17:12:51.183283Z", "iopub.status.idle": "2026-10-01T17:12:51.186791Z", "shell.execute_reply": "2026-10-01T17:12:51.186360Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "MLP parameters: 11,897\n", "4-gram table: 531,441\n", " C.weight (27, 10)\n", " hidden.weight (200, 30)\n", " hidden.bias (200,)\n", " out.weight (27, 200)\n", " out.bias (27,)\n" ] } ], "source": [ "n_params = sum(p.numel() for p in model.parameters())\n", "print(f\"MLP parameters: {n_params:,}\")\n", "print(f\"4-gram table: {vocab_size ** 4:,}\")\n", "for name, p in model.named_parameters():\n", " print(f\" {name:15s} {tuple(p.shape)}\")" ] }, { "cell_type": "markdown", "id": "2d3097ed", "metadata": {}, "source": [ "Let's push a small batch of 4 examples through the model step by step and check the shapes." ] }, { "cell_type": "code", "execution_count": 8, "id": "278bcb48", "metadata": { "execution": { "iopub.execute_input": "2026-10-01T17:12:51.188571Z", "iopub.status.busy": "2026-10-01T17:12:51.188404Z", "iopub.status.idle": "2026-10-01T17:12:51.192492Z", "shell.execute_reply": "2026-10-01T17:12:51.192055Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "input (4, 3)\n", "embedded (4, 3, 10)\n", "flattened (4, 30)\n", "logits (4, 27)\n" ] } ], "source": [ "xb = Xtr[:4].to(device)\n", "emb = model.C(xb)\n", "print(\"input \", tuple(xb.shape))\n", "print(\"embedded \", tuple(emb.shape))\n", "print(\"flattened \", tuple(emb.view(4, -1).shape))\n", "print(\"logits \", tuple(model(xb).shape))" ] }, { "cell_type": "markdown", "id": "ff7a6a0d", "metadata": {}, "source": [ "## 6. Minibatch training\n", "We have ~180k training examples; instead of using all of them for every step, each step uses a random **minibatch** of 32.\n", "The gradient is noisier but each step is much cheaper, so we can take many more steps; this is how essentially all neural networks are trained.\n", "We drop the learning rate from 0.1 to 0.01 for the last quarter of training to settle into a good minimum (this takes about a minute on one CPU core)." ] }, { "cell_type": "code", "execution_count": 9, "id": "d6bb5b6a", "metadata": { "execution": { "iopub.execute_input": "2026-10-01T17:12:51.194173Z", "iopub.status.busy": "2026-10-01T17:12:51.193987Z", "iopub.status.idle": "2026-10-01T17:13:25.024955Z", "shell.execute_reply": "2026-10-01T17:13:25.024277Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "step 0 minibatch loss 3.3311\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "step 5000 minibatch loss 2.4112\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "step 10000 minibatch loss 2.0580\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "step 15000 minibatch loss 1.8247\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "step 20000 minibatch loss 2.4291\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "step 25000 minibatch loss 2.0780\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "step 30000 minibatch loss 2.0041\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "step 35000 minibatch loss 2.0040\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "step 40000 minibatch loss 1.9643\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "step 45000 minibatch loss 2.4243\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "step 49999 minibatch loss 2.3230\n" ] } ], "source": [ "optimizer = torch.optim.SGD(model.parameters(), lr=0.1)\n", "max_steps, batch_size = 50_000, 32\n", "lossi = []\n", "\n", "model.train()\n", "for step in range(max_steps):\n", " if step == int(0.75 * max_steps):\n", " for group in optimizer.param_groups:\n", " group[\"lr\"] = 0.01 # simple manual learning-rate drop\n", "\n", " ix = torch.randint(0, Xtr.shape[0], (batch_size,), generator=g)\n", " xb, yb = Xtr[ix].to(device), Ytr[ix].to(device)\n", "\n", " loss = F.cross_entropy(model(xb), yb)\n", " optimizer.zero_grad()\n", " loss.backward()\n", " optimizer.step()\n", "\n", " lossi.append(loss.item())\n", " if step % 5000 == 0 or step == max_steps - 1:\n", " print(f\"step {step:6d} minibatch loss {loss.item():.4f}\")" ] }, { "cell_type": "markdown", "id": "d76445a9", "metadata": {}, "source": [ "Minibatch losses are noisy, so we also plot a running average over 500 steps; the drop at step 37,500 is the learning-rate decrease." ] }, { "cell_type": "code", "execution_count": 10, "id": "866cf438", "metadata": { "execution": { "iopub.execute_input": "2026-10-01T17:13:25.027372Z", "iopub.status.busy": "2026-10-01T17:13:25.026906Z", "iopub.status.idle": "2026-10-01T17:13:25.460987Z", "shell.execute_reply": "2026-10-01T17:13:25.460597Z" } }, "outputs": [ { "data": { "image/png": "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9ttvZ8aMGcPIZDLm1Vdf9ap+FLwRQgg3Ti9QZjPD6FpC82c2s6777t27mV27djG///4788YbbzByuZz55ptvrPc/88wzTP/+/e32+e677xipVMoolUrGbDYzU6ZMYUaPHs189913zK+//spcd911zBVXXMEYjUaGYRjm4sWLDAAmPT2deeutt5gdO3Yw9fX1rB7faDQyffr0YUaNGsX8+OOPzHvvvcdkZGQwAJhdu3Zdeqk916Ejs9nMDBs2jLniiiuY77//nvn444+Z1NRU5pFHHrE+7q5du5js7Gzmn//8J7Nr1y6msrLS6bHy8vKYQYMGMVdddRVz++23M99//73d/f/9738ZAHYBjtFoZGJjY5kVK1awLtPRDz/8wMTGxjLvvfces2XLFub1119npk6dyjAMw/z8888MAObzzz9ndu3axZw4ccKr9yo+Pp5Zvnw588svvzBTpkxhcnNzmdbWVo+P25G/greQdZuKRCL8+OOPKC4uxqFDhxAdHY2VK1eioKDArtwdd9yBa665BgAgFAqxbNkyp8dLSkoCAAgEAvzwww/W4yYkJGDw4MFIS0sL7BMihBDimkEDvJzpuVwgPFUFiKNZFR06dKj1/6NGjYJGo8Fbb72FW265BQBw++23Y/HixThx4gR69+4NAPj8888xdepUxMXF4ccff8SePXtQVlYGmUwGABg7diyysrKwfv16XH/99dbjP/vss3jooYe8evzvvvsOFy5cQHl5uXWinlAoxD333GPd76effmJdB4v//ve/OHToEEpKSpCeng4ASExMxE033YT58+cjNzcXw4YNg0QiQUFBAYYNG+byNSwoKMCMGTPQo0cP7NmzB7Nnz8YTTzyB559/HgBQWloKsVhsvW4D7dfutLQ0lJaWsi7T0Y4dOzBu3DjMnTsXQHseWMvrO2jQIABAv3790KdPHwDw6r2aP38+/vGPfwAAxo8fj/z8fLz//vt45JFH3D5uoIR8zFuvXr3Qq1cvl/dfddVV1v9LpVLWiXc9HZcQQgjp6MCBA3j33Xdx4cIFtLS0oLGxEVqt1np/9+7dMXjwYHz++ed4+eWXoVQq8fPPP+Prr78GAGzduhUGgwHXXHMNmPbeLQDt465PnTplFxCMGDHC68c/cOAABg4caJdh4eqrr7Y7hjd1sNi3bx/69+9vDdwAYNKkSTCbzTh8+DBy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1NlWXFwcfSHDBL0X4YPei/BA70P4oPciPAT6fWA7FyDs5yItWbLEmsdNr9fjlVdesU5QMBqNePLJJ6HRaDBjxgzrPvfeey/ef/99VFZWAgDWrl2L4uJi3HvvvcF/AoQQQgghfhTSlreff/4ZL774ojUY+8tf/oK4uDjMnTsXc+fOBQCcP38eR44cAQCIRCK0tLQgMzMTGRkZqK6uRnx8PNatW4eePXtaj/vss8/i7NmzKCoqQk5ODioqKvDWW29hyJAhwX+ShBBCCCF+FNLg7corr8SKFSsctmdnZ1v//9RTT6GlpQVAe76kF198Ef/6179w9uxZJCQkICMjw2FMmkQiwTfffIOqqirU1taiqKgo7JLzSiQSPPfccw5dtST46L0IH/RehAd6H8IHvRfhIdzeBx7DZk4qIYQQQggJC2E/5o0QQgghhPyJgjdCCCGEkAhCwRshhBBCSASh4C0EfvzxR9x0000YN24cFixYAIVCEeoqRRSVSoX//Oc/GDt2LObNm+e0jEajwQsvvIDx48dj6tSp+OKLL0JapjPSaDR46623MH36dFx77bV45pln0NDQ4FCuuLgY99xzD6666ircc889KC4uDmmZzkihUODll1/GlClTMHXqVCxevBjNzc0O5b744gtMnToV48ePxwsvvACNRhPSMp2ZQqHAxIkTMWzYMIf7lEolFi5ciHHjxuHGG2/EunXrQlqmM3r33XcxbNgwu7/rrrvOodz+/futS27OmzcPFy9eDGkZ1hgSVF988QUjEomYV199lVm3bh0zdOhQZvDgwYzBYAh11SKCWq1mMjIymIceeoiZPHkyM3LkSKflJk2axPTq1YtZu3Yts2rVKiYqKor597//HbIyndHIkSOZv/3tb8zatWuZn3/+mRk7dixTUFDANDY2WsucPXuWkcvlzD333MP88ssvzN13383I5XLm3LlzISnTWV1xxRXMokWLmA0bNjBr1qxhBg8ezPTr18/uvLJ8+XJGJpMxb7/9NrN27VqmZ8+ezKRJk+yOE8wynd2MGTOYPn36MB0vs0ajkbnyyiuZK6+8klm3bh3z2muvMUKhkPn0009DUqazevrpp5mBAwcyu3btsv4dOHDArszBgwcZqVTKPProo8wvv/zCzJgxg0lLS2NqampCUsYbFLwFWX5+PjN//nzr7crKSobP5zNfffVVCGsV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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "losses = torch.tensor(lossi)\n", "smooth = losses.view(-1, 500).mean(dim=1)\n", "plt.figure(figsize=(7, 3.5))\n", "plt.plot(losses, alpha=0.3, lw=0.5, label=\"minibatch loss\")\n", "plt.plot(torch.arange(len(smooth)) * 500 + 250, smooth, label=\"average of 500 steps\")\n", "plt.axhline(2.47, color=\"gray\", ls=\"--\", label=\"bigram (≈2.47)\")\n", "plt.xlabel(\"step\"); plt.ylabel(\"cross-entropy loss\"); plt.ylim(1.5, 3.5)\n", "plt.legend(); plt.show()" ] }, { "cell_type": "markdown", "id": "0c27593e", "metadata": {}, "source": [ "## 7. Evaluate on the train and validation sets\n", "For evaluation we compute the loss over *all* examples. `model.eval()` switches layers like dropout to evaluation mode (we have none, but it is good habit) and `torch.no_grad()` tells PyTorch not to record operations for backprop, saving memory and time." ] }, { "cell_type": "code", "execution_count": 11, "id": "583096c5", "metadata": { "execution": { "iopub.execute_input": "2026-10-01T17:13:25.462758Z", "iopub.status.busy": "2026-10-01T17:13:25.462599Z", "iopub.status.idle": "2026-10-01T17:13:25.752996Z", "shell.execute_reply": "2026-10-01T17:13:25.752532Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "train loss: 2.1011\n", "val loss: 2.1402\n", "bigram: ~2.47\n" ] } ], "source": [ "@torch.no_grad()\n", "def split_loss(X, Y):\n", " model.eval()\n", " loss = F.cross_entropy(model(X.to(device)), Y.to(device))\n", " model.train()\n", " return loss.item()\n", "\n", "print(f\"train loss: {split_loss(Xtr, Ytr):.4f}\")\n", "print(f\"val loss: {split_loss(Xva, Yva):.4f}\")\n", "print( \"bigram: ~2.47\")" ] }, { "cell_type": "markdown", "id": "916e5598", "metadata": {}, "source": [ "Both losses are clearly below the bigram's ≈2.47, so the extra context helps.\n", "The train and val losses are close, which means the model is **not overfitting**: it does as well on unseen names as on the ones it trained on.\n", "If train loss kept falling while val loss rose, the model would be memorizing; the validation set is how we would notice (and how we should choose model size, learning rate, etc., saving the test set for one final check)." ] }, { "cell_type": "markdown", "id": "22257bd0", "metadata": {}, "source": [ "## 8. Generate names\n", "Generation works like before, except the model now sees the last 3 characters: we start from `...`, sample the next character from the softmax of the logits, slide the window, and stop at `.`." ] }, { "cell_type": "code", "execution_count": 12, "id": "cb1a106a", "metadata": { "execution": { "iopub.execute_input": "2026-10-01T17:13:25.754906Z", "iopub.status.busy": "2026-10-01T17:13:25.754747Z", "iopub.status.idle": "2026-10-01T17:13:25.764437Z", "shell.execute_reply": "2026-10-01T17:13:25.763985Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tami\n", "rucmikalas\n", "soren\n", "retario\n", "vin\n" ] } ], "source": [ "@torch.no_grad()\n", "def generate(n=5):\n", " model.eval()\n", " for _ in range(n):\n", " out, context = [], [0] * block_size\n", " while True:\n", " logits = model(torch.tensor([context], device=device))\n", " probs = F.softmax(logits, dim=1)\n", " ix = torch.multinomial(probs.cpu(), num_samples=1, generator=g).item()\n", " if ix == 0:\n", " break\n", " out.append(itos[ix])\n", " context = context[1:] + [ix]\n", " print(\"\".join(out))\n", " model.train()\n", "\n", "generate()" ] }, { "cell_type": "markdown", "id": "77d98454", "metadata": {}, "source": [ "## Takeaways\n", "- An `nn.Module` bundles layers and parameters; `nn.Embedding` is a learnable lookup table shared across context positions, which avoids the exponential blow-up of n-gram tables.\n", "- With ~12k parameters and 3 characters of context, the MLP beats the bigram (≈2.47) on names it has never seen.\n", "- Training uses random minibatches; evaluation uses `model.eval()` + `torch.no_grad()` on a held-out validation set to check for overfitting.\n", "\n", "In Topic 5 we scale this same model up to words on WikiText-103, which needs proper data-loading and checkpointing tools." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.5" } }, "nbformat": 4, "nbformat_minor": 5 }