Module 5 Setup (Check This First)
Module 5 runs on the machine Module 4 left: a Unix terminal (WSL on Windows), uv, Python 3.12.8 inside the (bootcamp) environment at ~/dev/bootcamp, VS Code opened on that folder with the Python extension, and in (bootcamp) the libraries Modules 2 to 4 installed, PyTorch and torchvision among them at the processor-only builds Module 4 put there. It also runs on what Section 4.5 left in ~/dev/bootcamp: FashionMNIST in the data folder, the three files fashion.py, image_loop.py and trained.py, and the two models Lesson 4.5.2 saved, because Section 5.1 imports those files and loads those models instead of building them again. This page confirms the machine, rebuilds Section 4.5's files and models if you are starting here, says where Module 5's own files go and which lesson installs its one new library, and ends with a checklist that must pass before Lesson 5.1.1.
By the end of this page you will have:
- Confirmed that
(bootcamp)answers with Python 3.12.8 and holds PyTorch 2.14.1 and torchvision 0.29.1 beside the libraries Module 5 imports - FashionMNIST,
fashion.py,image_loop.py,trained.py,fashion_mlp.ptandfashion_linear.ptin~/dev/bootcamp, the last two scoring what Section 4.5 scored - Module 3's
listings.csvand Lesson 4.3.1'sprep_net.pyin~/dev/bootcamp, which Lesson 5.4.3 reads - The lesson that installs Module 5's one new library
If you are starting here
Module 5 assumes every step of Module 0's setup page and the libraries Modules 2 to 4 install. If you skipped the earlier modules because you already train networks in PyTorch, do that page first, start to finish. Then, in ~/dev/bootcamp with (bootcamp) active, install the five libraries Module 5 imports beside PyTorch, then PyTorch and torchvision from PyTorch's own index of processor-only builds, at the versions every Module 5 result came from:
uv pip install numpy==2.5.2 pandas==3.0.5 python-dateutil==2.9.0.post0 matplotlib==3.11.1 scikit-learn==1.9.1 scipy==1.18.1
uv pip install torch==2.14.1 torchvision==0.29.1 --index-url https://download.pytorch.org/whl/cpuThe first line adds 18 libraries in a fresh (bootcamp), the six named and what they need, and the second 11, torch==2.14.1+cpu and torchvision==0.29.1+cpu among them, each as a + line. Module 4's setup page explains the processor-only build and the index, and what to do on a Mac with an Intel processor, which runs Modules 4 to 6 on Ubuntu.
Lesson 5.4.3 also reads Module 3's dataset through Lesson 4.3.1's prep_net.py. Module 4's setup page shows where the course's listings.csv download goes, ~/dev/bootcamp, and prep_net.py is the first block of Lesson 4.3.1, saved there under that name.
Section 5.1 starts from Section 4.5's three files and its two trained models. Save each block below in ~/dev/bootcamp under the name above it. fashion.py downloads FashionMNIST into a folder named data the first time it runs, about 85 MB with its archives, and reads it from there after that, and it splits the training images into the 50,000 the networks fit and the 10,000 that choose between them:
fashion.py
import torch
from torch.utils.data import DataLoader, random_split
from torchvision import datasets, transforms
train_full = datasets.FashionMNIST("data", train=True, download=True, transform=transforms.ToTensor())
test_set = datasets.FashionMNIST("data", train=False, download=True, transform=transforms.ToTensor())
# 50,000 images to fit, 10,000 to choose on, the same draw every run
train_set, val_set = random_split(train_full, [50_000, 10_000], generator=torch.Generator().manual_seed(42))
train_loader = DataLoader(train_set, batch_size=64, shuffle=True, generator=torch.Generator().manual_seed(42))
val_loader = DataLoader(val_set, batch_size=1000)
test_loader = DataLoader(test_set, batch_size=1000)
if __name__ == "__main__":
print(len(train_set), len(val_set), len(test_set))
print(len(train_loader), len(val_loader), len(test_loader))image_loop.py, the loss, the fully connected network, the accuracy and one epoch of the loop:
import torch
from torch import nn
loss_fn = nn.CrossEntropyLoss()
def mlp():
torch.manual_seed(42)
return nn.Sequential(nn.Flatten(), nn.Linear(784, 128), nn.ReLU(), nn.Linear(128, 10))
def accuracy(model, loader):
model.eval()
correct = total = 0
with torch.no_grad():
for x, y in loader:
correct += (model(x).argmax(dim=1) == y).sum().item()
total += len(y)
model.train()
return correct / total
def train_epoch(model, optimizer, loader):
total = 0.0
for x, y in loader:
loss = loss_fn(model(x), y)
loss.backward()
optimizer.step()
optimizer.zero_grad()
total += loss.item() * len(y)
return total / len(loader.dataset)train_mlp.py, which trains the fully connected network for five epochs and saves it:
import torch
from torch import optim
from fashion import train_loader, val_loader
from image_loop import accuracy, mlp, train_epoch
model = mlp()
optimizer = optim.Adam(model.parameters(), lr=0.001)
for epoch in range(1, 6):
train_loss = train_epoch(model, optimizer, train_loader)
print(epoch, f"{train_loss:.4f}", f"{accuracy(model, val_loader):.4f}")
torch.save(model.state_dict(), "fashion_mlp.pt")train_linear.py, which trains the linear model the same way, in a script of its own so that it reads the same five shuffles of train_loader the network read:
import torch
from torch import nn, optim
from fashion import train_loader, val_loader
from image_loop import accuracy, train_epoch
torch.manual_seed(42)
linear = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))
optimizer = optim.Adam(linear.parameters(), lr=0.001)
for epoch in range(1, 6):
train_loss = train_epoch(linear, optimizer, train_loader)
print(epoch, f"{train_loss:.4f}", f"{accuracy(linear, val_loader):.4f}")
torch.save(linear.state_dict(), "fashion_linear.pt")trained.py, which builds both models and loads what the two scripts saved:
import torch
from torch import nn
from fashion import test_loader
from image_loop import mlp, accuracy
network = mlp()
network.load_state_dict(torch.load("fashion_mlp.pt", weights_only=True))
network.eval()
linear = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))
linear.load_state_dict(torch.load("fashion_linear.pt", weights_only=True))
linear.eval()
if __name__ == "__main__":
# 0.1173
print(f"{accuracy(mlp(), test_loader):.4f}")
# 0.8677 0.8372
print(f"{accuracy(network, test_loader):.4f}", f"{accuracy(linear, test_loader):.4f}")Run the two training scripts in this order, each of which took under a minute on the machine the lessons were run on:
python3 train_mlp.py
python3 train_linear.py1 0.5727 0.8342
2 0.4132 0.8627
3 0.3705 0.8645
4 0.3439 0.8695
5 0.3224 0.8725
1 0.6700 0.8169
2 0.4895 0.8389
3 0.4551 0.8454
4 0.4375 0.8431
5 0.4243 0.8510The first five lines are the network's epochs, the training loss and the validation accuracy, and the last five the linear model's. These are the figures of the machine the lessons were run on, on the eight threads PyTorch used there, and a machine whose processor gives PyTorch another number of threads can print other last digits from the fourth epoch on, as Lesson 4.5.2 shows. The run that produces them is the same either way, and your later lessons' figures are then your machine's.
Where Module 5 runs
Every lesson, lab and capstone in this module runs on your processor, and nothing needs a graphics card. Section 5.1's longest runs train a small convolutional network for five epochs, and each finished in under two minutes on the machine the lessons were run on, where your machine takes its own time. Module 4's setup page covers the processor-only build of PyTorch every number came from and the Ubuntu route for a Mac with an Intel processor, and both hold for Module 5 unchanged.
Where Module 5's files live
Every script a Module 5 lesson asks you to write goes straight into ~/dev/bootcamp beside Section 4.5's files, saved under the exact name the lesson gives it, and runs from there with python3 followed by that name, as in Module 4, so a traceback names it by its full path, /home/goku/dev/bootcamp/ and the name, /Users/goku/ on macOS. Section 5.1 saves files that its later lessons import or load, blocks.py, cnn.py, augment.py and the trained networks fashion_cnn.pt and fashion_cnn_aug.pt, so each lesson of the section runs after the ones before it. Every chart a lesson saves as a .png file lands beside your scripts.
Section 5.1 teaches on FashionMNIST, already in data. Each later section names its own data in the lesson that first uses it, so there is nothing else to fetch now.
DON'T:
- DON'T move
dataor renamefashion.py,image_loop.pyortrained.py. Every Section 5.1 script imports them by those names from the folder it runs in, andfashion.pyreads the images fromdataby that name. - DON'T retrain the two Section 4.5 models with changed settings. Section 5.1 sets its networks beside their scores, 0.8677 and 0.8372 on the test images, and two other models change every comparison.
Installing into (bootcamp)
Module 5 installs the way Module 4 did, with uv pip install, (bootcamp) active and an exact version after ==, in the lesson that first uses the library.
| Library | Version | Installed in |
|---|---|---|
| transformers, Hugging Face's library of pretrained models, with tokenizers | 5.20.2, 0.23.3 | Lesson 5.4.1 |
Sections 5.1 to 5.3 install nothing: they run on PyTorch and torchvision, which Module 4 installed, and Section 5.3 reads its data with pandas, which Module 2 installed.
Every session starts the same way
Open VS Code on ~/dev/bootcamp, open its built-in terminal, and look at the prompt. It must start with (bootcamp). If it does not, activate the environment:
cd ~/dev/bootcamp && source .venv/bin/activateSetup checklist (pass ALL of these before Lesson 5.1.1)
Open a fresh terminal, then run:
cd ~/dev/bootcamp
source .venv/bin/activate
python3 --version # Python 3.12.8
# /home/goku/dev/bootcamp/.venv/bin/python3 (macOS: /Users/goku/dev/bootcamp/.venv/bin/python3)
which python3
uv pip list # the list below
ls data/FashionMNIST/raw
python3 trained.pyls prints the four FashionMNIST files and their four archives:
t10k-images-idx3-ubyte
t10k-images-idx3-ubyte.gz
t10k-labels-idx1-ubyte
t10k-labels-idx1-ubyte.gz
train-images-idx3-ubyte
train-images-idx3-ubyte.gz
train-labels-idx1-ubyte
train-labels-idx1-ubyte.gzpython3 trained.py prints the untrained network's score on the test images, then the two saved models':
0.1173
0.8677 0.8372uv pip list prints, on a machine that did every install of Modules 2 to 4 and nothing else:
Package Version
----------------- -----------
cloudpickle 3.1.2
contourpy 1.4.0
cycler 0.12.1
et-xmlfile 2.0.0
filelock 4.2.4
fonttools 4.68.0
fsspec 2026.9.0
jinja2 3.1.6
joblib 1.6.0
kiwisolver 1.5.1
markupsafe 3.0.3
matplotlib 3.11.1
mpmath 1.3.0
narwhals 2.28.0
networkx 3.7
numpy 2.5.2
openpyxl 3.1.5
packaging 26.3
pandas 3.0.5
pillow 13.0.0
pyparsing 3.3.3
python-dateutil 2.9.0.post0
scikit-learn 1.9.1
scipy 1.18.1
seaborn 0.13.2
setuptools 78.1.0
six 1.17.0
sympy 1.14.0
threadpoolctl 3.7.0
torch 2.14.1+cpu
torchvision 0.29.1+cpu
typing-extensions 4.16.0
xgboost-cpu 3.4.1Your prompt must show (bootcamp) the whole time, and every line of Module 0's setup checklist must still pass as well. In the list, the eight libraries Module 5 runs on must read exactly as shown, numpy 2.5.2, pandas 3.0.5, python-dateutil 2.9.0.post0, matplotlib 3.11.1, scikit-learn 1.9.1, scipy 1.18.1, torch 2.14.1+cpu and torchvision 0.29.1+cpu, the last two reading 2.14.1 and 0.29.1 on a Mac. openpyxl, seaborn and xgboost-cpu belong to Modules 2 and 3, no Module 5 lesson imports them, and their lines may be missing if you started here. The other lines are libraries those need, installed with them and never pinned, so their versions, and which of them appear, can differ on your machine. If ls reports that data/FashionMNIST/raw does not exist, fashion.py has not run in this folder yet, and python3 fashion.py downloads the files and prints 50000 10000 10000 and 782 10 10. If trained.py raises FileNotFoundError, one of the two .pt files is missing, and the training script that writes it is under If you are starting here. If its second line prints other last digits, the two models were trained on another number of threads, and the lessons still run. Do not start Lesson 5.1.1 until every line passes.