Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Adaptive moment estimation optimizer

Until now, we have used the stochastic gradient descent (SGD) optimizer to update parameters. Its logic is very simple: multiply the gradient by a fixed learning rate, and that is it.

But it has a flaw: one size fits all. All the parameters share one learning rate, and it never changes from start to finish. In practice, different parameters, and different stages of training, need different step sizes:

  • Some parameters always have large gradients and others always have small ones. With the same learning rate, the large ones tend to overshoot and the small ones barely move;

  • In the early stage of training we can usually take bold steps, while near convergence we need to fine-tune carefully.

In this chapter, we introduce a smarter optimizer: the adaptive moment estimation (Adam) optimizer. It adjusts the effective step size of each parameter individually. Put simply: when the gradient has stayed small for a long time, Adam increases the effective step size; when the gradient has stayed large for a long time, Adam decreases it. Adam is the most commonly used optimizer for training neural network models today.

Tensor

Dataset

Abstract class

Character-encoding dataset

Model

Abstract layer

Linear layer

Composite layer

Sequential layer

Embedding layer

Activation functions

Hyperbolic tangent (Tanh)

Loss functions

Abstract class

Cross-entropy loss function

Optimizers

Before introducing the new optimizer, we also first extract an abstract class for optimizers.

Abstract class

The abstract class defines two methods:

  • step (step method): an abstract method that updates all the parameters from the gradients;

  • zero_grad (zero-gradient method): zeroes the gradients of all the parameters before each iteration.

Stochastic gradient descent optimizer

We also change the existing stochastic gradient descent optimizer to inherit from the abstract class. It only needs to implement the step method.

Adaptive moment estimation optimizer

The moment in the name of the adaptive moment estimation optimizer refers to two statistics of the gradient. Adam maintains two moments for each parameter individually:

  • mm (the first moment): the exponentially weighted moving average (EWMA) of the gradient. It acts like inertia on the gradient, making the update direction smoother so that it is not thrown off by a single random fluctuation;

  • vv (the second moment): the exponentially weighted moving average of the squared gradient, which reflects the magnitude of the gradient. For a parameter whose gradient is always large, vv is large and the actual step size is automatically reduced; conversely, for a parameter whose gradient is always small, vv is small and the actual step size is automatically enlarged.

Exponentially weighted moving average

The purpose of a weighted moving average is to make the changes of the gradient (or the squared gradient) smoother. The formulas are:

mt=β1mt−1+(1−β1)gtm_t = \beta_1 m_{t-1} + (1 - \beta_1)g_t
vt=β2vt−1+(1−β2)gt2v_t = \beta_2 v_{t-1} + (1 - \beta_2){g_t}^2

Where:

  • mtm_t, vtv_t: the exponentially weighted averages at the current step tt;

  • mt−1m_{t-1}, vt−1v_{t-1}: the exponentially weighted averages at the previous step (step t−1t-1);

  • gtg_t, gt2g_t^2: the current gradient and squared gradient;

  • β1\beta_1, β2\beta_2: the decay rates of the gradient (hyperparameters, usually 0.9 and 0.999), which decide the weight given to past information.

Step size scaling

When updating, mm decides the direction, and dividing by v\sqrt{v} scales the step size:

p  −=  lr⋅m^v^+ϵp \;{-}{=}\; lr \cdot \frac{\hat{m}}{\sqrt{\hat{v}} + \epsilon}

Where:

  • pp: the parameter;

  • lrlr: the learning rate;

  • m^\hat{m}: the exponentially weighted average of the gradient;

  • v^\hat{v}: the exponentially weighted average of the squared gradient;

  • ϵ\epsilon: a tiny number that prevents division by 0.

Both m^\hat{m} and v^\hat{v} here need bias correction.

Bias correction

In the early stage of training, m0m_0 and v0v_0 are usually initialized to 0. As a result, in the first few steps the values of mtm_t and vtv_t are far too small (close to 0). To remove this error, we usually apply bias correction. Taking mm as an example, the formula is:

mt^=mt1−β1t\hat{m_t} = \frac{m_t}{1 - {\beta_1}^t}

Where:

  • mt^\hat{m_t}: the corrected exponentially weighted average;

  • mtm_t: the exponentially weighted average;

  • β1\beta_1: the decay rate of the gradient;

  • tt: the number of steps the optimizer has updated so far.

As tt grows, β1t{\beta_1}^t approaches 0 and the denominator approaches 1, so the correction naturally fades away.

⚠️ Note: The step count tt here is the number of times the optimizer has updated the parameters. It is not the same thing as the “time step” of reading one character in the RNN of the previous chapter.

Gradient clipping

The adaptive moment estimation optimizer also has a gradient clipping method, clip_grad_norm.

The gradient computation of an RNN passes through many time steps and occasionally becomes suddenly huge (exploding gradients), throwing the parameters far off. The purpose of gradient clipping is this: if the total norm of the gradients of all the parameters taken together exceeds a threshold, they are all scaled down proportionally, keeping the step size within a safe range.

Adaptive moment estimation with weight decay optimizer

The adaptive moment estimation with weight decay (AdamW) optimizer is a small improvement on Adam, and is standard equipment for training large models such as GPT. On top of Adam, it adds weight decay: at every update, the weights themselves are also pulled a tiny bit toward 0.

The purpose is to prevent overfitting: if no weight is allowed to grow too large, the model is less likely to “memorize” the details of the training data.

Note that only matrices (ndim >= 2) are decayed; one-dimensional parameters such as biases are not. This is also a rule of thumb from practice.

Recurrent neural network

Recurrent cell

RNN model

Trainer

Abstract class

RNN trainer

In the trainer, before calling the step method step, we first call the gradient clipping method clip_grad_norm to prevent exploding gradients.

Hyperparameters

Learning rate

Batch size

Number of epochs

Context size

Embedding size

Modeling

We change the optimizer to the adaptive moment estimation with weight decay (AdamW) optimizer.

Training

Evaluation

prediction:	32 steps, each (6970, 65)
total loss:	Tensor(65.93744561104684)

Inference

ROMEO:
I not beting you at sheenes hew so ene I's have boo?

GRUMPIO:
Westeesilv bees
tha my sapin, it and ofte, couther me it,
Ane sceat, bot, mance?

Prevees live hem?

GOMYe leald het emen, Beran: I but graed cruith, quep a you geed, I
Anthing will sunf a Sor

In this chapter, we upgraded the optimizer from the “one size fits all” SGD to the “tailor-made” AdamW:

  • Adam: adjusts the effective step size of each parameter individually (momentum for the direction, scale for the step size);

  • Gradient clipping: prevents exploding gradients;

  • Weight decay: prevents overfitting.

💡 Tip: In general, Adam and AdamW converge faster than SGD early in training, but their final generalization may be worse than that of a carefully tuned SGD. For Transformer-based models, AdamW remains the most commonly used choice.

Exercises

  1. Try making the threshold max_norm of the gradient clipping method clip_grad_norm larger or smaller, and observe how training differs.