Exercises — PyTorch tensors and operations
A quick vocabulary reminder so nothing below is a surprise:
Here is a tensor, is its rank, and is the size of axis . The big symbol just means "multiply all of these together", the same way means "add all of these together".
Level 1 — Recognition
Exercise 1.1 — Read a shape
A tensor is created with torch.zeros(4, 1, 5). State its rank, its shape, and its numel.
Recall Solution
- Shape is exactly the arguments: .
- Rank = how many numbers in that tuple = .
- numel = multiply them: .
Picture it as 4 sheets, each sheet has 1 row of 5 numbers → little cells.
Exercise 1.2 — Which creator?
You want a tensor of samples drawn from the standard normal distribution (mean 0, spread 1). Which of torch.rand(2,3), torch.randn(2,3), torch.ones(2,3) do you pick, and why not the others?
Recall Solution
Pick torch.randn(2,3).
randgives uniform numbers in — always positive, no bell curve.onesgives all — no randomness at all.randn(the extra n = normal) gives the bell-curve numbers we asked for, centred at 0.
Level 2 — Application
Exercise 2.1 — Broadcasting shapes
You add a tensor of shape to a tensor of shape . Does it work? If so, what is the result shape? Walk the rule.
Recall Solution
Yes, result shape is . Walk the broadcasting rule (align shapes on the right):
- Ranks differ ( vs ), so pad the smaller with a leading 1: .
- Compare axis by axis: vs . Axis-1: ✓. Axis-0: vs — one of them is 1, so the size-1 side is stretched to 4. ✓
- Result: .
See the figure — the row of 3 gets copied down onto every one of the 4 rows.

Exercise 2.2 — Reduction with a chosen axis
Given
compute x.sum(dim=0) and x.sum(dim=1). State the resulting shape of each.
Recall Solution
The rule: dim=k means "collapse axis " — that axis disappears.
dim=0collapses the rows (the length-2 axis), summing down each column:dim=1collapses the columns (the length-3 axis), summing across each row:

Level 3 — Analysis
Exercise 3.1 — Will this matmul run?
For each pair, say whether A @ B is legal and give the output shape:
(a) , (b) , (c) , .
Recall Solution
The law of matrix multiply: the inner two dimensions must match; the outer ones become the result.
- (a) : inner ✓ → output . Legal.
- (b) : inner ✗ → illegal, mismatch error.
- (c) Leading is a batch axis (same on both), inner ✓ → output . Legal.

Exercise 3.2 — keepdim and broadcasting
A batch x has shape . You want to subtract each column's mean from that column (a mini version of batch norm). Compare x - x.mean(dim=0) versus x - x.mean(dim=0, keepdim=True). Do both work? Why does the second one always work safely?
Recall Solution
x.mean(dim=0)collapses axis 0 → shape . Then broadcasts: ✓. Works here.x.mean(dim=0, keepdim=True)keeps axis 0 as size 1 → shape . Then broadcasts directly ✓.
Both give the same numbers in this case. But if you'd reduced along dim=1 instead you'd get , and would try to pad to and fail (4≠3). keepdim=True gives , which broadcasts against cleanly. So keepdim=True is the safe habit — the reduced axis stays in place as a size-1 slot ready to stretch.
Level 4 — Synthesis
Exercise 4.1 — Build a linear layer by hand
Input x has shape (32 MNIST samples, each 784 pixels). You want 128 outputs per sample. Design the weight W and bias b shapes, write the forward pass, and give the output shape. Then count how many multiply-adds the matmul does.
Recall Solution
PyTorch convention: with x as .
Wmust turn 784 → 128, so shape .bis one number per output, shape .- Forward:
y = x @ W + b. - Shapes: ; then broadcasts .
- Output shape .
Multiply-adds in the matmul: each of the output entries is a sum over the inner axis of length 784:
Exercise 4.2 — Reshape a batch of images for a dense layer
x = torch.randn(10, 3, 28, 28) (10 RGB images). Flatten everything except the batch axis so you can feed a fully-connected layer. Write the call and give the new shape and its numel (to prove nothing was lost).
Recall Solution
Use x.flatten(start_dim=1) — keep axis 0, merge the rest:
Check numel is conserved: before ; after . ✓ Reshaping only reorganises the same numbers; it never creates or destroys any.
Level 5 — Mastery
Exercise 5.1 — Trace a full mini forward pass
Given the tiny exact tensors
compute y = x @ W + b fully by hand, then apply ReLU (which replaces every negative entry with 0 — here nothing is negative). Give the final matrix.
Recall Solution
x is , W is → inner ✓ → x@W is . Each entry is row-of-x · column-of-W:
Add b = [1,1,1] to every row (broadcast ):
ReLU: all entries already positive, so the output is unchanged:
Exercise 5.2 — Memory sharing gotcha
a = torch.tensor([1.0, 2.0, 3.0])
b = a.view(3, 1)
b[0, 0] = 99.0What is a afterward, and why? Then state the one-line fix if you wanted a untouched.
Recall Solution
a becomes [99.0, 2.0, 3.0].
view returns a new shape label onto the same underlying memory — it does not copy. Writing through b writes the shared storage, so a sees it too.
Fix: break the sharing with a copy — b = a.view(3, 1).clone() (or a.reshape(...).clone()).
Recall Self-check reveals
What does dim=k do in a reduction? ::: Collapses (removes) axis ; that axis disappears from the shape.
Broadcasting aligns shapes on which side? ::: The right; then pads missing leading axes with 1 and stretches size-1 axes.
Inner-dimension rule for A @ B? ::: The last axis of A must equal the second-to-last axis of B.
Why keepdim=True? ::: It leaves the reduced axis as size 1 so the result broadcasts back against the original.
Does view copy data? ::: No — it shares memory; use .clone() to break sharing.
Connections: 3.1.01-neural-network-fundamentals · 3.2.03-backpropagation · 3.3.02-building-modelspytorch · 2.4.01-numpy-fundamentals · 3.4.05-batch-normalization · 3.5.02-convolutional-layers · 4.2.01-gpu-acceleration