Matrices and Multiplication
Batching predictions is a single matrix multiply
A matrix is a collection of vectors, and matrix multiplication applies transformations (including whole model predictions) to many examples at once.
What you will learn
- Interpret matrices as bundles of training rows or as transformations
- Multiply matrices with correct dimension rules
- See a linear regression prediction as X·w
What is this?
A matrix is a 2D grid of numbers. In ML it plays two roles: it stores data (each row one example) and it represents a linear transformation (each column maps input directions to output directions). Multiplying a weights matrix by a data matrix computes predictions for every row at once — which is why 'vectorization' is matrix multiplication.
Why do you need it?
- np.dot / @ between X (n×d) and w (d×1) scores all n examples in one operation.
- Neural network layers are matrix multiplications of activations by weight matrices.
- GPUs are tuned to make matrix multiplies brutally fast, so code that uses them wins.
- Understanding shapes prevents a whole class of silent bugs.
Mental model
A recipe card being applied to many kitchens at once
Matrix multiplication applying one transform to all data rows
The recipe is the weight matrix: same transformation, applied simultaneously to every input, producing every output at once.
How it works
- Matrix A (m×k) times B (k×n) yields C (m×n): each entry cᵢⱼ is the dot product of row i of A with column j of B.
- The inner dimensions must match: k on both sides. 'm×k · k×n = m×n'.
- Rotation, scaling and shearing are all linear transformations encoded as matrices.
- A linear regression prediction ŷ = Xw + b is matrix-vector multiply then add bias — over the whole dataset at once.
- Matrix multiplication is NOT commutative: AB ≠ BA in general.
One matrix multiply scores the whole dataset.
Examples
Batch prediction as a matrix multiply
import numpy as npX = np.array([ [1, 2], # example 1 [3, 4], # example 2 [5, 6], # example 3])w = np.array([2, -1.0]) # learned weightsb = 0.5y_hat = X @ w + b # shape (3,)print(y_hat) # [0.5, 3.5, 6.5]print(X.shape, w.shape) # (3, 2) (2,)Each row of X is dotted with w, then bias is added. The same computation happens 3 times inside one numpy call — that's the batching that makes numpy, GPUs and deep learning fast.
In production
- An ad-bidding system scores 10M ad candidates per second via batched matrix multiplies on GPUs.
- A linear model served as a single weight vector rides inside a matrix multiply at inference, so latency is microseconds.
- Recommendation factorizations materialize as matrix products of user and item embeddings.
Best practices
- Write shapes as comments or assert them: assert X.shape[1] == w.shape[0].
- Use @ for matrix multiply and * for element-wise; they are not interchangeable.
- Keep X as a 2D array even for one example — it keeps @ semantics uniform.
Common mistakes
- Swapping * and @ produces a broadcast instead of a true multiply.
- Passing transposed data — shape (d×n) instead of (n×d) — yields wrong results silently.
- Forgetting that AB ≠ BA when reorganizing a pipeline.
Debugging tips
- Print A.shape, B.shape immediately before the multiply to catch mismatch at the source.
- Verify on a 2×2 toy example: multiply by hand, compare with numpy.
- If results explode or become NaN after a multiply, check for integer overflow or mixed dtypes.
Interview checkpoint
Quick quiz
A is 3×4 and B is 4×5. What is A@B's shape?
Matrix multiplication is commutative: A@B always equals B@A.