Skip to content
ELECTRONICS ENGINEERINGelectronics-engineering.com
Machine Learning and Neural Networks

Optimisers: SGD, momentum, RMSProp and Adam with bias correction

Mini-batch stochastic gradient descent, momentum, RMSProp, Adam and the bias correction proved, AdamW, warm-up and step decay, comparison of the methods on the Rosenbrock function.

https://www.electronics-engineering.com/en/optimisers-sgd-momentum-adam-rosenbrock/

No ratings yet: be the first to rate this page.

The gradient descent of lesson 1 works, but on neural networks it is slow: the error surface has narrow, long valleys, flat regions and millions of dimensions with very different curvatures. Modern optimisers modify the update rule to go faster and more stably. This lesson presents mini-batch stochastic gradient descent, momentum, RMSProp and Adam (the most used optimiser), proves why Adam needs the “bias correction”, discusses the choice of step size over time, and compares the methods on the Rosenbrock function, a curved valley that is the classic test bench.

Stochastic gradient descent

The gradient of the loss is an average over all n examples. With millions of examples, computing it entirely at each step is a waste. Stochastic gradient descent (SGD) uses at each step a mini-batch B of a few tens or hundreds of examples drawn at random:

    \[ \mathbf g_k = \frac{1}{|B|}\sum_{i\in B}\nabla\ell_i(\mathbf w_k),\qquad \mathbf w_{k+1} = \mathbf w_k - \eta\,\mathbf g_k \]

\mathbf g_k is an unbiased estimate of the true gradient (the mean of a random sample has the population mean as its expectation), with a variance that decreases as 1/|B|. The noise is not only a defect: it helps to escape flat regions and, according to many studies, leads to “wider” minima that generalise better. A complete pass over the data is called an epoch.

Momentum

In a narrow valley the gradient points mostly towards the walls: descent bounces from side to side and advances slowly along the bottom. Momentum (Polyak, 1964: the “heavy ball method”) accumulates a velocity:

    \[ \mathbf v_{k+1} = \beta\,\mathbf v_k + \mathbf g_k,\qquad \mathbf w_{k+1} = \mathbf w_k - \eta\,\mathbf v_{k+1} \]

with \beta \approx 0.9. The gradient components that change sign at every step (across the valley) cancel in the average; those that always have the same sign (along the valley) add up. If the gradient were constant, the velocity would tend to \mathbf g/(1 - \beta): with \beta = 0.9 a step ten times longer in the good direction.

RMSProp and Adam: one step size per parameter

Different parameters can have gradients of very different scales (for example the weights of the first layers and those of the last). RMSProp (Hinton, 2012) divides each parameter’s step by a moving average of the root of its squared gradient: those with large gradients take shorter steps, those with small ones longer steps. Adam (Kingma and Ba, 2014) combines this idea with momentum:

    \[ \mathbf m_k = \beta_1\mathbf m_{k-1} + (1 - \beta_1)\mathbf g_k,\qquad \mathbf s_k = \beta_2\mathbf s_{k-1} + (1 - \beta_2)\mathbf g_k^2 \]

    \[ \hat{\mathbf m}_k = \frac{\mathbf m_k}{1 - \beta_1^k},\qquad \hat{\mathbf s}_k = \frac{\mathbf s_k}{1 - \beta_2^k},\qquad \mathbf w_{k+1} = \mathbf w_k - \eta\,\frac{\hat{\mathbf m}_k}{\sqrt{\hat{\mathbf s}_k} + \epsilon} \]

with the default values \beta_1 = 0.9, \beta_2 = 0.999, \epsilon = 10^{-8}. The effective step is almost independent of the gradient’s scale: it is about \eta in the direction of the sign of the average gradient.

Theorem (bias correction). If the gradients have constant mean \mathbb E[\mathbf g_i] = \mathbf g and \mathbf m_0 = 0, then \mathbb E[\mathbf m_k] = (1 - \beta_1^k)\,\mathbf g; so \hat{\mathbf m}_k has mean exactly \mathbf g.

Proof. Unrolling the recursion, \mathbf m_k = (1 - \beta_1)\sum_{i=1}^k\beta_1^{k-i}\mathbf g_i. Taking the mean, \mathbb E[\mathbf m_k] = (1 - \beta_1)\,\mathbf g\sum_{j=0}^{k-1}\beta_1^j = (1 - \beta_1)\frac{1 - \beta_1^k}{1 - \beta_1}\mathbf g = (1 - \beta_1^k)\,\mathbf g. The same holds for \mathbf s_k with \beta_2. ∎

Without correction, in the first steps \mathbf m and \mathbf s would be very close to zero (they start from zero) and, especially with \beta_2 = 0.999, the denominator would be underestimated: the first steps would be huge. After a few thousand steps \beta^k \approx 0 and the correction no longer matters. AdamW (2017) separates the weight penalty (weight decay) from the adaptive step, and is today the default choice for transformers.

The step size over time

A large constant step advances quickly but at the end “dances” around the minimum; a small one is precise but slow. This is why the step size is varied during training:

  • warm-up: for a few hundred or thousand steps the step grows from zero to its full value, while Adam’s estimates settle and the network leaves the chaotic initial phase;
  • decay: linear, stepwise, or cosine (the step follows half a cosine period down to almost zero). It was also seen in the PPO of the reinforcement learning course: the step decreasing to zero stabilised the final policy.

The comparison on the Rosenbrock function

The function f(x, y) = (1 - x)^2 + 100(y - x^2)^2 has its minimum at (1, 1) at the bottom of a narrow, curved, banana-shaped valley: at the bottom of the valley the gradient is almost zero, on the walls huge. Starting from (−1.5, 2), we count how many steps are needed to reach f \lt  10^{-6}:

methodstep \etasteps for f \lt  10^{-6}
gradient descent0.00115,681
momentum (\beta = 0.9)0.0011,484
Adam0.022,286
The trajectories of the three methods on the Rosenbrock function
The grey level curves draw the banana valley; the star is the minimum at (1, 1). The three trajectories, gradient descent dashed black, momentum blue and Adam orange, go straight to the bottom of the valley and then follow it to the minimum, the black dot being the start. The path is almost the same: what changes is the number of steps to travel it, almost 16 thousand for gradient descent, fewer than 1500 for momentum.

Momentum is about ten times faster than plain descent (15,681 / 1,484 = 10.6), as predicted by the factor 1/(1 - \beta) = 10. Adam, with a step that does not depend on the gradient’s scale, arrives in a similar number of steps. On real neural networks the differences are often less clear-cut and depend on the problem: SGD with momentum is still widely used for convolutional networks, Adam and AdamW for transformers and recurrent networks. The choice of step size almost always matters more than the choice of optimiser.

import numpy as np

f = lambda p: (1 - p[0]) ** 2 + 100 * (p[1] - p[0] ** 2) ** 2
grad = lambda p: np.array([-2 * (1 - p[0]) - 400 * p[0] * (p[1] - p[0] ** 2), 200 * (p[1] - p[0] ** 2)])

def optimise(method, eta, steps=20000):
    p, v, m, s = np.array([-1.5, 2.0]), np.zeros(2), np.zeros(2), np.zeros(2)
    for k in range(1, steps + 1):
        g = grad(p)
        if method == "gradient":
            p = p - eta * g
        elif method == "momentum":
            v = 0.9 * v + g
            p = p - eta * v
        else:                                              # Adam
            m = 0.9 * m + 0.1 * g
            s = 0.999 * s + 0.001 * g * g
            m_hat, s_hat = m / (1 - 0.9 ** k), s / (1 - 0.999 ** k)     # bias correction
            p = p - eta * m_hat / (np.sqrt(s_hat) + 1e-8)
        if f(p) < 1e-6:
            return k
    return None

for method, eta in (("gradient", 1e-3), ("momentum", 1e-3), ("adam", 2e-2)):
    print(f"{method:9s}: f < 1e-6 after {optimise(method, eta)} steps")
Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
1
0
Would love your thoughts, please comment.x
()
x