The implicit function theorem and gradients through solvers
Before this lesson: lesson 04 (the chain rule as a product of Jacobians), lesson 05 (JVP and VJP, why reverse mode brackets the product from the loss side) and lesson 08 (matrix-free products such as HVPs). From linear algebra: lesson 03 (inverse, "solve, do not invert"), lesson 13 (conditioning) and lesson 14 (CG and GMRES). Time: about 70 minutes, plus the notebook.
Why this matters #
- Deep equilibrium models (DEQs) find a fixed point and train with an implicit gradient, so memory does not grow with the number of solver iterations (Bai, Kolter and Koltun 2019).
- Bilevel optimization. Hyperparameter tuning and meta-learning have an inner problem (training loss) and an outer loss on validation data. The hypergradient comes from the optimality condition of the inner problem (Lorraine, Vicol and Duvenaud 2020; implicit MAML, Rajeswaran et al. 2019).
- Optimization layers. OptNet (Amos and Kolter 2017) differentiates the solution of a quadratic program through its optimality (KKT) conditions.
- ML for science. A discretized steady PDE links a state (pressure, a wavefield) to parameters (permeability, wave speed). The adjoint method gives the gradient of a misfit with respect to millions of parameters for one extra linear solve. It is the same theorem.
1. Predict first #
2. The picture #
One dimension: the slope of a curve you never solve #
The equation with defines . Now forget the formula . When moves by , the solution must move by so that stays zero. To first order, changes by
Set and solve for the ratio:
At , , so . This equals , but we used only and its partial derivatives at the solution.
Where it fails. At the solution is , so . There the two branches meet, the tangent of the curve is vertical, and for there is no real solution. Such a point is a fold. The condition rules out exactly this situation.
Drag the violet point along the curve (horizontal axis , vertical axis ). The blue line has the implicit slope . The orange secant joins the solutions at , found by Newton's method from the current . They agree everywhere except near a fold, where , the tangent turns vertical and the secant has no second point. Try the S-shaped cubic: it has three solutions for some , and each branch has its own derivative.
The linear case in dimensions #
Let with an invertible and . Then and . Here and , so . Near a solution, a smooth nonlinear behaves like its linear approximation, so the same formula holds locally. That is the implicit function theorem.
Fixed points: a feedback loop #
Let , and write and at the fixed point. A change moves directly by . That move goes through again and moves by times it, and so on:
This Neumann series converges when the spectral radius (the largest ) is below 1. Each solver iteration adds one term. The implicit derivative is the whole sum.
Move and watch the cobweb. The iteration walks between the curve and the diagonal , and stops at the fixed point. The dashed curve is : its fixed point moved by about . The readout compares this implicit slope with the derivative of the -step iteration (unrolled). For , the upper fixed point repels the iteration, but the implicit formula still gives its slope.
Argmins: a minimizer is a root #
If minimizes a smooth function over , then . So the argmin is a root of , and is the Hessian . Everything above applies.
The equation with defines . Use only the partial derivatives of : what is at ?
, and , so . Check: . The answer drops the minus sign of the formula; inverts the ratio.
3. Definitions and main results #
Notation. (as many equations as unknowns). and are the partial Jacobians. is the Jacobian of the solution map . A map is if it is differentiable with continuous derivatives.
3.1 The implicit function theorem #
Theorem (implicit function theorem). Let be near , with and invertible. Then there are open sets and and a unique map such that, for every , is the only solution of in . The map is , , and
Proof of the derivative formula (given that exists and is ).
- For every , . A function that is zero everywhere has derivative zero: .
- is the composition . The chain rule (lesson 04) gives .
- So .
- is invertible at . Its determinant is continuous, so it stays nonzero on a smaller . Multiply on the left by .
Shapes: . The formula uses only at the solution. It does not care how was found.
Why the solution exists and is unique (sketch)
- Define , a map from to itself.
- Its Jacobian is block triangular, , with determinant at .
- By the inverse function theorem, has a inverse near .
- The solution is the first block of . It is because is, and it is unique near because is one-to-one there (Blondel and Roulet, §11.3.4).
Fixed points. For , set . Then and , so
The condition is that is invertible, that is, 1 is not an eigenvalue of . A contraction ( in some induced norm) is enough, but it is not necessary: a repelling fixed point also has a derivative (worked example (b)).
Argmins. For with , set :
where holds the mixed partials . It needs an invertible Hessian at , for example strongly convex in .
A fixed point in one dimension has and at . What is ?
. The feedback loop amplifies the direct effect by : here the sum . The answer 1 or 1.1 keeps only the first terms of this sum, which is what a short unrolled solver computes.
3.2 The VJP form: one adjoint solve #
Training needs the gradient of a scalar , not the Jacobian. Let be the upstream gradient, and the direct dependence of on (often zero).
Proposition (adjoint form). Let solve . Then .
Proof.
- Chain rule: .
- Insert the theorem: , where .
- Bracket from the right, as reverse mode does (lesson 05): , that is, solves .
- Then : one VJP of with cotangent .
Cost. Forming needs solves with (one per column of ) and stores numbers. The adjoint form needs one solve with and one VJP, for any .
Matrix-free solves. The products are VJPs of in , so a Krylov solver finds without forming (linear-algebra lesson 14). Use conjugate gradient (CG) when is symmetric positive definite. This is the case for the argmin of a strongly convex , where each product is an HVP of (lesson 08). Otherwise use GMRES or BiCGSTAB.
Fixed points. The adjoint system is , and . When is a contraction, the plain iteration
converges to , with one VJP of per step. Its rate is the spectral radius of , the same as the forward iteration, because and have the same eigenvalues.
Move (the number of solver iterations) and the contraction. The chart shows three errors on a log scale: the forward error (grey), the error of the unrolled gradient (backprop through steps) and the error of the implicit gradient evaluated at . Both gradients improve geometrically; the implicit one is about as accurate as the forward solve. The bars show the memory: unrolling stores iterates, the implicit gradient stores one point.
3.3 Unrolled versus implicit #
Unrolling runs for steps and backpropagates through all of them. If the iteration starts at the fixed point (, so every ), the chain rule gives : the first terms of the Neumann series. The missing tail is , so the error shrinks like , where is the spectral radius of . From another start the error also decays geometrically (in worked example (b) it is proportional to ).
| Unrolled (backprop through steps) | Implicit (theorem at ) | |
|---|---|---|
| What it differentiates | the -step algorithm, exactly | the solution map |
| Memory | all iterates and the intermediates of every step: grows like | and one graph of at : independent of |
| Backward cost | VJPs of one step | one linear solve (some VJPs of in ) plus one VJP in |
| Error against the true | truncation (about ) plus the forward error | proportional to the forward error , plus the error of the adjoint solve |
| Needs | a differentiable solver | differentiable at and invertible; any forward solver |
Accuracy of the implicit gradient. In practice you apply the formula at an approximate solution . Blondel et al. (2022, Theorem 1) show: if is well conditioned near , and are Lipschitz there, and is bounded at , then the Jacobian estimate at has error at most . So the gradient is about as accurate as the forward solve. The constant grows as the smallest singular value of shrinks, that is, as gets close to singular (linear-algebra lesson 13).
When unrolling is the right choice. When you want the gradient of what you actually computed: a few inner steps by design (MAML-style adaptation, learned optimizers), or a solution that is not unique or not smooth.
A DEQ layer reaches its fixed point in iterations. Compared with backpropagation through the 50 iterations, the implicit gradient needs memory that…
The theorem uses only at the solution, so the solver path can be discarded. The adjoint solve may iterate, but each step needs only VJPs of at the same point , so it reuses one graph. Some memory is always needed: and the graph of one evaluation of .
3.4 Ridge regression: a hyperparameter gradient #
The inner problem is with , and . Its optimality condition is
The partial Jacobians are (symmetric positive definite) and (a column). The theorem gives
For a validation loss with , the adjoint form gives with (here ). One solve, and no closed form of is needed, only its optimality condition.
Corollary (the norm shrinks). whenever , because (linear-algebra lesson 07).
Drag with the slider. Top: the validation loss against with the tangent line whose slope is the hypergradient from one linear solve. Bottom: the weights and the norm . Notice that always falls as grows, but a single weight can rise. Press Hypergradient step to take gradient-descent steps on .
Envelope theorem: when no solve is needed
If the outer loss is the optimal value itself, , then . The implicit term vanishes because , so no solve is needed. This is Danskin's theorem (Blondel and Roulet §11.2). It is why the gradient of a log-partition function or of a dual objective is simple.
Answers to section 1. (1) Unrolled memory grows linearly in : every iterate and the intermediates of every evaluation of are stored. Yes: the theorem gives the exact gradient from alone, with one adjoint solve and one VJP ; memory does not depend on . (2) Not every weight: in worked example (c), at and , so grows. But always shrinks (the corollary).
4. Worked example #
(a) A 2-D root. Two unknowns and one parameter :
At , is a root: .
- Partial Jacobians: , with , so the theorem applies. .
- .
- .
- Check without the theorem: gives . Then at , so , and . ✓
- Prediction: at , . The exact root is . The error, about , is second order in .
- Where it fails: . On the curve it is zero when , that is at and . There the branch through meets a second branch (at its root is , with ). The theorem is local: each branch has its own derivative.
(b) A fixed point and its unrolled gradient. at . The fixed points solve , that is : and .
- At : and , so . Check: has derivative at . ✓
- At : , so the iteration moves away from this point. But , and the theorem gives (check: has derivative ). The theorem needs invertibility, not a contraction.
- At the two fixed points merge at , where and : the theorem fails.
- Unrolled, started at : . Started at , forward-mode differentiation of the -step map gives the second row:
| 1 | 2 | 5 | 10 | 20 | |
|---|---|---|---|---|---|
| start at | 0.25 | 0.375 | 0.484 | 0.49951 | 0.4999995 |
| start at | 0.25 | 0.344 | 0.465 | 0.49797 | 0.4999961 |
The implicit answer costs one division. Unrolling needs about 20 steps, and 20 stored iterates, for 5–6 correct digits.
(c) A ridge hypergradient. Three training samples, two features, : , . One validation sample , , so .
- and .
- , with and .
- Optimality: gives .
- .
- Forward route: , so .
- Adjoint route: solve : . Then . ✓
- , so increasing lowers the validation loss.
- The norm: , while grows.
- Check with the closed form : its derivative at is . ✓
5. In code #
NumPy and SciPy check the numbers of section 4. The solver is a black box; the derivative comes from the equation at the solution.
import numpy as np
from scipy.optimize import fsolve
# (a) 2-D root: implicit Jacobian vs finite differences of a black-box solver
F = lambda x, t: [x[0] + x[1]**2 - t, x[0] * x[1] - 1]
root = lambda t: fsolve(F, [1.0, 1.0], args=(t,), xtol=1e-13)
x = root(2.0)
Fx, Ft = np.array([[1, 2 * x[1]], [x[1], x[0]]]), np.array([-1.0, 0.0])
h = 1e-5
print(-np.linalg.solve(Fx, Ft), (root(2 + h) - root(2 - h)) / (2 * h)) # [-1. 1.] [-1. 1.]
print(root(2.1)) # [0.92094247 1.08584415]
# (b) fixed point x = (x^2 + t)/4 at t = 3: unrolled derivative by forward mode, from x0 = 0
def unrolled(t, K, x=0.0, dx=0.0):
for _ in range(K):
x, dx = (x * x + t) / 4, (2 * x * dx + 1) / 4 # dx_{k+1} = f_x dx_k + f_t
return dx
print([round(unrolled(3.0, K), 7) for K in (1, 2, 5, 10, 20)])
# [0.25, 0.34375, 0.4650059, 0.4979725, 0.4999961] -> implicit: (1/4)/(1 - 1/2) = 0.5
# (c) ridge hypergradient with one solve
X, y = np.array([[1.0, 1.0], [1.0, 0.0], [0.0, 1.0]]), np.array([1.0, 2.0, 0.0])
lam = 1.0
A = X.T @ X + lam * np.eye(2)
w = np.linalg.solve(A, X.T @ y)
wbar = np.array([0.0, w[1] - 1.0]) # gradient of V = (w2 - 1)^2 / 2
u = np.linalg.solve(A, wbar) # adjoint solve (A is symmetric)
print(w, -np.linalg.solve(A, w), -w @ u) # [1. 0.] [-0.375 0.125] -0.125
In PyTorch you attach the implicit gradient to a solver with a custom backward. The forward pass runs the solver without recording a graph; the backward pass solves the adjoint equation at :
import torch
class FixedPoint(torch.autograd.Function):
"""x* = f(x*, theta) for f(x, theta) = (x^2 + theta) / 4, with an implicit backward."""
@staticmethod
def forward(ctx, theta):
x = torch.zeros_like(theta)
for _ in range(200): # any solver; no graph is recorded here
x = (x * x + theta) / 4
ctx.save_for_backward(x)
return x
@staticmethod
def backward(ctx, xbar):
(x,) = ctx.saved_tensors
f_x, f_theta = x / 2, 0.25 # partial derivatives of f at x*
u = xbar / (1 - f_x) # adjoint solve (I - f_x)^T u = xbar
return f_theta * u # f_theta^T u
theta = torch.tensor(3.0, dtype=torch.float64, requires_grad=True)
x = FixedPoint.apply(theta)
x.backward()
print(x.item(), theta.grad.item()) # 1.0 0.5
In JAX, jax.lax.custom_root and the library JAXopt (Blondel et al. 2022) do the same for roots and optimality
conditions.
6. Where it shows up #
- Deep equilibrium models. A DEQ layer finds with Broyden or Anderson iterations and trains with the implicit VJP, so memory does not grow with the number of iterations. Cheaper variants truncate the adjoint solve or set ("Jacobian-free backprop"); their gradients are approximate by design (deep learning).
- Bilevel optimization. Lorraine, Vicol and Duvenaud (2020) tune millions of hyperparameters with a truncated Neumann series of HVPs for the inverse Hessian. Implicit MAML (Rajeswaran et al. 2019) solves the adjoint system with CG on HVPs.
- Optimization layers. OptNet differentiates the KKT conditions of a quadratic program. For a loss with smooth and non-smooth (an penalty), the proximal-gradient fixed point serves as the equation (optimization).
- Matrix identities. (check yourself 2) and the VJP of a linear solve are the theorem applied to and to (linear-algebra lesson 16).
- ML for science. For a discretized steady PDE , the gradient of a misfit with respect to all parameters costs one adjoint solve with : for example one Helmholtz system per source and frequency in frequency-domain full-waveform inversion. An implicit time step (backward Euler for stiff terms) is a root problem, differentiated the same way. The time-continuous case is the adjoint method for ODEs, used by neural ODEs (Chen et al. 2018; ML for science).
7. Common mistakes #
- Differentiating an unconverged solution. The formula assumes . Check the forward residual first; the gradient error is about proportional to .
- Forgetting the transpose. The adjoint solve uses . It equals only when is symmetric, as for an argmin (a Hessian). For a DEQ, is not symmetric.
- Sign errors in the fixed-point form. With : and . If depends on directly, do not drop .
- Letting autograd record the solver. Then you pay unrolled memory anyway and get the unrolled gradient. Run
the solver without a graph (
torch.no_grad()), evaluate once at with a graph for the VJPs, and attach the implicit gradient in a custom backward. - Using the theorem where it does not hold. singular or nearly singular (folds and bifurcations), non-unique minimizers (ridge with and rank-deficient ), or not differentiable at (a ReLU kink, a constraint that becomes active).
- The plain adjoint iteration without a contraction. does not converge when the spectral radius of is . Use GMRES instead.
8. Check yourself #
- The circle defines near . Find with the
theorem. Where on the circle does it fail for as a function of ?
Answer
and , so (check: gives ). It fails at , : there , the two branches meet and the tangent is vertical. - Derive from the theorem.
Answer
solves . Differentiate: , so . The partial derivative in is the linear map , which is invertible exactly when is. - The fixed point . Give , the unrolled derivative after steps from , and
the smallest with relative error below 1%.
Answer
Implicit: . Unrolled: , so and the relative error is . and , so . - and . Compare forming with the adjoint route for .
Answer
has entries (8 GB in float64) and needs solves with (one LU factorization, then pairs of triangular solves). The adjoint route needs one solve and one VJP , and stores nothing of size . - Show that of ridge regression decreases in , and say why one coordinate can still grow.
Answer
for , since . The direction has a negative inner product with , but the off-diagonal entries of mix the coordinates, so a single coordinate can grow (worked example (c): ). - The forward iteration converges with local rate 0.9 (the spectral radius of at ).
Does the adjoint iteration converge, and how many steps does each extra correct digit cost?
Answer
Yes. Its iteration matrix has the same eigenvalues as , so the error shrinks by about 0.9 per step: steps per digit. A Krylov solver such as GMRES can need far fewer.
State the derivative formula of the implicit function theorem for .
, with both partial Jacobians evaluated at .
What condition does the implicit function theorem need (besides and )?
must be invertible. Where it is singular (a fold), branches meet and the derivative can be infinite.
Derivative of a fixed point ?
. It needs invertible (1 is not an eigenvalue of ), not a contraction.
Compute for the fixed point of .
.
How do you get for without forming ?
Solve , then : one adjoint solve and one VJP.
Why does the implicit gradient need memory independent of the number of solver iterations ?
It uses only and its derivatives at the solution ; the solver path is not needed, so nothing from the iterations is stored.
What is for ridge regression?
, from differentiating .
When is the implicit gradient inaccurate?
When the solver has not converged (error about proportional to ) or when is nearly singular (the error constant grows).
Why can unrolling be the right choice?
When you want the gradient of the few-step computation you actually run (MAML, learned optimizers), or when the solution is not unique or not smooth.
9. Interview angle #
- "How does a DEQ backpropagate with constant memory?" Implicit function theorem at : solve with VJPs (fixed-point iteration or a Krylov method), then . Only is stored.
- "How do you get the gradient of the validation loss with respect to weight decay without unrolling?" Differentiate the optimality condition: with the training Hessian (for ridge, ), and get by CG on HVPs or a truncated Neumann series.
- "What is the VJP of ?" Solve ; then and .
- "When would you unroll instead?" For the gradient of a few-step or early-stopped computation, or when the solution is not unique or not smooth.
- "What happens at a fold?" is singular, the derivative is infinite (vertical tangent) and two branches meet; near the fold the implicit gradient is ill-conditioned.
10. Practice #
The notebook for this lesson runs in Colab. Five exercises, each with a check cell and a folded solution:
newton_rootandimplicit_jacobianfor the 2-D system of worked example (a); check with finite differences.implicit_vjp: the adjoint solve withscipy.sparse.linalg.gmresand CG on aLinearOperator, for a system with 200 unknowns.fixed_pointandfixed_point_vjpfor a small DEQ-like layer; compare with the unrolled gradient for .ridge_hypergradienton the diabetes data set (scikit-learn), then gradient descent on .- The gradient of a softmax-regression solution with respect to its L2 weight, from the optimality condition.
11. Watch and read #
- Kolter, Duvenaud and Johnson, Deep Implicit Layers (NeurIPS 2020 tutorial), chapter 2: naive differentiation through solvers, the implicit function theorem, and fixed-point JVPs and VJPs.
- Blondel et al. (2022), Efficient and Modular Implicit Differentiation: §2 (roots, fixed points, optimality conditions; one linear solve), Theorem 1 (error at most ).
- Blondel and Roulet, The Elements of Differentiable Programming (free), chapter 11: bilevel optimization, envelope theorems, the implicit function theorem and its proof, adjoint state method.
- Bai, Kolter and Koltun (2019), Deep Equilibrium Models.
- Lorraine, Vicol and Duvenaud (2020), Optimizing Millions of Hyperparameters by Implicit Differentiation.
- Rajeswaran et al. (2019), Meta-Learning with Implicit Gradients.
- Amos and Kolter (2017), OptNet: Differentiable Optimization as a Layer in Neural Networks.
Runs in your browser with nothing to install. The notebook repeats the key demos and has exercises with checks; solutions are inside, folded.
No Google account needed: Python runs inside your browser. The first start downloads about 40 MB; your changes are saved in this browser only.