A fixed learning rate rarely works for the entire training run: large rates help early exploration; small rates fine-tune near minima. Learning rate schedulers adjust LR automatically by epoch or validation feedback.
Module 6.1 introduced the learning rate hyperparameter; this lesson automates its schedule inside the training loop.
param_groups[0]["lr"].Learning Objectives
By the end of this lesson, students should be able to:
- Attach a PyTorch scheduler to an optimizer and call
scheduler.step()correctly. - Use
StepLR,ReduceLROnPlateau, andCosineAnnealingLR. - Distinguish schedulers stepped per epoch vs per batch.
- Log current LR each epoch for debugging plateau behavior.
- Save and restore
scheduler_state_dictin checkpoints. - Match scheduler choice to training duration and architecture scale.
Common PyTorch Schedulers
| Scheduler | When LR changes | Best for |
|---|---|---|
StepLR | Every N epochs, multiply by gamma | Simple staged decay |
ReduceLROnPlateau | When val metric stalls | Adaptive fine-tuning |
CosineAnnealingLR | Smooth cosine decay per epoch | Modern CNN/ViT training |
OneCycleLR | Per batch (warmup + decay) | Fast convergence (see Warmup lesson) |
StepLR and CosineAnnealingLR
Time-based schedulers step once per epoch after training (and usually after validation). Read LR from the optimizer for logging.
ReduceLROnPlateau
Metric-driven scheduler steps on validation loss, not blindly by epoch. Pass the metric to scheduler.step(val_loss).
scheduler.step() SignatureReduceLROnPlateau.step(val_loss) needs the metric. Calling it with no args does nothing useful. Conversely, do not pass val_loss to StepLR—it takes no arguments.
Checkpointing Scheduler State
Resumed training must restore scheduler internal counters (last epoch, bad epochs in plateau). Include scheduler.state_dict() in checkpoints.
When validation stalls, the first question is “what was the learning rate?” TensorBoard/WandB LR curves catch silent scheduler bugs.
Knowledge Check
- Short Answer: Why decay learning rate during training? Answer: Large steps early, small steps for fine convergence near minima.
- True/False:
ReduceLROnPlateausteps every epoch regardless of metrics. Answer: False—steps when metric stops improving. - Multiple Choice:
CosineAnnealingLRLR shape: (a) linear, (b) cosine, (c) random. Answer: (b). - Short Answer: Where do you read current LR? Answer:
optimizer.param_groups[0]["lr"]. - Short Answer:
StepLR(step_size=10, gamma=0.1)effect? Answer: Multiply LR by 0.1 every 10 epochs. - True/False: Scheduler state should be in checkpoints. Answer: True when resuming training.
- Multiple Choice: After validation, for StepLR you call: (a)
scheduler.step(), (b)scheduler.step(val_loss), (c)optimizer.zero_grad(). Answer: (a). - Short Answer: What does
factor=0.5mean in ReduceLROnPlateau? Answer: Halve LR when triggered. - Short Answer:
eta_minin cosine annealing? Answer: Minimum LR at end of cycle. - Multiple Choice: OneCycleLR steps per: (a) epoch only, (b) batch, (c) never. Answer: (b).
Key Takeaways
- Schedulers modulate LR by time (Step, Cosine) or validation feedback (Plateau).
- Call the correct
step()signature; log LR every epoch. - Persist scheduler state when checkpointing long runs.
- Next: Warmup—ramp LR up before decay.
Hands-on idea: Train the same model with constant LR vs cosine schedule; overlay validation curves.
Discussion prompt: When is a fixed LR acceptable (e.g. fine-tuning last layer only)?