The problem
Plain SGD (stochastic gradient descent) moves every weight against the gradient of the current mini-batch. That gradient is noisy, so the path zigzags. Momentum smooths it: it keeps a running direction, the velocity, built from all the recent gradients, and moves the weights along that instead.
You will implement one step of SGD with momentum, in the form used by PyTorch's torch.optim.SGD.
One step, in two lines
First update the velocity, then move the weights with the new velocity:
where:
- (theta) is the parameter array
param, and its gradientgrad; - is the velocity
velocity, with the same shape asparam, and all zeros before the first step; - (eta) is the learning rate
lr; - (mu) is
momentum, usually : the share of the old velocity that is kept; - means "replace with".
In words: the new velocity is 90% of the old one plus the current gradient, and the parameters move a step of size lr against it.
Example. One parameter,
lr = 0.1,momentum = 0.9, starting atparam = 1.0withvelocity = 0.0. Three steps:
step gradnew velocity new param 1 0.5 2 0.5 3 In step 2 the same gradient moves the parameter almost twice as far as in step 1: the velocity has built up. In step 3 the gradient changes sign, but the velocity is still positive, so the parameter keeps going down, only more slowly: one noisy gradient does not reverse the direction.
With momentum = 0 the velocity is just the current gradient, and this is plain SGD.
What to implement
sgd_momentum_step(param, grad, velocity, lr, momentum=0.9): return the pair (new_param, new_velocity).
Requirements
- Do not modify the input arrays: return new ones. (Real optimizers update in place for speed; here returning values makes each step easy to test.)
momentum=0must be plain SGD.- Works for parameters of any shape.
Hint
The learning rate multiplies the velocity, not the gradient. The form , then , is the one of Sutskever et al. (2013): a fine method, but not the one asked for here. The theory page explains when the two differ.