Math for CS and ML · 15 min

Derivatives and gradients: shrink the gap

Shrink the gap between two points until the secant becomes the tangent, estimate slopes in code without losing digits to rounding, and see why the gradient points uphill straight across the contour lines.

01Why it matters

How fast, right now?

A car's speedometer reads 50 km/h. Speed is distance over time, yet the needle shows a speed at a single instant, when no time passes. What can that number mean?

Machine learning asks the same question. A model's loss depends on millions of weights, and training asks of each: if this weight grew a tiny bit, how fast would the loss change, and which way? For one input the answer is a derivative; for all of them at once, the gradient. Both come from one move: measure a slope across a small gap, then let the gap shrink.

02Key parts

The pieces you will see

secant slope
The slope of the line through two points of a curve, P=(a,f(a))P = (a, f(a)) and Q=(a+h,f(a+h))Q = (a + h, f(a + h)): rise over run.
derivative f′(a)
What the secant slopes settle on as hh shrinks to 0 from both sides: the curve's slope at the single point aa.
tangent line
The line through PP with slope f′(a)f'(a): the closest straight fit to the curve near PP.
partial derivative ∂f/∂x
The slope as xx changes while every other input is held fixed.
gradient ∇f
All the partial derivatives stacked into a vector. It points the way ff rises fastest.

03See it work

Shrink the gap

PP sits on f(x)=x2f(x) = x^2 at a=1a = 1. A slope needs two points, so take a second point QQ a gap hh further along, measure the slope between them, and shrink hh.

As h shrinks from 2 to 0.01, the secant slope goes 4, 3, 2.5, 2.25, 2.1, 2.01, and from the left, h = −0.01 gives 1.99. Both sides close in on 2, the slope of the tangent. Then the slope is measured at ten points from x = −2.7 to 2.7: the graph of f′(x) = 2x is a straight line.

For x2x^2, algebra shows why:

(a+h)2−a2h=2ah+h2h=2a+h\frac{(a + h)^2 - a^2}{h} = \frac{2ah + h^2}{h} = 2a + h

At a=1a = 1 that is 2+h2 + h: every secant misses the tangent's slope by exactly hh. As hh shrinks to 0 from either side, 2a+h2a + h settles on 2a2a, so the derivative of x2x^2 is 2x2x. In general,

f′(a)=lim⁡h→0f(a+h)−f(a)hf'(a) = \lim_{h \to 0} \frac{f(a + h) - f(a)}{h}

and the limit must be the same from both sides. That is the needle's number: average speeds over shorter and shorter intervals, settling on one value.

Done at every point, this makes f′f' a function of its own, the Slope f′(x) graph above. Its sign says which way ff is going: negative left of 0, where x2x^2 falls, positive right of it. It is 0 where ff levels off, at peaks and valleys. Its size says how sensitive ff is: at x=2.7x = 2.7, f′=5.4f' = 5.4, so a small step in xx moves ff about 5.4 times as far; near 0, ff hardly moves.

04Predict

Your turn: a sharp corner

Now PP sits at the corner of f(x)=∣x∣f(x) = |x|, at 0. Predict how the secant slope changes as hh shrinks, whether a secant from the left agrees, then whether ff goes uphill or downhill as the sweep moves along.

Make 8 predictions: step forward and answer each question before the next step plays.

0 of 8 made

05Try it

Slopes in code, and slopes on a map

A computer can't let hh reach 0, so it stops at a small hh and divides. This program measures the forward difference, the secant slope with QQ to the right of PP, for x2x^2 at a=3a = 3 with hh = 0.5, 0.25 and 0.125.

def f(x):
    return x * x

def secant_slope(a, h):
    return (f(a + h) - f(a)) / h

a = 3
h = 0.5
while h >= 0.125:
    print(secant_slope(a, h))
    h = h / 2

Points on both sides of aa do better. The central difference, f(a+h)−f(a−h)2h\frac{f(a + h) - f(a - h)}{2h}, averages the forward and backward slopes. On x2x^2 those are 2a+h2a + h and 2a−h2a - h, so the errors cancel exactly; in general what is left is proportional to h2h^2. For exe^x at 0 (slope 1) with h=0.01h = 0.01, forward gives 1.0050 and central 1.0000167.

So why not take h=10−20h = 10^{-20}? Because floats have gaps (see floating point). For x2x^2 at 3 in float64, h=10−8h = 10^{-8} gives 5.99999996, h=10−12h = 10^{-12} gives 6.0005, and h=10−16h = 10^{-16} gives 0: floats near 3 are about 4×10−164 \times 10^{-16} apart, so 3+10−163 + 10^{-16} rounds back to 3. Gradient checking tests backpropagation this way: nudge each weight about 10−510^{-5} either way and compare the central difference of the loss with the backward pass's answer.

Nobody works out every derivative from the limit. A few rules, each proved once from it, cover this lesson's functions:

  • Power rule: xnx^n gives nxn−1n x^{n-1}, so x3x^3 gives 3x23x^2. A constant gives 0.
  • Constant multiple and sum: (cf)′=cf′(c f)' = c f' and (f+g)′=f′+g′(f + g)' = f' + g', so x3/3−xx^3/3 - x gives x2−1x^2 - 1.
  • Two special functions: exe^x is its own derivative, and sin⁡x\sin x gives cos⁡x\cos x (in radians).
eˣ at a = 0.5. The secant slopes fall from about 5.27 at h = 2 to 1.657 at h = 0.01 (1.641 from the left) and settle on 1.6487: e^0.5, the height of P. f′ comes out as eˣ again. Try another in the box, such as sine at 2.

The rules assume the curve is smooth where you use them.

A loss depends on many weights at once. For f(x,y)f(x, y), the partial derivative ∂f/∂x\partial f/\partial x is the ordinary derivative in xx with yy held fixed like a number, and ∂f/∂y\partial f/\partial y the other way round. In the narrow valley f(x,y)=x2/20+5y2f(x, y) = x^2/20 + 5y^2 they are x/10x/10 and 10y10y. Stacked, they make the gradient ∇f=(x/10,10y)\nabla f = (x/10, 10y), which at (−3.5,1.5)(-3.5, 1.5) is (−0.35,15)(-0.35, 15).

Walk in the direction of a unit vector uu, and the slope underfoot is the dot product ∇f⋅u\nabla f \cdot u. That is largest when uu points along ∇f\nabla f, so the gradient points the way ff rises fastest, and its length is that steepest slope: about 15 at (−3.5,1.5)(-3.5, 1.5), where walking along +x+x gives just −0.35. At right angles to ∇f\nabla f the slope is 0, which is along the contour line: the gradient crosses contour lines at right angles.

The valley x²/20 + 5y² from (−3.5, 1.5), with small steps (η = 0.02). Each arrow, −η·∇f, is at right angles to the contour line where it starts. The first gradient is (−0.35, 15), so the path heads almost straight across the valley, not towards the minimum at (0, 0), then creeps along the floor: after 40 steps it is only at (−3.23, 0).

The tangent guess works in many dimensions too: f(p+Δ)≈f(p)+∇f⋅Δf(p + \Delta) \approx f(p) + \nabla f \cdot \Delta for a small step Δ\Delta. Step by Δ=−η∇f\Delta = -\eta \nabla f and the guess falls by η ∣∇f∣2\eta\,|\nabla f|^2, so a small enough step against a nonzero gradient always goes downhill. Gradient descent is that one idea, repeated.

06Check yourself

Check yourself

  1. Question 1 of 6

    A curve has no gaps or jumps. At x = 3 its secant slopes settle on 2 from the right and 0.5 from the left. What is f′(3)?

    Your answer comes back in Review in a few days, so it sticks.

  2. Question 2 of 6

    f(4) = 10 and f′(4) = −2. What is the best estimate of f(4.1)?

  3. Question 3 of 6

    With h = 0.2, a forward difference is off by 0.08 and a central difference by 0.004. Roughly how far off is each with h = 0.1?

  4. Question 4 of 6

    In float64, a forward difference for the slope of x² at 4 with h = 10⁻¹⁴ gives 7.816, not 8. What would most likely bring it closer?

  5. Question 5 of 6

    f(x, y) = x² + 3y. At (2, 1), how steep is the steepest climb, and how steep is the ground walking in the +y direction?

  6. Question 6 of 6

    On a map of f, the contour lines near a point P run east to west, f is higher to the north, and the highest point on the map lies to the north-east. Which way does ∇f point at P?

07Explain it back

Say it in your own words

What is the derivative f′(a), how can a computer estimate it, and what does the gradient tell you when f has several inputs?

08Recap

What to remember

  • f′(a)f'(a) is the limit of the secant slope as h→0h \to 0, from both sides. At a corner, like ∣x∣|x| or ReLU at 0, the sides disagree and there is none.
  • The sign of f′f' says rising or falling, it is 0 at smooth peaks and valleys, and its size says how sensitive ff is. Near aa, f(a+h)≈f(a)+f′(a) hf(a + h) \approx f(a) + f'(a)\,h.
  • Rules: xnx^n gives nxn−1n x^{n-1}, constant factors stay, sums split, exe^x stays exe^x, and sin⁡x\sin x gives cos⁡x\cos x.
  • The forward difference's error is proportional to hh, the central difference's to h2h^2, and too small an hh loses digits to rounding.
  • The gradient stacks the partial derivatives. It points the way ff rises fastest, its length is that slope, it crosses contour lines at right angles, and the slope along a unit vector uu is ∇f⋅u\nabla f \cdot u.
  • Next: gradient descent walks against the gradient, and backpropagation computes it for every weight. Then try Backpropagate through a neuron by hand.
Back to path