In our treatment of neural networks, we
introduced backpropagation, an algorithm that computes gradients in multilayer perceptrons by propagating them layer by layer with
the chain rule. However, architectures
with residual connections, attention mechanisms, and dynamic control flow do not fit neatly into the sequential layer abstraction.
We need a more general framework.
Automatic differentiation (AD) is that framework. Rather than relying on a layer-by-layer structure, AD operates on
arbitrary computational graphs: directed acyclic graphs (DAGs) where each node represents an elementary operation
and edges encode data dependencies. Given such a graph, AD systematically applies the chain rule to compute derivatives that are
numerically exact, that is, exact up to floating-point rounding. The results are neither finite-difference
approximations nor symbolic expressions that can explode in size.
Definition: Automatic Differentiation
Let \(U \subseteq \mathbb{R}^n\) be open and let \(f : U \to \mathbb{R}^m\) be decomposed into a sequence of elementary
operations, each differentiable at the point where it is evaluated, and represented as a computational graph.
Automatic differentiation computes the
Jacobian
\(J_f \in \mathbb{R}^{m \times n}\) of \(f\) at a point \(\mathbf{x} \in U\) (or products involving it) by applying the chain
rule systematically through the graph. Two basic modes exist:
Forward-mode AD:
propagates Jacobian-vector products \(J_f\, \mathbf{v}\) from inputs to outputs. Cost: one forward pass per input
direction, so \(n\) passes assemble the full Jacobian. Efficient when \(n \ll m\).
Reverse-mode AD:
propagates vector-Jacobian products \(\mathbf{u}^\top J_f\) from outputs to inputs. Cost: one backward pass per
output direction, so \(m\) passes assemble the full Jacobian. Efficient when \(m \ll n\).
Since neural network training involves a scalar loss (\(m = 1\)) with millions of parameters (\(n \gg 1\)), reverse-mode AD,
which is backpropagation in this context, computes the full gradient in a single backward pass, after one forward pass that
records the intermediate values.
Analytic Example of Reverse-Mode AD
To make the process of automatic differentiation concrete, we walk through an analytic example using a composite scalar-valued
function of two variables. We decompose the function into primitive operations, represent it as a computational graph, and compute
its gradients using reverse-mode automatic differentiation (that is, backpropagation).
Consider the following function
\[
f(x_1, x_2) = \log \left((x_1 + x_2)^2 + \sin(x_1 x_2) \right).
\]
For this function and its derivatives to be strictly defined in the real domain, we require the input \((x_1, x_2)\) to satisfy
\((x_1 + x_2)^2 + \sin(x_1 x_2) \gt 0\).
We decompose this into primitive operations:
\[
\begin{align*}
&x_3 = x_1 + x_2 \\\\
&x_4 = x_3^2 \\\\
&x_5 = x_1 x_2 \\\\
&x_6 = \sin(x_5) \\\\
&x_7 = x_4 + x_6 \\\\
&x_8 = \log(x_7) = f
\end{align*}
\]
This computational graph makes the DAG structure explicit. Notice the following:
Each input variable (\(x_1\) and \(x_2\)) has multiple outgoing edges and contributes to
different intermediate computations
The graph flows from inputs at the top to the output at the bottom
During backpropagation, gradients flow in the reverse direction (from \(f\) back to \(x_1\) and \(x_2\))
As the graph shows, each input variable contributes to two intermediate nodes:
\(x_1\) influences both \(x_3\) (via addition) and \(x_5\) (via multiplication)
\(x_2\) influences both \(x_3\) (via addition) and \(x_5\) (via multiplication)
To find the gradients with respect to the input variables, we therefore sum the contributions from all paths. The
sum is exactly what the chain rule produces
when \(f\) is viewed as a function of \((x_3, x_5)\). The row vector
\(\bigl(\frac{\partial f}{\partial x_3}, \frac{\partial f}{\partial x_5}\bigr)\) multiplies the \(2 \times 2\) Jacobian of
\((x_1, x_2) \mapsto (x_3, x_5)\), and each entry of the product is a sum of two terms, one per path:
The power of automatic differentiation lies in its systematic approach:
Decompose complex functions into simple primitive operations
Apply the chain rule mechanically through the computational graph
Sum gradients when variables contribute through multiple paths
Because each step is mechanical, the whole process can be automated.
In the AD literature, the accumulated gradient \(\frac{\partial f}{\partial x_i}\) is often called the adjoint of
\(x_i\) and denoted \(\bar{x}_i\).
Applications of AD
Automatic differentiation is the computational engine behind deep learning frameworks. Two widely used frameworks illustrate
complementary design philosophies that reflect different sides of the AD abstraction:
PyTorch: an imperative, eager-execution framework with dynamic computational graphs and reverse-mode AD via
autograd. It is the most common framework in NLP and computer vision research and is widely used for LLM training.
Our sample code below uses it.
JAX: a functional framework offering composable function transformations such as grad,
vmap, and jit. Its jvp and vjp transformations implement the two modes of AD
defined above (grad is built on vjp), and they compose with vmap (vectorization) and
jit (compilation). It is widely used for differentiable physics, scientific computing, and equivariant neural
networks. Equivariant networks return in our discussion of geometric deep learning.
These systems rely on automatic differentiation to:
Train neural networks by computing gradients of loss functions with respect to millions to billions of parameters or more
Optimize differentiable models and simulators in physics, robotics, and finance
Perform end-to-end differentiation through control flow, dynamic loops, and even solver calls (for
example, differentiable physics)
The same structural pattern recurs outside calculus. It consists in attaching information to each primitive operation and letting
composition rules carry it through automatically. The Jacobian is one instance of such "structured side-information" propagated by a
composition law. The formal methods page identifies another instance,
in which the side-information attached to each program step is a proof of correctness and the composition law is logical inference.