Everything in this track, in one script
This is the capstone: a complete vision pipeline that folds together every piece you've learned in this track. Preprocessing as layers (lesson 1), augmentation that's on for training and off for inference (lesson 2), a backend-agnostic fit() (lesson 3), and a folder-loaded dataset with cache/prefetch (lesson 4) — all collapsed into one model definition plus one fit() call.
Why the preprocessing lives inside the model
Look at where Rescaling and the augmentation block sit: they're the first layers, ahead of any Conv2D. That placement is the whole point. The model now expects raw [0, 255] images as input and does its own normalization internally. There's no separate preprocessing script to keep in sync, and no chance of train/serve skew — the saved .keras file is the preprocessing. Augmentation, being a Random* block, automatically goes quiet at inference, so production sees clean rescaling and nothing else.
Deploy = copy one file
Because the transform travels with the weights, deployment is as boring as it should be: copy the .keras file to the serving box, keras.saving.load_model(), and call predict() on raw images. No preprocessing code ships alongside it, no environment to reproduce, no drift. That's the engineering payoff of treating data as a first-class part of the model rather than a script bolted on the side.