Learn ML

Chapter 10 of 25

Calculus for Neural Networks

Derivatives, gradients, and the chain rule that makes learning possible

19 min read

Motivation

Linear algebra, from the last chapter, tells you what a neural network computes — a chain of matrix multiplications and activations. Calculus is what tells the network how to get better. Every single weight update that ever happens during training is, underneath the surface, the result of a derivative calculation. If linear algebra is the network's anatomy, calculus is its learning mechanism.

This chapter builds the calculus toolkit — derivatives, partial derivatives, gradients, and above all the chain rule — that you need to fully understand backpropagation, coming up soon. Take the chain rule section seriously: it is, without much exaggeration, the single most important piece of math in this entire course.

A Real-Life Scenario

Imagine you're adjusting the temperature dial on an oven while baking bread, trying to hit a perfect golden crust. You don't know the exact function relating dial position to crust color, but you can experiment: nudge the dial up slightly, see if the crust darkens faster or slower than before. That nudge-and-observe process — how much does the output change when I change this one input by a tiny amount? — is exactly what a derivative measures.

Now imagine that instead of one dial, you have a million dials (the weights of a neural network), and instead of eyeballing crust color, you have a single number telling you how wrong the whole network's prediction was (the loss). You can't nudge a million dials one at a time and see what happens — that would take forever. What you need is a way to instantly know, for every dial simultaneously, which direction to turn it to make the loss smaller. That's exactly what gradients and the chain rule deliver, and it's exactly what makes training feasible at all.

Building the Intuition

Here's the picture to hold before any formulas:

  • A derivative tells you the instantaneous rate of change of a function — nudge the input a tiny bit, and the derivative tells you how much and in which direction the output moves.
  • A partial derivative does the same thing, but for a function of many variables at once, treating every variable except one as temporarily frozen.
  • The gradient collects every partial derivative into a single vector that points in the direction of steepest increase — its negative points toward the fastest way to decrease the function, which is exactly what we want when trying to shrink a loss.
  • The chain rule is how you compute a derivative through a chain of nested functions — and a neural network, layer stacked on layer, is nothing but a very long chain of nested functions.

The Math Behind It

The Derivative

Derivative
f(x)=dfdx=limh0f(x+h)f(x)hf'(x) = \frac{df}{dx} = \lim_{h \to 0} \frac{f(x+h)-f(x)}{h}

Intuition: nudge xx by a tiny amount hh and see how much f(x)f(x) changes, then shrink that nudge toward zero. If f(x)>0f'(x) > 0, increasing xx increases f(x)f(x); if f(x)<0f'(x) < 0, increasing xx decreases f(x)f(x). This is precisely the information used to decide which direction to move a weight during training: we want to know which way to nudge it to decrease the loss.

Common derivatives used throughout this course
FunctionDerivative
f(x) = c (constant)f'(x) = 0
f(x) = xⁿf'(x) = nxⁿ⁻¹
f(x) = eˣf'(x) = eˣ
f(x) = ln(x)f'(x) = 1/x
f(x) = σ(x) = 1/(1+e⁻ˣ)f'(x) = σ(x)(1−σ(x))
f(x) = tanh(x)f'(x) = 1 − tanh²(x)
Memorize these two

The sigmoid and tanh derivatives above get used constantly once we reach activation functions and backpropagation. It's worth being able to re-derive σ(x)=σ(x)(1σ(x))\sigma'(x) = \sigma(x)(1-\sigma(x)) from the quotient rule at least once, so it isn't just a memorized fact.

Partial Derivatives

A neural network's loss doesn't depend on one variable — it depends on every weight and bias simultaneously, which can number in the millions. To handle functions of many variables, we need partial derivatives.

Partial Derivative

For a function f(x1,x2,,xn)f(x_1, x_2, \dots, x_n), the partial derivative with respect to xix_i, written fxi\dfrac{\partial f}{\partial x_i}, measures ff's rate of change with respect to xix_i while holding every other variable constant.

Worked example: let f(x,y)=3x2y+2y3f(x,y) = 3x^2y + 2y^3.

fx=6xy (treating y as constant),fy=3x2+6y2 (treating x as constant)\frac{\partial f}{\partial x} = 6xy \ (\text{treating } y \text{ as constant}), \qquad \frac{\partial f}{\partial y} = 3x^2 + 6y^2 \ (\text{treating } x \text{ as constant})

At (x,y)=(1,2)(x,y)=(1,2): fx=6(1)(2)=12\frac{\partial f}{\partial x} = 6(1)(2) = 12, and fy=3(1)2+6(2)2=3+24=27\frac{\partial f}{\partial y} = 3(1)^2+6(2)^2 = 3+24 = 27.

The Gradient

Gradient
f=[f/x1f/x2f/xn]\nabla f = \begin{bmatrix} \partial f/\partial x_1 \\ \partial f/\partial x_2 \\ \vdots \\ \partial f/\partial x_n \end{bmatrix}

Intuition: the gradient collects every partial derivative into one vector that points in the direction of steepest increase of ff at that point. Its negative, f-\nabla f, points toward steepest decrease. This single fact is the entire foundation of gradient descent: to shrink a loss function, move the parameters in the direction of f-\nabla f.

Gradient Descent on a Bowl-Shaped Loss SurfaceIllustration coming soon
Each ellipse is a curve of constant loss for f(w1,w2) = w1² + 2w2². The negative gradient (red arrow) always points perpendicular to the local contour, straight toward the minimum — this is the direction gradient descent follows.
Jacobians and Hessians, briefly

When a function outputs a vector rather than a scalar (as many layers of a network do), the full collection of partial derivatives forms a matrix called the Jacobian. When you take second-order partial derivatives of a scalar function, you get a matrix called the Hessian, describing local curvature. This course's derivations rely primarily on first-order gradients, but both terms are worth recognizing — the Jacobian shows up naturally when reasoning about backpropagation through an entire layer at once, and the Hessian underlies second-order optimization methods and the idea of how "sharp" a loss minimum is.

The Chain Rule

This is the one piece of math this entire course is quietly building toward. It is the mathematical fact that makes backpropagation possible.

Chain Rule (Single Variable)

If y=f(u)y = f(u) and u=g(x)u = g(x), so yy depends on xx only through uu, then:

dydx=dydududx\frac{dy}{dx} = \frac{dy}{du}\cdot\frac{du}{dx}

Intuition: if yy changes dydu\frac{dy}{du} times as fast as uu, and uu changes dudx\frac{du}{dx} times as fast as xx, then yy changes dydududx\frac{dy}{du}\cdot\frac{du}{dx} times as fast as xx. Rates of change simply multiply along a chain of dependencies.

A simple numeric worked example: let y=(3x+1)2y = (3x+1)^2. Set u=3x+1u = 3x+1, so y=u2y=u^2.

dydu=2u,dudx=3    dydx=2u3=6u=6(3x+1)=18x+6\frac{dy}{du} = 2u, \qquad \frac{du}{dx}=3 \quad\implies\quad \frac{dy}{dx} = 2u\cdot 3 = 6u = 6(3x+1) = 18x+6

Check by direct expansion: y=(3x+1)2=9x2+6x+1y=(3x+1)^2 = 9x^2+6x+1, so dydx=18x+6\frac{dy}{dx}=18x+6 — the two methods agree, exactly as they must. Concretely, at x=2x=2: u=3(2)+1=7u = 3(2)+1=7, so dydx=6(7)=42\frac{dy}{dx} = 6(7) = 42, and direct expansion gives 18(2)+6=4218(2)+6=42 too.

Now suppose a neural network has many variables feeding into the final loss through many paths at once — this is the situation in every real layer.

Multivariate Chain Rule

If zz depends on y1,y2,,yky_1, y_2, \dots, y_k, and each yjy_j depends on xx, then:

zx=j=1kzyjyjx\frac{\partial z}{\partial x} = \sum_{j=1}^k \frac{\partial z}{\partial y_j}\cdot\frac{\partial y_j}{\partial x}

Why this matters: in an MLP, the loss LL depends on a weight ww in an early layer only indirectly, through every neuron in every later layer that weight's output eventually influences. The multivariate chain rule is exactly what lets us sum up the contribution of every one of those paths to compute L/w\partial L/\partial w — this is, quite literally, what backpropagation implements.

Think of it as a computational graph

Picture a neural network as a computational graph: a directed graph where each node is an operation (a matrix multiply, an addition, an activation function) and edges represent data flowing between operations. The chain rule says: to compute the derivative of the final loss with respect to any node, multiply the local derivatives along every path from that node to the loss, and sum over all such paths. Backpropagation is simply an efficient algorithm for doing this for every parameter in the network at once, by traversing the graph backward exactly one time.

Gradient Descent: A First Look

Gradient Descent Update Rule
θθηθL(θ)\theta \leftarrow \theta - \eta \nabla_\theta L(\theta)

Where: θ\theta is every trainable parameter (weights and biases), L(θ)L(\theta) is the loss, θL(θ)\nabla_\theta L(\theta) is its gradient with respect to the parameters, and η>0\eta > 0 is the learning rate.

Intuition: since θL\nabla_\theta L points toward steepest increase in loss, stepping in the opposite direction, θL-\nabla_\theta L, decreases it. The learning rate η\eta controls the size of that step — this same update rule is exactly what a later chapter on optimization builds on in full detail.

Implementing It

import numpy as np
 
def f(x):
    return (3*x + 1)**2
 
def numerical_derivative(f, x, h=1e-6):
    return (f(x + h) - f(x - h)) / (2*h)
 
x0 = 2.0
analytical = 18*x0 + 6            # derived by hand above
numerical = numerical_derivative(f, x0)
 
print(f"Analytical derivative at x={x0}: {analytical}")
print(f"Numerical  derivative at x={x0}: {numerical:.6f}")

This compares a hand-derived ("analytical") derivative against a numerical approximation using tiny finite differences — nudging xx by a small hh in both directions and measuring the resulting change in ff. The two should agree almost exactly (both give 42 here). This technique is called gradient checking, and it's an invaluable debugging tool once you implement backpropagation from scratch: it catches subtle sign errors or incorrect chain-rule applications that would otherwise silently make a network train incorrectly.

Use gradient checking when debugging a from-scratch implementation

If your hand-derived gradients don't match a numerical finite-difference check to several decimal places, trust the numerical check — there's a bug somewhere in your analytical derivation or its implementation, almost always a misapplied chain rule step or a sign flip.

Key Takeaways

Key Takeaways
  • The derivative measures a function's instantaneous rate of change; partial derivatives extend this to functions of many variables, holding all others fixed.
  • The gradient f\nabla f collects every partial derivative into a vector pointing toward steepest increase; its negative points toward steepest decrease.
  • The chain rule, dydx=dydududx\frac{dy}{dx} = \frac{dy}{du}\cdot\frac{du}{dx}, lets you differentiate through nested (composed) functions — exactly the structure of a layered neural network.
  • The multivariate chain rule sums contributions over every path of dependency, and is the precise mathematical basis of backpropagation.
  • Gradient descent updates parameters by moving them in the direction of θL-\nabla_\theta L, scaled by a learning rate η\eta.
  • Gradient checking (comparing analytical derivatives against numerical finite-difference estimates) is a standard way to catch bugs in a from-scratch backpropagation implementation.

Common Mistakes

Forgetting to hold other variables constant

When computing f/x\partial f/\partial x for a multivariable function, every other variable must be treated as a fixed constant during that differentiation — mixing this up (differentiating with respect to the wrong variable, or forgetting a term that depends on x hidden inside a 'constant') is one of the most common early mistakes with partial derivatives.

Dropping a link in the chain rule

When a dependency chain has three or more nested functions (yy depends on uu, uu depends on vv, vv depends on xx), it's easy to skip a link and multiply only two of the three derivatives together. Every link in the chain must be included: dydx=dydududvdvdx\frac{dy}{dx} = \frac{dy}{du}\cdot\frac{du}{dv}\cdot\frac{dv}{dx}.

Interview Corner

Quick Check
1. Using the chain rule, what is dy/dx for y = (3x+1)^2 at x = 2?
2. Why does gradient descent update parameters in the direction of −∇θL rather than +∇θL?

Where This Shows Up in Practice

Every single training step of every neural network in existence is the chain rule, applied automatically and efficiently across every layer, computing exactly how much each weight should move to reduce the loss. Combined with the matrix and vector operations from the previous chapter, you now have both halves of the toolkit needed to derive backpropagation completely, layer by layer, symbol by symbol — which is exactly where this course goes next, right after one more chapter on probability and statistics that explains why we use the loss functions we use in the first place.