Learn ML

Chapter 12 of 25

Optimization Theory

How a network actually searches for good weights

18 min read

Motivation

Imagine you're standing somewhere on a foggy mountain range at night, and your only goal is to reach the lowest valley. You can't see more than a few feet in any direction. All you can do is feel the slope under your feet, take a step downhill, feel again, and repeat. That's it. That's the entire strategy.

That blind, step-by-step descent is not a metaphor we're borrowing loosely — it is, almost exactly, what happens every time a neural network trains. "Training a model" sounds like a mysterious, almost magical process, but underneath the vocabulary it is one very concrete thing: searching for the set of numbers (weights and biases) that makes a loss function as small as possible. Every neuron, every layer, every activation choice you've studied so far only matters because, eventually, something has to go find good values for all of it. This chapter is about that "something."

A Real-Life Scenario

Picture a delivery company trying to minimize the total distance its trucks drive every day. There's no formula you can solve once and be done — the "cost" (total distance) depends on hundreds of interacting decisions (which truck goes where, in what order), and the landscape of possible costs is lumpy, full of better and worse regions, with no obvious shortcut to the best one. The company's planners nudge the routes a little, check whether total distance went down, nudge again, and keep repeating.

A neural network's training loop is the same story, except the "routes" are millions of weights, and the "total distance" is the loss function. Instead of a human planner nudging things by hand, gradient descent does the nudging automatically, guided by calculus instead of intuition.

Building the Intuition

Before touching a single equation, hold onto three ideas:

  • Training is search, not calculation. There's no closed-form formula that spits out the best weights directly — the network has to iteratively try, measure, and adjust.
  • The loss function is the landscape. Every possible setting of the weights is a point on this landscape, and the height at that point is how bad the network's predictions are. Training means walking downhill on this landscape.
  • The landscape's shape matters enormously. A landscape shaped like a smooth bowl is easy to descend — go downhill anywhere, and you eventually reach the one and only bottom. A landscape full of dips, ridges, and flat plateaus is a much harder walk, and this second kind of landscape is exactly what a real neural network produces.

The Math Behind It

Training as an Optimization Problem

The General Training Objective
θ=argminθ L(θ)=argminθ 1Ni=1N(fθ(x(i)),y(i))\theta^{*} = \arg\min_{\theta}\ L(\theta) = \arg\min_{\theta}\ \frac{1}{N}\sum_{i=1}^{N} \ell\big(f_\theta(\mathbf{x}^{(i)}), y^{(i)}\big)

Where: θ\theta is the collection of every trainable parameter in the network (all weights and biases stacked together), fθf_\theta is the network's function, \ell is a per-example loss (cross-entropy, squared error, or any of the losses covered in the next chapter), and L(θ)L(\theta) is the average loss over the whole training set.

Intuition: This single line is the entire goal of training, stated precisely. Every optimizer you'll meet — plain gradient descent, Momentum, RMSProp, Adam — is just a different strategy for solving this exact same search problem, more reliably or more efficiently than the last.

This connects directly to earlier chapters

The perceptron's mistake-driven update rule and backpropagation's error signals were both, quietly, already doing this. Backpropagation computes θL(θ)\nabla_\theta L(\theta) — the gradient of this exact objective — and this chapter formalizes what to do with that gradient once you have it.

Convex vs. Non-Convex Landscapes

Convexity
f(λx1+(1λ)x2)λf(x1)+(1λ)f(x2),x1,x2, λ[0,1]f(\lambda\mathbf{x}_1 + (1-\lambda)\mathbf{x}_2) \leq \lambda f(\mathbf{x}_1) + (1-\lambda)f(\mathbf{x}_2), \qquad \forall\, \mathbf{x}_1, \mathbf{x}_2,\ \lambda\in[0,1]

Intuition: A function is convex if a straight line connecting any two points on its graph never dips below the graph itself. Picture a single smooth bowl: no matter where you start, walking downhill always leads to the same, unique bottom. That's what convexity buys you — a guarantee.

MLP loss surfaces are not convex

The loss surface of a Multi-Layer Perceptron with hidden layers is, in general, non-convex. Gradient descent is not theoretically guaranteed to find the single best solution — it can get stuck. This is one of the sharpest differences between a plain linear model and an MLP: swap one hidden layer in, and you trade a friendly bowl-shaped landscape for a lumpy, unpredictable one. In practice, though, research on large modern networks has found that most of the local dips gradient descent lands in still generalize well — the more relevant obstacle turns out to be saddle points, not bad local minima.

Critical Points: Minima, Maxima, and Saddle Points

A critical point is any point θ\theta where L(θ)=0\nabla L(\theta) = \mathbf{0} — the landscape is momentarily flat in every direction. Not all flat spots are the same:

TypeWhat it looks likeEffect on training
Local minimumLower than every nearby pointGradient descent settles here and stays
Local maximumHigher than every nearby pointUnstable — any nudge moves away from it
Saddle pointGoes up in some directions, down in othersGradients shrink to near-zero in most directions, stalling training for a long stretch even though it isn't truly stuck
Saddle points, not bad minima, are the real villain

In the extremely high-dimensional spaces neural networks live in (millions of weights), it turns out saddle points vastly outnumber bad local minima. A network can spend a long time crawling across a near-flat saddle region — not because it's trapped, but because the slope is so gentle in almost every direction that progress is painfully slow.

Convex vs Non-Convex Loss LandscapesIllustration coming soon
A convex loss surface (left) guarantees gradient descent finds the single global minimum. An MLP's non-convex loss surface (right) may contain multiple local minima, saddle points, and flat plateaus.

Batch, Stochastic, and Mini-Batch Gradient Descent

The basic update rule is θθηθL(θ)\theta \leftarrow \theta - \eta\nabla_\theta L(\theta), but there's a choice hiding inside it: how much data do you use to compute that gradient before taking a step?

Three ways to compute the gradient before each parameter update
VariantGradient computed overTrade-off
Batch Gradient DescentThe entire training set, every stepAccurate direction, but painfully slow per update on large datasets
Stochastic Gradient Descent (SGD)A single random exampleFast updates, but a noisy, jittery path
Mini-Batch Gradient DescentA small random subset (e.g. 32-256 examples)The practical standard — balances speed and stability

The full comparison — including code and how these interact with modern optimizers like Adam — is the subject of the next chapter. For now, the key idea is simply that "gradient descent" is a family, not a single algorithm.

The Role of the Learning Rate

The learning rate is the single most consequential hyperparameter here

If η\eta is too large, each step overshoots the minimum, and training can oscillate wildly or diverge outright. If η\eta is too small, training is stable but crawls forward so slowly it can take forever to reach a good solution, and it's far more likely to get stuck wandering a plateau or saddle region for a very long time.

Learning Rate Explorer

Pick a learning rate and step through gradient descent on a simple bowl-shaped loss curve. Watch what happens when the rate is too small, just right, or too large.

Step 0

Try stepping through and watch how it behaves.

Worked Example: Gradient Descent by Hand

Minimize L(θ)=θ24θ+5L(\theta) = \theta^2 - 4\theta + 5, starting at θ0=0\theta_0 = 0 with learning rate η=0.3\eta = 0.3.

Step 1 — the gradient: L(θ)=2θ4L'(\theta) = 2\theta - 4.

Iteration 1: θ0=0    L(0)=4    θ1=00.3(4)=1.2\theta_0 = 0 \implies L'(0) = -4 \implies \theta_1 = 0 - 0.3(-4) = 1.2

Iteration 2: θ1=1.2    L(1.2)=1.6    θ2=1.20.3(1.6)=1.68\theta_1 = 1.2 \implies L'(1.2) = -1.6 \implies \theta_2 = 1.2 - 0.3(-1.6) = 1.68

Iteration 3: θ2=1.68    L(1.68)=0.64    θ3=1.680.3(0.64)=1.872\theta_2 = 1.68 \implies L'(1.68) = -0.64 \implies \theta_3 = 1.68 - 0.3(-0.64) = 1.872

Each step's correction shrinks as θ\theta approaches the minimum — that's the gradient itself shrinking, since L(θ)=2θ4L'(\theta) = 2\theta - 4 approaches zero as θ2\theta \to 2. Continuing this process, θ\theta converges toward θ=2\theta^{*}=2, which checks out algebraically: L(θ)=0    θ=2L'(\theta) = 0 \implies \theta = 2, and L(θ)=2>0L''(\theta) = 2 > 0 confirms it's a minimum, not a maximum.

Reading a loss curve

Plotting loss against iteration number is one of the most useful habits in all of deep learning. Steadily decreasing and flattening means healthy convergence. Wild oscillation means the learning rate is too high. Painfully slow, near-flat descent means it's too low.

Implementing It

import numpy as np
 
def L(theta):
    return theta**2 - 4*theta + 5
 
def grad_L(theta):
    return 2*theta - 4
 
theta = 0.0
lr = 0.3
history = [theta]
 
for step in range(15):
    g = grad_L(theta)
    theta = theta - lr * g
    history.append(theta)
 
print("Trajectory of theta:", [round(t, 4) for t in history])
print("Final theta (should approach 2.0):", round(theta, 4))
print("Final loss (should approach 1.0):", round(L(theta), 4))

This mirrors the hand-traced example exactly: each iteration recomputes the gradient at the current point and takes a proportional step against it. Running it confirms theta converges to approximately 2.0, matching the algebraic solution.

Key Takeaways

Key Takeaways
  • Training a network is fundamentally search: finding θ\theta that minimizes L(θ)=1Ni(fθ(x(i)),y(i))L(\theta) = \frac{1}{N}\sum_i \ell(f_\theta(\mathbf{x}^{(i)}), y^{(i)}).
  • Convex loss surfaces have one global minimum reachable reliably by gradient descent; MLP loss surfaces are generally non-convex.
  • In high-dimensional non-convex optimization, saddle points are typically more disruptive to training than bad local minima.
  • Batch, stochastic, and mini-batch gradient descent trade off gradient accuracy against per-update computational cost.
  • The learning rate controls both the stability and the speed of convergence — too large diverges, too small crawls.

Common Mistakes

Assuming gradient descent always finds the best solution

That guarantee only holds for convex functions. An MLP's loss surface almost never is convex, so "the loss stopped decreasing" doesn't necessarily mean "we found the best possible weights" — it might just mean training has hit a saddle point or a mediocre local minimum.

Treating the learning rate as a minor detail

It's tempting to leave the learning rate at whatever default a tutorial uses. In practice, it's often the single hyperparameter most responsible for whether training succeeds at all — always watch the loss curve when trying a new value.

Interview Corner

Quick Check
1. Why are saddle points considered more relevant than bad local minima when training large neural networks?
2. What happens if the learning rate in gradient descent is set far too high?

Where This Shows Up in Practice

Every training run you'll ever launch — whether it's a two-layer MLP or a billion-parameter language model — is an instance of this exact search problem. The specific algorithm used to conduct that search (plain gradient descent, Momentum, Adam, and beyond) is the subject of the next two chapters, but the underlying goal never changes: find θ\theta that makes L(θ)L(\theta) as small as possible, one step at a time, guided by the gradient.