Skip to content
coden

Gradient descent: how a model learns

Learning rate, zigzag in narrow valleys, momentum, Adam, stochastic descent in mini-batches and local minima — with animations of real trajectories.

24 minutes Matěj Žalmánek 2026-10-15

Series AI basics Part 11 of 52
  1. Map of artificial intelligence: what is what and how it all fits together
  2. A brief history of artificial intelligence: from Turing to language models
  3. Data, model, training, inference: the basic terms on a single example
  4. How to read mathematical notation: symbols, indices, sums and quantifiers
  5. Sets and relations: the building blocks of definitions in AI
  6. Functions and mappings: why every AI model is a function
  7. Logic and proofs: the rules AI reasons by
  8. Graphs and trees: the structure that both search and neural networks stand on
  9. Linear algebra for machine learning: vectors, matrices and why AI mostly multiplies
  10. Derivatives, the gradient and the chain rule: how a model finds out which way to learn
  11. Gradient descent: how a model learns
  12. What probability is: from rolling dice to the Kolmogorov axioms
  13. Conditional probability and Bayes’ theorem: how to update your estimate when you learn something new
  14. Random variables and the cumulative distribution function: one function that tells you everything about a distribution
  15. Probability density and probability mass functions: why a continuous variable has zero probability at a point
  16. Expected value, variance and covariance: where a distribution lies, how wide it is and what goes with what
  17. Overview of probability distributions: Bernoulli, binomial, Poisson, uniform, normal and exponential
  18. Law of large numbers and central limit theorem: why averages behave so predictably
  19. Statistics and parameter estimation: maximum likelihood, MAP and confidence intervals
  20. Information theory: entropy, cross-entropy and KL divergence — where loss functions come from
  21. State-space search: BFS, DFS, UCS and A* with animations
  22. Games and adversaries: minimax, alpha-beta pruning and Monte Carlo tree search
  23. Constraint satisfaction: backtracking, constraint propagation and AC-3 on sudoku and a map of Czech regions
  24. Logic and knowledge systems: forward and backward chaining, resolution and expert systems
  25. Planning: STRIPS, the blocks world, heuristics from relaxation and planning in AI agents
  26. Local search and simulated annealing: a travelling salesman through the Czech regional capitals
  27. Genetic algorithms: population, crossover, mutation and selection on a backpack for a hike
  28. Evolution strategies and genetic programming: from the one-fifth rule to Kepler’s law
  29. Ant colony optimization: how a pheromone trail finds a short path
  30. Particle swarm optimisation: inertia, personal experience and the swarm’s experience
  31. Neuroevolution: evolving the weights and shape of neural networks, and the NEAT algorithm
  32. Fuzzy sets and membership functions: how to write down “somewhat warm”
  33. Fuzzy logic and probability: why “somewhat warm” does not mean “probably warm”
  34. Fuzzy logic: t-norms, implications and IF–THEN rules
  35. Fuzzy control: Mamdani and Sugeno from a fan to a pole on a cart
  36. Fuzzy clustering: the fuzzy c-means algorithm and points between clusters
  37. Neuro-fuzzy systems (ANFIS): fuzzy rules that learn from data
  38. Markov chains: the transition matrix, the stationary distribution and PageRank
  39. Hidden Markov models: the Viterbi algorithm and the dishonest casino
  40. Bayesian networks: why the grass is wet and what it means for the sprinkler
  41. The Kalman filter: how to estimate where a car is and how fast it goes from imprecise measurements
  42. Types of machine learning: supervised, unsupervised, semi-supervised and more
  43. Prompts, context and RAG: how to give a model the right information
  44. Variational autoencoders (VAE): new images from a continuous latent space
  45. Generative adversarial networks (GAN): the forger versus the detective
  46. Diffusion models: how pure noise becomes an image
  47. Markov decision processes: states, actions, rewards and the Bellman equations
  48. Q-learning and DQN: learning the value of actions, from a table to a neural network
  49. Policy gradient and PPO: learning the policy directly
  50. How an AI agent works: a language model in a loop with tools
  51. Programming with AI agents: the task, tests and review
  52. Evaluating and securing AI systems: how to measure and how to keep watch

Full series syllabus 52 of 83 topics published

What you will take away
  • How gradient descent works and why the learning rate matters most.
  • Why plain descent zigzags in a narrow valley and how momentum and Adam fix it.
  • Why networks learn in small random batches and what local minima and saddle points mean.

Useful to know first: Derivatives, the gradient and the chain rule: how a model finds out which way to learn

In the previous parts we prepared everything we need: a model is a function with parameters, the loss function is a landscape over the space of parameters, and the gradient points in the steepest direction uphill. Now we put it together into the algorithm by which almost every neural network in the world learns — gradient descent. Its idea fits into a single sentence, and its details decide whether a model learns in an hour, in a week, or not at all.

1. The idea: downhill in the fog

Definition — gradient descent

Let d ∈ ℕ, d ≥ 1, and let J : ℝd → ℝ be a differentiable loss function with the gradient ∇J : ℝd → ℝd, ∇J(θ) = (∂J/∂θ1(θ), …, ∂J/∂θd(θ)) (see the part on derivatives and the gradient).

Gradient descent is the algorithm:

  • input: initial parameters θ0 ∈ ℝd, a learning rate η ∈ ℝ, η > 0, a tolerance ε > 0 and a maximum number of steps T ∈ ℕ;
  • output: the parameters θt ∈ ℝd at the moment it stops.
  1. Set t = 0.
  2. If ‖∇J(θt)‖ < ε or t = T, stop and return θt.
  3. Set θt+1 = θt − η ∇J(θt), increase t by 1 and continue with step 2.

So the algorithm repeatedly moves the parameters by η times the gradient against its direction, until the gradient is almost zero or the steps run out.

In plain words

You are standing on a hill in thick fog and want to get down into the valley. You can't see anything, you only feel the slope under your feet. You take a step where the ground falls the most and look around again. The gradient is that slope, the learning rate is the length of the step. There is nothing more to it.

θt+1 = θt − η ∇J(θt)

θt+1
the new parameters — the vector of all weights and biases of the model after one step
θt
the current parameters — each step only corrects what we already have; learning is gradual refinement, not computing the result in one go
−
the gradient points in the direction of the steepest ascent of the loss; we want to reduce the loss, so we go the opposite way
η
the learning rate — the gradient describes the landscape only in the close neighbourhood of the point, so we may take only a limited step; η decides how long
∇J(θt)
the gradient of the loss at the current point — the vector of partial derivatives ∂J/∂θi; each component says how much and in which direction the given parameter makes the loss worse
Each parameter moves in proportion to how much the loss depends on it, and against the direction in which it increases the loss.

As an algorithm, including the condition for when to stop (ε is a small tolerance, e.g. 10−6):

def gradientni_sestup(grad_J, theta, eta, max_kroku, eps):
    for t in range(max_kroku):
        g = grad_J(theta)             # gradient at the current point
        if norma(g) < eps:            # almost flat: we are (almost) at a stationary point
            break
        theta = theta - eta * g       # step against the gradient, all components at once
    return theta

2. Where the gradient comes from: the forward and backward pass

The rule θ ← θ − η∇J(θ) assumes that we have the gradient. But a model with millions of parameters cannot compute it numerically — that would mean two passes through the network for each parameter separately. The gradient is computed by backpropagation of the error: the model is broken down into elementary operations, a computation graph, and each operation can do only two things — compute its output from its inputs and say how the output depends on each input (its local derivative).

We show it on a single neuron: two inputs, the weighted-sum basis function z = w1x1 + w2x2 + b, the logistic activation ŷ = σ(z) and the binary cross-entropy loss for the target t = 1. The boxes are operations. Values flow forward in green, gradients flow back in orange; at the bottom is the formula of the step being carried out. You can stop the animation and go through it step by step with the buttons:

∂L/∂w₁ = −0.5 ∂L/∂w₂ = −1 p₁ = 0.5 ∂L/∂p₁ = −0.5 p₂ = −0.6 ∂L/∂p₂ = −0.5 ∂L/∂b = −0.5 z = 0 ∂L/∂z = −0.5 ŷ = 0.5 ∂L/∂ŷ = −2 L = 0.693 ∂L/∂L = 1 × × + σ L x₁ = 1 w₁ = 0.5 w₁ = 0.75 x₂ = 2 w₂ = −0.3 w₂ = 0.2 b = 0.1 b = 0.35 t = 1 inputs and parameters x₁ = 1, x₂ = 2, t = 1; w₁ = 0.5, w₂ = −0.3, b = 0.1; η = 0.5 forward pass p₁ = w₁ · x₁ = 0.5 · 1 = 0.5 forward pass p₂ = w₂ · x₂ = −0.3 · 2 = −0.6 forward pass z = p₁ + p₂ + b = 0.5 + (−0.6) + 0.1 = 0 forward pass ŷ = σ(z) = 1 / (1 + e^(−z)) = 0.5 forward pass L = −t ln ŷ − (1 − t) ln(1 − ŷ) = 0.693 backward pass ∂L/∂ŷ = −t/ŷ + (1 − t)/(1 − ŷ) = −2 backward pass ∂L/∂z = ∂L/∂ŷ · σ′(z) = ∂L/∂ŷ · ŷ(1 − ŷ) = −2 · 0.25 = −0.5 backward pass ∂L/∂p₁ = ∂L/∂p₂ = ∂L/∂b = ∂L/∂z · 1 = −0.5 backward pass ∂L/∂w₁ = ∂L/∂p₁ · x₁ = −0.5 · 1 = −0.5 backward pass ∂L/∂w₂ = ∂L/∂p₂ · x₂ = −0.5 · 2 = −1 descent step w₁ ← 0.5 − 0.5·(−0.5) = 0.75, w₂ ← 0.2, b ← 0.35; loss 0.693 → 0.201
A single neuron as a graph of operations: forward pass, backward pass and a descent step forward pass backward pass
Definition — computation graph, forward and backward pass

Let G = (U, H) be a directed acyclic graph with a finite set of nodes U and a set of edges H ⊆ U × U; we write an edge (u, v) ∈ H as u → v. For v ∈ U let par(v) = {u ∈ U : u → v} denote the set of its parents. G is a computation graph if and only if

  1. each node v carries a real value, which we denote by the same letter v;
  2. the nodes with par(v) = ∅ are inputs (data and parameters) and their values are given;
  3. each node v with par(v) ≠ ∅ has a differentiable function fv, and its value is v = fv((u)u ∈ par(v));
  4. one marked node L ∈ U is the loss.

A topological order is a numbering U = {v1, …, vN} such that vi → vj ⇒ i < j (it always exists in an acyclic graph).

The forward pass computes the values v1, …, vN in this order according to item 3 — each node only after all its parents.

The backward pass computes for each node u ∈ U its adjoint ū = ∂L/∂u in the reverse order vN, …, v1: it sets L̄ = 1 and for u ≠ L uses the multivariable chain rule

ū = ∑v : u → v v̄ · ∂fv/∂u

(an empty sum is 0). So for each node the backward pass adds up the contributions from all the nodes that u feeds into; each edge is used exactly once in the process.

Local derivatives of the operations in the figure

All quantities are real numbers: p1, p2, b, w, x, z ∈ ℝ, the target t ∈ {0, 1} and the output ŷ ∈ (0, 1).

Sum z = p1 + p2 + b: ∂z/∂p1 = ∂z/∂p2 = ∂z/∂b = 1 — a sum passes the gradient to all its inputs unchanged.

Product p = wx: ∂p/∂w = x and ∂p/∂x = w — the gradient is multiplied by the other factor.

Logistic function σ : ℝ → (0, 1), σ(z) = 1/1 + e−z: σ′(z) = e−z/(1 + e−z)2 = σ(z)(1 − σ(z)) = ŷ(1 − ŷ), where ŷ = σ(z).

Cross-entropy L = −t ln ŷ − (1 − t) ln(1 − ŷ): ∂L/∂ŷ = −t/ŷ + 1 − t/1 − ŷ.

Theorem — the error of the neuron is ŷ − t

Let t ∈ {0, 1}, z ∈ ℝ, let ŷ = σ(z) be the logistic function and L = −t ln ŷ − (1 − t) ln(1 − ŷ) the cross-entropy. Then

∂L/∂z = ŷ − t.

Proof. The chain rule through ŷ: ∂L/∂z = ∂L/∂ŷ · ∂ŷ/∂z = (−t/ŷ + 1 − t/1 − ŷ) · ŷ(1 − ŷ) = −t(1 − ŷ) + (1 − t)ŷ = ŷ − t. ∎

In the figure: ∂L/∂z = 0.500 − 1 = −0.500. Dividing by ŷ and multiplying by ŷ(1 − ŷ) cancel each other out — that is why cross-entropy is paired with the logistic function (and, as you will see, with softmax too).

Theorem — the backward pass is cheap

Let G = (U, H) be a computation graph with E = |H| edges in which every node affects the loss (from every node there is a path to L), and let each value fv and each local derivative ∂fv/∂u be computable in constant time. Then the backward pass computes all the adjoints ū, u ∈ U — among them all the derivatives ∂L/∂θi with respect to the parameters — in time O(E), that is, of the same order as the forward pass and independently of the number of parameters.

Proof. In the formula for ū each edge u → v appears in a sum exactly once, so all the sums together have E terms. Every node except L has at least one outgoing edge, so |U| ≤ E + 1 and the work on the individual nodes is also O(E). ∎

The numerical derivative L(θ + hei) − L(θ − hei)/2h (ei is the i-th unit vector, h > 0 a small number) would need two forward passes per parameter — for a network with a billion parameters, two billion passes instead of one backward pass.

In plain words

Forward, we compute what the network answers. Backward, we compute who is to blame for the error and how much: the loss sends a “reproach” of 1 into the last box, which multiplies it by how sensitively it reacts to its input and passes it on. A sum splits the reproach equally among everyone, a product sends it to each input multiplied by the other one. When the reproach reaches a parameter, it is exactly that parameter’s component of the gradient.

After one step with η = 0.5 the parameters move against the gradient to w1 = 0.75, w2 = 0.2, b = 0.35, and the loss drops from 0.693 to 0.201. Notice that the weight w2 moved the most: its input x2 = 2 is the largest, so the result depends on it the most.

3. Example: backpropagation through a network with softmax in every layer

A real network is just a bigger computation graph. The operations are grouped into layers and instead of numbers, vectors flow. We take a network in which every neuron has the weighted-sum basis function and every layer has the softmax activation, and derive backpropagation in general for n layers: first the error of the last layer, then of layer n − 1 and finally a recursion that works for a network of any depth. Then we recompute everything on concrete numbers.

Softmax in hidden layers is hardly ever used in practice — hidden layers usually have ReLU, and softmax tends to be only at the output. As a demonstration, though, it is excellent: its derivative is a full matrix, because each output depends on all the inputs of the layer. So you can clearly see what backpropagation does when the activation mixes neurons with each other.

Definition — network, loss and layer error

For m ∈ ℕ, m ≥ 1, softmax is the function softmax : ℝm → (0, 1)m given component-wise by (see the part on softmax)

softmax(z)i = ezi/∑k=1m ezk,   i = 1, …, m.

Let n ∈ ℕ, n ≥ 1, be the number of layers, d0, d1, …, dn ≥ 1 the widths of the layers, x ∈ ℝd0 the input, and for ℓ = 1, …, n let W(ℓ) ∈ ℝdℓ×dℓ−1 be the weights and b(ℓ) ∈ ℝdℓ the biases of layer ℓ. A network with softmax in every layer computes a(0) = x and for ℓ = 1, …, n

z(ℓ) = W(ℓ)a(ℓ−1) + b(ℓ) ∈ ℝdℓ,   a(ℓ) = softmax(z(ℓ)) ∈ (0, 1)dℓ,

component-wise zi(ℓ) = ∑j=1dℓ−1 Wij(ℓ)aj(ℓ−1) + bi(ℓ) for i = 1, …, dℓ (the weighted-sum basis function).

The target is a vector t ∈ {0, 1}dn with ∑k tk = 1 (a single one at the position of the correct class) and the loss is the cross-entropy

L = −∑k=1dn tk ln ak(n).

The error of layer ℓ ∈ {1, …, n} is the vector

δ(ℓ) = ∂L/∂z(ℓ) ∈ ℝdℓ,   i.e. δi(ℓ) = ∂L/∂zi(ℓ).

So the error of a layer says how the loss depends on the input of the activation; the gradients of the weights and biases can then be read off from it.

Lemma 1 — the Jacobian matrix of softmax

Let m ∈ ℕ, m ≥ 1, z ∈ ℝm and a = softmax(z). For i, j ∈ {1, …, m} let δij denote the Kronecker delta (δij = 1 for i = j, otherwise 0). Then for all i, j ∈ {1, …, m}

∂ai/∂zj = ai(δij − aj),

in matrix form

J = ∂a/∂z = diag(a) − aaT ∈ ℝm×m.

Proof. Let S = ∑k=1m ezk, so that ∂S/∂zj = ezj. By the quotient rule

for i = j: ∂ai/∂zi = eziS − eziezi/S2 = ai − ai2,

for i ≠ j: ∂ai/∂zj = −eziezj/S2 = −aiaj. ∎

We will need two properties: J is symmetric and each of its rows (and columns) has sum zero, because ∑j ai(δij − aj) = ai − ai∑jaj = 0.

Theorem 2 — the error of the last layer: δ⁽ⁿ⁾ = a⁽ⁿ⁾ − t

Let the network, the target t and the loss L be as in the definition above. Then

δ(n) = a(n) − t.

Proof. We write a = a(n), z = z(n). The loss depends on a as ∂L/∂ai = −ti/ai. Each zj affects all the ai, so we sum over i and use Lemma 1:

δj(n) = ∑i ∂L/∂ai · ∂ai/∂zj = ∑i (−ti/ai) · ai(δij − aj) = −tj + aj ∑i ti = aj − tj,

because ∑i ti = 1. ∎

It has the same form as ŷ − t for a single neuron: the logarithm in the loss cancels the exponential in softmax, and of the whole Jacobian matrix only the difference “what the network said” minus “what it should have said” remains.

Theorem 3 — the error of layer n − 1

Let n ≥ 2, let the network, the target and the loss be as in the definition above, and let J(n−1) = diag(a(n−1)) − a(n−1)(a(n−1))T be the Jacobian matrix of the softmax of layer n − 1 (Lemma 1). Let g(n−1) = ∂L/∂a(n−1) ∈ ℝdn−1. Then

  1. g(n−1) = (W(n))T δ(n),   component-wise gj = ∑i Wij(n) δi(n);
  2. δ(n−1) = J(n−1) g(n−1),   component-wise δj(n−1) = aj (gj − a·g),

where a = a(n−1), g = g(n−1) and a·g = ∑i aigi is the average of g weighted by the activations of the layer (the weights ai are positive and sum to 1).

Proof. First the gradient with respect to the outputs of layer n − 1. Since zi(n) = ∑j Wij(n)aj(n−1) + bi(n), we have ∂zi(n)/∂aj(n−1) = Wij(n), and by the chain rule gj = ∑i ∂L/∂zi(n) · Wij(n) = ∑i Wij(n) δi(n), which is item 1.

So the error goes back along the same weights the signal took forward, only in the opposite direction — hence the transpose. Then it passes back through the softmax of layer n − 1; by Lemma 1 and thanks to the symmetry of J:

δj(n−1) = ∑i gi ∂ai/∂zj = ∑i ai(δij − aj)gi = ajgj − aj ∑i aigi = aj (gj − a·g),

which is item 2. ∎

Interpretation: a neuron gets an error proportional to how far “its” gradient gj is above the weighted average of the whole layer, and multiplied by its activation as well. Softmax does not distinguish the absolute level, only the ratios — that is why the average is subtracted.

Theorem 4 — the recursion for any layer and the gradients of the parameters

Let the network, the target and the loss be as in the definition above, let J(ℓ) be the Jacobian matrix of the softmax of layer ℓ (Lemma 1), ⊙ denote component-wise multiplication and 1 the vector of ones. Then

  1. (recursion) for ℓ = n − 1, n − 2, …, 1 g(ℓ) = (W(ℓ+1))T δ(ℓ+1),   δ(ℓ) = J(ℓ)g(ℓ) = a(ℓ) ⊙ (g(ℓ) − (a(ℓ)·g(ℓ)) 1), where g(ℓ) = ∂L/∂a(ℓ);
  2. (gradients of the parameters) for ℓ = 1, …, n, i = 1, …, dℓ and j = 1, …, dℓ−1 ∂L/∂Wij(ℓ) = δi(ℓ) aj(ℓ−1),   i.e. ∂L/∂W(ℓ) = δ(ℓ)(a(ℓ−1))T,   ∂L/∂b(ℓ) = δ(ℓ).

Proof. (1) The argument of Theorem 3 nowhere used that layer n is the last one — only that z(ℓ+1) depends on a(ℓ) linearly with the matrix W(ℓ+1) and that a(ℓ) = softmax(z(ℓ)). Written out over all the layers:

δ(ℓ) = J(ℓ)(W(ℓ+1))T J(ℓ+1)(W(ℓ+2))T ⋯ J(n−1)(W(n))T (a(n) − t).

(2) The weight Wij(ℓ) affects only zi(ℓ), with the derivative ∂zi(ℓ)/∂Wij(ℓ) = aj(ℓ−1); the bias bi(ℓ) with the derivative 1. The chain rule gives ∂L/∂Wij(ℓ) = δi(ℓ) · aj(ℓ−1) and ∂L/∂bi(ℓ) = δi(ℓ). ∎

So the gradient of a weight is “the error of the neuron the weight leads into, times the activity of the neuron it leads from”. A weight from an inactive neuron does not learn.

Corollary 5 — the errors in a layer sum to zero

Let the network, the target and the loss be as in the definition above. Then for every layer ℓ ∈ {1, …, n}

∑j=1dℓ δj(ℓ) = 0,   and therefore also   ∑j=1dℓ ∂L/∂bj(ℓ) = 0.

Proof. For ℓ = n: ∑(aj − tj) = 1 − 1 = 0. For the hidden layers: 1Tδ(ℓ) = 1TJ(ℓ)g(ℓ) = 0, because the columns of J sum to zero (Lemma 1). ∎

The reason goes deeper: softmax does not change when you add the same number to all the zi in a layer. In the direction (1, 1, …, 1) the loss is therefore flat and the gradient cannot point into it.

Theorem 6 — a softmax layer at least halves the error

Let m ≥ 1, a ∈ (0, 1)m with ∑i ai = 1 (an output of softmax) and J = diag(a) − aaT. Then all eigenvalues of J lie in the interval [0, 1/2], and therefore for every g ∈ ℝm

‖Jg‖ ≤ 1/2 ‖g‖.

Proof. J is symmetric, so it has real eigenvalues. Row i has ai(1 − ai) on the diagonal and off it the numbers −aiaj, whose absolute values add up to ai(1 − ai). By the Gershgorin circle theorem every eigenvalue lies in one of the intervals [0, 2ai(1 − ai)], and 2a(1 − a) ≤ 1/2 for every a ∈ ℝ. For a symmetric matrix, ‖Jg‖ ≤ max |λ| · ‖g‖, where the maximum is over the eigenvalues λ. ∎

So on the way back each softmax layer at least halves the error (unless the weights amplify it). That is one of the reasons softmax is not put into hidden layers: in a deep network the gradient would hardly reach the first layers. You will see it in the example too.

In plain words

The last layer has it easiest: its error is simply “what the network said minus what it should have said”. Each further layer back gets the error from the layer above it, sent along the same weights as the signal, only in reverse, and then filters it through the derivative of its activation. With softmax that filter subtracts the average and multiplies by the activity of the neuron. In the end the gradient of each weight is the product of two numbers we already have: the error at its end and the activity at its start.

On numbers: a 2 → 3 → 3 → 2 network

Input x = 1.00.5, the correct class is the first one, t = 10. Three layers (n = 3) with softmax, weights and biases:

W(1) = 0.5−0.40.30.8−0.60.2, b(1) = 0.1−0.20.0,   W(2) = 0.7−0.50.2−0.30.40.60.10.9−0.8, b(2) = 0.00.1−0.1,   W(3) = 1.2−0.70.4−0.50.60.9, b(3) = 0.2−0.2.

input a⁽⁰⁾ = x layer 1 z = Wa + b → softmax layer 2 z = Wa + b → softmax layer 3 z = Wa + b → softmax 1.000 0.500 0.398 δ −0.095 0.440 δ 0.096 0.162 δ −0.001 0.303 δ −0.237 0.357 δ 0.181 0.340 δ 0.056 0.570 δ −0.430 0.430 δ 0.430 t = 1 t = 0 L = 0.562 L = 0.147 input and target a⁽⁰⁾ = x = (1.000, 0.500), t = (1.000, 0.000) forward pass z⁽1⁾ = W⁽1⁾ a⁽0⁾ + b⁽1⁾ = (0.400, 0.500, −0.500), a⁽1⁾ = softmax(z⁽1⁾) forward pass z⁽2⁾ = W⁽2⁾ a⁽1⁾ + b⁽2⁾ = (0.091, 0.254, 0.206), a⁽2⁾ = softmax(z⁽2⁾) forward pass z⁽3⁾ = W⁽3⁾ a⁽2⁾ + b⁽3⁾ = (0.450, 0.169), a⁽3⁾ = softmax(z⁽3⁾) forward pass L = −∑ tₖ ln aₖ⁽3⁾ = −ln 0.570 = 0.562 backward pass δ⁽3⁾ = a⁽3⁾ − t = (−0.430, 0.430) backward pass g = (W⁽3⁾)ᵀ δ⁽3⁾ = (−0.731, 0.559, 0.215), δⱼ⁽2⁾ = aⱼ (gⱼ − a·g), a·g = 0.051 backward pass g = (W⁽2⁾)ᵀ δ⁽2⁾ = (−0.215, 0.241, 0.017), δⱼ⁽1⁾ = aⱼ (gⱼ − a·g), a·g = 0.023 descent step W⁽ˡ⁾ ← W⁽ˡ⁾ − η δ⁽ˡ⁾ (a⁽ˡ⁻¹⁾)ᵀ, b⁽ˡ⁾ ← b⁽ˡ⁾ − η δ⁽ˡ⁾, η = 1.0; loss 0.562 → 0.147
A network with softmax in every layer: forward layer by layer, errors δ back layer by layer a⁽ˡ⁾ — forward pass δ⁽ˡ⁾ = ∂L/∂z⁽ˡ⁾ — backward pass

Forward pass. Each layer computes the weighted-sum basis function and then softmax:

layer ℓz(ℓ) = W(ℓ)a(ℓ−1) + b(ℓ)a(ℓ) = softmax(z(ℓ))
1(0.400, 0.500, −0.500)(0.398, 0.440, 0.162)
2(0.091, 0.254, 0.206)(0.303, 0.357, 0.340)
3(0.450, 0.169)(0.570, 0.430)

For example, the first component of the first layer: z1(1) = 0.5 · 1.0 + (−0.4) · 0.5 + 0.1 = 0.400 and a1(1) = e0.400/e0.400 + e0.500 + e−0.500 = 0.398. The network gives the correct class the probability 0.570, so the loss is L = −ln 0.570 = 0.562.

The last layer (ℓ = 3). By Theorem 2:

δ(3) = a(3) − t = 0.5700.430 − 10 = −0.4300.430,   ∂L/∂W(3) = δ(3)(a(2))T = −0.4300.430 0.3030.3570.340 = −0.130−0.153−0.1460.1300.1530.146,   ∂L/∂b(3) = δ(3).

A negative δ1 means “increase z1”: the descent step subtracts the negative gradient, so the weights into the correct output grow and the weights into the wrong one decrease. The components sum to zero (Corollary 5).

Layer n − 1 (ℓ = 2). By Theorem 3 we first send the error back along the weights:

g(2) = (W(3))Tδ(3) = 1.2−0.5−0.70.60.40.9 −0.4300.430 = −0.7310.5590.215,

for example g1 = 1.2 · (−0.430) + (−0.5) · 0.430 = −0.731. Then through the softmax of layer 2. The Jacobian matrix and the weighted average are

J(2) = diag(a(2)) − a(2)(a(2))T = 0.211−0.108−0.103−0.1080.229−0.121−0.103−0.1210.224,   a(2)·g(2) = 0.051,

and so δ(2) = J(2)g(2) = −0.2370.1810.056; for example δ1(2) = 0.303 · (−0.731 − 0.051) = −0.237. The gradient of the weights:

∂L/∂W(2) = δ(2)(a(1))T = −0.094−0.104−0.0380.0720.0800.0290.0220.0250.009,   ∂L/∂b(2) = δ(2).

Layer 1. The same recursion one layer lower (Theorem 4):

g(1) = (W(2))Tδ(2) = −0.2150.2410.017,   a(1)·g(1) = 0.023,   δ(1) = a(1) ⊙ (g(1) − 0.023 · 1) = −0.0950.096−0.001,

∂L/∂W(1) = δ(1)xT = −0.0948−0.04740.09590.0479−0.0011−0.0005.

The size of the error shrinks on the way back: ‖δ(3)‖ = 0.608, ‖δ(2)‖ = 0.304, ‖δ(1)‖ = 0.135 — exactly as Theorem 6 predicts. That is why the weights of the first layer learn the slowest.

Check and step. Backpropagation is just the chain rule, and so it can be verified numerically: the central difference L(W11(1) + h) − L(W11(1) − h)/2h with h = 10−6 gives −0.094798 and the backward pass −0.094798. One descent step with η = 1.0 (all weights and biases at once, W(ℓ) ← W(ℓ) − η ∂L/∂W(ℓ)) lowers the loss from 0.562 to 0.147, and the probability of the correct class rises from 0.570 to 0.863.

4. Learning rate: how long a step

The step length is the most important choice in the whole algorithm. We show it on the simplest landscape, the parabola J(x) = x2, starting at x = 4. The derivative is 2x, so each step does x ← x − η · 2x = (1 − 2η)x. Twelve steps for four different learning rates:

parameter x (unitless) loss f(x) (unitless) η = 0.1 — slowly
parameter x (unitless) loss f(x) (unitless) η = 0.4 — fast
parameter x (unitless) loss f(x) (unitless) η = 0.9 — oscillates
parameter x (unitless) loss f(x) (unitless) η = 1.05 — diverges
Twelve steps along the parabola x² for four learning rates
  • η = 0.1 — each step shortens the distance to the minimum by only a fifth. After twelve steps the ball is still only at x ≈ 0.27.
  • η = 0.4 — each step shortens it fivefold; after a few steps the ball is practically at the bottom.
  • η = 0.9 — the step is so long that the ball jumps over to the other side. Still it gets closer, because it jumps ever shorter arcs.
  • η = 1.05 — every time it jumps further than it was: instead of going down it flies outward, and after twelve steps it is at x ≈ 12.55. Learning diverges.
Theorem — when descent on the parabola converges

Let J : ℝ → ℝ, J(x) = x2, a start x0 ∈ ℝ, x0 ≠ 0, a learning rate η > 0 and xt+1 = xt − ηJ′(xt) for t = 0, 1, 2, … Then

  1. xt = (1 − 2η)t x0 for all t ∈ ℕ0;
  2. xt → 0 (descent converges to the minimum) if and only if |1 − 2η| < 1, i.e. if and only if η < 1;
  3. for η = 0.5, x1 = 0 — descent ends in the minimum in a single step.

Proof. One step is xt+1 = xt − η · 2xt = (1 − 2η)xt; by induction we get the power. The sequence qt tends to zero exactly for |q| < 1. ∎

xt = (1 − 2η)t x0

xt
the position after t steps — at the same time the distance from the minimum at zero
1 − 2η
the coefficient of one step — the number 2 is the second derivative (curvature) of the parabola; how much a step shortens the distance depends on the product of the learning rate and the curvature. A negative coefficient means jumping over to the other side
t
the number of steps — the coefficient multiplies again at every step, which is why the distance shrinks (or grows) geometrically
x0
the start — the result is proportional to it: twice as far from the minimum means twice as far after t steps too
The whole course of descent on the parabola in one formula.
Example — the numbers from the figure

η = 0.1: coefficient 1 − 0.2 = 0.8,   x1 = 0.8 · 4 = 3.2,   x12 = 0.812 · 4 ≈ 0.0687 · 4 ≈ 0.27

η = 0.4: coefficient 0.2,   x1 = 0.8,   x2 = 0.16,   x3 = 0.032 — each step five times closer

η = 0.9: coefficient −0.8,   x1 = −3.2,   x2 = 2.56,   x3 = −2.048 — it jumps, but |x| decreases

η = 1.05: coefficient −1.1,   x1 = −4.4,   x2 = 4.84,   x12 = (−1.1)12 · 4 ≈ 3.138 · 4 ≈ 12.55

Theorem — a general bound on the learning rate

(1) Let a > 0, J : ℝ → ℝ, J(x) = ax2/2 (the second derivative is a), η > 0 and x0 ≠ 0. Then a descent step is x ← (1 − ηa)x, and descent converges to the minimum 0 if and only if

0 < η < 2/a.

The parabola x2 has a = 2, hence the bound 1.

(2) In general: let J : ℝd → ℝ be differentiable with a gradient that has a Lipschitz constant L > 0, i.e. ‖∇J(u) − ∇J(v)‖ ≤ L‖u − v‖ for all u, v ∈ ℝd (the curvature nowhere exceeds L), and let 0 < η ≤ 1/L. Then J(θt+1) ≤ J(θt) for every t — the loss does not increase in any step (a standard result, see e.g. Nesterov: Introductory Lectures on Convex Optimization, 2004, sec. 1.2.3). So the learning rate must be governed by the steepest curvature of the landscape.

In plain words

A small step is safe but slow. A big step is fast until it overshoots. Too big a step breaks learning: instead of falling, the error grows until it becomes infinite.

5. Narrow valleys and zigzag

Real landscapes are not round bowls. They tend to be long, narrow valleys — steep in one direction, almost flat in another. Take J(x, y) = x2/2 + 10y2, twentyfold steeper in the y direction. Plain descent has a problem here: the learning rate must be small because of the steep direction (otherwise it would diverge in y), and with such a small step it barely moves in the flat x direction. On top of that, in the y direction it keeps jumping from side to side:

parameter x (unitless) parameter y (unitless)
Three methods in a narrow valley: how many steps to a loss below 0.01 gradient descent: 36 stepsmomentum: 9 stepsAdam: 9 steps

Each method has its own best learning rate, found by trial. Even so, plain descent needs 36 steps and zigzags, while momentum and Adam are at the bottom in 9. The next two chapters show why.

Why plain descent zigzags in the valley

The gradient of the valley is ∇J(x, y) = (x, 20y) — each coordinate has its own curvature, 1 in the x direction and 20 in the y direction. A descent step therefore splits into two independent steps, as with the parabola above:

x ← (1 − η · 1) x,   y ← (1 − η · 20) y

x
the coordinate along the bottom of the valley — here the landscape is almost flat
1 − η · 1
the coefficient in the flat direction — the small curvature 1 gives a coefficient close to 1, so x shrinks only a little at each step
y
the coordinate across the valley — steep walls
1 − η · 20
the coefficient in the steep direction — the curvature 20 quickly pulls it below zero; for its absolute value to stay below 1, η must be < 2/20 = 0.1
One learning rate for both directions: the steep direction decides how large it may be, and the flat direction then suffers.
Definition — condition number

Let d ≥ 1 and let A ∈ ℝd×d be a symmetric positive definite matrix; its eigenvalues are real and positive; let λmin > 0 be the smallest and λmax the largest of them. The condition number of the matrix A is

κ = λmax/λmin ≥ 1,

the ratio of the largest and the smallest eigenvalue. For a quadratic loss J : ℝd → ℝ, J(θ) = 1/2 θTAθ, the eigenvalues of A are the curvatures in the principal directions, and the condition number of the loss is the condition number of A. Our valley has A = diag(1, 20), so κ = 20.

For this loss the following holds (a standard result): gradient descent with learning rate η converges from every start if and only if 0 < η < 2/λmax. Even with the best fixed choice η = 2/λmin + λmax we only have ‖θt+1‖ ≤ κ − 1/κ + 1 ‖θt‖ (the minimum is at θ = 0) — for us 19/21 ≈ 0.905. The larger κ, the closer this coefficient is to 1 and the slower the descent.

In plain words

The condition number says how many times the steepest direction is steeper than the flattest. A round bowl has 1 and descent goes straight down. A valley with the number 20 is twenty times “more elongated”, and descent wastes time in it.

Example — where the 36 steps come from

η = 0.09:   x ← 0.91 · x,   y ← (−0.8) · y   (colours as in the formula above)

start (−4.0, 1.2),   after step 1 (−3.64, −0.96),   after step 2 (−3.312, 0.768),   after step 3 (−3.014, −0.614)

The sign of y alternates (the coefficient is negative) — that is the zigzag; |y| shrinks 1.25 times per step, x only 1.1 times.

A loss below 0.01 mainly requires x2/2 < 0.01, that is |x| < √0.02 ≈ 0.141:

4 · 0.91t < 0.141   ⇔   t > ln 0.141/4/ln 0.91 ≈ 35.4,   so 36 steps.

6. Momentum: a ball with inertia

Definition — descent with momentum

Let J : ℝd → ℝ be a differentiable loss function, θ0 ∈ ℝd the initial parameters, η > 0 the learning rate and β ∈ [0, 1) the momentum coefficient. Descent with momentum sets v0 = 0 ∈ ℝd and for t = 0, 1, 2, … computes

vt+1 = β vt − η ∇J(θt),   θt+1 = θt + vt+1;

it stops in the same way as gradient descent (a small gradient or the number of steps used up). The vector vt ∈ ℝd is the “velocity”, and β says how much of it carries over to the next step (typically 0.9; in our valley 0.6 works best). For β = 0 it is plain gradient descent.

In plain words

Instead of a careful walker, a heavy ball. Where the gradient keeps pointing the same way (along the valley), the ball picks up speed. Where the direction alternates (across the valley), the back-and-forth movements cancel each other out. The zigzag dies down and the ball rolls on downhill.

vt+1 = β vt − η ∇J(θt)

vt+1
the new velocity — the parameters move by this much in this step (θt+1 = θt + vt+1)
β
“imperfect friction” — how much of the previous velocity remains; it must be less than 1, otherwise old gradients would never be forgotten and the ball would not stop
vt
the previous velocity — the memory of previous steps; thanks to it, steps in the same direction add up and steps back and forth cancel
η ∇J(θt)
an ordinary descent step — the “force” that pushes the ball downhill at this point
Written out: vt = −η(∇Jt−1 + β∇Jt−2 + β2∇Jt−3 + …) — a sum of past gradients with weights that fade geometrically.
Theorem — momentum lengthens the step up to 1/1 − β times

Let η > 0, β ∈ [0, 1), g ∈ ℝd, let the gradient stay the same throughout the descent, ∇J(θt) = g for all t (an even slope), and v0 = 0. Then for every t ≥ 1

vt = −ηg(1 + β + … + βt−1) = −ηg 1 − βt/1 − β   and   vt → −η/1 − β g   for t → ∞.

Proof. By induction from vt+1 = βvt − ηg; the sum of a geometric series, and βt → 0 because 0 ≤ β < 1. ∎

On an even slope the step therefore settles at η/1 − β times the gradient: for β = 0.6 that is a 2.5 times longer step, for the usual β = 0.9 ten times. When the sign of the gradient alternates, the sum of the series, on the contrary, almost cancels out.

Example — the first two steps in the valley (η = 0.1, β = 0.6)

θ0 = (−4, 1.2),   ∇J = (−4, 24),   v1 = −0.1 · (−4, 24) = (0.4, −2.4),   θ1 = (−3.6, −1.2)

∇J(θ1) = (−3.6, −24),   v2 = 0.6 · (0.4, −2.4) − 0.1 · (−3.6, −24) = (0.24 + 0.36, −1.44 + 2.4) = (0.6, 0.96)   (colours as in the formula above)

θ2 = (−3.6 + 0.6, −1.2 + 0.96) = (−3.00, −0.24)

In the x direction the step lengthened from 0.4 to 0.6 (the gradient keeps the same sign); in the y direction the velocity −2.4 and the new pull +2.4 almost cancelled out, and the ball is near the bottom of the valley (y = −0.24). After two steps plain descent is only at (−3.31, 0.77).

7. Adam: its own step for every parameter

Definition — Adam (Kingma and Ba, 2014)

Let J : ℝd → ℝ be a differentiable loss function. Adam is the algorithm:

  • input: initial parameters θ0 ∈ ℝd, a learning rate η > 0, coefficients β1, β2 ∈ [0, 1), a small number ε > 0 and a number of steps T ∈ ℕ;
  • output: the parameters θT ∈ ℝd.

Set m0 = s0 = 0 ∈ ℝd and for t = 1, 2, …, T do (all operations on vectors — square, square root, division — are element-wise):

  1. gt = ∇J(θt−1);
  2. mt = β1mt−1 + (1 − β1)gt (average of the gradients);
  3. st = β2st−1 + (1 − β2)gt2 (average of the squares of the gradients);
  4. m̂t = mt/1 − β1t,   ŝt = st/1 − β2t (bias correction, see the next definition);
  5. θt = θt−1 − η m̂t/√ŝt + ε.

Usual values: β1 = 0.9, β2 = 0.999, ε = 10−8. So Adam takes a step in the direction of the average gradient, divided in each component by the typical size of the gradient in that component.

In plain words

Adam is momentum that additionally remembers, for each parameter, how large its gradients tend to be, and divides the step by them. So in the steep direction it takes shorter steps, in the flat one longer — as if the valley were stretched into a round bowl. That is why it heads to the goal almost straight (in the figure it only overshoots a little at the end, because it still carries inertia), and why it is today the default choice for training neural networks.

Definition — exponential moving average

Let g1, g2, … be a sequence of real numbers (or vectors in ℝd) and β ∈ [0, 1). The exponential moving average of this sequence is the sequence (mt)t ≥ 0 given by the recursion

m0 = 0,   mt = βmt−1 + (1 − β)gt   for t ≥ 1,

written out mt = (1 − β) ∑k=1t βt−kgk. For t ≥ 1 and β > 0 its bias correction is

m̂t = mt/1 − βt.

The weights (1 − β)βt−k, k = 1, …, t, add up to only 1 − βt, not 1 — the missing part falls on the initial zero. That is why mt is biased towards zero at the beginning, and the correction turns it into a true weighted average (after the correction the weights sum to 1; with a constant gk = g, exactly m̂t = g).

θ ← θ − η · m̂/√ŝ + ε

θ
the parameters; everything else is computed element-wise, so each parameter has its own step
η
the learning rate — since the rest of the fraction has a size of roughly 1, for Adam η is directly the approximate step length in each parameter
m̂
the corrected average of the gradients (the first moment) — the direction, as with momentum: noise and zigzag cancel out in the average
√ŝ
the square root of the average of the squares of the gradients (the second moment) — the typical size of the gradient in this parameter; dividing by it brings the steep and the flat direction to the same scale
ε
a small number (typically 10−8) — just a safeguard so as not to divide by zero for a parameter whose gradient is always zero
Step = learning rate × direction/typical size — the step length no longer depends on how steep the given direction is.
Example — Adam’s first step in the valley (η = 0.5)

g = ∇J(−4, 1.2) = (−4, 24),   m1 = (1 − β1)g,   m̂1 = m1/1 − β1 = g = (−4, 24)

s1 = (1 − β2)g2,   ŝ1 = g2 = (16, 576),   √ŝ1 = (4, 24)

m̂1/√ŝ1 ≈ (−4/4, 24/24) = (−1, 1)   (we neglect ε = 10−8),   θ1 = (−4, 1.2) − 0.5 · (−1, 1) = (−3.5, 0.7)   (colours as in the formula above)

The gradient in the y direction is six times larger than in the x direction, and yet both parameters moved by the same 0.5. Plain descent would have moved six times further in the y direction than in the x direction.

def adam(grad_J, theta, eta, beta1=0.9, beta2=0.999, eps=1e-8, kroku=1000):
    m = s = 0                                   # vectors of zeros, the same size as theta
    for t in range(1, kroku + 1):
        g = grad_J(theta)
        m = beta1 * m + (1 - beta1) * g         # average of the gradients (direction)
        s = beta2 * s + (1 - beta2) * g**2      # average of the squares (size), element-wise
        m_hat = m / (1 - beta1**t)              # correction for the initial zero
        s_hat = s / (1 - beta2**t)
        theta = theta - eta * m_hat / (sqrt(s_hat) + eps)
    return theta

8. Stochastic descent: learning in batches

Definition — stochastic gradient descent (SGD)

Let n ≥ 1 be the number of examples in the data, let L1, …, Ln : ℝd → ℝ be the differentiable losses of the individual examples, and let the total loss be their average

J(θ) = 1/n ∑i=1n Li(θ).

Stochastic gradient descent is gradient descent (with the inputs θ0, η and a number of steps as above) in which at each step t, instead of ∇J(θt), the estimate

gt = 1/|Bt| ∑i ∈ Bt ∇Li(θt),   θt+1 = θt − ηgt

is used, where the mini-batch Bt ⊆ {1, …, n} is a non-empty set of indices chosen anew at random at each step (typically of a fixed size |Bt| ≪ n). An epoch is a stretch of steps during which each of the n examples is used exactly once (when the data are shuffled and gone through in batches of size b, that is n/b steps, if n is divisible by b).

In plain words

Computing the gradient over a billion examples is expensive. It is enough to look at a few random ones and take their average: the estimate of the slope is a little noisy, but it costs a fraction of the work. For the price of one exact step you take hundreds of approximate ones.

g = 1/|B| ∑i ∈ B ∇Li(θ)

g
the estimate of the gradient — used instead of ∇J(θ) in the usual step θ ← θ − ηg
1/|B|
division by the batch size — it turns the sum into an estimate of the whole average J; without it a larger batch would mean a longer step
∑i ∈ B
the sum only over the randomly chosen batch — this is where the saving is: |B| computations instead of n
∇Li(θ)
the gradient of the loss on one example — the direction in which this particular example would like to move the parameters
The average of the “wishes” of a few random examples as an estimate of the wishes of all.
Theorem — the batch gradient is an unbiased estimate

Let J = 1/n ∑i=1n Li be as in the definition of SGD, θ ∈ ℝd fixed and b ≥ 1. Let I1, …, Ib be independent random indices, each uniformly distributed on {1, …, n} (sampling with replacement), and

g = 1/b ∑k=1b ∇LIk(θ).

Then

  1. E[g] = ∇J(θ) — the estimate is unbiased;
  2. for each component j = 1, …, d, var(gj) = 1/b var(∂LI1/∂θj(θ)), so the standard deviation (typical error) of the estimate decreases as 1/√b.

Proof. (1) For one random index I, E[∇LI(θ)] = ∑i=1n 1/n ∇Li(θ) = ∇J(θ); the average of b such estimates has the same expected value. (2) The variance of the average of b independent identically distributed quantities is the variance of one divided by b. ∎

In practice (and in our program) the data are shuffled instead of sampled independently and taken in batches one after another — each example is used exactly once per epoch. That hardly changes the shape of the conclusion.

Definition — mean squared error (MSE) and its gradient

Let n ≥ 1 and let (xi, yi) ∈ ℝ2, i = 1, …, n, be the data. For the parameters (a, b) ∈ ℝ2 of the line ŷ = ax + b, the mean squared error is the function J : ℝ2 → ℝ,

J(a, b) = 1/n ∑i=1n (axi + b − yi)2.

Let ei = axi + b − yi denote the error on the i-th example. Then (derivative of a composite function)

∂J/∂a = 2/n ∑i=1n eixi,   ∂J/∂b = 2/n ∑i=1n ei.

SGD computes the same sums, only over the batch B and with 2/|B| instead of 2/n.

def sgd(data, theta, eta, davka, epoch):
    for _ in range(epoch):
        zamichej(data)                            # a new random order in every epoch
        for zacatek in range(0, len(data), davka):
            B = data[zacatek : zacatek + davka]
            g = prumer(grad_L(theta, priklad) for priklad in B)
            theta = theta - eta * g
    return theta

On a linear regression with 40 points we compare full descent (gradient over all 40 points) with SGD in batches of 4 points:

0.10.010.001 step (iteration) MSE loss (log scale)
Loss over 60 steps (logarithmic axis) full descent SGD, batches of 4

After 60 steps full descent has a loss of 0.0017 and SGD 0.0027 — the SGD curve is bumpy, but almost as low. Yet each SGD step went through only 4 points instead of 40, that is tenfold less work. With real data of millions of examples, that difference is decisive. And the noise has an upside too: it helps jump out of shallow pits.

full descent: 60 steps · 40 points = 2,400 gradients of individual points = 60 epochs

SGD: 60 steps · 4 points = 240 gradients = 240/40 = 6 epochs

9. Local minima and saddle points

Gradient descent finds the bottom of the valley it started in. A convex function has only one bottom; for a non-convex one it depends on the start. The function x4 − 3x2 + x from the part on functions has two minima:

local minimum global minimum parameter x (unitless) loss f(x) (unitless)
Same algorithm, different start, different bottom

A ball starting at x = 2 ends up in the local minimum at x ≈ 1.13 with value ≈ −1.07. A ball from x = −2 finds the global minimum at x ≈ −1.30 with value ≈ −3.51. In the high dimensions of neural networks it turns out that bad local minima are rarer than one would expect — the bigger trouble tends to be saddle points, places where the gradient is zero but the landscape goes up in one direction and down in another. The noise of SGD and momentum help slide off them.

Definition — local and global minimum, stationary point, saddle point

Let J : ℝd → ℝ and θ* ∈ ℝd.

  1. θ* is a global minimum of J if and only if ∀θ ∈ ℝd : J(θ*) ≤ J(θ).
  2. θ* is a local minimum of J if and only if ∃r > 0 ∀θ ∈ ℝd : ‖θ − θ*‖ < r ⇒ J(θ*) ≤ J(θ). A local maximum is defined in the same way with ≥ instead of ≤.
  3. If J is differentiable, θ* is a stationary point if and only if ∇J(θ*) = 0.
  4. θ* is a saddle point if and only if it is a stationary point and neither a local minimum nor a local maximum.

Gradient descent stops at a stationary point, whatever it is. If J is twice continuously differentiable, the type of a stationary point is distinguished by the Hessian matrix H ∈ ℝd×d, Hij = ∂2J/∂θi ∂θj(θ*): if all its eigenvalues are positive, θ* is a local minimum; all negative — a local maximum; both positive and negative — a saddle point. If some eigenvalue is zero and the others have the same sign, the test does not decide.

Example — the stationary points of the function x⁴ − 3x² + x

f ′(x) = 4x3 − 6x + 1 = 0   ⇒   x ≈ −1.301,   x ≈ 0.170,   x ≈ 1.131 (numerically, by Newton’s method)

f ″(x) = 12x2 − 6:   f ″(−1.301) ≈ 14.3 > 0 — minimum,   f ″(0.170) ≈ −5.65 < 0 — maximum,   f ″(1.131) ≈ 9.35 > 0 — minimum

f(−1.301) ≈ −3.51,   f(0.170) ≈ 0.08,   f(1.131) ≈ −1.07

The maximum near 0.17 is the “ridge” between the two valleys: a ball starting to the right of it rolls into the local minimum, to the left into the global one. A saddle point cannot arise in one variable — it needs at least two directions. The simplest is J(x, y) = x2 − y2: at the origin ∇J = (2x, −2y) = 0, and H = diag(2, −2) has eigenvalues of both signs.

Theorem — for a convex function every local minimum is global

Definition. Let J : ℝd → ℝ. The function J is convex if and only if

∀u, v ∈ ℝd ∀λ ∈ [0, 1] : J(λu + (1 − λ)v) ≤ λJ(u) + (1 − λ)J(v)

— the segment between two points of the graph nowhere lies below the graph.

Theorem. Let J : ℝd → ℝ be convex and θ* ∈ ℝd a local minimum of J. Then θ* is a global minimum of J.

Proof. Suppose for contradiction that there is u ∈ ℝd with J(u) < J(θ*). For the points θλ = λu + (1 − λ)θ* we have J(θλ) ≤ λJ(u) + (1 − λ)J(θ*) < J(θ*) for every λ ∈ (0, 1]. For small λ, θλ lies arbitrarily close to θ* — a contradiction with local minimality. ∎

The parabola and the valley from the previous sections are convex; the loss of a neural network with nonlinear activations in general is not — that is why the start matters for networks.

10. How it is done in practice

  • Adam or SGD with momentum — the two most common choices. Adam works well right away; SGD with momentum tends to be a little better after careful tuning.
  • Learning-rate schedule — a slow start at the beginning (warmup), then a gradual decrease. Big steps pay off far from the goal, small ones close to it.
  • Batch size — typically 32 to thousands of examples; it is limited by the memory of the graphics card.
  • Epochs and early stopping — the data is passed through repeatedly, and training stops when the error on data the model has not seen stops improving.
  • Data normalization — when the inputs have a similar range, the landscape is rounder and descent is easier.

11. Summary

  • Gradient descent repeats θ ← θ − η∇J(θ): a step against the gradient.
  • The learning rate decides: a small one is slow, a large one oscillates, too large diverges.
  • In narrow valleys plain descent zigzags; momentum adds inertia, Adam its own step for every parameter.
  • SGD computes the gradient from small batches — it is noisy, but every step is many times cheaper.
  • Descent finds the bottom of the valley it started in; in non-convex landscapes the start matters.

With this part, the mathematics you need to understand learning is complete. The next modules of the series — probability, machine learning and neural networks — build on it.

Do you see it differently? Write to support@coden-app.com.

An Agent on your computer, driven from your phone