← All tutorials

Vectors and Matrices

How models compare vectors and how matrices move them.

On this page

1 Everything is a vector 2 Length is the norm 3 The dot product scores agreement 4 Projection keeps one direction 5 A matrix times a vector is a layer 6 Shapes, batches and other products 7 The determinant measures area 8 Inverse and rank 9 Vectors and matrices in NumPy and PyTorch 10 From fixed numbers to chance 11 References

Models work on lists of numbers. Three tools carry almost every later page: length (clipping), the dot product and angle (attention, comparing task gradients) and matrices, which move a whole space at once (linear layers, turning a word’s vector by its position, small fine-tuning updates).

1 Everything is a vector

A vector is an ordered list of numbers, drawn as an arrow from the origin. Attention, convolutions, multitask learning and Multilayer Perceptrons (MLP) all store data this way. In shapes such as (B, T, d), each size names an axis: B counts examples, T positions in a sequence and d numbers per vector. A token is a word piece; its embedding is its learned vector.

1image patch 2token embedding 3gradient 4weight row 9 numbers cat ... 512 numbers (3, 4), illustrative (−1, 1) (d,)one vector (B, d)a batch (B, T, d)a batch ofsequences
Figure 1. Four vectors from the site 1 to 4, and the three shapes vectors come in.

2 Length is the norm

A gradient says how the loss changes as each weight moves. The loss is the model's error score, and a weight is one learned number. Clipping in recurrent neural networks (RNNs), which read a sequence step by step, caps a gradient's length. GradNorm balances the gradient lengths of tasks trained together, and k-means clustering and k-nearest-neighbor (k-NN) search measure distances as lengths. PyTorch's clip_grad_norm_ rescales a gradient so its length is at most max_norm (Optimizers in Practice).

clipping one illustrative gradient g = (3, 4)result
length of g√9 + 16 = 5
max_norm 1scaled by 1/5 to (0.6, 0.8), length 1, same direction
max_norm 10unchanged, 5 is under the cap
a real modelevery weight's gradient joins one long vector, capped as a whole
The length of an arrow, by Pythagoras: square each entry, add, take the square root.
‖a‖ = √a12 + a22 + … + ad2
a1 to ad are the d entries of a; the double bars mean length. Squaring stops signs from cancelling, adding collects every axis, and the square root returns to the entries’ units.
‖a‖ = √Σi ai2
Σi adds the term for every i from 1 to d. The distance between a and a second vector c is the length of a minus c, their difference.

3 The dot product scores agreement

Each token has a query, what it looks for, a key, what it offers, and a value, what it passes on. Attention scores keys against a query with dot products (Attention), and so does a convolution, which slides a small pattern of weights across an image. CLIP, a model that matches images to captions, and contrastive learning, training that pulls matching pairs together, score with the cosine, the dot product of the two vectors scaled to length 1 (below). The query and keys in this section are illustrative.

query q = (2, 2) against keyentry by entryscore
cat (2, 2)4 + 48
the (1, 0)2 + 02
sat (−1, −0.5)−2 − 1−3

Attention turns the raw scores 8, 2 and −3 into attention weights with the softmax, which makes every score positive and divides by their total, so the weights add to 1.

Multiply matching entries and add. The score is large when both arrows are long and point the same way, 0 at right angles, and negative when they point apart.
a · c = Σi ai ci
aici is the agreement on axis i, positive when both entries share a sign; Σi adds it over all d axes. So the score grows with both lengths and with how well the arrows line up.
a · c = aT c
The same number as a row times a column. The raised T, the transpose, turns the column a into a row; attention writes its scores this way.
‖a‖ = √a · a
A vector’s dot product with itself is the sum of its squares, so the norm of Section 2 is its square root.
keyscorekey lengthcosine
cat (2, 2)82.8281
the (1, 0)210.707
sat (−1, −0.5)−31.118−0.949
the, doubled to (2, 0)420.707

The query’s length is 2.828. Doubling a key doubles its score and leaves its cosine alone.

The dot product with both lengths divided out, so only direction is left: 1 for the same direction, 0 at right angles, −1 for opposite.
cos θ = a · c‖a‖ ‖c‖
θ is the angle between the arrows. The top is the dot product a · c; each length on the bottom removes one arrow’s size, so stretching an arrow moves the score but not the cosine.

CLIP scales every embedding to length 1 first, so one matrix product (Section 6) gives all its cosines at once. Attention skips that, so a longer key earns a bigger score.

Figure 2. Stretching the key by its square grip moves bar 1, not bar 2.

4 Projection keeps one direction

A task gradient is the gradient of one task’s loss with respect to the weights that several tasks share (Introduction to Multitask Learning). PCGrad removes the part of one task gradient that fights another, GradVac nudges the cosine between two task gradients toward a target, and multitask learning reads the fight from that cosine. PCA, which finds the main directions of a dataset, scores each image, such as a photo of a face, along one direction.

dot product −2 cosine −0.894, about 153° illustrative numbers 1 g1 = (2, 0) 2 g2 = (−1, 0.5) 3 along g1, (−1, 0) 4 kept, (0, 0.5)
Figure 3. The part of g2 along g1 3 fights g1; PCGrad keeps the rest 4.
The part of a that points along c. Subtracting it leaves the part of a at a right angle to c.
projc a = a · c‖c‖2 c
The top is the dot product of Section 3, the overlap of a with c. Dividing by ‖c‖2 turns it into a count of c-lengths, negative when a leans away, and the final c lays that count along c’s line.
a − projc a
The rest is orthogonal to c: its dot product with c is 0. PCGrad keeps only this part when two task gradients have a negative dot product.

5 A matrix times a vector is a layer

Every linear layer is this product: the hidden (inner) layer of an MLP, the query, key and value maps of Attention, and the weight row of logistic and linear regression. A matrix is a table of numbers, read as a stack of rows.

an MLP's hidden layer on the point x = (−2, 2)row of W times xplus biasoutput
row 1 (−1, 1)(−1)(−2) + (1)(2) = 4−22
row 2 (1, −1)(1)(−2) + (−1)(2) = −4−2−6

The weights, the bias (−2, −2) and the point are those of the MLP walkthrough.

Each output is the dot product of one row of W with the input, plus a bias.
y = W x + b
W has one column per entry of the input x and one row per output in y. The bias b shifts each output.
yi = Wi · x + bi
Row Wi is the direction output i listens to, so each output is a dot product from Section 3 plus its bias. A layer is one dot product per output, all at once.

6 Shapes, batches and other products

Score tables in Attention and Transformer Cost and Efficiency, padding masks, cross-attention, where one sequence attends to another, and pruning masks, which zero weights a model does not need, follow these rules.

6.1 Inner sizes match, outer sizes survive

Take six tokens at the original Transformer’s width 512: X has shape (6, 512). WQ, shape (512, 64), turns each token into a 64-number query, so dk = 64 is the query width. K stacks the keys the same way, S is the score table and h counts attention heads (parallel copies of attention).

X 6 × 512 × WQ 512 × 64 = Q 6 × 64 1inner sizesmatch 2outer sizessurvive Q 6 × 64 × KT 64 × 6 = S 6 × 6 one score perpair of tokens batch axes ride along (B, h, T, dk) × (B, h, dk, T) = (B, h, T, T)
Figure 4. The shared size 1 disappears; the outer sizes 2 make the result.

In a batch, the axes before the last two ride along. An axis of size 1 stretches to match the other side, which is called broadcasting. @ is the matrix product sign in NumPy and PyTorch.

operationshapesresult
scores per head(1, 8, 16, 64) @ (1, 8, 64, 16)(1, 8, 16, 16)
padding mask (hides filler tokens) on the scores(2, 1, 1, 5) with (2, 8, 5, 5)(2, 8, 5, 5), the mask reaches every head and query
each point’s 2 cluster scores in a Gaussian mixture, a clustering model (Section 7), divided by their total(272, 1) with (272, 2)(272, 2)

The sizes come from the code that turns each query and key by its position and the padding-mask code in Positional Encoding and Masking, and from the 272 points of the tool in Gaussian Mixture Models.

A matrix product pairs every row on the left with every column on the right. The inner sizes must match and the outer sizes survive.
(6 × 512)(512 × 64) = (6 × 64)
Each of the 6 token rows of X meets each of the 64 columns of WQ in one dot product of length 512. That is the layer of Section 5 run on 6 inputs at once, so the inner size 512 must agree on both sides and then disappears.
(…, 16, 64)(…, 64, 16) = (…, 16, 16)
@ multiplies the last two axes and treats the axes before them, shown as …, as a batch. These are the scores per head from the table: 16 queries against 16 keys. With h attention heads, queries (B, h, T, dk) times transposed keys give one (T, T) score table per example and head.

6.2 Two readings of a product

In attention, A holds the softmax weights, one row per query, and V holds the values, one row per token. A LoRA update is a small change added to a frozen (kept fixed) weight, built as a column times a row (Adapters).

readingexampleresult
a row of AV blends the rows of VAttention's weights 0.78, 0.17, 0.05 on illustrative value rows (1, 0), (0, 1), (1, 1)(0.83, 0.22)
two layers in a row are one layeran illustrative rank-1 LoRA update (rank 1: every output lies on one line, Section 8) on x = (1, 1): the row (1, 1), then the column (2, 1)the row gives 2, the column turns it into (4, 2); their product 2211 gives (4, 2) at once
The same product read two ways: each output row is a weighted sum of rows, and a chain of matrices folds into one.
(A V)i = Σj Aij Vj
The product of Section 6.1, read row by row: output row i blends the rows Vj of V with the weights Aij. Multitask learning blends task gradients the same way.
W2(W1 x) = (W2 W1) x
W2W1 is one matrix, computed once, so two linear layers with nothing between them are one layer. That is why an MLP puts a nonlinearity (a bend no matrix makes) such as ReLU, which sets negative values to 0, between layers, and why Adapters can merge a LoRA update (W1 the row, W2 the column) into the weight.

6.3 Entry by entry, and the outer product

⊙ multiplies matching entries. The Adam optimizer, a rule for updating weights, keeps two running averages: one of the gradient, and v, one of its square (Adaptive Optimizers).

operationexampleresult
transpose KTrows and columns of K swap(6, 64) becomes (64, 6)
average gradient divided by √v, entry by entryAdam, illustrative average gradient (1, 0.01) and v = (1, 0.0001)(1, 1), gradients 100 times apart take the same step
column times rowerror e = (−0.1604, 0) times input x = (−2, 2), computed from the MLP walkthrough’s network0.321−0.32100, the weight gradient
Two products that keep every entry instead of summing. The outer product pairs every entry of one vector with every entry of the other.
(a ⊙ c)i = ai ci
The dot product of Section 3 without its Σ. Adam divides each coordinate by the square root of its own v (Gradient Balancing Inside the Training Loop). Pruning masks and dropout masks set chosen entries to 0, and dropout picks them at random during training. The gates in Conformer, a speech model, and in LSTMs, recurrent networks with a memory, multiply one signal by another.
(e xT)ij = ei xj
One entry per pair, a rank-1 matrix (Section 8). A weight gradient is this table, each output’s error ei times each input xj (Backpropagation).

7 The determinant measures area

A Gaussian Mixture Model (GMM) fits data with Gaussian bumps, bell-shaped clouds of points, called components. Its density, how likely a point is, divides by the square root of the determinant of each component’s covariance, its spread. When one component shrinks onto a point, that determinant nears 0. The likelihood, how well the model explains the data, then runs to infinity. LayerNorm rescales each feature (one entry of a vector) by a learned γ (The Transformer Block). RoPE turns a query or key by an angle set by its position (Positional Encoding and Masking).

matrixentries, row by rowdetthe plane
illustrative γ = (2, 1) as a diagonal matrix2, 0, 0, 12areas double
RoPE turn by 40°0.766, −0.643, 0.643, 0.7661areas, lengths and angles kept
rank-1 LoRA update2, 2, 1, 10lands on one line
the MLP walkthrough’s W from Section 5−1, 1, 1, −10both outputs read only the second input minus the first

The LoRA update is illustrative too; 40° is one position’s turn in the RoPE figure of Positional Encoding and Masking. A diagonal matrix scales each axis on its own, as LayerNorm’s γ and a diagonal covariance in GMMs do.

The factor by which a 2 × 2 matrix scales area. A determinant of 0 means the matrix flattens the plane onto a line or a point. A matrix’s inverse is the move that undoes it, and a flattened plane cannot be undone, so a determinant of 0 means no inverse (Inverse and rank).
det w11w12w21w22 = w11w22 − w12w21
wij is the entry in row i, column j. The columns (w11, w21) and (w12, w22) are where the sides of the unit square (corners (0, 0) and (1, 1)) land, and the determinant is the signed area of the parallelogram they span. It is positive when column 2 sits counterclockwise from column 1 and negative when the move mirrors the plane. When both off-diagonal entries are 0 it is just the area of a rectangle, the two diagonal entries multiplied. For a square W from Section 5, as many outputs as inputs, it says how much every region of the input is stretched or squashed.
vol(W C) = |det W| vol(C)
C is any region, WC where W moves it, vol its volume (area in two dimensions) and the bars drop the sign. For any square matrix, as many rows as columns, the determinant is this one scale factor; np.linalg.det computes it, and the GMM density of this section needs it for its covariance, one row and column per feature.
start from

Figure 5. The shaded area is the determinant; lined-up columns give 0.

8 Inverse and rank

Linear regression’s direct formula for the best weights contains an inverse, RoPE needs a turn that can be undone (Positional Encoding and Masking), and LoRA (Adapters) and collapse checks, which test whether a model’s outputs have squeezed onto a few directions, count rank. Correlation says how strongly two pixels brighten together, 1 meaning always (Probability and Bayes Rule). The correlation 0.61 for two face pixels below is illustrative.

matrixdetinverse
two face pixels, illustrative correlation 0.61: 10.610.6110.6281.593−0.971−0.9711.593; times the matrix it gives the identity I (1s on the diagonal from top left to bottom right, 0s elsewhere)
rank-1 LoRA update 22110none
RoPE turn R by 40°1RT, the turn back
The inverse is the move that undoes a matrix. It exists only when the determinant is not 0, because a flattened plane cannot be spread out again.
W−1 W = I
I, the identity from the table, moves nothing; W then W−1 puts every point back.
R−1 = RT
Turning back undoes turning, so a turn’s transpose is its inverse.

At 40° per position, RoPE turns a query at position 3 by 120° and a key at position 1 by 40°; move both one place later and the 80° gap between them, and so their score, stays the same.

Two turns combine into one turn by their difference, so a turned query and key score by how far apart they sit, not where.
RmT Rn = Rn−m
Here m and n are token positions: Rm turns by the angle of position m, and its transpose, its inverse, turns back. Back by m, then forward by n, is one turn by the gap from m to n.
(Rm q)T(Rn k) = qT Rn−m k
The score of a query q at position m and a key k at position n, the dot product of Section 3 after both turn. By the first line it depends on the gap from m to n alone.

The rank is the number of independent directions left after the move; a rank-r matrix is a sum of r outer products (Section 6.3). The illustrative LoRA update is one outer product, the column (2, 1) times the row (1, 1), so its rank is 1. A rank-r LoRA update is a tall thin matrix with r columns times a short wide one with r rows. Embeddings that use few directions have low rank, the collapse the checks look for.

rank 2both directions used rank 1collapsed onto a line
Figure 6. Collapsed embeddings line up, and the rank drops.

9 Vectors and matrices in NumPy and PyTorch

The code on the MLP page, Attention and contrastive learning use these calls and shapes.

objectshapenote
one vector(d,)a 1-D array
a batch of vectors(B, d)one row per example
a batch of sequences(B, T, d)the input to attention
a linear layer’s weight W(out, in)used as the input times W transposed, plus the bias
attention scores(B, h, T, T)every query against every key

PyTorch builds that weight with nn.Linear, given the number of inputs and the number of outputs. Attention scores multiply the queries by the keys after transpose swaps the last two axes of the keys.

Clipping and attention scores in NumPy. Clipping runs once per training step (one weight update), after the gradients are computed; scores run every time the model runs.

import numpy as np
g = np.array([3.0, 4.0])  # an illustrative gradient
max_norm = 1.0
length = np.linalg.norm(g)  # 5.0
clipped = g * min(1.0, max_norm / length)  # [0.6 0.8]

q = np.array([2.0, 2.0])  # query
keys = np.array([[2.0, 2.0],  # cat
                 [1.0, 0.0],  # the
                 [-1.0, -0.5]])  # sat
scores = keys @ q  # [ 8.  2. -3.]
key_len = np.linalg.norm(keys, axis=1)
cosines = scores / (key_len * np.linalg.norm(q))
# [ 1.     0.707 -0.949]
  1. 1Clips the gradient (3, 4) to length 1, Section 2.
  2. 2Scores three keys against one query in a single matrix-vector product, Section 3 and Section 5.
  3. 3Divides out both lengths to get the cosines, Section 3.

Layer and mask shapes in PyTorch. The layer runs every time the model runs; the mask is built once per batch.

import torch
import torch.nn as nn
x = torch.randn(6, 512)  # 6 tokens, width 512
w_q = nn.Linear(512, 64, bias=False)
assert w_q.weight.shape == (64, 512)  # (out, in)
assert w_q(x).shape == (6, 64)

scores = torch.randn(2, 8, 5, 5)  # (B, h, T, T)
keep = torch.ones(2, 5, dtype=torch.bool)
keep[1, 3:] = False  # padding at the end of sequence 2
mask = keep[:, None, None, :]  # (2, 1, 1, 5)
masked = scores.masked_fill(~mask, float("-inf"))
  1. 1Makes queries with a linear layer; its weight is stored as (out, in), Section 6.1.
  2. 2Reshapes a padding mask from (B, T) to (B, 1, 1, T) so it broadcasts over heads and queries, Section 6.1.

Determinant, rank, inverse and solve in NumPy, run once on fixed matrices.

import numpy as np
corr = np.array([[1.0, 0.61], [0.61, 1.0]])  # face pixels
lora = np.array([[2.0, 2.0], [1.0, 1.0]])  # rank-1 update
w_mlp = np.array([[-1.0, 1.0], [1.0, -1.0]])  # the MLP walkthrough's layer

dets = [np.linalg.det(mat) for mat in (corr, lora, w_mlp)]  # 0.628, 0, 0
ranks = [np.linalg.matrix_rank(mat) for mat in (corr, lora, w_mlp)]  # 2, 1, 1
inv_corr = np.linalg.inv(corr)  # [[1.593 -0.971] [-0.971 1.593]]

z = np.linalg.solve(corr, np.array([1.0, 1.0]))  # [0.621 0.621]
  1. 1Sets up the three matrices of Section 7 and Section 8.
  2. 2Reads each one's determinant and rank, and inverts the one that has an inverse.
  3. 3Finds the vector that the correlation matrix maps to (1, 1), directly, with no inverse formed.

Four traps catch most shape and matrix bugs.

10 From fixed numbers to chance

Every vector on this page held fixed numbers. How do we describe numbers that chance picks, like the next token a language model samples? Probability and Bayes Rule starts there.

11 References