TAI BUI
Back to curriculum
LearnPython

Calculus for Machine Learning

A derivative tells you which way is downhill. That's the entire trick a neural network uses to learn.

TIME: ~60 minutesPREREQUISITES: Phase 1, Lessons 01-03

Learning Objectives

  • Compute numerical and analytical derivatives for common ML functions (x^2, sigmoid, cross-entropy)
  • Implement gradient descent from scratch to minimize a loss function in 1D and 2D
  • Derive the gradient of a linear regression model and train it via manual weight updates
  • Explain the Hessian matrix, Taylor series approximations, and their connection to optimization methods

The Problem

A neural network can have millions of weights, and every one of them is a knob. Training means turning each knob in whatever direction makes the model slightly less wrong. Calculus is what tells you that direction.

Without it, you'd be trying random changes and hoping for the best. With a derivative for every weight, you know exactly how nudging that one number moves the error, so you turn each knob the right way instead of guessing.

Warm-up0/3
1. If a hiking trail is flat at one point and steeply uphill at another, at which point are you working harder to climb, instant by instant?Warm-up
A side-view line of a hiking trail's height over distance, nearly flat for the first stretch then rising steeply, with Point A marked on the flat part and Point B marked on the steep part.
2. Standing on a hillside, you want to walk uphill as fast as possible. Common sense says you should walk in whichever direction the ground...Warm-up
A topographic-style view from above of a hillside with concentric rings around a hiker's position at the center, and five labeled arrows pointing in different walking directions, with no steepness given for any of them.
3. A straight line passes through the points (0, 1) and (2, 5). What is its slope?Warm-up
A line on a grid passing through two marked points, (0, 1) and (2, 5), with axes numbered but no rise, run or slope value written anywhere.

The Concept

What is a derivative?

A derivative measures the rate of change: for a function y = f(x), f'(x) tells you how much y moves when you nudge x by a tiny amount.

Geometrically, it's the slope of the tangent line at that point.

f(x) = x^2:

xf(x)f'(x) (slope)
000 (flat, at the bottom)
112
244 (tangent line slope at this point)
396

At x=2 the slope is 4: nudge x slightly to the right and y moves by roughly four times that nudge. At x=0 the slope is 0, so you're sitting at the bottom of the bowl.

The formal definition:

f'(x) = lim   f(x + h) - f(x)
        h->0  -----------------
                     h

In code, skip the limit and use a very small h instead. That's the numerical derivative.

Partial derivatives: one variable at a time

A partial derivative holds every variable constant except one, then takes the derivative with respect to that single variable. Real functions have many inputs, and a neural network's loss depends on thousands of weights, so isolating the effect of just one of them at a time is exactly what a partial derivative gives you.

f(x, y) = x^2 + 3xy + y^2

df/dx = 2x + 3y     (treat y as a constant)
df/dy = 3x + 2y     (treat x as a constant)

Each partial derivative answers one question: nudge just this one weight, how does the loss move?

The gradient: vector of all partial derivatives

The gradient collects every partial derivative into a single vector. For a function f(x, y, z):

grad f = [ df/dx, df/dy, df/dz ]

It points in the direction of steepest ascent, so to minimize a function you walk the opposite way.

Contour plot of f(x,y) = x^2 + y^2:

The function forms a bowl shape with concentric circles as contour lines. The minimum is at (0, 0).

Pointgrad f-grad f (descent direction)
(1, 1)[2, 2] (points uphill, away from minimum)[-2, -2] (points downhill, toward minimum)
(0, 0)[0, 0] (flat, at the minimum)[0, 0]

That's gradient descent in one picture: compute the gradient, flip its sign, take a step.

The connection to optimization

Training a neural network is an optimization problem. The loss function L(w1, w2, ..., wn) measures how wrong the model is, and the goal is to minimize it.

Gradient descent update rule:

  w_new = w_old - learning_rate * dL/dw

For every weight:
  1. Compute the partial derivative of loss with respect to that weight
  2. Subtract a small multiple of it from the weight
  3. Repeat

The learning rate sets the step size: too big and you overshoot the minimum, too small and you crawl toward it.

Loss landscape (1D slice):

The loss function L(w) forms a curve with peaks and valleys as the weight w varies.

FeatureDescription
Global minimumThe lowest point on the entire curve: the best solution
Local minimumA valley that is lower than its neighbors but not the lowest overall
SlopeGradient descent follows the slope downhill from any starting point

Gradient descent just follows the slope downhill. It can get stuck in a local minimum, but in a high-dimensional space with millions of weights, that turns out to rarely matter in practice.

Numerical vs analytical derivatives

There are two ways to compute a derivative.

Analytical: apply the rules of calculus by hand. For f(x) = x^2, that gives f'(x) = 2x. Exact. Fast.

Numerical: approximate straight from the definition. Compute f(x+h) and f(x-h) for a tiny h, then take the difference.

Numerical (central difference):

f'(x) ~= f(x + h) - f(x - h)
          -----------------------
                  2h

h = 0.0001 works well in practice

Numerical derivatives are slower but work for any function; analytical derivatives are fast but require deriving the formula by hand. Neural network frameworks use a third approach: automatic differentiation, which computes exact derivatives mechanically. You'll meet it in Phase 3.

Derivatives by hand for simple functions

You'll see these same derivatives over and over in ML.

Function        Derivative       Used in
--------        ----------       -------
f(x) = x^2     f'(x) = 2x      Loss functions (MSE)
f(x) = wx + b  f'(w) = x        Linear layer (gradient w.r.t. weight)
                f'(b) = 1        Linear layer (gradient w.r.t. bias)
                f'(x) = w        Linear layer (gradient w.r.t. input)
f(x) = e^x     f'(x) = e^x     Softmax, attention
f(x) = ln(x)   f'(x) = 1/x     Cross-entropy loss
f(x) = 1/(1+e^-x)  f'(x) = f(x)(1-f(x))   Sigmoid activation

For f(x) = x^2:

f(x) = x^2    f'(x) = 2x

  x    f(x)   f'(x)   meaning
  -2    4      -4      slope tilts left (decreasing)
  -1    1      -2      slope tilts left (decreasing)
   0    0       0      flat (minimum!)
   1    1       2      slope tilts right (increasing)
   2    4       4      slope tilts right (increasing)

For f(w) = wx + b with x=3, b=1:

f(w) = 3w + 1    f'(w) = 3

The derivative with respect to w is just x.
If x is big, a small change in w causes a big change in output.

The chain rule

The chain rule tells you how to differentiate a composition of functions.

If y = f(g(x)), then dy/dx = f'(g(x)) * g'(x)

Example: y = (3x + 1)^2
  outer: f(u) = u^2       f'(u) = 2u
  inner: g(x) = 3x + 1    g'(x) = 3
  dy/dx = 2(3x + 1) * 3 = 6(3x + 1)

A neural network is nothing but a chain of functions: input -> linear -> activation -> linear -> activation -> loss. Backpropagation is the chain rule applied over and over, from output back to input. That's the entire algorithm.

The Hessian Matrix

The gradient tells you the slope. The Hessian tells you the curvature.

The Hessian is the matrix of second-order partial derivatives. For a function f(x1, x2, ..., xn), entry (i, j) of the Hessian is:

H[i][j] = d^2f / (dx_i * dx_j)

For a 2-variable function f(x, y):

H = | d^2f/dx^2    d^2f/dxdy |
    | d^2f/dydx    d^2f/dy^2 |

What the Hessian tells you at a critical point (where gradient = 0):

Hessian propertyMeaningExample surface
Positive definite (all eigenvalues > 0)Local minimumBowl pointing up
Negative definite (all eigenvalues < 0)Local maximumBowl pointing down
Indefinite (mixed eigenvalues)Saddle pointHorse saddle shape

Example: f(x, y) = x^2 - y^2 (a saddle function)

df/dx = 2x       df/dy = -2y
d^2f/dx^2 = 2    d^2f/dy^2 = -2    d^2f/dxdy = 0

H = | 2   0 |
    | 0  -2 |

Eigenvalues: 2 and -2 (one positive, one negative)
--> Saddle point at (0, 0)

Compare with f(x, y) = x^2 + y^2 (a bowl):

H = | 2  0 |
    | 0  2 |

Eigenvalues: 2 and 2 (both positive)
--> Local minimum at (0, 0)

Why the Hessian matters in ML:

Newton's method uses the Hessian to take better optimization steps than gradient descent. Instead of just following the slope, it accounts for curvature:

Newton's update:    w_new = w_old - H^(-1) * gradient
Gradient descent:   w_new = w_old - lr * gradient

Newton's method converges faster because the Hessian "rescales" the gradient: steep directions get smaller steps, flat directions get larger steps.

The catch: for a neural network with N parameters, the Hessian is N x N. A model with 1 million parameters would need a 1 trillion-entry matrix, which is why practical optimizers approximate it instead of computing it directly.

MethodWhat it usesCostConvergence
Gradient descentFirst derivatives onlyO(N) per stepSlow (linear)
Newton's methodFull HessianO(N^3) per stepFast (quadratic)
L-BFGSApproximate Hessian from gradient historyO(N) per stepMedium (superlinear)
AdamPer-parameter adaptive rates (diagonal Hessian approx)O(N) per stepMedium
Natural gradientFisher information matrix (statistical Hessian)O(N^2) per stepFast

In practice, Adam is the default optimizer in deep learning: it approximates second-order information cheaply by tracking a running mean and variance of the gradients for each parameter.

Taylor Series Approximation

Any smooth function can be approximated locally by a polynomial:

f(x + h) = f(x) + f'(x)*h + (1/2)*f''(x)*h^2 + (1/6)*f'''(x)*h^3 + ...

The more terms you include, the better the approximation gets, though only close to x.

Why Taylor series matter for ML:

  • First-order Taylor = gradient descent. When you use f(x + h) ~ f(x) + f'(x)*h, you are making a linear approximation. Gradient descent minimizes this linear model to choose h = -lr * f'(x).

  • Second-order Taylor = Newton's method. Using f(x + h) ~ f(x) + f'(x)*h + (1/2)*f''(x)*h^2, you get a quadratic model. Minimizing it gives h = -f'(x)/f''(x), which is exactly Newton's step.

  • Loss function design. MSE and cross-entropy are smooth, which means their Taylor expansions are well-behaved. This is not an accident. Smooth losses make optimization predictable.

Approximation order    What it captures    Optimization method
-------------------    -----------------   -------------------
0th order (constant)   Just the value      Random search
1st order (linear)     Slope               Gradient descent
2nd order (quadratic)  Curvature           Newton's method
Higher orders          Finer structure     Rarely used in ML

The key insight: every gradient-based optimizer is doing the same thing, approximating the loss function locally and stepping to the minimum of that approximation.

Integrals in ML

Derivatives tell you rates of change. Integrals compute accumulation: area under a curve.

In ML, you rarely compute integrals by hand, but the concept is everywhere:

Probability. For a continuous random variable with density p(x):

P(a < X < b) = integral from a to b of p(x) dx

The area under the probability density curve between a and b is the probability of landing in that range.

Expected value. The average outcome weighted by probability:

E[f(X)] = integral of f(x) * p(x) dx

The expected loss over a data distribution is an integral. Training minimizes an empirical approximation of this.

KL divergence. Measures how different two distributions are:

KL(p || q) = integral of p(x) * log(p(x) / q(x)) dx

Used in VAEs, knowledge distillation, and Bayesian inference.

Normalization constants. In Bayesian inference:

p(w | data) = p(data | w) * p(w) / integral of p(data | w) * p(w) dw

The denominator is an integral over all possible parameter values. It is often intractable, which is why we use approximations like MCMC and variational inference.

Integral conceptWhere it appears in ML
Area under curveProbability from density functions
Expected valueLoss functions, risk minimization
KL divergenceVAEs, policy optimization, distillation
NormalizationBayesian posteriors, softmax denominator
Marginal likelihoodModel comparison, evidence lower bound (ELBO)

Multivariable Chain Rule in a Computation Graph

The chain rule isn't limited to a straight line of scalar functions. In a neural network, variables fan out and merge, and here's how derivatives flow through a simple forward pass:

Mermaid diagram

The backward pass runs the same graph right to left, computing gradients:

Mermaid diagram

Each arrow multiplies by its local derivative, and the gradient for any parameter is the product of every local derivative along the path from loss back to that parameter. Where paths branch and merge, you sum the contributions: that's the multivariate chain rule.

That's the whole of backpropagation: the chain rule applied mechanically across a computation graph, from output back to every input.

The Jacobian matrix

The Jacobian is the matrix containing every partial derivative of every output with respect to every input. Whenever a function maps a vector to a vector, the way a neural network layer does, that's the shape its derivative takes.

For f: R^n -> R^m, the Jacobian J is an m x n matrix:

x1x2...xn
f1df1/dx1df1/dx2...df1/dxn
f2df2/dx1df2/dx2...df2/dxn
...............
fmdfm/dx1dfm/dx2...dfm/dxn

You'll never compute a Jacobian by hand for a real network; PyTorch handles that. But knowing it exists tells you what to expect from the shapes in backpropagation: a layer that maps R^n to R^m has an m x n Jacobian, and the gradient flows backward through its transpose.

Why this matters for neural networks

Every weight in a neural network gets its own gradient, and that gradient tells you exactly how to nudge the weight to shrink the loss.

Mermaid diagram

Mermaid diagram

Each weight update:

  • W1 = W1 - lr * dL/dW1
  • W2 = W2 - lr * dL/dW2

The forward pass produces a prediction and a loss. The backward pass turns that loss into a gradient for every weight. Every weight takes a small step downhill, and you repeat that millions of times. That's deep learning.

Check: The Concept0/33
1. What does the derivative of a function at a point measure?Define
The curve f of x equals x squared with one point marked and a straight tangent line touching the curve only at that point, with a small triangle showing a change in x and a change in y but no numbers written.
2. What is a partial derivative?Define
The function f of x, y equals x squared plus 3xy plus y squared shown in two identical boxes, one labeled treat y as fixed and vary x only, the other labeled treat x as fixed and vary y only.
3. What is the gradient of a function of several variables?Define
Three arrows labeled d f d x, d f d y and d f d z all feeding into a bracketed column of three question marks labeled equals grad f.
4. What does gradient descent do?Define
A bowl-shaped curve with a ball marked at four positions connected by arrows, moving step by step from partway up the curve toward the bottom.
5. What is the learning rate in gradient descent?Define
The same bowl-shaped curve drawn twice: Run A with ten closely spaced marked positions, Run B with four widely spaced marked positions on its way down.
6. What does the chain rule let you compute?Define
A flow of five boxes labeled x, g, u, f and y in order with arrows between them, showing x passing through function g to become u, then through function f to become y.
7. What is the numerical (central difference) approximation for f'(x)?Define
The curve f of x equals x squared with three points marked, x minus h, x and x plus h, and a straight line connecting the two outer points, with no formula written.
8. What is backpropagation?Define
A flowchart of a forward pass: input flows through weight matrix W1, a relu activation, weight matrix W2, a softmax, and finally a loss, left to right.
Reused from the lesson's own forward-pass diagram.
9. For a function f: R^n -> R^m, what shape is its Jacobian matrix?Define
A box listing 3 inputs, x1, x2, x3, and a separate box listing 2 outputs, f1, f2, with an arrow from inputs toward outputs passing through a question mark labeled Jacobian J, and no grid or shape drawn.
10. What is the Hessian of a function?Define
A 2 by 2 bracketed grid holding the symbols d2f/dx2, d2f/dxdy, d2f/dydx and d2f/dy2, with no specific function or numbers given.
11. What does a Taylor series do?Define
A smooth curve with one marked point, next to two other curves, a straight dashed one and a gently bending dashed one, both touching the true curve closely near that point and separating from it farther away.
12. What does integrating a probability density p(x) over the range [a, b] give you?Define
A bell-shaped density curve p of x with the region between two marked points, a and b, shaded and marked with a question mark, no value given for the shaded area.
13. Which pairing of function and derivative is correct?Define
Two curve panels, a sigmoid S-shaped curve on the left and a natural log curve on the right, each labeled f of x and with f prime of x equals question mark written beneath it.
14. In gradient descent, what does the update rule 'w = w - lr * dL/dw' accomplish?Explain
A bowl-shaped loss curve L of w with the current weight w_old marked on its left slope, with no arrow or next position drawn.
15. Why does gradient descent subtract the gradient instead of adding it?Explain
A curve with one marked point and an arrow from that point labeled gradient, with no note about which direction is uphill or downhill.
16. What is the main tradeoff between numerical and analytical derivatives?Explain
Two separate flows: evaluate f at x plus h, evaluate f at x minus h, then subtract and divide by 2h, labeled numerical; and apply calculus rules to get a formula, labeled analytical.
17. In a computation graph where a variable's path to the loss branches and later merges, how does the multivariable chain rule say you compute the gradient for that variable?Explain
A box labeled w with two arrows leading to two separate boxes, path A and path B, and both of those leading into one shared final box labeled L, with a question mark where the two paths meet.
18. Why can't Newton's method (which uses the Hessian matrix) be directly applied to neural networks with millions of parameters?Explain
A box labeled N equals 1,000,000 parameters with an arrow into a box labeled Hessian N by N, 1,000,000,000,000 entries, with no judgment written about whether that is workable.
19. Why can Newton's method take better steps than plain gradient descent?Explain
Two curve panels side by side, a steeply curving bowl on the left and a gently curving bowl on the right, with no claim written about step size.
20. At a point where the gradient is zero, what does the Hessian add?Explain
A curve with one marked flat point labeled grad equals 0, next to a separate 2 by 2 matrix of question marks labeled Hessian, with nothing else drawn.
21. Which optimization method corresponds to keeping only the first-order term of a function's Taylor series approximation?Explain
A Taylor expansion f of x plus h approximately equals f of x plus f prime of x times h, with the quadratic term and beyond struck through and dropped, leaving only the linear piece.
22. At a critical point, the Hessian has one positive eigenvalue and one negative eigenvalue. What does this indicate?Explain
Two boxes, eigenvalue 1 marked positive and eigenvalue 2 marked negative, with a question asking what kind of critical point this describes, no shape or name drawn.
23. For f(x, y) = x^2 + 3xy + y^2, what is the partial derivative df/dy?Apply
The function f of x, y equals x squared plus 3xy plus y squared, with the terms 3xy and y squared underlined and a note to differentiate only those with respect to y, treating x as a constant.
24. For y = f(g(x)) = (3x + 1)^2, applying the chain rule dy/dx = f'(g(x)) * g'(x), what is dy/dx?Apply
Two boxes: outer f of u equals u squared with f prime of u equals 2u, and inner g of x equals 3x plus 1 with g prime of x equals 3, with a note that dy by dx equals f prime of g of x times g prime of x, not multiplied out.
25. For f(x, y) = x^2 + y^2, what is -grad f at the point (1, 1)?Apply
A bowl-shaped contour plot of f of x, y equals x squared plus y squared, concentric rings around the origin, with the point (1, 1) marked and one arrow labeled grad f equals [2, 2] pointing away from the center.
26. At a point where f'(x) = 6 and f''(x) = 2, what step h does Newton's method take?Apply
The Newton's method step formula, h equals negative f prime of x divided by f double prime of x, with f prime of x = 6 and f double prime of x = 2 given and h left as a question mark.
27. Your gradient descent loss drops for a few steps, then starts oscillating and growing without bound. What's the most likely cause?Analyze
A line chart of loss against training step that dips down briefly and then oscillates with swings that get larger each time, trending upward overall.
Illustrative: typed to match the pattern the stem describes, not a captured training run.
28. Gradient descent started exactly at (0, 0) on f(x, y) = x^2 - y^2 never moves. What explains it?Analyze
A contour plot of f of x, y equals x squared minus y squared, showing hyperbola-shaped curves and two diagonal lines through the origin, with the origin marked and labeled grad equals [0, 0].
29. Gradient descent on a 1D loss settles in a shallow valley while a deeper valley exists. What happened?Analyze
A curve with two valleys of different depths, with a marker resting at the bottom of the shallower valley on one side and a deeper valley visible elsewhere on the curve.
Minima found by scanning the real curve for points lower than both neighbors.
30. Which comparison of gradient descent and Newton's method per step is correct?Analyze
A table with columns method, what it uses, cost per step and converges; gradient descent uses first derivatives only and Newton's method uses the full Hessian, with the cost and converges columns left as question marks for both rows.
31. You must train a model with tens of millions of parameters and want more than plain gradient descent. Which design fits?Design
A chart of compute cost per step against parameter count N, with three unlabeled curves shaped like O(N), O(N^2) and O(N^3), and a vertical dashed line marking tens of millions of parameters.
32. A Bayesian posterior has a denominator that integrates over every parameter value and cannot be computed. What does the lesson point you toward?Design
Bayes' rule, p of w given data equals p of data given w times p of w divided by Z, with Z boxed and marked as an integral over every parameter value that cannot be computed directly, and a question about what to do instead.
33. You minimize a smooth loss with only 20 parameters. Which method is worth considering?Design
The same cost-against-parameter-count chart with three unlabeled O(N), O(N^2) and O(N^3) curves, now with the vertical dashed line marking N = 20.

Build It

Step 1: Numerical derivative from scratch

python
def numerical_derivative(f, x, h=1e-7):
    return (f(x + h) - f(x - h)) / (2 * h)
 
def f(x):
    return x ** 2
 
for x in [-2, -1, 0, 1, 2]:
    numerical = numerical_derivative(f, x)
    analytical = 2 * x
    print(f"x={x:2d}  f'(x) numerical={numerical:.6f}  analytical={analytical:.1f}")

The numerical result matches the analytical one out to many decimal places.

Step 2: Partial derivatives and gradients

python
def numerical_gradient(f, point, h=1e-7):
    gradient = []
    for i in range(len(point)):
        point_plus = list(point)
        point_minus = list(point)
        point_plus[i] += h
        point_minus[i] -= h
        partial = (f(point_plus) - f(point_minus)) / (2 * h)
        gradient.append(partial)
    return gradient
 
def f_multi(point):
    x, y = point
    return x**2 + 3*x*y + y**2
 
grad = numerical_gradient(f_multi, [1.0, 2.0])
print(f"Numerical gradient at (1,2): {[f'{g:.4f}' for g in grad]}")
print(f"Analytical gradient at (1,2): [2*1+3*2, 3*1+2*2] = [{2*1+3*2}, {3*1+2*2}]")

Step 3: Gradient descent to find the minimum of f(x) = x^2

python
x = 5.0
lr = 0.1
for step in range(20):
    grad = 2 * x
    x = x - lr * grad
    print(f"step {step:2d}  x={x:8.4f}  f(x)={x**2:10.6f}")

Starting from x=5, each step lands closer to the minimum at x=0.

Step 4: Gradient descent on a 2D function

python
def f_2d(point):
    x, y = point
    return x**2 + y**2
 
point = [4.0, 3.0]
lr = 0.1
for step in range(30):
    grad = numerical_gradient(f_2d, point)
    point = [p - lr * g for p, g in zip(point, grad)]
    loss = f_2d(point)
    if step % 5 == 0 or step == 29:
        print(f"step {step:2d}  point=({point[0]:7.4f}, {point[1]:7.4f})  f={loss:.6f}")

Step 5: Comparing numerical and analytical derivatives

python
import math
 
test_functions = [
    ("x^2",      lambda x: x**2,          lambda x: 2*x),
    ("x^3",      lambda x: x**3,          lambda x: 3*x**2),
    ("sin(x)",   lambda x: math.sin(x),   lambda x: math.cos(x)),
    ("e^x",      lambda x: math.exp(x),   lambda x: math.exp(x)),
    ("1/x",      lambda x: 1/x,           lambda x: -1/x**2),
]
 
x = 2.0
print(f"{'Function':<12} {'Numerical':>12} {'Analytical':>12} {'Error':>12}")
print("-" * 50)
for name, f, df in test_functions:
    num = numerical_derivative(f, x)
    ana = df(x)
    err = abs(num - ana)
    print(f"{name:<12} {num:12.6f} {ana:12.6f} {err:12.2e}")

Step 6: Computing the Hessian numerically

python
def hessian_2d(f, x, y, h=1e-5):
    fxx = (f(x + h, y) - 2 * f(x, y) + f(x - h, y)) / (h ** 2)
    fyy = (f(x, y + h) - 2 * f(x, y) + f(x, y - h)) / (h ** 2)
    fxy = (f(x + h, y + h) - f(x + h, y - h) - f(x - h, y + h) + f(x - h, y - h)) / (4 * h ** 2)
    return [[fxx, fxy], [fxy, fyy]]
 
def saddle(x, y):
    return x ** 2 - y ** 2
 
def bowl(x, y):
    return x ** 2 + y ** 2
 
H_saddle = hessian_2d(saddle, 0.0, 0.0)
H_bowl = hessian_2d(bowl, 0.0, 0.0)
print(f"Saddle Hessian: {H_saddle}")  # [[2, 0], [0, -2]] -- mixed signs
print(f"Bowl Hessian:   {H_bowl}")    # [[2, 0], [0, 2]]  -- both positive

The saddle's Hessian has eigenvalues 2 and -2, mixed signs, confirming a saddle point. The bowl's Hessian has eigenvalues 2 and 2, both positive, confirming a minimum.

Step 7: Taylor approximation in action

python
import math
 
def taylor_approx(f, f_prime, f_double_prime, x0, h, order=2):
    result = f(x0)
    if order >= 1:
        result += f_prime(x0) * h
    if order >= 2:
        result += 0.5 * f_double_prime(x0) * h ** 2
    return result
 
x0 = 0.0
for h in [0.1, 0.5, 1.0, 2.0]:
    true_val = math.sin(h)
    t1 = taylor_approx(math.sin, math.cos, lambda x: -math.sin(x), x0, h, order=1)
    t2 = taylor_approx(math.sin, math.cos, lambda x: -math.sin(x), x0, h, order=2)
    print(f"h={h:.1f}  sin(h)={true_val:.4f}  order1={t1:.4f}  order2={t2:.4f}")

Near x0=0, sin(x) ~ x is the first-order Taylor approximation. It's excellent for small h and breaks down for large h, which is why gradient descent works best with small learning rates: each step assumes the linear approximation is accurate.

Step 8: Why this matters for a neural network

python
import random
 
random.seed(42)
 
w = random.gauss(0, 1)
b = random.gauss(0, 1)
lr = 0.01
 
xs = [1.0, 2.0, 3.0, 4.0, 5.0]
ys = [3.0, 5.0, 7.0, 9.0, 11.0]
 
for epoch in range(200):
    total_loss = 0
    dw = 0
    db = 0
    for x, y in zip(xs, ys):
        pred = w * x + b
        error = pred - y
        total_loss += error ** 2
        dw += 2 * error * x
        db += 2 * error
    dw /= len(xs)
    db /= len(xs)
    total_loss /= len(xs)
    w -= lr * dw
    b -= lr * db
    if epoch % 40 == 0 or epoch == 199:
        print(f"epoch {epoch:3d}  w={w:.4f}  b={b:.4f}  loss={total_loss:.6f}")
 
print(f"\nLearned: y = {w:.2f}x + {b:.2f}")
print(f"Actual:  y = 2x + 1")

Every gradient-based training loop follows exactly this pattern: predict, compute the loss, compute the gradients, update the weights.

Check: Build It0/9
1. Why does gradient descent work best with small learning rates?Explain
The curve sin of x next to the straight line y equals x, close together near zero and pulling apart farther out, with marked points at x = 0.5, 1.0 and 2.0 on each curve.
2. Gradient descent on f(x) = x^2 starts at x = 5 with lr = 0.1 and gradient 2x. What is x after the first update?Apply
The curve f of x equals x squared with the starting point x equals 5 marked and its tangent line drawn there, a note that the learning rate is 0.1, and no next position marked.
3. The 2D loop starts at (4, 3) on f = x^2 + y^2 with lr = 0.1. Where is the point after one step?Apply
A contour plot of f of x, y equals x squared plus y squared with the starting point (4, 3) marked, a note that the learning rate is 0.1, and no arrow or next point drawn.
4. In the from-scratch linear regression loop, the code accumulates dw += 2 * error * x and db += 2 * error for each sample. What do dw and db represent?Apply
A two-line code snippet reading dw plus equals 2 times error times x, and db plus equals 2 times error, with a question asking what dw and db represent.
5. In the regression loop with w = 0, b = 0 and one sample x = 2, y = 3, what are dw and db for that sample?Apply
The update formulas pred equals w times x plus b, error equals pred minus y, dw equals 2 times error times x, and db equals 2 times error, with w = 0, b = 0, x = 2, y = 3 given and every right-hand value left as a question mark.
6. For sin(h) around x0 = 0, what does the first-order Taylor approximation give at h = 0.1?Apply
The first-order Taylor formula, f of x0 plus h approximately equals f of x0 plus f prime of x0 times h, with x0 = 0 and h = 0.1 given and the approximation left as a question mark.
7. What analytical gradient should the numerical gradient of x^2 + 3xy + y^2 match at (1, 2)?Apply
The function f of x, y equals x squared plus 3xy plus y squared, with the point (1, 2) given and grad f at (1, 2) equals a bracket of two question marks, no partial-derivative formulas shown.
8. A numerical derivative of x^3 at x = 2 with h = 1e-7 disagrees with 3x^2 by a large amount. What is the best first check?Analyze
Two boxes: the analytical derivative, 3 times 2 squared equals 12, and a numerical derivative at h equals 1e-7 marked as not matching, with a warning symbol between them.
Illustrative scenario; a real central-difference run at this h matches 12 almost exactly.
9. You hand-derived the gradient for a new custom loss. How should you gain confidence in it before training?Design
Two boxes, a formula gradient derived by hand and a numerical gradient from finite differences, with arrows from both pointing down into a question mark labeled match.

Use It

NumPy gives you the same operations, just faster and more concise:

python
import numpy as np
 
x = np.array([1, 2, 3, 4, 5], dtype=float)
y = np.array([3, 5, 7, 9, 11], dtype=float)
 
w, b = np.random.randn(), np.random.randn()
lr = 0.01
 
for epoch in range(200):
    pred = w * x + b
    error = pred - y
    loss = np.mean(error ** 2)
    dw = np.mean(2 * error * x)
    db = np.mean(2 * error)
    w -= lr * dw
    b -= lr * db
 
print(f"Learned: y = {w:.2f}x + {b:.2f}")

You just built gradient descent from scratch by hand. PyTorch will automate the gradient computation later, but the update loop underneath is identical.

Author's Note

The first time I trained a model without understanding what backward() was actually doing, I spent two days chasing a bug that turned out to be a completely correct gradient — I just didn't believe the number because I couldn't have predicted it myself. Once you've computed a handful of these derivatives by hand and watched gradient descent take its first few steps, autodiff stops being a black box and becomes what it actually is: a shortcut. It's faster than working out the chain rule by hand every time, not a replacement for knowing what the chain rule is doing. Build the numerical gradient checker from Build It before you trust anyone else's autograd, PyTorch included.

Exercises

  1. Implement numerical_second_derivative(f, x) using numerical_derivative called twice. Verify that the second derivative of x^3 at x=2 is 12.
  2. Use gradient descent to find the minimum of f(x, y) = (x - 3)^2 + (y + 1)^2. Start from (0, 0). The answer should converge to (3, -1).
  3. Add momentum to the gradient descent loop: maintain a velocity vector that accumulates past gradients. Compare convergence speed with and without momentum on f(x) = x^4 - 3x^2.

Key Terms

TermWhat people sayWhat it actually means
Derivative"The slope"The rate of change of a function at a point. Tells you how much the output changes per unit change in input.
Partial derivative"Derivative of one variable"The derivative with respect to one variable while all others are held constant.
Gradient"Direction of steepest ascent"A vector of all partial derivatives. Points in the direction that increases the function fastest.
Gradient descent"Go downhill"Subtract the gradient (times a learning rate) from the parameters to reduce the loss. The core of neural network training.
Learning rate"Step size"A scalar that controls how big each gradient descent step is. Too large: diverge. Too small: converge slowly.
Chain rule"Multiply the derivatives"The rule for differentiating composed functions: df/dx = df/dg * dg/dx. The mathematical basis of backpropagation.
Jacobian"Matrix of derivatives"When a function maps vectors to vectors, the Jacobian is the matrix of all partial derivatives of outputs with respect to inputs.
Numerical derivative"Finite differences"Approximating a derivative by evaluating the function at two nearby points and computing the slope between them.
Backpropagation"Reverse-mode autodiff"Computing gradients layer by layer from output to input using the chain rule. How neural networks learn.
Hessian"Matrix of second derivatives"The matrix of all second-order partial derivatives. Describes the curvature of a function. Positive definite Hessian at a critical point means local minimum.
Taylor series"Polynomial approximation"Approximating a function near a point using its derivatives: f(x+h) ~ f(x) + f'(x)h + (1/2)f''(x)h^2 + ... The basis for understanding why gradient descent and Newton's method work.
Integral"Area under the curve"The accumulation of a quantity over a range. In ML, integrals define probabilities, expected values, and KL divergence.

Further Reading

Code

Ships With