Mathematical Foundations

I.9 · Mathematical Language

Every symbol has a shape.

Machine-learning papers are written in a compact notation, and almost every misreading comes from a shape or an index. Learn the conventions of this book once, check that products fit, and see which symbol is a number, which a set, and which a place.

An array and its shape: Xij↔X[i-1, j-1]X_{ij}\leftrightarrow\texttt{X[i-1,\ j-1]}

Try these

The object

from 1 to 8, whole numbers only

from 1 to 8, whole numbers only

from 0 to 8, whole numbers only

from 0 to 8, whole numbers only

Each cell shows its position in the flattened array, counting from 0 and reading row by row. Thick outline: the chosen entry. Tinted: the rest of its row and column.

n=4n=4 · index ii
example (row); one step in i moves 3 positions
d=3d=3 · index jj
feature (column); one step in j moves 1 position
the shape of a matrix, as NumPy's .shape
(4, 3)
number of entries, 4 · 3
12
the chosen entry, indices from 1
X₂,₃
the same entry in NumPy, each index minus 1
X[1, 2]
its position in the flattened array
1 * 3 + 2 = 5
the whole row, shape (3,)
X[1, :]
the whole column, shape (4,)
X[:, 2]

= exact · ⚠ undefined

The Python being run

import numpy as np

X = np.arange(12).reshape(4, 3)
X.shape        # (4, 3)
X[1, 2]        # X₂,₃ is 5

X₂,₃ is X[1, 2]: subtract 1 from every index, because mathematics counts from 1 and NumPy from 0. The entry sits at position 5 when the array is read row by row (the last index changes fastest). A row is one example, a column is one feature.

X∈R4×3X\in \mathbb{R}^{4\times 3}
X2,3 is stored at position 1⋅3+2=5X_{2,3}\ \text{is stored at position}\ 1\cdot 3+2=5

Choose an object (a number, a vector, a data matrix or a batch of sequences), its sizes and the entry you point at. The picture numbers every cell by its place in the flattened array, the readout gives the shape and the position, and the Python being run is shown beside it. Typed values that are not allowed are rejected, not changed; an index outside its axis is reported, not repaired.

Try it before reading on. Look at the matrix: its rows are examples and its columns are features. Point at an entry with ii and jj and read the NumPy expression that names it. Then point beyond the last row, and then at 00. One of those raises an error in Python and the other does not. By the end of the chapter you will read the shape of every object in a formula, check that a product exists, and tell the minimum of a loss from the place where it is reached.

Intuition: a symbol is a promise about shape

A formula in a paper is a sentence in which every symbol makes a promise. A plain italic letter such as xx promises one number. A bold letter such as x\mathbf{x} promises a list of numbers, and the book always means a column. A capital letter such as XX promises a table. A calligraphic letter such as X\mathcal{X} promises a stack of tables. If you know the promise, you can read most of a formula without knowing what it computes: you only ask whether the pieces fit.

That is also how you find errors. A product of two tables exists only if their sizes agree in one place. A gradient has one entry for every parameter. An average needs at least one thing to average. Each of these is a check on shape or on count, and none of them needs any arithmetic.

Two decisions run through the whole book and are worth learning now, because they are where a paper and a program part ways:

  • Examples are rows, features are columns. The data matrix X∈Rn×dX\in\mathbb{R}^{n\times d} has nn rows, one per example, and dd columns, one per feature. An individual example x(i)\mathbf{x}^{(i)} is a row of XX written as a column vector.
  • Mathematics counts from 1, NumPy from 0. The entry in the ii-th row and jj-th column is written with indices ii and jj and stored at X[i - 1, j - 1]. Mixing the two conventions is the commonest way to read the right number from the wrong place.

Definition

Objects and their shapes. The set Rd\mathbb{R}^{d} is the set of columns of dd real numbers, Rn×d\mathbb{R}^{n\times d} the set of tables with nn rows and dd columns, and RB×T×d\mathbb{R}^{B\times T\times d} the set of stacks of BB tables with TT rows and dd columns each. The statement x∈Rd\mathbf{x}\in\mathbb{R}^{d} is therefore a statement about shape. NumPy writes the same facts as tuples: a vector is (d,), a matrix (n, d), a tensor (B, T, d). A NumPy vector of shape (d,) is one-dimensional; it is not a column of shape (d, 1), and the difference matters in a few operations.

Indices and positions. An entry of a matrix has two indices, XijX_{ij}. An array is stored as one long list, row by row (row-major order). In a matrix with dd columns, the entry with zero-based indices (r,c)(r, c) is at position r d+cr\,d + c. In a tensor with shape B×T×dB\times T\times d, zero-based indices (b,t,f)(b, t, f) sit at position (b T+t) d+f(b\,T + t)\,d + f. One step along the last axis moves one position, and one step along the first axis moves a whole slab.

Products and transposes. The transpose X⊤X^{\top} swaps rows and columns, so an n×dn\times d matrix becomes d×nd\times n. The product ABAB of an m×pm\times p matrix and a p×qp\times q matrix exists exactly when the inner sizes match, and then its shape is the outer pair, m×qm\times q. The matrix–vector product is the special case q=1q=1. The product X⊤XX^{\top}X of a data matrix is always defined and always square, with one row and one column per feature. The elementwise product, written a⊙b\mathbf{a}\odot\mathbf{b}, multiplies entry by entry and needs equal shapes; it is a * b in NumPy, whereas the matrix product is A @ B.

Norms. The norm ∥x∥\lVert\mathbf{x}\rVert is a measure of size. Three are used constantly:

∥x∥1=∑j∣xj∣,∥x∥2=∑jxj2,∥x∥∞=max⁡j∣xj∣.\lVert\mathbf{x}\rVert_1=\sum_{j}\lvert x_j\rvert,\qquad \lVert\mathbf{x}\rVert_2=\sqrt{\sum_{j}x_j^{2}},\qquad \lVert\mathbf{x}\rVert_\infty=\max_{j}\lvert x_j\rvert .

For every x∈Rd\mathbf{x}\in\mathbb{R}^{d} they satisfy ∥x∥∞≤∥x∥2≤∥x∥1≤d ∥x∥∞\lVert\mathbf{x}\rVert_\infty\le\lVert\mathbf{x}\rVert_2\le\lVert\mathbf{x}\rVert_1\le d\,\lVert\mathbf{x}\rVert_\infty, and each is 00 only for the zero vector. When no subscript is written, ∥x∥\lVert\mathbf{x}\rVert means the Euclidean norm ∥x∥2\lVert\mathbf{x}\rVert_2.

Minimum against arg min. For a loss LL, the minimum min⁡θL(θ)\min_{\theta}L(\theta) is the smallest value the loss takes; it is a number. The arg min arg min⁡θL(θ)\argmin_{\theta}L(\theta) is the set of places θ\theta where that value is reached; it is a set, and it may have more than one element. Adding the same constant to every loss changes the minimum and leaves the arg min unchanged. NumPy’s np.argmin is a third thing again: the position, counting from 00, of the first smallest entry of an array.

Expectation. For values x1,…,xkx_1,\dots,x_k with probabilities pi≥0p_i\ge0 that add to 11,

E[X]=∑i=1kpi xi.\mathbb{E}[X]=\sum_{i=1}^{k}p_i\,x_i .

When the probabilities come from counts cic_i, they are pi=ci/(c1+⋯+ck)p_i=c_i/(c_1+\dots+c_k). If every count is 00, the division is by 00 and there is no distribution, so the expectation is undefined; it is not 00. The expectation is a weighted average, and it need not be one of the values: a die never shows 3.53.5.

Gradient. For a function ff of a parameter vector θ∈Rd\theta\in\mathbb{R}^{d}, the gradient ∇θf\nabla_{\theta}f collects one slope for each parameter, so it lies in Rd\mathbb{R}^{d} as well: the gradient has the shape of θ\theta. How such slopes are found belongs to Part III, Calculus. Here only the notation matters, together with one fact about computing: an estimate made with a small step hh is an approximation, written with ≈\approx, and it is never exactly the gradient.

Mechanics: how to read and check a formula

Objects, indices and positions

The stage at the top of the chapter is the place to practise indices. Switch between the four kinds of object and watch the readout: the shape tuple, the number of entries, the NumPy expression for the chosen entry, its position in the flattened array and the stride along each axis (how many positions one step along that axis moves). With a vector, only one index exists; with a tensor there are three, and the picture shows one slab per example.

Three things deserve a deliberate test. First, point at the last entry of each kind of object and confirm that its position is one less than the number of entries. Second, set an index one beyond its axis and read the verdict: Python raises an error, and the stage says so instead of picking a nearby entry. Third, set an index to 00. In mathematics that index does not exist; in NumPy a negative index is legal and counts from the end, so a program may silently read the wrong entry. The stage tells those two outcomes apart.

Do the shapes fit?

Do the shapes fit?

Try these

The product

from 1 to 8, whole numbers only

from 1 to 8, whole numbers only

from 1 to 8, whole numbers only

Rectangles are drawn to scale. For a product the inner two sizes must be equal; the outer two are the shape of the result.

the first operand, shape (n, d)
(4, 3)
the vector, shape (p,)
(3,)
the inner dimensions, which must be equal
3 = 3
the product, shape (outer dimensions)
(4,)

= exact · ⚠ undefined

The Python being run

import numpy as np

X = np.ones((4, 3))
w = np.ones(3)
X @ w          # shape (4,)

A matrix times a vector needs as many columns as the vector has entries (d = p). The result has one entry per row: one number per example. Result shape: (4,).

Xw: (4×3)(3)→(4)X\mathbf{w}:\ \left(4\times 3\right)\left(3\right)\to \left(4\right)

XwX\mathbf{w} is read: X times w.

Choose a product and the sizes of its operands. The rectangles are drawn to scale; the two inner sizes must be equal and the outer pair is the shape of the result. When they differ, the result is undefined and the stage says which two numbers disagree. The Python being run shows the error that NumPy would raise.

Read the rule off the picture and not off a formula: for a product, put the two operands next to each other and look at the sizes that touch. When they are equal they cancel, and what remains is the shape of the answer. The preset with a mismatch shows the failure; the transposed product shows the usual repair, and the Gram preset shows why X⊤XX^{\top}X never fails. Note that the order matters: the product XWXW may exist while WXWX does not.

Three ways to measure a vector

Three ways to measure a vector: ∥x∥1, ∥x∥2, ∥x∥∞\lVert\mathbf{x}\rVert_1,\ \lVert\mathbf{x}\rVert_2,\ \lVert\mathbf{x}\rVert_\infty

Try these

Draw the ball of the

from −4 to 4, up to 2 decimal places

from −4 to 4, up to 2 decimal places

The vector (3, 4) drawn from the origin. Three small unit balls are drawn around the origin: a diamond for ℓ₁, a circle for ℓ₂ and a square for ℓ∞. The larger outline is the ℓ₂ ball of radius 5, and the vector lies on it.

Dashed: the unit balls, diamond (ℓ₁), circle (ℓ₂) and square (ℓ∞). Solid: the ball of the chosen norm through x. The three outlines differ in shape, not only in colour.

ℓ₁ norm, the sum of absolute values
7
ℓ₂ norm, the Euclidean length
5
ℓ∞ norm, the largest absolute value
4
the sum of the squares, exact
25

= exact · ≈ rounded to 6 decimals

The Python being run

import numpy as np

x = np.array([3, 4])
np.linalg.norm(x, ord=1)       # l1
np.linalg.norm(x)              # l2, the default
np.linalg.norm(x, ord=np.inf)  # l-infinity

For x = (3, 4): ℓ∞ ≤ ℓ₂ ≤ ℓ₁ ≤ 2·ℓ∞ always holds, and it holds here (4 ≤ 5 ≤ 7 ≤ 2 · 4). The vector lies on the boundary of the ℓ₂ ball (a circle) that passes through it.

∥x∥1=∣3∣+∣4∣=3+4=7\lVert\mathbf{x}\rVert_1=\lvert 3\rvert+\lvert 4\rvert=3+4=7
∥x∥2=(3)2+(4)2=25=5\lVert\mathbf{x}\rVert_2=\sqrt{(3)^2+(4)^2}=\sqrt{25}=5
∥x∥∞=max⁡(∣3∣,∣4∣)=4\lVert\mathbf{x}\rVert_\infty=\max\left(\lvert 3\rvert,\lvert 4\rvert\right)=4
∥x∥∞=4 ≤ ∥x∥2=5 ≤ ∥x∥1=7 ≤ 2∥x∥∞=8\lVert\mathbf{x}\rVert_\infty=4\ \le\ \lVert\mathbf{x}\rVert_2=5\ \le\ \lVert\mathbf{x}\rVert_1=7\ \le\ 2\lVert\mathbf{x}\rVert_\infty=8

Choose the vector by typing its two components or dragging it, and choose which norm's ball to draw through it. The dashed outlines are the unit balls of the three norms: a diamond, a circle and a square. Every length is exact: a square root is shown as a radical, and an approximation is labelled as one.

The three balls differ in shape, and that is the whole idea. The norm of the vector is the factor by which the unit ball of that norm must be stretched to reach it, so the diamond, the circle and the square give three different answers for the same arrow. The chain of inequalities in the definition is visible: the square contains the circle and the circle contains the diamond. Check the preset on a coordinate axis, where all three norms agree, and the preset on a diagonal, where they are as far apart as they can be.

Minimum, arg min and the position NumPy reports

Where is the loss smallest? arg min⁡θL(θ)\argmin_{\theta}L(\theta) against min⁡θL(θ)\min_{\theta}L(\theta)

Try these

The loss is

from −3 to 3, whole numbers only

from 0 to 6, whole numbers only

The loss at each grid point. Position is the index NumPy uses, counting from 0.
positionθL(θ)smallest?
0−437no
1−326no
2−217no
3−110no
405no
512no
621minimiser, the one np.argmin reports
732no
845no

Changing the offset b moves the minimum value but never the arg min: adding the same number to every loss cannot change which points are smallest.

the smallest loss: a VALUE
1
where the loss is smallest: a POINT
{2}
np.argmin(L): the 0-based POSITION of the first minimum
6
thetas[np.argmin(L)]: the parameter at that position
2

= exact

The Python being run

import numpy as np

thetas = np.arange(-4, 5)
L = (thetas - 2) ** 2 + 1
np.min(L)                # 1: a value
thetas[np.argmin(L)]     # 2: a parameter
np.argmin(L)             # 6: a position

The minimum is the VALUE 1. The arg min is the PLACE where it is reached: the point 2. np.argmin(L) returns neither: it returns the position 6 (counting from 0) of the FIRST minimum, and thetas[6] = 2.

L(θ)=(θ−2)2+1L(\theta)=\left(\theta-2\right)^{2}+1
min⁡θL(θ)=1\min_{\theta}L(\theta)=1
arg min⁡θL(θ)={2}\argmin_{\theta}L(\theta)=\left\{2\right\}

Choose a loss and the offset b. The table lists the loss at each grid point with its NumPy position counted from zero; the smallest rows are marked, and the one np.argmin reports is outlined. The minimum value, the arg min set and the np.argmin position are three separate readouts.

Change the offset and watch which readout moves. Choose the loss with two wells and read the three results side by side: a set with two elements, a single number, and a single position. They answer three different questions, and a program that stores one of them in a variable meant for another is wrong without raising any error.

An average with weights

An average with weights: E[X]=∑ipixi\mathbb{E}[X]=\sum_i p_i x_i

Try these

The values are

from 0 to 99, whole numbers only

from 0 to 99, whole numbers only

from 0 to 99, whole numbers only

from 0 to 99, whole numbers only

from 0 to 99, whole numbers only

from 0 to 99, whole numbers only

Each value, how often it was seen, and its share of the total.
xicipipixi
111/211/21
222/214/21
331/73/7
444/2116/21
555/2125/21
662/712/7

The probabilities are not typed in: they are the counts divided by their total. That division is the step that fails when every count is 0.

the total count
21
the probabilities added (must be exactly 1)
1
the expectation
13/34.333333
the most frequent value
6

= exact · ≈ rounded to 6 decimals · ⚠ undefined

The Python being run

import numpy as np

values = np.array([1, 2, 3, 4, 5, 6])
counts = np.array([1, 2, 3, 4, 5, 6])
p = counts / counts.sum()      # p_i = c_i / total
np.average(values, weights=p)  # about 13/3

The probabilities are the counts divided by the total 21, so they add to exactly 1. E[X] = 13/3 is not a value X can take: an expectation is an average, not a likely outcome. The most frequent value (the mode) is 6; the expectation is a different summary.

pi=ci21p_i=\dfrac{c_i}{21}
E[X]=∑ipixi=121⋅1+221⋅2+17⋅3+421⋅4+521⋅5+27⋅6=133\mathbb{E}[X]=\sum_i p_i x_i=\frac{1}{21}\cdot 1+\frac{2}{21}\cdot 2+\frac{1}{7}\cdot 3+\frac{4}{21}\cdot 4+\frac{5}{21}\cdot 5+\frac{2}{7}\cdot 6=\frac{13}{3}

Choose a set of values and type how often each was seen. The probabilities are computed as counts divided by their total, and the expectation is the sum of probability times value. When every count is zero the division is by zero and the stage reports the expectation as undefined, with the reason.

The expectation is an ordinary sum, the kind written with sigma in the previous chapter, with weights that add to 11. Compare it with the value seen most often (the mode): they are different numbers in general, and the expectation need not be a value that ever occurs. Press the no-data preset and see that the stage will not invent a distribution.

The shape of a gradient

A gradient has the shape of θ: ∇θf\nabla_{\theta}f against a finite difference

A preview of Part III, Calculus: this stage is about the notation (what ∇θf\nabla_{\theta}f is, what shape it has, and what a numerical estimate of it looks like), not about how to differentiate.

Try these

Step h

from −4 to 4, up to 2 decimal places

from −4 to 4, up to 2 decimal places

Error = finite difference minus exact partial derivative, in double arithmetic.
step herror in θ₁error in θ₂
10⁻¹≈ 0.100000≈ 0.300000
10⁻³ (chosen)≈ 0.001000≈ 0.003000
10⁻⁶≈ 0.000001≈ 0.000003
10⁻⁹ smallest≈ 1.65481×10⁻⁷≈ 0.000001
10⁻¹³≈ −0.010480≈ 0.008172

Every number in this table is a computed double, so every line says ≈. The exact gradient comes from the formula, not from any step.

shape of θ and of the gradient: the same
(2,)
the function value
13
exact partial derivative, 2θ₁
2
exact partial derivative, 6θ₂
12
finite difference in θ₁, h = 10⁻³ (a computed double)
2.001000
finite difference in θ₂, h = 10⁻³ (a computed double)
12.003000
estimate minus exact, in θ₁
0.001000
estimate minus exact, in θ₂
0.003000

= exact · ≈ computed, rounded to 6 decimals

The Python being run

import numpy as np

def f(theta):
    return theta[0] * theta[0] + 3 * theta[1] * theta[1]

t1, t2 = 1.0, 2.0
theta = np.array([t1, t2])
grad = np.array([2 * t1, 6 * t2])   # exact, shape (2,)
h = 1e-3
e_j = np.array([1.0, 0.0])
(f(theta + h * e_j) - f(theta)) / h  # an estimate of grad[0]

The gradient ∇f = (2, 12) has the same shape as θ: one entry per parameter. The finite difference is only an estimate, off by about 0.003 at h = 10⁻³; among these five steps the smallest error at this θ is at h = 10⁻⁹. A smaller step is not always a better one: past some point rounding error grows.

f(θ)=θ12+3θ22=13f(\theta)=\theta_1^{2}+3\theta_2^{2}=13
∇θf=(2θ16θ2)=(212)∈R2\nabla_{\theta}f=\begin{pmatrix}2\theta_1\\6\theta_2\end{pmatrix}=\begin{pmatrix}2\\12\end{pmatrix}\in\mathbb{R}^{2}
θ=(12),h=10−3\theta=\begin{pmatrix}1\\2\end{pmatrix},\quad h=10^{-3}

Choose the point theta and the step h. The exact gradient of the function is shown as a column with the shape of theta; the estimates below are computed with a finite difference in double arithmetic, so every one of them says approximately equal. The table shows the error for each step.

Treat this as a preview of Part III. Nothing in the stage asks you to differentiate; it shows that the symbol ∇θf\nabla_{\theta}f names a column with the same number of entries as θ\theta, and that a numerical estimate is only an approximation whose error first falls and then grows as the step shrinks.

Worked examples

Each example is short enough to do by hand, and each can be checked against a stage. The numbers are not the ones in the exercises at the end of the chapter.

A batch of images. A mini-batch holds B=32B=32 images, each a grid with T=7T=7 rows of d=5d=5 numbers. It is a tensor of shape 32×7×532\times7\times5, and it holds 32⋅7⋅5=112032\cdot7\cdot5=1120 numbers. In zero-based terms the entry with batch index b=3b=3, row t=1t=1 and column f=2f=2 is at position (3⋅7+1)⋅5+2=112(3\cdot7+1)\cdot5+2=112. Flattening each image to a vector of length 3535 gives a matrix of shape 32×3532\times35 with the same 11201120 numbers.

Does the product exist? Let XX be 9×49\times4 and w∈R4\mathbf{w}\in\mathbb{R}^{4}. The inner sizes are 44 and 44, so XwX\mathbf{w} exists and has shape (9,)(9,): one number per example. Now let v∈R9\mathbf{v}\in\mathbb{R}^{9}. Then XvX\mathbf{v} does not exist (4≠94\ne9), but X⊤vX^{\top}\mathbf{v} does: (4×9)(9)(4\times9)(9) gives (4,)(4,), one number per feature. The matrix X⊤XX^{\top}X is 4×44\times4 and XX⊤XX^{\top} is 9×99\times9.

Three norms. For x=(3, −4)⊤\mathbf{x}=(3,\,-4)^{\top}: ∥x∥1=3+4=7\lVert\mathbf{x}\rVert_1=3+4=7, ∥x∥2=9+16=5\lVert\mathbf{x}\rVert_2=\sqrt{9+16}=5 and ∥x∥∞=4\lVert\mathbf{x}\rVert_\infty=4. The chain 4≤5≤7≤2⋅44\le5\le7\le2\cdot4 holds. For x=(1,1)⊤\mathbf{x}=(1,1)^{\top} the Euclidean norm is 2\sqrt2, an irrational number that a program can only approximate; the stage keeps it as a radical.

Place against value. Take the loss L(θ)=(θ−1)2+5L(\theta)=(\theta-1)^2+5 on the integers from −2-2 to 44. The smallest value is 55, reached only at θ=1\theta=1, so the minimum is 55 and the arg min is {1}\{1\}. In an array that starts at θ=−2\theta=-2, the position that np.argmin returns is 1−(−2)=31-(-2)=3. Adding 1010 to the loss makes the minimum 1515 and leaves {1}\{1\} and the position 33 untouched.

An expectation from counts. A spinner showed 11 twice, 22 once and 44 once. The total is 44, the probabilities are 12,14,14\tfrac12,\tfrac14,\tfrac14, and E[X]=12⋅1+14⋅2+14⋅4=2\mathbb{E}[X]=\tfrac12\cdot1+\tfrac14\cdot2+\tfrac14\cdot4=2. Doubling every count changes nothing, since the probabilities are the same.

Executable reference code

Run the Python examples below to follow the calculations step by step. The comments record what each line returns.

First shapes, indices, positions and products: a vector, a data matrix, a tensor, the conversion between mathematical and NumPy indices, the flattened position of an entry, the transpose, matrix products with their shapes, and the error raised when the inner sizes disagree.

code/python/notation_shapes.pyshapes, indices, positions and products in NumPy
import numpy as np

# Conventions: a vector is a column of d numbers; a data matrix X has n EXAMPLES as rows and d FEATURES as columns.
# Mathematics counts from 1 (X_{ij}, i = 1..n, j = 1..d); NumPy counts from 0, so X_{ij} is X[i - 1, j - 1].
X = np.arange(12).reshape(4, 3)  # n = 4 examples, d = 3 features; the entry in row r, column c is 3 * r + c
x = np.array([2.0, -1.0, 0.5])  # a vector in R^3
w = np.array([1.0, 0.0, -1.0])
W = np.arange(6).reshape(3, 2)
a = np.array([1.0, 2.0, 3.0])
b = np.array([4.0, 5.0, 6.0])
X3 = np.arange(24).reshape(2, 3, 4)  # a tensor: B = 2 examples, T = 3 positions, d = 4 features

n = X.shape[0]  # the number of examples (rows)
d = X.shape[1]  # the number of features (columns)
B, T, d3 = X3.shape
shape_vector = x.shape  # (3,): a one-dimensional array, NOT a column (3, 1)
shape_matrix = X.shape  # (4, 3)

i, j = 2, 3  # a mathematical (1-based) example number and feature number
entry = X[i - 1, j - 1]  # X_{2,3} is X[1, 2] = 3 * 1 + 2 = 5
row = X[i - 1, :]  # the whole example i, a vector with d = 3 entries
column = X[:, j - 1]  # the whole feature j, a vector with n = 4 entries
flat_position = int(np.ravel_multi_index((i - 1, j - 1), X.shape))  # row-major: (i - 1) * d + (j - 1) = 5
same_entry = X.ravel()[flat_position] == entry  # True: the flattened array lists row 1 first, then row 2, ...

Xt = X.T  # the transpose swaps the axes: shape (3, 4)
Xw = X @ w  # (4 x 3)(3) -> (4,): one number per example
XW = X @ W  # (4 x 3)(3 x 2) -> (4, 2)
G = X.T @ X  # (3 x 4)(4 x 3) -> (3, 3): one row and one column per feature
dot = a @ b  # the dot product: 1*4 + 2*5 + 3*6 = 32.0, a scalar
hadamard = a * b  # the elementwise product, written with a circled dot in the notation
indicator = (x > 0).astype(int)  # the indicator 1[x_j > 0], entry by entry

try:
    X @ np.ones(4)  # X has d = 3 columns but this vector has 4 entries: the inner dimensions differ
    mismatch = 'no error'
except ValueError:
    mismatch = 'ValueError'

element_of_tensor = X3[1, 2, 3]  # the last element: 1 * 12 + 2 * 4 + 3 = 23
tensor_slice_shape = X3[1].shape  # one example of the batch: (3, 4), T positions with d features each

indices = []
for i in range(1, n + 1):  # the mathematical index range 1, ..., n; the matching row is X[i - 1]
    indices.append(int(X[i - 1, 0]))

print(shape_vector, shape_matrix, int(entry), row.tolist(), column.tolist(), flat_position, bool(same_entry))
print(Xt.shape, Xw.tolist(), XW.shape, G.shape, float(dot), hadamard.tolist(), indicator.tolist(), mismatch)
print(n, d, B, T, d3, int(element_of_tensor), tensor_slice_shape, indices)

Then norms and the three meanings of minimum: the three norms with the chain of inequalities, the Euclidean norm of a vector whose length is not a whole number, and min, argmin and np.argmin told apart on a table with a tie.

code/python/notation_norms_argmin.pynorms, minimum against arg min, and np.argmin
import math
from fractions import Fraction

import numpy as np

# Norms. For x = (3, 4) every norm is a whole number; for (1, 1) the l2 norm is sqrt(2), an irrational number that no double stores exactly.
x = np.array([3.0, 4.0])
l1 = np.linalg.norm(x, ord=1)  # |3| + |4| = 7
l2 = np.linalg.norm(x)  # sqrt(3**2 + 4**2) = 5
linf = np.linalg.norm(x, ord=np.inf)  # max(|3|, |4|) = 4
chain = bool(linf <= l2 <= l1)  # ||x||_inf <= ||x||_2 <= ||x||_1 for every vector

# The same l2 norm exactly: the squared norm is a rational number, and an integer square root decides whether the norm is rational.
sum_of_squares = Fraction(3) ** 2 + Fraction(4) ** 2
root = math.isqrt(25)
exact_l2 = Fraction(root) if root * root == sum_of_squares else None  # Fraction(5, 1)
diagonal = np.linalg.norm(np.array([1.0, 1.0]))  # 1.4142135623730951, the nearest double to sqrt(2)
diagonal_squared_is_two = diagonal * diagonal == 2.0  # False: squaring the rounded root does not return exactly 2

# arg min versus min. The loss on a grid of candidate parameters: L(theta) = (theta**2 - 1)**2 + 1 has TWO minimisers, -1 and 1.
thetas = np.arange(-4, 5)
L = (thetas**2 - 1) ** 2 + 1
best_value = np.min(L)  # the minimum VALUE: 1
best_position = int(np.argmin(L))  # the 0-based POSITION of the FIRST minimum: 3
best_theta = thetas[np.argmin(L)]  # the parameter at that position: -1 (the other minimiser, 1, is not reported)
all_minimisers = thetas[L == best_value].tolist()  # [-1, 1]: argmin as a SET
p = np.array([0.1, 0.5, 0.4])
most_likely = int(np.argmax(p))  # the position of the largest entry: 1

# Conventions: log is the natural logarithm; bits need log2.
nats = np.log(math.e)  # 1.0
bits = np.log2(8.0)  # 3.0

print(float(l1), float(l2), float(linf), chain, exact_l2, float(diagonal), diagonal_squared_is_two)
print(int(best_value), best_position, int(best_theta), all_minimisers, most_likely, float(nats), float(bits))

Finally the notation of averages, sums over an axis and the gradient: an expectation from counts with exact fractions, the failure of the division by zero, a conditional probability as a ratio, sums along each axis, and a finite difference that only approximates the gradient.

code/python/notation_expectation_gradient.pyexpectation, sums over axes, and a gradient with the shape of its parameters
from fractions import Fraction

import numpy as np

# Expectation of a finite distribution: E[X] = sum_i p_i x_i, with p_i >= 0 and sum_i p_i = 1.
# Counts become probabilities by dividing by their total: p_i = c_i / sum(c). The division is the taught step, and it is only defined for a non-zero total.
values = np.array([1, 2, 3, 4, 5, 6])  # the faces of a die
counts = np.array([1, 2, 3, 4, 5, 6])  # how often each face was seen
p = counts / counts.sum()  # 1/21, 2/21, ..., 6/21 (floating point)
sum_of_p = float(p.sum())  # about 1.0
expectation = np.average(values, weights=p)  # sum(p * values): about 13/3 = 4.333...
exact_p = [Fraction(int(c), int(counts.sum())) for c in counts]
exact_expectation = sum(pi * int(v) for pi, v in zip(exact_p, values))  # Fraction(13, 3), exact
exact_sum_of_p = sum(exact_p)  # Fraction(1, 1)

fair = [Fraction(1, 6)] * 6
fair_expectation = sum(pi * int(v) for pi, v in zip(fair, values))  # Fraction(7, 2): a die never shows 3.5

try:
    Fraction(0, int(np.zeros(6).sum()))  # all counts zero: the total is 0, so there is no distribution
    zero_total = 'no error'
except ZeroDivisionError:
    zero_total = 'ZeroDivisionError'

# Probability notation as arithmetic on a small table of joint counts: P(A | B) = P(A and B) / P(B).
mask = values > 4  # the event A: the die shows more than 4
p_A = np.sum(p[mask])  # P(A) = (5 + 6) / 21
p_AB = Fraction(5, 21)  # P(A and B) with B = "the face is odd": only face 5 is odd and above 4
p_B = Fraction(1 + 3 + 5, 21)  # P(B) = 9/21
p_A_given_B = p_AB / p_B  # Fraction(5, 9)

# Sums and means over an axis, with the index convention stated: a.sum(axis=0) adds DOWN the rows.
a = np.array([[1, 2, 3], [4, 5, 6]])
total = np.sum(a)  # 21
by_column = a.sum(axis=0).tolist()  # [5, 7, 9]: one sum per column (feature)
by_row = a.sum(axis=1).tolist()  # [6, 15]: one sum per row (example)
product = np.prod(a)  # 720
mean = np.mean(a)  # 3.5

# The gradient of f(theta) = theta1**2 + 3 * theta2**2 has the SAME SHAPE as theta, and a finite difference only approximates it.
t1, t2 = 1.0, 2.0
theta = np.array([t1, t2])
grad = np.array([2 * t1, 6 * t2])  # (2, 12), exact for these values
same_shape = grad.shape == theta.shape  # True


def f(theta):
    return theta[0] * theta[0] + 3 * theta[1] * theta[1]  # the same operations, in the same order, as the stage


h = 1e-3
e_j = np.array([1.0, 0.0])  # the first coordinate direction
estimate = (f(theta + h * e_j) - f(theta)) / h  # about 2.001: close to 2 but not equal
error = float(estimate - grad[0])  # about 0.001: the step h shows up in the error

x_abs = abs(-2.5)  # |x| = 2.5
A = {1, 2, 3}
member = 2 in A  # x in A

print(float(sum_of_p), float(expectation), exact_expectation, exact_sum_of_p, fair_expectation, zero_total)
print(float(p_A), p_A_given_B, int(total), by_column, by_row, int(product), float(mean))
print(grad.tolist(), same_shape, round(float(estimate), 3), round(error, 3), x_abs, member)

Explore: the notation table

The table lists the symbols of the book with how each is read aloud, what it means, the shape of what it names, the Python that writes the same thing and where the idea is developed later. Search it by a word, narrow it by category, and use it when a later chapter shows a symbol you do not recognise. Every Python snippet marked as runnable appears in the reference code above.

The notation table

Show

Showing all 47 entries.

Objects and shapes

  • x∈Rx\in\mathbb{R}
    Read as
    x in R
    Means
    A single real number, written in italics.
    Shape
    a number: () in NumPy
    Python
    no direct equivalent
    Developed in
    Part I · Scalars, quantities, units, powers and roots
  • x∈Rd\mathbf{x}\in\mathbb{R}^{d}
    Read as
    bold x in R to the d
    Means
    A column of d real numbers (d components). In this book a vector is always a column.
    Shape
    d × 1; (d,) in NumPy
    Python
    x = np.array([2.0, -1.0, 0.5])
    Developed in
    Part II · Linear Algebra
  • X∈Rn×dX\in\mathbb{R}^{n\times d}
    Read as
    capital X in R n by d
    Means
    A data matrix: n examples as rows, d features as columns.
    Shape
    n × d; (n, d) in NumPy
    Python
    X = np.arange(12).reshape(4, 3)
    Developed in
    Part II · Linear Algebra
  • X∈RB×T×d\mathcal{X}\in\mathbb{R}^{B\times T\times d}
    Read as
    calligraphic X in R B by T by d
    Means
    A batch of B sequences, each with T positions and d features per position.
    Shape
    B × T × d; (B, T, d)
    Python
    X3 = np.arange(24).reshape(2, 3, 4)
    Developed in
    Part VIII · Vectorized computation
  • nn
    Read as
    n
    Means
    The number of examples: the number of rows of X.
    Shape
    a whole number
    Python
    n = X.shape[0]
    Developed in
    Part V · Data summaries: mean, median, mode
  • dd
    Read as
    d
    Means
    The number of features: the number of columns of X, or the length of a feature vector.
    Shape
    a whole number
    Python
    d = X.shape[1]
    Developed in
    Part II · Linear Algebra
  • B,  TB,\;T
    Read as
    B and T
    Means
    The batch size and the sequence length of a tensor.
    Shape
    two whole numbers
    Python
    B, T, d3 = X3.shape
    Developed in
    Part VII · From token logits to language-model loss
  • x(i)\mathbf{x}^{(i)}
    Read as
    x, example i
    Means
    The i-th example, a row of X written as a column vector. The index is a superscript in parentheses, so it cannot be mistaken for a power.
    Shape
    d × 1
    Python
    row = X[i - 1, :]
    Developed in
    Part V · Data summaries: mean, median, mode

Indices and slices

  • XijX_{ij}
    Read as
    X sub i j
    Means
    The entry in row i and column j. The mathematical indices start at 1.
    Shape
    a number
    Python
    X[i - 1, j - 1]
    Developed in
    Part II · Matrices as linear transformations
  • xj(i)x^{(i)}_{j}
    Read as
    x, example i, feature j
    Means
    Feature j of example i: the same number as X_{ij}.
    Shape
    a number
    Python
    x_i[j - 1]
    Developed in
    Part V · Regression fundamentals
  • Xi,:X_{i,:}
    Read as
    X sub i, colon
    Means
    The whole row i: example i with all its d features.
    Shape
    d entries; (d,)
    Python
    X[i - 1, :]
    Developed in
    Part II · Matrix × vector
  • X:,jX_{:,j}
    Read as
    X sub colon, j
    Means
    The whole column j: feature j across all n examples.
    Shape
    n entries; (n,)
    Python
    X[:, j - 1]
    Developed in
    Part II · Matrix × vector
  • i=1,…,ni=1,\dots,n
    Read as
    i from 1 to n
    Means
    The index takes the values 1, 2, …, n, both ends included. In Python the same loop is range(1, n + 1).
    Shape
    a list of n values
    Python
    for i in range(1, n + 1):
    Developed in
    Part I · Indexed quantities and summation

Products, transpose and norms

  • X⊤X^{\top}
    Read as
    X transpose
    Means
    Swaps rows and columns: an n × d matrix becomes d × n.
    Shape
    d × n
    Python
    X.T
    Developed in
    Part II · Transpose and orthogonality
  • XwX\mathbf{w}
    Read as
    X times w
    Means
    Matrix times vector: one number per example. The inner dimensions must agree (d columns, d entries).
    Shape
    n entries; (n,)
    Python
    X @ w
    Developed in
    Part II · Matrix × vector
  • XWXW
    Read as
    X times W
    Means
    Matrix times matrix: (n × d)(d × k) gives n × k.
    Shape
    n × k
    Python
    X @ W
    Developed in
    Part II · Matrix × matrix as composition
  • X⊤XX^{\top}X
    Read as
    X transpose X
    Means
    The d × d matrix of feature-by-feature inner products: (d × n)(n × d) gives d × d.
    Shape
    d × d
    Python
    X.T @ X
    Developed in
    Part V · Covariance matrices and multivariate spread
  • a⊤b\mathbf{a}^{\top}\mathbf{b}
    Read as
    a transpose b
    Means
    The dot product: the sum of a_i b_i, one number.
    Shape
    a number
    Python
    a @ b
    Developed in
    Part II · Dot product, angle, and orthogonality
  • a⊙b\mathbf{a}\odot\mathbf{b}
    Read as
    a circle-dot b
    Means
    The elementwise product: multiply entry by entry. The result has the shape of a and b.
    Shape
    same as a and b
    Python
    a * b
    Developed in
    Part VIII · Vectorized computation
  • ∥x∥2\lVert\mathbf{x}\rVert_2
    Read as
    the two-norm of x
    Means
    The Euclidean length: the square root of the sum of the squares of the entries.
    Shape
    a number ≥ 0
    Python
    np.linalg.norm(x)
    Developed in
    Part II · Norms, magnitude, and normalization
  • ∥x∥1\lVert\mathbf{x}\rVert_1
    Read as
    the one-norm of x
    Means
    The sum of the absolute values of the entries.
    Shape
    a number ≥ 0
    Python
    np.linalg.norm(x, ord=1)
    Developed in
    Part II · Norms, magnitude, and normalization
  • ∥x∥∞\lVert\mathbf{x}\rVert_\infty
    Read as
    the infinity-norm of x
    Means
    The largest absolute value among the entries.
    Shape
    a number ≥ 0
    Python
    np.linalg.norm(x, ord=np.inf)
    Developed in
    Part II · Norms, magnitude, and normalization
  • 1[xj>0]\mathbb{1}[x_j>0]
    Read as
    indicator that x j is positive
    Means
    The indicator: 1 when the statement in brackets is true, 0 when it is false.
    Shape
    0 or 1
    Python
    (x > 0).astype(int)
    Developed in
    Part IV · Events and probability mass

Sums and averages

  • ∑i=1nai\sum_{i=1}^{n}a_i
    Read as
    the sum of a i for i from 1 to n
    Means
    The accumulator of a loop: add the terms one by one. Both bounds are included.
    Shape
    a number
    Python
    np.sum(a)
    Developed in
    Part I · Indexed quantities and summation
  • ∑i=1nXij\sum_{i=1}^{n}X_{ij}
    Read as
    the sum of X i j over i
    Means
    The sum down column j: one number per feature. In NumPy this is a sum over axis 0, the row axis.
    Shape
    d entries
    Python
    a.sum(axis=0)
    Developed in
    Part VIII · Vectorized computation
  • ∏i=1nai\prod_{i=1}^{n}a_i
    Read as
    the product of a i for i from 1 to n
    Means
    Multiply the factors one by one. An empty product is 1.
    Shape
    a number
    Python
    np.prod(a)
    Developed in
    Part VII · Logarithms and log probabilities in computation
  • xˉ=1n∑i=1nxi\bar{x}=\frac{1}{n}\sum_{i=1}^{n}x_i
    Read as
    x bar equals one over n times the sum
    Means
    The mean: the sum divided by the number of terms, n, which is the last index only when the indices start at 1.
    Shape
    a number
    Python
    np.mean(a)
    Developed in
    Part V · Data summaries: mean, median, mode

Parameters and optimisation

  • θ\theta
    Read as
    theta
    Means
    The parameters of a model, collected in one vector.
    Shape
    p × 1; (p,)
    Python
    no direct equivalent
    Developed in
    Part VI · Objective functions and optimization landscapes
  • L(θ)L(\theta)
    Read as
    L of theta
    Means
    The loss: one number that says how badly the parameters θ fit the data.
    Shape
    a number
    Python
    no direct equivalent
    Developed in
    Part VI · Objective functions and optimization landscapes
  • arg min⁡θL(θ)\argmin_{\theta}L(\theta)
    Read as
    arg min over theta of L of theta
    Means
    The parameter value (a point, or a set of points when there is a tie) at which the loss is smallest. It is a location, not a loss value.
    Shape
    same as θ
    Python
    thetas[np.argmin(L)]
    Developed in
    Part VI · Local vs global optima and stationary points
  • min⁡θL(θ)\min_{\theta}L(\theta)
    Read as
    min over theta of L of theta
    Means
    The smallest value the loss takes. It is a loss value, not a location.
    Shape
    a number
    Python
    np.min(L)
    Developed in
    Part VI · Local vs global optima and stationary points
  • arg max⁡kpk\argmax_{k}p_k
    Read as
    arg max over k of p k
    Means
    The position (class, outcome) with the largest entry, as a 0-based position in NumPy.
    Shape
    a whole number
    Python
    np.argmax(p)
    Developed in
    Part VII · Logits and softmax
  • θ^\hat{\theta}
    Read as
    theta hat
    Means
    An estimate of θ computed from the data. A hat marks an estimate; it is not the true value.
    Shape
    same as θ
    Python
    no direct equivalent
    Developed in
    Part V · Estimators and estimation
  • θ∗\theta^{*}
    Read as
    theta star
    Means
    The optimal parameter: a minimiser of the loss. A star marks an optimum.
    Shape
    same as θ
    Python
    no direct equivalent
    Developed in
    Part VI · Objective functions and optimization landscapes

Probability

  • P(A)P(A)
    Read as
    P of A
    Means
    The probability of the event A: a number from 0 to 1.
    Shape
    a number in [0, 1]
    Python
    p_A = np.sum(p[mask])
    Developed in
    Part IV · Events and probability mass
  • P(A∣B)P(A\mid B)
    Read as
    P of A given B
    Means
    The probability of A when B is known to have happened: P(A and B) divided by P(B), defined only when P(B) > 0.
    Shape
    a number in [0, 1]
    Python
    p_AB / p_B
    Developed in
    Part IV · Conditional probability as restricted sample space
  • E[X]=∑ipixi\mathbb{E}[X]=\sum_{i}p_i x_i
    Read as
    the expectation of X
    Means
    The probability-weighted average of the values. It need not be a value that X can take.
    Shape
    a number
    Python
    np.average(values, weights=p)
    Developed in
    Part IV · Expectation
  • X∼pX\sim p
    Read as
    X is distributed as p
    Means
    The random variable X follows the distribution p.
    Shape
    a distribution
    Python
    no direct equivalent
    Developed in
    Part IV · Random variables

Functions and gradients

  • f:Rd→Rf:\mathbb{R}^{d}\to\mathbb{R}
    Read as
    f from R d to R
    Means
    A function that takes d numbers and returns one number: a loss is such a function of the parameters.
    Shape
    in: d entries, out: a number
    Python
    def f(theta):
    Developed in
    Part I · Functions as input → transformation → output
  • ∂f∂θj\frac{\partial f}{\partial\theta_j}
    Read as
    the partial derivative of f with respect to theta j
    Means
    How fast f changes when only θ_j changes. A finite difference approximates it; it is not equal to it.
    Shape
    a number
    Python
    (f(theta + h * e_j) - f(theta)) / h
    Developed in
    Part III · Multivariable functions and partial derivatives
  • ∇θL\nabla_{\theta}L
    Read as
    the gradient of L with respect to theta
    Means
    The vector of all the partial derivatives of L. It has the same shape as θ: one entry per parameter.
    Shape
    same as θ
    Python
    grad = np.array([2 * t1, 6 * t2])
    Developed in
    Part III · Gradient and directional derivatives

Conventions and signs

  • log⁡x\log x
    Read as
    log of x
    Means
    The natural logarithm, also written ln. Bits need log₂, always written with the base.
    Shape
    a number
    Python
    np.log(math.e)
    Developed in
    Part VII · Logarithms and log probabilities in computation
  • log⁡2x\log_2 x
    Read as
    log base two of x
    Means
    The logarithm in bits.
    Shape
    a number
    Python
    np.log2(8.0)
    Developed in
    Part VII · Self-information
  • ∣x∣\lvert x\rvert
    Read as
    absolute value of x
    Means
    The distance of the number x from 0.
    Shape
    a number ≥ 0
    Python
    abs(-2.5)
    Developed in
    Part I · Scalars, quantities, units, powers and roots
  • x∈Ax\in A
    Read as
    x is in A
    Means
    x is an element of the set A.
    Shape
    true or false
    Python
    2 in A
    Developed in
    Part I · Sets, intervals, and relations
  • ≈\approx
    Read as
    approximately equal
    Means
    A rounded or computed value, such as a floating-point result. An equals sign promises an exact value.
    Shape
    a statement
    Python
    no direct equivalent
    Developed in
    Part VIII · Floating-point representation
  • a:=ba:=b
    Read as
    a is defined to be b
    Means
    A definition, not a claim to be checked.
    Shape
    a definition
    Python
    no direct equivalent
    Developed in
    Part I · Algebraic expressions, equations and inequalities
Search the table by a word such as transpose, norm or mean, or choose a category. The count of matching symbols is announced, and an empty result says so and offers a button that shows everything again.

These questions have definite answers; check each against the stages above.

  • In the shape stage, choose a matrix with more rows than columns and point at the last entry. How many entries are there, and what is the position of the last one? Does the same hold for a tensor?
  • Set the matrix index ii to 00 and then to one more than the number of rows. Which of the two raises an error in Python, and why can the other be worse?
  • In the product stage, find sizes for which XwX\mathbf{w} fails but X⊤wX^{\top}\mathbf{w} works. What does that say about which of the two sizes is the number of examples?
  • In the norm stage, find a vector for which all three norms are equal. Then find one for which the Euclidean norm is not a whole number, and read how the stage writes it.
  • In the arg min stage, choose the flat bottom and read the three results. How many elements does the arg min have, and which one does np.argmin report?
  • In the expectation stage, choose the fair die. Is the expectation one of the faces? Then set one count to 00 and the others unchanged: what happens to the probability of that face?
  • In the gradient stage, choose the smallest step and then the largest. Which error is smaller? Is it the smallest step that gives the best estimate?
  • In the table, search for “norm” and then for a word that does not occur. What does the table say, and how do you get the full list back?

Common mistakes

Numerical considerations

Everything in the stages is exact except where it says otherwise. In a program, three habits are worth learning from the start.

Comparing two floating-point numbers with == is the same trap in a smaller setting. The Euclidean norm of (1,1)(1,1) is 2\sqrt2, which no double represents exactly; squaring the computed value gives a number that is close to 22 and often not equal to it. Compare with a tolerance, as np.isclose does, or keep exact values while you can, as the stages do.

Two more habits: an average of an empty batch should be handled explicitly and reported as undefined instead of letting a division by zero propagate as nan; and a Euclidean norm squares every entry before adding, so a vector with entries near 1020010^{200} overflows to infinity even though its length is a perfectly ordinary double. np.linalg.norm([1e200, 1e200]) returns inf (with a warning), while math.hypot(1e200, 1e200), which scales before squaring, returns about 1.41×102001.41\times10^{200}.

Connections to engineering and machine learning

  • Data matrices. A table of nn examples and dd features is X∈Rn×dX\in\mathbb{R}^{n\times d}. A model XwX\mathbf{w} gives one prediction per example, and the first thing to check in a pipeline is that X.shape[1] equals len(w).
  • Batches of sequences. A language model works on tensors of shape B×T×dB\times T\times d: a batch, positions and features. Most shape bugs in deep-learning code are an axis in the wrong place, which is why shapes belong in comments and in assertions.
  • The Gram matrix. X⊤XX^{\top}X is a d×dd\times d table with one row and column per feature. It reappears in least squares, in covariance and in principal components, which later parts take up.
  • Regularisation. The penalties ∥w∥1\lVert\mathbf{w}\rVert_1 and ∥w∥22\lVert\mathbf{w}\rVert_2^{2} are the first two norms of the weights. The diamond and the circle in the norm stage are the reason the first tends to produce zero weights and the second only small ones.
  • Training is an arg min. Fitting a model means finding θ\theta in arg min⁡θL(θ)\argmin_{\theta}L(\theta). The minimum value tells you how good the fit is, the arg min tells you what the parameters are, and when the loss has a flat direction the arg min is a whole set.
  • Losses are expectations. A population loss is E[ℓ(θ;X)]\mathbb{E}[\ell(\theta;X)] and the loss on a batch is its estimate by an average over the examples in the batch. The expectation notation is the language of Part IV, Probability, and the averages over examples are the sums of the previous chapter.
  • Gradient descent. The update θ←θ−η ∇θL\theta\leftarrow\theta-\eta\,\nabla_{\theta}L only makes sense because the gradient has the shape of θ\theta. When a program raises a shape error in an update, the first suspect is a gradient with a different shape.

Exercises

Answer each question and press Check. A wrong answer tells you which mistake it looks like. After one attempt you may open a worked solution.

calculation

Which entry is X[2, 3]?

A data matrix X has n = 5 examples (rows) and d = 4 features (columns). A line of NumPy code reads X[2, 3]. In the notation of the book, with indices counted from 1, that is the entry X with which example number and which feature number? And at which position does it sit in the flattened array, counting from 0 and reading row by row?

construction

The last entry

X has n = 4 examples and d = 3 features. Name its LAST entry in the book's notation, counting from 1, and say where it sits in the flattened array (counting from 0).

calculation

The shapes of two products

X has shape (6, 4), W has shape (4, 3). Give the shape of X W, and the shape of Xᵀ X.

prediction

Is the product defined?

X has shape (5, 3) and w has 5 entries. What happens with X @ w, and what does the transpose do?

Choose one answer

calculation

Three norms of one vector

For x = (−6, 8) compute the ℓ₁ norm, the ℓ₂ norm and the ℓ∞ norm.

calculation

The value and the place

The loss L(θ) = (θ − 3)² + 2 is tabulated at the whole numbers θ = −4, −3, …, 4 and stored in an array L in that order. Give the smallest loss (the min), the parameter at which it is reached (the arg min), and the value of np.argmin(L).

explanation

Two equally good minimisers

The loss L(θ) = ((θ − 2)² − 1)² is tabulated at θ = −4, −3, …, 4 (an array of nine numbers, in that order). It is smallest at both θ = 1 and θ = 3. What does np.argmin(L) return?

Choose one answer

calculation

An expectation from counts

A game has the possible payoffs −1, 0 and 2. In 10 plays the payoff −1 appeared 2 times, 0 appeared 3 times and 2 appeared 5 times. Treat the counts as weights: the probabilities are the counts divided by their total. What is the expectation E[X] as an exact fraction?

prediction

No observations

You build probabilities from counts by dividing each count by the total, p_i = c_i / (c_1 + … + c_k). Every count is 0. What is the expectation E[X]?

Choose one answer

prediction

The shape of a gradient

A model has p = 5 parameters collected in a vector θ in R⁵, and a loss L(θ) that is a single number. What is the shape of the gradient ∇_θ L?

Choose one answer

Summary and checkpoints

  • A symbol promises a shape: italic for a number, bold for a column vector x∈Rd\mathbf{x}\in\mathbb{R}^{d}, a capital for a table, a calligraphic capital for a stack of tables. The data matrix X∈Rn×dX\in\mathbb{R}^{n\times d} has examples as rows and features as columns.
  • Mathematics counts from 11 and NumPy from 00: the entry with indices i,ji,j is X[i - 1, j - 1]. Arrays are stored row by row; an entry at zero-based (r,c)(r,c) of a matrix with dd columns is at position r d+cr\,d+c. A negative index wraps; an index past the end raises an error.
  • A product ABAB exists when the inner sizes agree and has the outer pair as its shape. The transpose swaps the sizes. X⊤XX^{\top}X is always d×dd\times d.
  • The norms ∥x∥1\lVert\mathbf{x}\rVert_1, ∥x∥2\lVert\mathbf{x}\rVert_2 and ∥x∥∞\lVert\mathbf{x}\rVert_\infty are three measures of size with ∥x∥∞≤∥x∥2≤∥x∥1≤d ∥x∥∞\lVert\mathbf{x}\rVert_\infty\le\lVert\mathbf{x}\rVert_2\le\lVert\mathbf{x}\rVert_1\le d\,\lVert\mathbf{x}\rVert_\infty.
  • The minimum is a value, the arg min is a set of places, and np.argmin is the position of the first smallest entry.
  • E[X]=∑ipixi\mathbb{E}[X]=\sum_i p_ix_i with pi=ci/∑cp_i=c_i/\sum c; it is undefined when there are no observations.
  • The gradient ∇θf\nabla_{\theta}f has the shape of θ\theta, and a finite-difference estimate is an approximation with a best step.

Checkpoints. You can move on when you can, without the stage:

  1. Say the shape of XX, of X⊤X^{\top}, of XwX\mathbf{w} and of X⊤XX^{\top}X for a data matrix with nn examples and dd features.
  2. Convert a mathematical pair of indices to the NumPy expression and to the flattened position.
  3. Decide whether a product of two shapes exists and give the shape of the result, or the two sizes that disagree.
  4. State the three norms and the order of their sizes.
  5. Distinguish the minimum, the arg min and np.argmin, and say which of the three changes when a constant is added to the loss.
  6. Compute an expectation from counts and say when it does not exist.

The map of the book

97 of 97 chapters written · eight Parts

demo Foundation demo Try the live vector example Open as a page

Part I

Mathematical Language

The notation and mental objects everything else uses.

9 of 9 chapters written

  1. I.1 Scalars, quantities, units, powers and roots available
  2. I.2 Coordinates and points available
  3. I.3 Vectors: components, magnitude, and direction reference chapter available
  4. I.4 Algebraic expressions, equations and inequalities available
  5. I.5 Functions as input → transformation → output available
  6. I.6 Essential function families available
  7. I.7 Sets, intervals, and relations available
  8. I.8 Indexed quantities and summation available
  9. I.9 The notation map for ML available

Part II

Linear Algebra

Matrices as transformations: the strongest foundation in the book.

19 of 19 chapters written

  1. II.1 Vector addition and subtraction available
  2. II.2 Scalar multiplication and vector scaling available
  3. II.3 Norms, magnitude, and normalization available
  4. II.4 Dot product, angle, and orthogonality available
  5. II.5 Projection and distance to a direction available
  6. II.6 Linear combinations and span available
  7. II.7 Linear independence, basis, and coordinates available
  8. II.8 Matrices as linear transformations available
  9. II.9 Matrix × vector available
  10. II.10 Matrix × matrix as composition available
  11. II.11 Transpose and orthogonality available
  12. II.12 Determinant: orientation and area/volume scaling available
  13. II.13 Linear systems as intersecting constraints available
  14. II.14 Gaussian elimination and row operations available
  15. II.15 Rank and invertibility available
  16. II.16 Inverse matrices available
  17. II.17 Eigenvalues and eigenvectors available
  18. II.18 Orthogonal bases and least-squares geometry available
  19. II.19 Singular Value Decomposition available

Part III

Calculus

Change, local approximation, and sensitivity made visible.

15 of 15 chapters written

  1. III.1 Limits through approach available
  2. III.2 Continuity and local behavior available
  3. III.3 Derivative as secant → tangent available
  4. III.4 Derivative as rate of change and local linear model available
  5. III.5 Derivative rules available
  6. III.6 Chain rule available
  7. III.7 Multivariable functions and partial derivatives available
  8. III.8 Gradient and directional derivatives available
  9. III.9 Jacobian available
  10. III.10 Computational graphs and automatic differentiation available
  11. III.11 Hessian and curvature available
  12. III.12 Integrals as accumulation available
  13. III.13 Fundamental derivative/integral connection available
  14. III.14 Numerical differentiation available
  15. III.15 Numerical integration available

Part IV

Probability

Uncertainty through sample spaces, evidence, and repetition.

16 of 16 chapters written

  1. IV.1 Random experiments, outcomes, and sample spaces available
  2. IV.2 Events and probability mass available
  3. IV.3 Counting and finite probability where needed available
  4. IV.4 Conditional probability as restricted sample space available
  5. IV.5 Independence available
  6. IV.6 Bayes' theorem as probability-mass update available
  7. IV.7 Random variables available
  8. IV.8 PMF, PDF, and CDF available
  9. IV.9 Bernoulli and Binomial distributions available
  10. IV.10 Uniform and Gaussian distributions available
  11. IV.11 Expectation available
  12. IV.12 Variance and standard deviation available
  13. IV.13 Joint, marginal, and conditional distributions available
  14. IV.14 Covariance and correlation available
  15. IV.15 Law of Large Numbers available
  16. IV.16 Central Limit Theorem available

Part V

Statistics

From observed data to estimates, intervals, and likelihood.

10 of 10 chapters written

  1. V.1 Data summaries: mean, median, mode available
  2. V.2 Spread: variance, standard deviation, robust interpretation available
  3. V.3 Population, sample, and sampling variability available
  4. V.4 Estimators and estimation available
  5. V.5 Confidence intervals through repeated sampling available
  6. V.6 Covariance matrices and multivariate spread available
  7. V.7 Regression fundamentals available
  8. V.8 Likelihood available
  9. V.9 Maximum Likelihood Estimation available
  10. V.10 Maximum A Posteriori estimation available

Part VI

Optimization

Learning as repeated parameter updates governed by an objective.

10 of 10 chapters written

  1. VI.1 Objective functions and optimization landscapes available
  2. VI.2 Local vs global optima and stationary points available
  3. VI.3 Convexity available
  4. VI.4 Gradient descent flagship chapter available
  5. VI.5 Learning rate and convergence behavior available
  6. VI.6 Momentum available
  7. VI.7 Stochastic and mini-batch gradient descent available
  8. VI.8 Adam intuition available
  9. VI.9 Constraints and projected/penalized intuition available
  10. VI.10 Numerical stopping and optimization diagnostics available

Part VII

Information Theory

Logarithms, entropy, and the loss behind token prediction.

8 of 8 chapters written

  1. VII.1 Logarithms and log probabilities in computation available
  2. VII.2 Self-information available
  3. VII.3 Entropy available
  4. VII.4 Cross entropy and negative log-likelihood available
  5. VII.5 KL divergence available
  6. VII.6 Logits and softmax available
  7. VII.7 Numerical stability: log-sum-exp and stable softmax available
  8. VII.8 From token logits to language-model loss available

Part VIII

Numerical Computing

Why equivalent expressions behave differently on real machines.

10 of 10 chapters written

  1. VIII.1 Floating-point representation available
  2. VIII.2 Rounding and representation error available
  3. VIII.3 Error propagation and conditioning available
  4. VIII.4 Catastrophic cancellation available
  5. VIII.5 Overflow and underflow available
  6. VIII.6 Stable algorithms available
  7. VIII.7 Numerical linear algebra realities available
  8. VIII.8 Sparse matrices and sparse structure available
  9. VIII.9 Vectorized computation available
  10. VIII.10 Reproducibility, random seeds, and nondeterminism available