Learn machine learning from scratch

Start at chapter 1 and build up: what a model is, how it measures its own mistakes, and how it learns. Everything is worked out in plain Python, with the maths shown rather than assumed. Two shorter tracks hold reference notes on the maths and on modern architectures.

Track Progress: 0 Completed
0%
Maths for MLLEVEL 2 · INTERMEDIATEModule 2 · Matrices

Special matrices: diagonal, symmetric, orthogonal, triangular, sparse

Matrices with a pattern are cheaper to store, faster to multiply or easy to invert, and ML code uses every one of these patterns.

10 min Prerequisites: Lesson 12 (transpose and inverse)

1. The idea

Some matrices have a pattern, and the pattern makes them cheap to store, fast to multiply or easy to invert. Machine learning code leans on all of these.

A diagonal matrix only scales each coordinate: multiplying by it is the same as multiplying element-wise by its diagonal, which is how the per-feature scale in a normalization layer works. A symmetric matrix equals its own transpose; covariance matrices and Hessians are always symmetric. An orthogonal matrix has columns of length 1 at right angles to each other, so it rotates or flips without stretching anything, and its inverse is simply its transpose.

A triangular matrix is zero on one side of the diagonal. The causal mask in a language model is lower triangular: token i may look at tokens 1 to i but never at later ones. A sparse matrix is mostly zeros and is stored as a list of its non-zero entries; graphs and one-hot encodings over huge vocabularies are full of them.

2. Try it: spot the pattern

Pick a kind of matrix. The diagonal is highlighted and zeros are faded, and the checks below are worked out from the numbers, not typed in.

A 4 by 4 matrix of the chosen kind (diagonal, symmetric, orthogonal, lower triangular or sparse), with its diagonal highlighted and zeros faded. Below, a sentence on what makes it special and computed checks: whether it equals its transpose, whether its transpose times itself is the identity, whether it is zero above or off the diagonal, and how many entries are non-zero.

3. The math

Diagonal
D=diag⁡(d1,…,dn)Dx=d⊙xD = \operatorname{diag}(d_1, \dots, d_n) \qquad D\mathbf{x} = \mathbf{d} \odot \mathbf{x}
⊙ is the element-wise product: no full matrix multiply needed.
Symmetric
A=A⊤A = A^\top
Entry (i, j) equals entry (j, i).
Orthogonal
Q⊤Q=IQ−1=Q⊤∥Qx∥2=∥x∥2Q^\top Q = I \qquad Q^{-1} = Q^\top \qquad \|Q\mathbf{x}\|_2 = \|\mathbf{x}\|_2
Lengths (and angles) are preserved.
Lower triangular
Lij=0  for j>iL_{ij} = 0 \ \text{ for } j > i
Zeros above the diagonal.
A causal mask
Mij={0j≤i−∞j>iM_{ij} = \begin{cases} 0 & j \le i \\ -\infty & j > i \end{cases}
Added to attention scores: −∞ becomes a weight of 0 after softmax, hiding the future.

4. The code (python)

mm2_special.py
import numpy as np

d = np.array([2.0, 0.5, -1.0])
x = np.array([1.0, 4.0, 3.0])
print(np.diag(d) @ x, d * x)                  # [ 2.  2. -3.] [ 2.  2. -3.]

t = np.radians(30)
Q = np.array([[np.cos(t), -np.sin(t)],
              [np.sin(t),  np.cos(t)]])
print(np.allclose(Q.T @ Q, np.eye(2)))        # True
print(round(np.linalg.norm(Q @ np.array([3.0, 4.0])), 6))   # 5.0

n = 4                                         # a causal mask for 4 tokens
mask = np.triu(np.full((n, n), -np.inf), k=1)
print(mask[1].tolist())                       # [0.0, 0.0, -inf, -inf]

5. You’ll see this in

6. Check yourself

Answer all 4 questions correctly to complete the chapter · 0 / 4 done
Q1/4 Where does diag(2, 3) send the point (1, 1)?
Q2/4 What is the inverse of an orthogonal matrix Q?
Q3/4 Which of these is always symmetric?
Q4/4 In a causal mask, what do the −∞ entries above the diagonal do?

Finished this chapter?

Weekly newsletter

What changed in ML architectures this week

New models worth knowing, benchmark moves, and one architecture explained in plain words. Free, once a week, unsubscribe anytime.