{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "cell-00",
   "metadata": {},
   "source": [
    "# Step 2 \u2014 Wire a Network by Hand, Then Train One\n",
    "\n",
    "**Solution notebook.** Two constructions. **Part A** builds a\n",
    "one-hidden-layer ReLU network, unit by unit and then as two matrix\n",
    "layers, that classifies points of the plane as inside or outside the\n",
    "diamond $|x_1|+|x_2|=1$ \u2014 *exactly*, with weights written down on paper\n",
    "rather than learned. **Part B** then rebuilds Step 1's bigram model as a\n",
    "differentiable parametric family and trains it by gradient descent, with\n",
    "a gradient derived by hand \u2014 no autograd yet. Both parts run in under a\n",
    "minute.\n",
    "\n",
    "Part A is Lecture 2, Example 4.6 and Theorem 7.1; Part B is Lecture 2's\n",
    "multinomial logistic regression (Proposition 3.4) applied to one-hot\n",
    "character features. The derivations below are the \"On paper first\"\n",
    "sections of the task, written out.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "parta-header",
   "metadata": {},
   "source": [
    "# Part A \u2014 Wire a Diamond Classifier by Hand\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-01",
   "metadata": {},
   "source": [
    "## On paper first\n",
    "\n",
    "**1. Four units whose activations sum to $r=|x_1|+|x_2|$.** For any real\n",
    "$t$, exactly one of $t$ and $-t$ is positive (or both are zero), so\n",
    "$\\operatorname{ReLU}(t)+\\operatorname{ReLU}(-t)=\\max(t,0)+\\max(-t,0)=|t|$.\n",
    "Apply it to each coordinate: the four hidden units\n",
    "\n",
    "$$\n",
    "h=\\bigl(\\operatorname{ReLU}(x_1),\\ \\operatorname{ReLU}(-x_1),\\\n",
    "\\operatorname{ReLU}(x_2),\\ \\operatorname{ReLU}(-x_2)\\bigr)^\\top\n",
    "$$\n",
    "\n",
    "have $h_1+h_2=|x_1|$ and $h_3+h_4=|x_2|$, so $\\mathbf 1^\\top h=r$.\n",
    "\n",
    "**2. As a matrix layer.** Each unit is $\\operatorname{ReLU}$ of an affine\n",
    "function of $\\mathbf x$, so $a_1=W_1\\mathbf x+b_1$, $h=\\operatorname{ReLU}(a_1)$ with\n",
    "\n",
    "$$\n",
    "W_1=\\begin{pmatrix}1&0\\\\-1&0\\\\0&1\\\\0&-1\\end{pmatrix}\\in\\mathbb R^{4\\times2},\n",
    "\\qquad b_1=\\mathbf 0\\in\\mathbb R^4,\n",
    "\\qquad a_1,h\\in\\mathbb R^4 .\n",
    "$$\n",
    "\n",
    "**3. The output layer.** We want $z_{\\mathrm{out}}=\\gamma(r-1)$ and\n",
    "$z_{\\mathrm{in}}=\\gamma(1-r)$. Since $r=\\mathbf 1^\\top h$,\n",
    "\n",
    "$$\n",
    "W_2=\\gamma\\begin{pmatrix}1&1&1&1\\\\-1&-1&-1&-1\\end{pmatrix}\\in\\mathbb R^{2\\times4},\n",
    "\\qquad\n",
    "b_2=\\gamma\\begin{pmatrix}-1\\\\1\\end{pmatrix}\\in\\mathbb R^2,\n",
    "\\qquad z=W_2h+b_2 .\n",
    "$$\n",
    "\n",
    "**4. The probability and the boundary.** For two classes, softmax\n",
    "reduces to a sigmoid of the logit difference (Lecture 2, Aside 3.1a):\n",
    "$p(\\mathrm{in}\\mid\\mathbf x)=\\sigma(z_{\\mathrm{in}}-z_{\\mathrm{out}})\n",
    "=\\sigma\\bigl(2\\gamma(1-|x_1|-|x_2|)\\bigr)$. Since $\\sigma$ is increasing\n",
    "with $\\sigma(0)=\\tfrac12$, the classifier says *inside* exactly when\n",
    "$|x_1|+|x_2|<1$: the boundary is the diamond with vertices $(\\pm1,0)$,\n",
    "$(0,\\pm1)$. The sign of $1-r$ does not depend on $\\gamma$, so $\\gamma$\n",
    "rescales the logits \u2014 how *confident* the network is \u2014 without moving\n",
    "the boundary at all."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-02",
   "metadata": {},
   "source": [
    "## 2.1 Write the hidden units separately\n",
    "\n",
    "Five test points, one per row. Each column of `h_units` is one hidden\n",
    "unit evaluated on all five points at once."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "cell-03",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:29:46.827383Z",
     "iopub.status.busy": "2026-08-30T22:29:46.827204Z",
     "iopub.status.idle": "2026-08-30T22:29:48.076528Z",
     "shell.execute_reply": "2026-08-30T22:29:48.075769Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([5, 2])\n",
      "tensor([[0.0000, -0.0000, 0.0000, -0.0000],\n",
      "        [0.5000, 0.0000, 0.2500, 0.0000],\n",
      "        [1.0000, 0.0000, 0.0000, -0.0000],\n",
      "        [0.8000, 0.0000, 0.5000, 0.0000],\n",
      "        [0.0000, 0.4000, 0.0000, 0.2000]])\n",
      "torch.Size([5, 4])\n",
      "tensor([0.0000, 0.7500, 1.0000, 1.3000, 0.6000])\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "\n",
    "X = torch.tensor([\n",
    "    [ 0.0,  0.0],   # inside\n",
    "    [ 0.5,  0.25],  # inside\n",
    "    [ 1.0,  0.0],   # boundary\n",
    "    [ 0.8,  0.5],   # outside\n",
    "    [-0.4, -0.2],   # inside, negative coordinates\n",
    "])\n",
    "print(X.shape)      # (5, 2): five points, two features per point\n",
    "\n",
    "h_units = torch.stack([\n",
    "    torch.relu( X[:, 0]),\n",
    "    torch.relu(-X[:, 0]),\n",
    "    torch.relu( X[:, 1]),\n",
    "    torch.relu(-X[:, 1]),\n",
    "], dim=1)\n",
    "\n",
    "print(h_units)\n",
    "print(h_units.shape)                 # (5, 4)\n",
    "r_units = h_units.sum(dim=1)\n",
    "print(r_units)                       # |x1| + |x2| for each point"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-04",
   "metadata": {},
   "source": [
    "> The four columns are active on the four half-planes $x_1>0$, $x_1<0$,\n",
    "> $x_2>0$, $x_2<0$ respectively \u2014 each unit measures how far the point\n",
    "> sits into \"its\" half-plane and is silent elsewhere. For\n",
    "> $(-0.4,-0.2)$: unit 1 sees $-0.4$ and outputs $0$; unit 2 sees $+0.4$\n",
    "> and outputs $0.4$; unit 3 sees $-0.2$, outputs $0$; unit 4 outputs\n",
    "> $0.2$. Row: $(0,\\,0.4,\\,0,\\,0.2)$, sum $0.6=|{-0.4}|+|{-0.2}|$. The\n",
    "> five rows are the checkpoint matrix."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-05",
   "metadata": {},
   "source": [
    "## 2.2 Assemble the first layer as a matrix\n",
    "\n",
    "The same four units as one weight matrix and one bias vector. The\n",
    "lecture writes one input as a column and computes $W_1\\mathbf x$; code\n",
    "stores a batch with one sample per row, so the same product is\n",
    "`X @ W1.T`: $(5\\times2)(2\\times4)+(4)=(5\\times4)$, the bias added to\n",
    "every row by broadcasting."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "cell-06",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:29:48.078441Z",
     "iopub.status.busy": "2026-08-30T22:29:48.078217Z",
     "iopub.status.idle": "2026-08-30T22:29:48.089732Z",
     "shell.execute_reply": "2026-08-30T22:29:48.089209Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([5, 4]) torch.Size([5, 4])\n",
      "matrix layer == four separate units \u2713\n"
     ]
    }
   ],
   "source": [
    "W1 = torch.tensor([\n",
    "    [ 1.0,  0.0],\n",
    "    [-1.0,  0.0],\n",
    "    [ 0.0,  1.0],\n",
    "    [ 0.0, -1.0],\n",
    "])\n",
    "b1 = torch.zeros(4)\n",
    "\n",
    "a1 = X @ W1.T + b1\n",
    "h = torch.relu(a1)\n",
    "\n",
    "print(a1.shape, h.shape)             # both (5, 4)\n",
    "assert torch.allclose(h, h_units)\n",
    "print('matrix layer == four separate units \u2713')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-07",
   "metadata": {},
   "source": [
    "## 2.3 Wire the output layer and softmax\n",
    "\n",
    "$(5\\times4)(4\\times2)+(2)=(5\\times2)$: two logits per point, columns\n",
    "ordered *outside, inside*. Subtracting each row's largest logit before\n",
    "exponentiating changes nothing \u2014 softmax is invariant under adding a\n",
    "constant to every logit in a row, since the constant factors out of\n",
    "numerator and denominator alike \u2014 but it keeps `exp` from overflowing\n",
    "when $\\gamma$ is large."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "cell-08",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:29:48.091261Z",
     "iopub.status.busy": "2026-08-30T22:29:48.091104Z",
     "iopub.status.idle": "2026-08-30T22:29:48.099233Z",
     "shell.execute_reply": "2026-08-30T22:29:48.098658Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[-4.0000,  4.0000],\n",
      "        [-1.0000,  1.0000],\n",
      "        [ 0.0000,  0.0000],\n",
      "        [ 1.2000, -1.2000],\n",
      "        [-1.6000,  1.6000]])\n",
      "tensor([[3.3535e-04, 9.9966e-01],\n",
      "        [1.1920e-01, 8.8080e-01],\n",
      "        [5.0000e-01, 5.0000e-01],\n",
      "        [9.1683e-01, 8.3173e-02],\n",
      "        [3.9166e-02, 9.6083e-01]])\n",
      "tensor([1.0000, 1.0000, 1.0000, 1.0000, 1.0000])\n"
     ]
    }
   ],
   "source": [
    "gamma = 4.0\n",
    "W2 = gamma * torch.tensor([\n",
    "    [ 1.0,  1.0,  1.0,  1.0],   # outside logit\n",
    "    [-1.0, -1.0, -1.0, -1.0],   # inside logit\n",
    "])\n",
    "b2 = gamma * torch.tensor([-1.0, 1.0])\n",
    "\n",
    "logits = h @ W2.T + b2            # (5, 2)\n",
    "shifted = logits - logits.max(dim=1, keepdim=True).values\n",
    "weights = shifted.exp()\n",
    "probs = weights / weights.sum(dim=1, keepdim=True)\n",
    "\n",
    "print(logits)\n",
    "print(probs)\n",
    "print(probs.sum(dim=1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-09",
   "metadata": {},
   "source": [
    "> Inside probabilities at $\\gamma=4$: **0.9997, 0.8808, 0.5000, 0.0832,\n",
    "> 0.9608** \u2014 i.e. $\\sigma(8)$, $\\sigma(2)$, $\\sigma(0)$, $\\sigma(-2.4)$,\n",
    "> $\\sigma(3.2)$, since $2\\gamma(1-r)=8(1-r)$ and $r=0,\\,0.75,\\,1,\\,1.3,\\,0.6$.\n",
    "> On the boundary point $(1,0)$ the logits tie and both probabilities\n",
    "> are exactly $\\tfrac12$; `argmax` would return index 0 (outside) there,\n",
    "> a tie-breaking convention of the software, not a property of the\n",
    "> classifier. Every row sums to 1."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-10",
   "metadata": {},
   "source": [
    "## 2.4 Package one forward pass\n",
    "\n",
    "The two layers as a function that returns every intermediate value.\n",
    "Then the two assertions the task asks for: the hidden layer sums to\n",
    "$|x_1|+|x_2|$, and the inside probability is\n",
    "$\\sigma(2\\gamma(1-|x_1|-|x_2|))$ \u2014 Theorem 7.1, checked numerically."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "cell-11",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:29:48.100844Z",
     "iopub.status.busy": "2026-08-30T22:29:48.100673Z",
     "iopub.status.idle": "2026-08-30T22:29:48.107804Z",
     "shell.execute_reply": "2026-08-30T22:29:48.107253Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hidden sum = |x1|+|x2| \u2713   p(in) = sigmoid(2\u03b3(1-|x1|-|x2|)) \u2713\n"
     ]
    }
   ],
   "source": [
    "def diamond_net(X, gamma=4.0):\n",
    "    W1 = torch.tensor([\n",
    "        [ 1.0,  0.0],\n",
    "        [-1.0,  0.0],\n",
    "        [ 0.0,  1.0],\n",
    "        [ 0.0, -1.0],\n",
    "    ], dtype=X.dtype)\n",
    "    b1 = torch.zeros(4, dtype=X.dtype)\n",
    "\n",
    "    W2 = gamma * torch.tensor([\n",
    "        [ 1.0,  1.0,  1.0,  1.0],\n",
    "        [-1.0, -1.0, -1.0, -1.0],\n",
    "    ], dtype=X.dtype)\n",
    "    b2 = gamma * torch.tensor([-1.0, 1.0], dtype=X.dtype)\n",
    "\n",
    "    a1 = X @ W1.T + b1\n",
    "    h = torch.relu(a1)\n",
    "    logits = h @ W2.T + b2\n",
    "\n",
    "    shifted = logits - logits.max(dim=1, keepdim=True).values\n",
    "    weights = shifted.exp()\n",
    "    probs = weights / weights.sum(dim=1, keepdim=True)\n",
    "    return a1, h, logits, probs\n",
    "\n",
    "a1, h, logits, probs = diamond_net(X)\n",
    "assert a1.shape == (5, 4)\n",
    "assert h.shape == (5, 4)\n",
    "assert logits.shape == (5, 2)\n",
    "assert probs.shape == (5, 2)\n",
    "\n",
    "# the two assertions of our own\n",
    "r = X.abs().sum(dim=1)                                   # |x1| + |x2|\n",
    "assert torch.allclose(h.sum(dim=1), r)\n",
    "assert torch.allclose(probs[:, 1], torch.sigmoid(2 * 4.0 * (1 - r)))\n",
    "print('hidden sum = |x1|+|x2| \u2713   p(in) = sigmoid(2\u03b3(1-|x1|-|x2|)) \u2713')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-12",
   "metadata": {},
   "source": [
    "## 2.5 Draw the decision surface\n",
    "\n",
    "Evaluate the network on a $201\\times201$ grid and plot the inside\n",
    "probability. `meshgrid` turns two coordinate axes into all coordinate\n",
    "pairs; flattening and stacking makes the usual one-point-per-row batch;\n",
    "`reshape` puts the answers back on the grid for the plotting routine."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "cell-13",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:29:48.109260Z",
     "iopub.status.busy": "2026-08-30T22:29:48.109094Z",
     "iopub.status.idle": "2026-08-30T22:29:48.760668Z",
     "shell.execute_reply": "2026-08-30T22:29:48.759994Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 600x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "axis = torch.linspace(-1.6, 1.6, 201)\n",
    "gx, gy = torch.meshgrid(axis, axis, indexing='xy')\n",
    "grid = torch.stack([gx.reshape(-1), gy.reshape(-1)], dim=1)\n",
    "\n",
    "_, _, _, grid_probs = diamond_net(grid, gamma=4.0)\n",
    "p_inside = grid_probs[:, 1].reshape(gx.shape)\n",
    "\n",
    "plt.figure(figsize=(6, 5))\n",
    "contour_plot = plt.contourf(gx.numpy(), gy.numpy(), p_inside.numpy(),\n",
    "                            levels=30, cmap='Purples')\n",
    "plt.contour(gx.numpy(), gy.numpy(), p_inside.numpy(),\n",
    "            levels=[0.5], colors='black', linewidths=2)\n",
    "plt.scatter(X[:, 0], X[:, 1], c='red', s=30)\n",
    "plt.xlabel('x1')\n",
    "plt.ylabel('x2')\n",
    "plt.axis('equal')\n",
    "plt.colorbar(contour_plot, label='p(inside | x)')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-14",
   "metadata": {},
   "source": [
    "The black $p=\\tfrac12$ contour is the diamond with vertices $(\\pm1,0)$,\n",
    "$(0,\\pm1)$. A single logistic-regression unit can only draw one line in\n",
    "this plane; four hidden ReLUs measure distances from the two axes, and\n",
    "their sum bends one line into four."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "partb-header",
   "metadata": {},
   "source": [
    "# Part B \u2014 From Counts to Parameters\n",
    "\n",
    "Rebuild Step 1's bigram model as a differentiable parametric family and\n",
    "train it by gradient descent \u2014 with a gradient derived by hand, no\n",
    "autograd. The pivot of the course: **from estimating a table to\n",
    "optimizing a function.**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c002",
   "metadata": {},
   "source": [
    "## Setup: data and tokenizer (Step 1's solution, reproduced)\n",
    "\n",
    "Every notebook in this series is self-contained: it re-creates what it\n",
    "needs from earlier steps in one compact cell, so you can run it top to\n",
    "bottom without opening the others. On Colab, uncomment the download."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "c003",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:29:48.762410Z",
     "iopub.status.busy": "2026-08-30T22:29:48.762187Z",
     "iopub.status.idle": "2026-08-30T22:29:48.873316Z",
     "shell.execute_reply": "2026-08-30T22:29:48.872473Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1,115,394 characters, vocab 65\n"
     ]
    }
   ],
   "source": [
    "# !wget -q https://raw.githubusercontent.com/karpathy/char-rnn/master/data/tinyshakespeare/input.txt\n",
    "import torch\n",
    "\n",
    "with open('input.txt') as f:\n",
    "    text = f.read()\n",
    "vocab = sorted(set(text))\n",
    "V = len(vocab)\n",
    "stoi = {ch: i for i, ch in enumerate(vocab)}\n",
    "itos = {i: ch for i, ch in enumerate(vocab)}\n",
    "encode = lambda s: [stoi[c] for c in s]\n",
    "decode = lambda ids: ''.join(itos[i] for i in ids)\n",
    "ids = torch.tensor(encode(text), dtype=torch.long)\n",
    "\n",
    "assert len(text) == 1_115_394 and V == 65\n",
    "print(f'{len(text):,} characters, vocab {V}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c004",
   "metadata": {},
   "source": [
    "## 2.6 Data as tensors\n",
    "\n",
    "Every adjacent pair, as parallel input/target vectors."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "c005",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:29:48.875054Z",
     "iopub.status.busy": "2026-08-30T22:29:48.874892Z",
     "iopub.status.idle": "2026-08-30T22:29:48.886556Z",
     "shell.execute_reply": "2026-08-30T22:29:48.885679Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1,115,393 training pairs\n"
     ]
    }
   ],
   "source": [
    "xs, ys = ids[:-1], ids[1:]\n",
    "n = len(xs)\n",
    "ar = torch.arange(n)\n",
    "print(f'{n:,} training pairs')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c006",
   "metadata": {},
   "source": [
    "## 2.7 Forward pass\n",
    "\n",
    "Row $a$ of $W$ is the logit vector for input character $a$, so `W[xs]`\n",
    "gathers all $n$ logit rows at once. The max-subtraction is the\n",
    "shift-invariance of softmax (Lecture 2, Prop. 1.2) spent on numerical\n",
    "stability \u2014 prove in one line that it changes nothing, then try\n",
    "removing it with 10\u00d7 larger initial weights and watch the `inf`s."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "c007",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:29:48.888771Z",
     "iopub.status.busy": "2026-08-30T22:29:48.888539Z",
     "iopub.status.idle": "2026-08-30T22:29:48.892216Z",
     "shell.execute_reply": "2026-08-30T22:29:48.891694Z"
    }
   },
   "outputs": [],
   "source": [
    "def loss_and_p(W, X=None, Y=None):\n",
    "    X, Y = (xs, ys) if X is None else (X, Y)\n",
    "    idx = torch.arange(len(X))\n",
    "    logits = W[X]\n",
    "    logits = logits - logits.max(dim=1, keepdim=True).values\n",
    "    p = logits.exp()\n",
    "    p = p / p.sum(dim=1, keepdim=True)\n",
    "    return -p[idx, Y].log().mean(), p"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c008",
   "metadata": {},
   "source": [
    "## 2.8 Backward pass \u2014 by hand\n",
    "\n",
    "The derivation (do it on paper before reading the code): for one pair\n",
    "$(a,b)$, $\\ell = -z_b + \\log\\sum_c e^{z_c}$, so\n",
    "$\\partial\\ell/\\partial z_j = p_j - \\mathbf 1_{j=b}$ \u2014 **probabilities\n",
    "minus target**. Averaged over the batch, each example's $p - y$ row is\n",
    "accumulated into row $x_t$ of $W$; that is exactly what `index_add_`\n",
    "does."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c009",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:29:48.893829Z",
     "iopub.status.busy": "2026-08-30T22:29:48.893548Z",
     "iopub.status.idle": "2026-08-30T22:29:48.896703Z",
     "shell.execute_reply": "2026-08-30T22:29:48.896042Z"
    }
   },
   "outputs": [],
   "source": [
    "def grad_fn(W):\n",
    "    _, p = loss_and_p(W)\n",
    "    dlogits = p.clone()\n",
    "    dlogits[ar, ys] -= 1.0          # p - y\n",
    "    dlogits /= n\n",
    "    dW = torch.zeros_like(W)\n",
    "    dW.index_add_(0, xs, dlogits)   # route each row back to its input char\n",
    "    return dW"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c010",
   "metadata": {},
   "source": [
    "## Validate before training \u2014 in float64\n",
    "\n",
    "Central finite differences against the analytic gradient. **The dtype\n",
    "is the whole game here.** The loss is a mean over a million examples,\n",
    "so a single entry of $\\nabla_W$ is $\\sim 2\\times10^{-5}$; the\n",
    "difference $\\mathcal L(W+hE)-\\mathcal L(W-hE)\\approx 2hg \\approx\n",
    "4\\times10^{-8}$ sits *below* float32's resolution\n",
    "$\\varepsilon|\\mathcal L| \\approx 3\\times10^{-7}$, and the check\n",
    "fails at relative error \u2248 5.9 **on a perfectly correct gradient**.\n",
    "In float64 the same check passes at $\\sim 3\\times10^{-7}$. If your\n",
    "finite-difference check ever fails, suspect the dtype before the\n",
    "mathematics. (We restrict to a 20k-pair subset so each loss evaluation\n",
    "is cheap.)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "c011",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:29:48.898418Z",
     "iopub.status.busy": "2026-08-30T22:29:48.898252Z",
     "iopub.status.idle": "2026-08-30T22:29:49.008852Z",
     "shell.execute_reply": "2026-08-30T22:29:49.008156Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "max relative error (float64): 3.29e-07\n",
      "gradient verified \u2014 never trust one you haven't finite-differenced\n"
     ]
    }
   ],
   "source": [
    "torch.manual_seed(1337)\n",
    "sub = 20_000\n",
    "Xs, Ys = xs[:sub], ys[:sub]\n",
    "Wt = (torch.randn(V, V) * 0.1).double()\n",
    "\n",
    "# analytic gradient on the subset\n",
    "_, p = loss_and_p(Wt, Xs, Ys)\n",
    "dl = p.clone(); dl[torch.arange(sub), Ys] -= 1.0; dl /= sub\n",
    "g = torch.zeros_like(Wt); g.index_add_(0, Xs, dl)\n",
    "\n",
    "h, errs = 1e-3, []\n",
    "for (i, j) in [(5, 7), (20, 40), (33, 2), (60, 60), (12, 12)]:\n",
    "    Wp = Wt.clone(); Wp[i, j] += h\n",
    "    Wm = Wt.clone(); Wm[i, j] -= h\n",
    "    num = (loss_and_p(Wp, Xs, Ys)[0] - loss_and_p(Wm, Xs, Ys)[0]) / (2 * h)\n",
    "    errs.append(abs((num - g[i, j]) / g[i, j]).item())\n",
    "print(f'max relative error (float64): {max(errs):.2e}')\n",
    "assert max(errs) < 1e-5\n",
    "print('gradient verified \u2014 never trust one you haven\\'t finite-differenced')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c012",
   "metadata": {},
   "source": [
    "## The count model, for comparison\n",
    "\n",
    "Step 1's answer, which two theorems say gradient descent must approach:\n",
    "the MLE is the normalized count matrix (Lecture 1, Thm 3.3), and the\n",
    "loss is convex in $W$ (Lecture 2, Ex. 2), so GD cannot be trapped\n",
    "elsewhere."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "c013",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:29:49.010745Z",
     "iopub.status.busy": "2026-08-30T22:29:49.010505Z",
     "iopub.status.idle": "2026-08-30T22:29:49.029683Z",
     "shell.execute_reply": "2026-08-30T22:29:49.028984Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "count model (add-one) CE: 2.4549\n"
     ]
    }
   ],
   "source": [
    "N = torch.zeros((V, V), dtype=torch.long)\n",
    "N.index_put_((xs, ys), torch.ones(n, dtype=torch.long), accumulate=True)\n",
    "P = (N + 1).float()\n",
    "P = P / P.sum(1, keepdim=True)\n",
    "ce_count = -P[xs, ys].log().mean().item()\n",
    "print(f'count model (add-one) CE: {ce_count:.4f}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c014",
   "metadata": {},
   "source": [
    "## 2.9 Gradient descent\n",
    "\n",
    "First, a learning-rate sweep \u2014 30 steps each from the same start. The\n",
    "reference numbers:\n",
    "\n",
    "| lr | 0.1 | 1 | 50 | 500 |\n",
    "|---|---|---|---|---|\n",
    "| loss @ 30 | 4.158 | 4.024 | **2.742** | 5.401 |\n",
    "\n",
    "The tiny rates are *converging, uselessly slowly*; 500 has gone above\n",
    "its starting point (overshooting the valley every step). Why does this\n",
    "convex problem tolerate lr 50 when Step 3's network will want 0.1?\n",
    "Because the gradient here is a mean over $10^6$ examples spread across\n",
    "4,225 entries \u2014 of order $10^{-5}$ \u2014 and the step size compensates.\n",
    "**Learning rates are not transferable constants**; they are inverse to\n",
    "the gradient scale of the specific problem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "c015",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:29:49.031836Z",
     "iopub.status.busy": "2026-08-30T22:29:49.031548Z",
     "iopub.status.idle": "2026-08-30T22:30:37.489934Z",
     "shell.execute_reply": "2026-08-30T22:30:37.489398Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "lr=   0.1: loss after 30 steps = 4.1577\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "lr=   1.0: loss after 30 steps = 4.0238\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "lr=  50.0: loss after 30 steps = 2.7420\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "lr= 500.0: loss after 30 steps = 5.4008\n"
     ]
    }
   ],
   "source": [
    "torch.manual_seed(0)\n",
    "W0 = torch.randn(V, V) * 0.01\n",
    "for lr in (0.1, 1.0, 50.0, 500.0):\n",
    "    W = W0.clone()\n",
    "    for _ in range(30):\n",
    "        W -= lr * grad_fn(W)\n",
    "    print(f'lr={lr:>6}: loss after 30 steps = {loss_and_p(W)[0].item():.4f}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c016",
   "metadata": {},
   "source": [
    "Now the real run: 300 full-batch steps at lr 50. Reference trajectory:\n",
    "4.1731 \u2192 2.6530 \u2192 2.5690 \u2192 2.5352 \u2192 2.5168 \u2192 2.5052 \u2192 **2.4973**\n",
    "(loss 2.4971 after the final update)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "c017",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:30:37.491677Z",
     "iopub.status.busy": "2026-08-30T22:30:37.491525Z",
     "iopub.status.idle": "2026-08-30T22:33:41.610692Z",
     "shell.execute_reply": "2026-08-30T22:33:41.610042Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "step    0  loss 4.1731\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "step   50  loss 2.6530\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "step  100  loss 2.5690\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "step  150  loss 2.5352\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "step  200  loss 2.5168\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "step  250  loss 2.5052\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "step  300  loss 2.4973\n"
     ]
    }
   ],
   "source": [
    "W = W0.clone()\n",
    "for step in range(301):\n",
    "    L, _ = loss_and_p(W)\n",
    "    if step % 50 == 0:\n",
    "        print(f'step {step:>4}  loss {L.item():.4f}', flush=True)\n",
    "    W -= 50.0 * grad_fn(W)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c018",
   "metadata": {},
   "source": [
    "## 2.10 The punchline \u2014 read it carefully\n",
    "\n",
    "Close, and visibly **not there**: 2.497 vs 2.455, still 0.042 nats\n",
    "apart after 300 steps. Both proofs are about the *limit*; the gap is\n",
    "about the *rate*, and the rate is governed by conditioning. Row $a$ of\n",
    "$W$ receives gradient mass proportional to how often character $a$\n",
    "occurs \u2014 common characters get strong signal, rare ones almost none \u2014\n",
    "so agreement should be excellent on busy rows and poor on rare ones.\n",
    "The next cell measures exactly that prediction."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "c019",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:33:41.612741Z",
     "iopub.status.busy": "2026-08-30T22:33:41.612558Z",
     "iopub.status.idle": "2026-08-30T22:33:41.812772Z",
     "shell.execute_reply": "2026-08-30T22:33:41.812064Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "final GD loss              : 2.4971\n",
      "count model CE             : 2.4549\n",
      "max  |softmax(W) - P|      : 0.5421\n",
      "mean |softmax(W) - P|      : 0.00522\n",
      "max  on rows with >1000 obs: 0.0698   (53 such rows)\n",
      "worst row: 'Q', which occurs 231 times in the corpus\n"
     ]
    }
   ],
   "source": [
    "Wsm = torch.softmax(W, dim=1)\n",
    "diff = (Wsm - P).abs()\n",
    "busy = N.sum(1) > 1000\n",
    "print(f'final GD loss              : {loss_and_p(W)[0].item():.4f}')\n",
    "print(f'count model CE             : {ce_count:.4f}')\n",
    "print(f'max  |softmax(W) - P|      : {diff.max().item():.4f}')\n",
    "print(f'mean |softmax(W) - P|      : {diff.mean().item():.5f}')\n",
    "print(f'max  on rows with >1000 obs: {diff[busy].max().item():.4f}'\n",
    "      f'   ({busy.sum().item()} such rows)')\n",
    "worst = diff.max(dim=1).values.argmax().item()\n",
    "print(f'worst row: {itos[worst]!r}, which occurs '\n",
    "      f'{N.sum(1)[worst].item()} times in the corpus')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c020",
   "metadata": {},
   "source": [
    "Reference values: max 0.542 over all entries, 0.0052 on average, 0.070\n",
    "on the 53 well-populated rows \u2014 and the worst row belongs to `Q`\n",
    "(231 occurrences against `e`'s 94,611), exactly as the conditioning\n",
    "argument predicts: the rows GD leaves wrong are the rows the data\n",
    "barely constrains. Run the sampler from Step 1 on `softmax(W)` and the\n",
    "text is indistinguishable from the count model's, because sampling\n",
    "almost never visits the rows that are still wrong.\n",
    "\n",
    "Which of Step 1's ingredients does $W \\approx 0$ at initialization play\n",
    "the role of? Initializing all logits near zero means all rows start\n",
    "near *uniform* \u2014 the same place add-one smoothing shrinks toward \u2014 and\n",
    "300 steps has not fully erased that prior from the starved rows.\n",
    "Early stopping **is** regularization; you have just watched it act.\n",
    "\n",
    "\u2192 Continue with [Step 3](../project/step-3): the last gradient anyone\n",
    "derives by hand, and the machine that derives all the rest."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-15",
   "metadata": {},
   "source": [
    "## Going further \u2014 change confidence without changing geometry\n",
    "\n",
    "The same grid at $\\gamma\\in\\{0.25,1,4,20\\}$, one colour scale for all\n",
    "four (`vmin=0, vmax=1`, so the panels are comparable)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "cell-16",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:33:41.814723Z",
     "iopub.status.busy": "2026-08-30T22:33:41.814498Z",
     "iopub.status.idle": "2026-08-30T22:33:42.280483Z",
     "shell.execute_reply": "2026-08-30T22:33:42.279636Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 1600x400 with 5 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "p(inside) = 1/2 on all four vertices, for every \u03b3 \u2713\n"
     ]
    }
   ],
   "source": [
    "gammas = [0.25, 1.0, 4.0, 20.0]\n",
    "fig, axes = plt.subplots(1, 4, figsize=(16, 4), sharex=True, sharey=True)\n",
    "for ax, g in zip(axes, gammas):\n",
    "    _, _, _, gp = diamond_net(grid, gamma=g)\n",
    "    pi = gp[:, 1].reshape(gx.shape).numpy()\n",
    "    im = ax.contourf(gx.numpy(), gy.numpy(), pi, levels=torch.linspace(0, 1, 31).numpy(),\n",
    "                     cmap='Purples', vmin=0, vmax=1)\n",
    "    ax.contour(gx.numpy(), gy.numpy(), pi, levels=[0.5], colors='black', linewidths=2)\n",
    "    ax.set_title(f'\u03b3 = {g}')\n",
    "    ax.set_aspect('equal')\n",
    "fig.colorbar(im, ax=axes, label='p(inside | x)', shrink=0.8)\n",
    "plt.show()\n",
    "\n",
    "# the boundary does not move: p = 1/2 on the diamond's vertices for every \u03b3\n",
    "vertices = torch.tensor([[1., 0.], [0., 1.], [-1., 0.], [0., -1.]])\n",
    "for g in gammas:\n",
    "    _, _, _, vp = diamond_net(vertices, gamma=g)\n",
    "    assert torch.allclose(vp[:, 1], torch.full((4,), 0.5))\n",
    "print('p(inside) = 1/2 on all four vertices, for every \u03b3 \u2713')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-17",
   "metadata": {},
   "source": [
    "1. **The diamond itself** \u2014 every point with $|x_1|+|x_2|=1$ \u2014 has\n",
    "   probability exactly $\\tfrac12$ in all four plots, because there\n",
    "   $z_{\\mathrm{in}}=z_{\\mathrm{out}}=0$ whatever $\\gamma$ is.\n",
    "2. **As $\\gamma$ grows**, probabilities away from the boundary saturate\n",
    "   toward $0$ and $1$: the purple band of uncertainty narrows, and at\n",
    "   $\\gamma=20$ the plot is essentially a two-colour picture of the\n",
    "   diamond's indicator function.\n",
    "3. **As $\\gamma\\to0$**, both logits go to $0$ and every point tends to\n",
    "   $p=\\tfrac12$: the network is still *correct* (the sign of\n",
    "   $z_{\\mathrm{in}}-z_{\\mathrm{out}}$ never changes) but maximally\n",
    "   unconfident, and the whole plane fades to the same mid-purple.\n",
    "4. Softmax at temperature $T$ is $\\operatorname{softmax}(z/T)$. Here\n",
    "   every logit is proportional to $\\gamma$, so\n",
    "   $\\operatorname{softmax}(z(\\gamma))=\\operatorname{softmax}(z(1)/T)$\n",
    "   with $T=1/\\gamma$: changing $\\gamma$ **is** changing the temperature.\n",
    "   Temperature rescales a distribution's sharpness and leaves its argmax\n",
    "   \u2014 the geometry \u2014 untouched. (Lecture 7 returns to this when we\n",
    "   sample.)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-18",
   "metadata": {},
   "source": [
    "## Going further \u2014 move and stretch the diamond\n",
    "\n",
    "For a centre $(a,b)$ and radii $r_1,r_2$ we want the hidden activations\n",
    "to sum to $\\dfrac{|x_1-a|}{r_1}+\\dfrac{|x_2-b|}{r_2}$. Since\n",
    "$|x_1-a|/r_1=\\operatorname{ReLU}\\!\\bigl(\\tfrac{x_1-a}{r_1}\\bigr)+\\operatorname{ReLU}\\!\\bigl(\\tfrac{a-x_1}{r_1}\\bigr)$,\n",
    "the four units are affine in $\\mathbf x$ with\n",
    "\n",
    "$$\n",
    "W_1=\\begin{pmatrix}1/r_1&0\\\\-1/r_1&0\\\\0&1/r_2\\\\0&-1/r_2\\end{pmatrix},\n",
    "\\qquad\n",
    "b_1=\\begin{pmatrix}-a/r_1\\\\ a/r_1\\\\ -b/r_2\\\\ b/r_2\\end{pmatrix},\n",
    "$$\n",
    "\n",
    "and the output layer is unchanged: inside when the sum is below $1$. The\n",
    "boundary $\\frac{|x_1-a|}{r_1}+\\frac{|x_2-b|}{r_2}=1$ has vertices\n",
    "$(a\\pm r_1,b)$ and $(a,b\\pm r_2)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "cell-19",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:33:42.282373Z",
     "iopub.status.busy": "2026-08-30T22:33:42.282159Z",
     "iopub.status.idle": "2026-08-30T22:33:42.398184Z",
     "shell.execute_reply": "2026-08-30T22:33:42.397445Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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98swDL8n6vK3rLHGIknXXz9BM2bM0Pr16zV//jwNHHi5NxLq8rjVqctJyGr7XXge/667an782267Tbfddpvy8/P1yiuvaPTo0dq5c6c6depUrzHXFQe1AoBFGe3aSbW8McrtLl+vEbz//jLvm7XL5dLrr7+m4cNH1PimOXr0GBUVFemZZ572Wb59+3bt27dPkjR06JU6fPiwli9f7r39//7v7zWO5eqrRys3N1evvfaad1lxcbE2b94sSXI4HIqNjVVeXl6jj0UqD5n+/fvrX/+aq8WLF2vixIn1etzq+HselY0eXfPvYsyY8sd/+unqH//LL7/0PkZCQoImTpyosrIyHTt2rNbn3lDMkACAVV0/QXrssZrXcbvLPwLcCDp37qzLLuunAQMGauvW73To0CF9+ulnNW7TqVMnzZ37L9166xStWLFC3bp10+7du5Wdna3//vf/SZK6dOmiRx55ROPHj/OGRkbGkRr/bz4tLU2vvvqapk27Q4sXL1bHjh311Vcb9OSTs9SzZ09J5XHx4IMP6MMPP1DHjh31+98/1Chj8ZgwYaKmTr1NMTExPp9gqcvvoCaVn8f06b7Hs6Slpen111/X7bffrkWLFqljx47asGGDnnrqKfXs2VOdOnXSm2++qVtuuUXp6ek655xztGvXLmVnZ2vJkiWSymeBbrzxRp1//vlq06aNPvroIw0bNsz7u2wMNsOo5mgoSJLy8/OVmJiovLw8n4O3gklpSQ3TtQCCWnFxsQ78sk+dOqUpJiam3tvbpk6t9sBWw2aTbpki49VXAzFUH5dfPlCXXnqpJk/+H61bt04ul0sjR4702V2zaNEipaSk6JJLLqmyfVZWllauXKnc3Fx169ZNl112WZXjMr766itt2rRJnTp10sCBAzVnzusaMWKkzjzzTBmGoZdeelFjx17jcyzEoUOHtGrVKhmGoQEDBuiMM87w3lZaWqoPPvhA+/fvU2JiC91www0BGUt18vPzNXfuP5WS0tHvuUtqelyn06lXXvmHrr9+gvejwtU9j4kTJ+rll1/SNdfU/XdRl+edk5OjtWvXKisrS927d1ffvn39Ps/i4mLt2bNHaWlV/w7X5z2UIKkFQQKgMZ1ukKi0VLa77pLemFN+PIndXj4r4naXx8jf/iY1wjcJe4LkL395IuD3jfqz2837csZABQm7bADAyqKiymdAHn741Jla27cv353TiGdqBQKNIAGAUJCWJv3hj43yaRp/pk27UykpKU30aAgHBAkAoN5q+z4XoL742C8AADAdQQIAAExHkACAiTznEOMDj7Cq2s5aW1ccQwIAJoqMjJLNZlNW1jElJbWu06nBgcrM+NivYRgqKSlRZmam7Ha7z5coNgRBAgAmioiIUHJyig4fPqjjx4+bPRxYlJkhGxcXpzPOOKPWLxysDUECACZrFtdMaZ26qKysVOy5QUNERUeY8rgRERGKjIwMSBARJAAQBCIiIhQRYc6bCqzPrCAJJA5qBQAApiNIAACA6QgSAABgOoIEAACYjiABAACmI0gAAIDpCBIAAGA6ggQAAJjOUidG27VrlxYsWKDdu3crNTVVN998s9LS0mrcxjAMvfPOO1q1apViYmI0fvx49e/fv4lGDAAA6sIyMyRvv/22RowYoaKiIvXt21d79+5Vt27dtHbt2hq3u+OOOzR9+nSdc845atGiha644gr961//apIxAwCAurEZFvnO64MHD6p9+/Y+p1YePXq0cnNztWbNGr/bbNu2Teeee65Wrlyp3/72t5KkmTNn6uWXX9ahQ4fq9M2E+fn5SkxMVF5enhISEgLzZAKstMRl9hAAACYK1lPH1+c91DIzJCkpKVW+5+HMM89UdnZ2tdukp6crKSlJAwcO9C679tprlZWVpfXr1zfaWAEAQP1YJkgqy87O1jvvvKMrrrii2nV27dqljh07+nwlcqdOnSRJu3fv9ruN0+lUfn6+zwUAADQuSwaJ0+nUNddco6SkJD322GPVrldcXKzmzZv7LIuJiVFERISKi4v9bjNr1iwlJiZ6L6mpqQEdOwAAqMpyQVJSUqJrrrlGBw4c0Mcff6z4+Phq101MTKyySyc3N1cul0stWrTwu82MGTOUl5fnvRw4cCCQwwcAAH5YKkhKS0s1btw4bd++XWvWrFFKSkqN65933nnas2ePTpw44V22detWSdK5557rdxuHw6GEhASfCwAAaFyWCZLS0lKNHz9e33//vdauXauOHTtWWaewsFDXXXedPvnkE0nSVVddpcjISP3jH/+QVH5Okueff16//vWv1aNHjyYdPwAAqJ5lToz27LPPasmSJbrsssv0wAMPeJc3a9ZMb7zxhqTy3Tnvvvuuhg4dqv79+6tNmzb65z//qcmTJ2vp0qXKzc1V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",
      "text/plain": [
       "<Figure size 600x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "p(inside) = 1/2 exactly at the four predicted vertices \u2713\n"
     ]
    }
   ],
   "source": [
    "def stretched_diamond_net(X, a=0.5, b=-0.25, r1=1.2, r2=0.6, gamma=4.0):\n",
    "    W1 = torch.tensor([\n",
    "        [ 1/r1,   0.0],\n",
    "        [-1/r1,   0.0],\n",
    "        [  0.0,  1/r2],\n",
    "        [  0.0, -1/r2],\n",
    "    ], dtype=X.dtype)\n",
    "    b1 = torch.tensor([-a/r1, a/r1, -b/r2, b/r2], dtype=X.dtype)\n",
    "    W2 = gamma * torch.tensor([[1., 1., 1., 1.], [-1., -1., -1., -1.]], dtype=X.dtype)\n",
    "    b2 = gamma * torch.tensor([-1.0, 1.0], dtype=X.dtype)\n",
    "\n",
    "    h = torch.relu(X @ W1.T + b1)\n",
    "    logits = h @ W2.T + b2\n",
    "    return torch.softmax(logits, dim=1)        # same as the by-hand softmax above\n",
    "\n",
    "a, b, r1, r2 = 0.5, -0.25, 1.2, 0.6\n",
    "axis2 = torch.linspace(-1.5, 2.5, 201)\n",
    "gx2, gy2 = torch.meshgrid(axis2, axis2, indexing='xy')\n",
    "grid2 = torch.stack([gx2.reshape(-1), gy2.reshape(-1)], dim=1)\n",
    "p2 = stretched_diamond_net(grid2, a, b, r1, r2)[:, 1].reshape(gx2.shape)\n",
    "\n",
    "plt.figure(figsize=(6, 5))\n",
    "plt.contourf(gx2.numpy(), gy2.numpy(), p2.numpy(), levels=30, cmap='Purples')\n",
    "plt.contour(gx2.numpy(), gy2.numpy(), p2.numpy(), levels=[0.5], colors='black', linewidths=2)\n",
    "predicted = torch.tensor([[a + r1, b], [a - r1, b], [a, b + r2], [a, b - r2]])\n",
    "plt.scatter(predicted[:, 0], predicted[:, 1], c='red', s=40, zorder=3, label='predicted vertices')\n",
    "plt.legend(); plt.axis('equal'); plt.xlabel('x1'); plt.ylabel('x2')\n",
    "plt.show()\n",
    "\n",
    "assert torch.allclose(stretched_diamond_net(predicted, a, b, r1, r2)[:, 1], torch.full((4,), 0.5))\n",
    "print('p(inside) = 1/2 exactly at the four predicted vertices \u2713')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-20",
   "metadata": {},
   "source": [
    "## Going further \u2014 a square needs another composition\n",
    "\n",
    "$\\max(u,v)=\\operatorname{ReLU}(u-v)+v$, so $\\max(|x_1|,|x_2|)$ needs one\n",
    "more ReLU layer *after* the absolute values are formed \u2014 a composition,\n",
    "not wider first layer. With $h$ the four units above, $u=h_1+h_2$ and\n",
    "$v=h_3+h_4$:\n",
    "\n",
    "$$\n",
    "a_2=W_{2}'\\,h=\\begin{pmatrix}1&1&-1&-1\\\\0&0&1&1\\end{pmatrix}h\n",
    "=\\begin{pmatrix}u-v\\\\ v\\end{pmatrix},\n",
    "\\qquad\n",
    "h_2=\\operatorname{ReLU}(a_2)=\\begin{pmatrix}\\operatorname{ReLU}(u-v)\\\\ v\\end{pmatrix}\n",
    "$$\n",
    "\n",
    "(the second unit passes $v\\ge0$ through unchanged), and\n",
    "$\\mathbf 1^\\top h_2=\\max(u,v)$. The output layer is the same rule as\n",
    "before on this sum. Dimensions: $W_1\\in\\mathbb R^{4\\times2}$,\n",
    "$W_2'\\in\\mathbb R^{2\\times4}$, $W_3\\in\\mathbb R^{2\\times2}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "cell-21",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-30T22:33:42.399870Z",
     "iopub.status.busy": "2026-08-30T22:33:42.399669Z",
     "iopub.status.idle": "2026-08-30T22:33:42.528786Z",
     "shell.execute_reply": "2026-08-30T22:33:42.528101Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 500x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def square_net(X, gamma=4.0):\n",
    "    h = torch.relu(X @ W1.T + b1)                                 # (N, 4): |x1|, |x2| split into halves\n",
    "    W2p = torch.tensor([[1., 1., -1., -1.], [0., 0., 1., 1.]])    # (2, 4)\n",
    "    h2 = torch.relu(h @ W2p.T)                                    # (N, 2): (ReLU(u - v), v)\n",
    "    W3 = gamma * torch.tensor([[1., 1.], [-1., -1.]])             # (2, 2)\n",
    "    b3 = gamma * torch.tensor([-1.0, 1.0])\n",
    "    return torch.softmax(h2 @ W3.T + b3, dim=1)\n",
    "\n",
    "m = torch.maximum(X[:, 0].abs(), X[:, 1].abs())\n",
    "assert torch.allclose(square_net(X)[:, 1], torch.sigmoid(2 * 4.0 * (1 - m)))\n",
    "\n",
    "p_sq = square_net(grid)[:, 1].reshape(gx.shape)\n",
    "plt.figure(figsize=(5, 5))\n",
    "plt.contourf(gx.numpy(), gy.numpy(), p_sq.numpy(), levels=30, cmap='Purples')\n",
    "plt.contour(gx.numpy(), gy.numpy(), p_sq.numpy(), levels=[0.5], colors='black', linewidths=2)\n",
    "plt.axis('equal'); plt.title('max(|x1|, |x2|) < 1: three layers, one square')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-22",
   "metadata": {},
   "source": [
    "**Count the wiring.** The diamond network has $4\\cdot2+4+2\\cdot4+2=22$\n",
    "scalar parameters, of which $4+0+8+2=14$ are nonzero: four in $W_1$\n",
    "(one per unit, choosing an axis and a sign), eight in $W_2$ (every\n",
    "hidden unit feeds both logits, with opposite signs), two in $b_2$ (the\n",
    "threshold $r=1$). Every one of them has a job you can name \u2014 which is\n",
    "the point of building a network by hand before letting gradient descent\n",
    "fill the numbers in.\n",
    "\n",
    "\u2192 Continue with [Step 3](../project/step-3): differentiate this very\n",
    "network \u2014 first with an autograd engine you write yourself, then with\n",
    "PyTorch's \u2014 and then train the first model of the course whose weights\n",
    "nobody wrote down."
   ]
  }
 ],
 "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.11.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}