Thomas Piacentini
← Workshop

Python exercise

Sweep the learning rate

Original text · English20 min

The learning rate decides if gradient descent converges, crawls or blows up. A rate sweep is the first experiment on any new model: train with each rate, keep the final loss, and pick the rate. In this lab you run the sweep on a small linear regression and compare the result with the bound that theory gives.

support.py gives the data, the grid of rates and the trainer. make_regression(seed) returns X of shape (64, 4) and y of shape (64,). train(X, y, lr, steps) runs full batch gradient descent on the mean squared error from w = 0. It returns the loss before each step and after the last step, an array of steps + 1 values. When the loss passes 1e10, the trainer stops and fills the rest of the curve with inf.

Task

Write five helper functions and answers().

  1. run_sweep(X, y, lrs, steps=STEPS) returns a float array of shape (len(lrs), steps + 1). Row i is train(X, y, lrs[i], steps).
  2. is_diverged(losses) returns True when the final loss is not finite or is larger than the first loss. Otherwise it returns False.
  3. best_lr(lrs, curves) returns the rate with the lowest final loss among the runs that did not diverge. If two runs have the same final loss, return the smaller rate. If every run diverged, return None.
  4. smallest_diverging_lr(lrs, curves) returns the smallest rate, by value, whose run diverged. If no run diverged, return None.
  5. stability_bound(X) returns 2 / \lambda_{max}, where \lambda_{max} is the largest eigenvalue of the Hessian H = \frac{2}{n} X^T X of the mean squared error.

Then do the experiment in answers().

  1. Make the data with make_regression(seed=0).
  2. Change the learning rate over LEARNING_RATES. Train each rate for STEPS steps.
  3. Measure the final loss of each run. Report the best rate as best_lr and its final loss as best_final_loss.
  4. Report the smallest rate that diverged as smallest_diverging_lr.
  5. Compute the theory bound on the same X. Report it as stability_bound.

Input and output

Name Type Shape Meaning
X float array (n, d) the inputs, one row for each example
y float array (n,) the targets
lrs list of floats (k,) the learning rates, in any order
steps int scalar the number of gradient steps
losses float array (steps + 1,) one loss curve
curves float array (k, steps + 1) one loss curve for each rate, in the order of lrs
  • run_sweep returns a float array of shape (k, steps + 1).
  • is_diverged returns a bool.
  • best_lr and smallest_diverging_lr return one element of lrs or None.
  • stability_bound returns a float.
  • answers() returns a dict with the four keys above. Each value is a Python float.

Constraints

  • A curve can hold inf or nan.
  • Do not change the input arrays.
  • Do not round the answers. The checks accept a relative difference of 1e-6 from the reference run.
  • Use numpy and the standard library only.

Examples

python
is_diverged(np.array([1.0, 2.0, 3.0]))
text
True
python
best_lr([0.1, 0.2, 0.3], np.array([[1.0, 0.5], [1.0, 0.2], [1.0, np.inf]]))
text
0.2
python
stability_bound(np.array([[1.0, 0.0], [0.0, 2.0]]))
text
0.5
python
X, y = make_regression(0)
train(X, y, 0.1, 3)
text
[3.95117454 0.8025197  0.6543398  0.57749216]
Code and artifacts 14
What you take away

Saved in your notebook on this device.

Sources and limits

Reading checkpoints are self-reported. Test results are recorded separately and apply to the executed cases.

AI Engineering from Scratch · 3f9715c · MIT

Download this file ↓