The experiment: does augmentation help
Now run the same project with a different decision — and see what it does. We did this with our stand-in; you will do it with your own data.
Two runs
python capstone.py --no-augment --out noaug.pt --summary noaug.json
python capstone.py --augment --out aug.pt --summary aug.json
Augmentation here: a mirror flip, a rotation of up to ±10°, a shift of up to 10 % and a scale of 0.9–1.1, applied freshly every time to the training images (lesson 9). The validation and test/ images stay untouched.
This is what we got. The first line is what you saw in the previous step.
without augmentation val 95.6% TEST 93.8% (93.75 %, 400 new images)
with augmentation val 90.6% TEST 89.0%
The full report with augmentation:
epoch 1 loss 0.5118 train acc 85.6% | val loss 0.3012 val acc 90.6%
epoch 2 loss 0.2428 train acc 90.9% | val loss 0.2755 val acc 90.6%
epoch 3 loss 0.1900 train acc 93.0% | val loss 0.3039 val acc 89.4%
epoch 4 loss 0.1691 train acc 94.2% | val loss 0.4211 val acc 87.5%
early stop at epoch 4: best val loss was 0.2755
validation accuracy: 90.6%
coat pullover sneaker tshirt <- predicted
coat 27 9 1 3
pullover 0 40 0 0
sneaker 0 0 40 0
tshirt 0 2 0 38
TEST accuracy: 89.0% on 400 new images
coat pullover sneaker tshirt <- predicted
coat 72 20 2 6
pullover 1 91 0 8
sneaker 0 0 100 0
tshirt 0 6 1 93
More than two runs
These two runs still mix two things: augmentation, and the fact that with it early stopping fired sooner. So we ran all four combinations.
| run | epochs | val | test | s |
|---|---|---|---|---|
aug_stop2 — with augmentation, --patience 2 |
4 | 90.6 % | 89.0 % | 174 |
aug_8ep — with augmentation, --patience 0 --epochs 8 |
8 | 93.1 % | 92.25 % | 269 |
noaug_stop2 — without it, --patience 2 (the default) |
6 | 95.6 % | 93.75 % | 221–293 |
noaug_5ep — without it, --patience 0 --epochs 5 |
5 | 93.75 % | 94.0 % | 232 |
(Seconds are from our busy computer, ±2×.)
What the table shows
1. The "good practice" did not help here. The only row where augmentation and early stopping work together is clearly worse: validation 90.6 % against 95.6 %, new images 89.0 % against 93.75 %. The loss is about 5 points on both sets, and larger than the error of a single measurement (±2.4).
2. The loss is concentrated in one class.
coat recall dropped to 0.68 on validation (27/40) and 0.72 on new images (72/100) — without augmentation it was 0.93 and 0.88. On new images 20 coats became pullovers (without augmentation — 10). The number "89.0 %" would not say that; the matrix does.
3. Early stopping stopped early.
With augmentation the validation loss went 0.3012 → 0.2755 → 0.3039 → 0.4211: it jumps, and the stop fired after epoch 4. The same --patience 2 without augmentation allowed 6 epochs. The training curve with augmentation was still rising; we do not know whether training longer would have got us further — the row aug_8ep (no stopping, 8 epochs) shows 92.25 %, still below the non-augmented ones.
4. Do not rank the three "non-augmented" rows.
93.75 %, 93.75 % and 94.0 % differ by one new image (0.25 points), and their error is ±2.4. noaug_5ep has the highest test but a lower val — we did not choose it, and that is right.
Why? Honestly — we do not know
We did not isolate why augmentation hurts here. Plausible reasons that we can only suspect:
- these pictures are 28×28 pixel thumbnails blown up to 224: a rotation and a shift on an image that small may erase what separates a coat from a pullover;
- 160 validation images combined with early stopping is touchy: one "bad" jump in an epoch, and it stops.
It looks plausible, but it is unchecked. Other data can behave differently: in a side experiment with coloured CIFAR-10 photos a network trained from scratch got 57.5 % with augmentation instead of 52.5 % (only 160 validation images, so a hint, not a proof). The lesson is not "augmentation is bad" but "nobody can tell you whether it helps your data" — only validation can.
The default was chosen on validation
That is why capstone.py defaults to --no-augment. What matters is how that was chosen: 95.6 % against 90.6 % on validation. The new images (93.75 % against 89.0 %) said the same, but the choice would have been identical without them. Had it gone the other way — validation for augmentation, new images against — we would still have chosen on validation and simply reported that the new images disagreed.
Your turn
Do at least two runs on your data: with and without augmentation. If you like, add a third (another --lr, another --epochs). Save each with its own --out and --summary, and write down how many runs you made: that is how many times you looked at test/.
Your answer may come out different from ours: if augmentation helps your data, that is the result.