Code

Real pictures: fashion.py and the first run

The tests pass — all six of your functions are correct. Now run them on real pictures.

Two files in this step, and both are already complete — they are not your task.

fashion.py — loading the data

The whole point of it is one call and one line of arithmetic:

ds = datasets.FashionMNIST(DATA_ROOT, train=(split == "train"), download=True)
x, y = ds.data, ds.targets      # x: [N, 28, 28] uint8
...
return x.reshape(len(x), -1).float() / 255.0, y
  • download=True — the first time it downloads the set (about 31 MB) into a downloads/ folder, later it finds it there.
  • x.reshape(len(x), -1) — your flatten_batch, only ready-made: [N, 28, 28] → [N, 784].
  • .float() / 255.0 — from uint8 0–255 to float32 0–1. You saw the same division in step 2.
  • n=... — take only the first n images. From lesson 3 on we use n=10_000, so every script runs in seconds.

The function returns (x, y): x is [n, 784] of type float32, y is [n] of type int64 (the class number 0–9). The file also holds CLASSES, the ten names.

What you may need to get this running

  • ModuleNotFoundError: No module named 'torchvision' — pip install torchvision into the same environment where you installed torch (the same story you met in lesson 1 with torch). fashion.py uses it only to download the data. Pillow, which you need in the homework, comes with it.
  • Python version. fashion.py uses the int | None notation, so you need Python 3.10 or newer.
  • The first run prints a long line of percentages (0.1%0.2%...) — that is the download. Silent afterwards.

tensors_demo.py — now complete

The right-hand panel now shows the complete version of your file: holes filled, functions written, and at the bottom image_demo() and main(). Compare it with yours — if the tests passed, it should look alike.

Three things were added:

  • from fashion import CLASSES, load_fashion at the top;
  • image_demo() — takes one picture and prints its shape and label;
  • main() — calls everything you wrote and prints what you saw in step 2.

Run it

python tensors_demo.py

You should see (the first time, download percentages come before this):

shape: torch.Size([2, 3]) dtype: torch.float32 device: cpu
a * 2 + 1 = tensor([[ 3.,  5.,  7.],
        [ 9., 11., 13.]])
a + row = tensor([[11., 22., 33.],
        [14., 25., 36.]])
a @ w = tensor([[-1.],
        [-1.]])
loss: 9.0
w.grad: -12.0 b.grad: -6.0
image shape: torch.Size([28, 28]) label: 9 Ankle boot
pixel range: 0.0 to 1.0
flattened for a neuron: torch.Size([784])

Every value matches the tables of step 2 — only now your code produced them. The last three lines are no longer from small numbers but from a real picture: [28, 28], label 9 (Ankle boot), [784].

Run the tests too — there are 11 now, since two about load_fashion were added:

$ python -m unittest
...........
----------------------------------------------------------------------
Ran 11 tests in 0.074s

OK

(The first time they take longer — the download.)