SGD
momentum
TensorFlow
optimization
machine learning

SGD with momentum in TensorFlow

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Plain stochastic gradient descent updates parameters only from the current gradient, which can make training noisy and slow. Momentum improves that behavior by carrying part of the previous update forward, so TensorFlow's SGD with momentum often converges faster and oscillates less on difficult loss surfaces.

What Momentum Adds to SGD

Regular SGD moves parameters opposite the gradient at each step. That works, but in curved regions of the loss surface the gradient direction can zigzag. Momentum introduces a velocity term that remembers recent gradients.

Intuitively:

  • gradients point downhill
  • momentum smooths repeated downhill movement
  • updates become more stable in narrow valleys

If consecutive gradients keep pointing in a similar direction, the velocity grows and the optimizer moves faster. If gradients alternate direction, momentum damps the oscillation.

In TensorFlow Keras, this is exposed through tf.keras.optimizers.SGD.

Basic TensorFlow Usage

The simplest way to enable momentum is:

python
1import tensorflow as tf
2
3optimizer = tf.keras.optimizers.SGD(
4    learning_rate=0.01,
5    momentum=0.9
6)

That optimizer can be passed directly into model.compile.

Here is a complete runnable example that fits a line y = 3x + 2 from synthetic data:

python
1import numpy as np
2import tensorflow as tf
3
4np.random.seed(0)
5tf.random.set_seed(0)
6
7x = np.random.randn(1000, 1).astype("float32")
8y = 3.0 * x + 2.0 + 0.2 * np.random.randn(1000, 1).astype("float32")
9
10model = tf.keras.Sequential([
11    tf.keras.layers.Dense(1, input_shape=(1,))
12])
13
14model.compile(
15    optimizer=tf.keras.optimizers.SGD(learning_rate=0.05, momentum=0.9),
16    loss="mse"
17)
18
19history = model.fit(x, y, epochs=20, batch_size=32, verbose=0)
20
21weights, bias = model.layers[0].get_weights()
22print("weight:", float(weights[0][0]))
23print("bias:", float(bias[0]))
24print("final_loss:", float(history.history["loss"][-1]))

This code is intentionally simple, but it shows the normal workflow: define the model, choose SGD with a momentum value, then train.

Choosing Learning Rate and Momentum

Momentum does not replace learning-rate tuning. The two hyperparameters interact.

Typical starting values are:

  • learning rate around 0.01 or 0.05 for simple models
  • momentum around 0.8 to 0.95

If the learning rate is too high, momentum can amplify instability rather than fix it. If the learning rate is too low, training may still crawl even with strong momentum.

A practical pattern is:

  1. find a learning rate that trains at all
  2. add momentum such as 0.9
  3. retune the learning rate after that

TensorFlow also supports Nesterov momentum:

python
1optimizer = tf.keras.optimizers.SGD(
2    learning_rate=0.01,
3    momentum=0.9,
4    nesterov=True
5)

Nesterov momentum looks ahead slightly before applying the gradient and can improve convergence in some models, though it is not automatically better in every case.

What the Optimizer Is Doing Internally

When momentum is enabled, TensorFlow keeps extra state for each trainable variable. That state is often called the velocity. Each step combines:

  • part of the old velocity
  • the new gradient

Then the variable is updated using that combined value. This is why momentum consumes a little more memory than plain SGD, but the cost is usually small compared with the rest of model training.

For custom training loops, usage is still straightforward:

python
1optimizer = tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0.9)
2
3for step in range(100):
4    with tf.GradientTape() as tape:
5        predictions = model(x, training=True)
6        loss = tf.reduce_mean(tf.square(predictions - y))
7
8    gradients = tape.gradient(loss, model.trainable_variables)
9    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

This matters when you need more control than model.fit provides, such as gradient clipping, multiple losses, or custom logging.

When Momentum Helps Most

Momentum is especially useful when:

  • gradients are noisy because batches are small
  • the loss surface has long shallow directions and steep side walls
  • plain SGD makes progress but converges too slowly

It is often a strong baseline for vision and large-scale training, especially when paired with learning-rate schedules. Even though adaptive optimizers like Adam are popular, momentum SGD remains competitive and is still a common final-training choice in many projects.

Common Pitfalls

The most common mistake is copying a momentum value such as 0.9 without retuning the learning rate. A configuration that worked for Adam or plain SGD may behave badly once momentum is added.

Another issue is misreading early training dynamics. Momentum can create an initially faster drop in loss, but if the learning rate is too aggressive the optimizer may overshoot and oscillate later.

Developers also forget that optimizer state matters when resuming training. If you restore model weights without restoring optimizer state, the effective training behavior changes because the saved velocity is gone.

Finally, do not assume momentum is always the best optimizer. It is a strong option, but the right choice depends on the model, data, schedule, and training budget.

Summary

  • Momentum adds a velocity term to SGD so updates are smoother and often faster.
  • In TensorFlow, use tf.keras.optimizers.SGD with a nonzero momentum.
  • Learning rate and momentum must be tuned together.
  • 'model.fit and custom training loops both support the optimizer cleanly.'
  • Restore optimizer state when continuing training from a checkpoint.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.