Drills

Drills

Four tasks, from easy to harder. You can do all of them in a new file or in the console — they do not touch the project files. For each I wrote what you should see, so you know whether you got it right.

Numbers marked "my machine" may differ on yours by about a percentage point.


1. Count the updates

10 000 images. Without running code, answer:

  • how many updates per epoch when batch_size is 64? When 10 000? When 1?
  • how many images does the last batch have when batch_size = 64?
  • how many updates in total does fit(..., epochs=10) make with batch 64?

Then check: len(loader) and [len(b[0]) for b in loader][-1].

You should see: 157 / 1 / 10 000, last batch — 16, total — 1 570.


2. One step on one number

w = torch.tensor(3.0, requires_grad=True)
loss = (w * 2 + 1 - 10) ** 2

Before running anything, answer by hand: what is loss? What is dloss/dw? What will w be after one step with lr = 0.1?

Then check: loss.backward(), w.grad, and torch.optim.SGD([w], lr=0.1).step().

You should see: loss 9.0, gradient −12.0, w becomes 4.2. Notice: the gradient is negative, so w grows — the step always goes against the gradient.


3. A learning-rate sweep

Use your fit. Run five epochs (seed 42, batch 64, LinearClassifier) with lr = 0.001, 0.01, 0.1 and 1.0. For each, print the final loss and accuracy (evaluate).

Answer: which lr is best? Why does lr = 1.0 not produce nan this time, as it did in lesson 4?

My machine:

lr 0.001  loss 1.4206 acc 65.5%
lr 0.01   loss 0.7481 acc 76.8%
lr 0.1    loss 0.5514 acc 80.0%
lr 1.0    loss 5.5408 acc 57.5%

Accuracy does not grow with lr — past 0.1 it falls. And no nan, because in lesson 4 it was the whole set per step: one bad leap and everything flies out. Here every step is corrected by the next batch.


4. Break the shuffle on purpose

In the FashionMNIST file the classes are already mixed. Sort the images by class:

order = torch.argsort(y, stable=True)
x_sorted, y_sorted = x[order], y[order]

Train the model (5 epochs, lr=0.1, batch 64) three ways: (a) original order, shuffle=True; (b) sorted, shuffle=False; (c) sorted, shuffle=True.

Before running, guess: which one will be bad and why?

My machine (accuracy after 5 epochs):

(a) original order, shuffle=True       80.0%
(b) sorted, shuffle=False              45.3%
(c) sorted, shuffle=True               82.6%

In (b) the batches come class by class: 64 boots in a row, the model learns "everything is a boot" and forgets it on the next batch. The first epoch's loss is even 7.09 with 10.0 % accuracy. shuffle=True fixes it all; (c) even edges past (a) — that is noise, not a conclusion.