Code

The data split — fill in two holes

Everything real that you learn in this lesson depends on two lines: where to cut. If validation images leak into training, every later number is a lie — and nobody will notice.

How we split

The FashionMNIST training file has 60 000 images. We cut it:

0 ……………………………… 49 999 | 50 000 …………………… 59 999
          training               validation

The official 10 000 test images are touched only at the very end. In this lesson we touch them once — in step 7, to show why they must not be used for decisions.

load_fashion already has three "split" names. Now it takes two from the training file:

split what it returns
"train" images 0 … 49 999
"val" images 50 000 … 59 999
"test" the official 10 000 (a different file)

The n parameter still means "the first n of what the split returned".

Your job

The fashion.py file has grown: the docstring describes the three splits, and train=(split == "train") was changed to train=(split != "test") — so that "val" also takes its images from the training file. The new test_fashion.py is the verdict.

Two holes, both in the same if/elif:

  • HOLE 1 — "train": keep only images 0 … 49 999 (and their labels y!).
  • HOLE 2 — "val": keep only 50 000 … 59 999.

Both are one-liners, similar to what you already do with n.

Run the test before filling anything in

$ python -m unittest test_fashion
FAIL: test_n_takes_the_first_n_of_the_split
AssertionError: False is not true : val[0] is not image 50 000
FAIL: test_train_is_the_first_50000_images
AssertionError: 60000 != 50000
FAIL: test_train_starts_at_image_0_and_ends_at_image_49999
AssertionError: False is not true : train[-1] is not image 49 999
FAIL: test_val_is_the_last_10000_images
AssertionError: 60000 != 10000
FAIL: test_val_starts_at_image_50000_so_nothing_is_shared_with_train
AssertionError: False is not true : val[0] is not image 50 000
Ran 6 tests in 0.4s

FAILED (failures=5)

The skeleton cuts nothing: both "train" and "val" return all 60 000. That is exactly the mistake this lesson is afraid of: the two sets coincide completely, and the "validation accuracy" would measure the same images it trained on.

Fill both holes — OK, 6 tests.

When it does not pass

  • val[0] is not image 50 000, but the lengths are right (10 000) — you took the wrong ten thousand. For example x[:10_000]: the size fits, but those are the first images, which are already in training. The sneakiest mistake — the sizes are right, only the content is not.
  • 55000 != 50000 — training "slid" too far and stepped onto validation.
  • 60000 != 50000, but x is already cut — you cut x but forgot y. There are 50 000 images and still 60 000 labels. x, y = x[...], y[...] changes both.