ML → Deep Learning via PyTorch — the Garment Classifier
25 min
Day 28: Dataset & DataLoader: feeding data efficiently
Getting data to the GPU without starving it
A fast GPU is useless if it sits idle waiting for data. PyTorch's Dataset and DataLoader solve this. A Dataset knows how to load one example by index (__getitem__) and how many there are (__len__). A DataLoader wraps it to yield batches, shuffle each epoch, and — crucially — load the next batch on background worker processes while the GPU chews on the current one. This is Stage 0 Day 2's generator idea, applied to training.
A custom Dataset for garment images, plus a DataLoader
from torch.utils.data import Dataset, DataLoader
from PIL import Image
class GarmentDataset(Dataset):
def __init__(self, paths, labels, transform):
self.paths, self.labels, self.transform = paths, labels, transform
def __len__(self):
return len(self.paths)
def __getitem__(self, i):
img = Image.open(self.paths[i]).convert("RGB")
return self.transform(img), self.labels[i]
loader = DataLoader(
GarmentDataset(paths, labels, transform),
batch_size=32, shuffle=True, num_workers=4, pin_memory=True,
)Batch size, shuffling, and why they matter
- Batch size trades off: larger batches use the GPU more efficiently and give smoother gradients, but need more memory and can generalize slightly worse.
- Shuffling each epoch prevents the model from learning the *order* of the data instead of the pattern.
num_workersparallelizes data loading;pin_memory=Truespeeds up the CPU→GPU transfer (that H2D copy from Day 26).
Key terms
- Dataset
- A class defining how to fetch one example by index and how many exist — the __getitem__/__len__ contract.
- DataLoader
- Wraps a Dataset to yield shuffled batches, using background workers to overlap loading with GPU compute.
- Batch
- A group of examples processed together in one forward/backward pass.
- Epoch
- One full pass through the entire training dataset.
Why does a DataLoader use num_workers > 0 (background worker processes)?