advanced28 min studyLesson 510 in Engineering

Derivative checks provide targeted evidence, not an oracle

Choose directional finite-difference scales, test adjoint consistency with shaped seeds, and separate smoothness, rounding, stochastic replay, and mutually wrong derivative rules.

On this page

What you’ll understand

  • Compare a JVP with a central directional finite difference at a valid smooth point.
  • Use an adjoint dot-product identity with compatible real shapes.
  • Explain why kinks, rounding, shared bugs, and uncontrolled state limit a passing check.

Automatic differentiation can faithfully compose an incorrect custom rule, so an independent check matters. Numerical perturbations and adjoint identities catch different mistakes. Neither is a universal proof: finite differences balance approximation and rounding, while two mutually wrong linear maps can satisfy the same dot identity. Build small checks whose mathematical target, runtime state, scale, and expected limitations are explicit before trusting a large model's plausible gradient norms.

A finite-difference step has two competing errors

For a smooth map at a valid input, the central directional difference [f(x+hv)−f(x−hv)]/(2h) approximates J_f(x)v. Its truncation error is typically second order in h under sufficient local smoothness and a fixed direction. Floating-point subtraction and function-evaluation error can grow in relative importance as h shrinks, so making h arbitrarily tiny is not a universal improvement. Scale perturbations to the input and direction, compare several h values, and examine both absolute and relative error where appropriate.

The familiar error sketch Ch²+Dε/h explains a possible U-shaped behavior, not an exact error law or universal optimal step. Constants depend on derivatives, evaluation scale, conditioning, and the numeric format. A symmetric quadratic can have zero central-difference truncation error in exact arithmetic, while a cubic has a visible h² term. Discontinuous branches, nonsmooth boundaries, invalid domains, or stochastic evaluations can violate the smooth deterministic assumptions entirely. Distinguish a checker failing its assumptions from a derivative implementation failing the intended contract.

f(x+hv)−f(x−hv)2h=Jf(x)v+O(h2),E(h)≈Ch2+Dϵh\frac{f(x+hv)-f(x-hv)}{2h}=J_f(x)v+O(h^2),\qquad E(h)\approx Ch^2+\frac{D\epsilon}{h}
For sufficiently smooth deterministic real f, fixed direction v, and h>0 small enough to remain in the valid domain. ε is a rounding-scale parameter; C and D carry the units required for the compared derivative. The error sketch is illustrative and can have vanishing or nonuniform terms.↔ Scroll wide equations horizontally.

An adjoint check verifies a different algebraic relationship

At fixed real input, compatible forward and reverse derivative products satisfy uᵀ(Jv)=vᵀ(Jᵀu). This is useful for large operators whose full Jacobian is impractical to form. Choose nontrivial seeds and verify dimensions before evaluating the scalar products. A transpose mistake, missing accumulation path, or incorrectly shaped reduction often breaks the identity. However, implementing JVP and VJP from the same wrong matrix can pass it exactly. Combine adjoint consistency with independent primal perturbations and hand-derived cases rather than treating two matching numbers as a proof of the true derivative.

For a scalar loss, compare directional differences with the gradient dot v instead of perturbing every coordinate if that matches the test target. Sparse layouts, aliases, custom rules, and higher-order paths need their own supported checks. PyTorch 2.9's gradcheck documentation describes assumptions and limitations, including numerical differences near nondifferentiable points. Use a suitable precision and tolerance, restore RNG and mutable state between evaluations, and avoid an optimizer update during the check. A stochastic output mismatch can otherwise dominate the derivative signal even when the rule is correct.

uT(Jv)=vT(JTu)u^\mathsf T(Jv)=v^\mathsf T(J^\mathsf T u)
J is an m×n real Jacobian at one fixed input, v an n-vector, and u an m-vector under Euclidean inner products. Both sides are scalars. This consistency identity alone cannot detect a pair of mutually compatible but incorrect derivative maps.↔ Scroll wide equations horizontally.

Report what the check actually covers

Choose inputs inside each valid branch and test boundary conventions separately. Include zero and scaled seeds, repeated indices, shared subexpressions, several shapes, and supported higher-order compositions. Preserve minimized failing examples and record framework version, dtype, device, state, and perturbation scale. A passing random-direction test can miss errors orthogonal to that direction; multiple directions improve evidence without proving every input. Explain whether the checker validates a true derivative, a declared surrogate, or a runtime convention, since a finite-difference mismatch can be expected for the latter two.

The quadratic lab shows why one numerical example can be unusually easy. Reset, explicitly set BOTH a=1 and x=1, predict analytic slope two, then Play or Step. Compute the central quotient for this quadratic on paper: its exact-arithmetic value is two for every nonzero h. Reset and re-set BOTH a=2 and x=1; the value is four. Edits retain t; playback traces an analytic curve and does not simulate rounding, change h, or run gradcheck. Use the cubic worked example to see nonzero truncation rather than concluding from the quadratic that step size never matters.

A cubic exposes the central difference's h² term

For f(x)=x³ at x=2 with direction one, compare central differences using h=0.1 and h=0.01 in exact arithmetic. Then check the adjoint identity for the earlier 3×2 Jacobian with v=(1,−1), u=(1,2,−1).

  1. The true derivative is 12. Expanding [(2+h)³−(2−h)³]/(2h) gives 12+h², so h=0.1 yields 12.01 and h=0.01 yields 12.0001 before rounding.

  2. For J=[[4,0],[3,2],[0,6]], Jv=(4,1,−6) and Jᵀu=(10,−2). The shapes match the three-output and two-input spaces.

  3. Both dot products equal twelve: u·Jv=4+2+6=12 and v·Jᵀu=10+2=12. This confirms this pair's adjoint consistency, while the independent cubic calculation illustrates a different numerical-error question.

The result

Smaller h reduces this cubic's exact truncation error, while the dot check verifies a compatible transpose relationship. Neither example proves arbitrary derivative code correct.

Explore the model

Interactive lab

Interactive lab · function

An easy quadratic can hide step-size limitations

For EACH run Reset, set BOTH a and x, predict, then Play or Step. Compare (1,1), slope two, with (2,1), slope four. Their central quotients are exact in ideal arithmetic for nonzero h. Edits retain t. The instrument has no perturbation control, floating-point error simulation, AD engine, or numerical derivative checker.

An easy quadratic can hide step-size limitationsThis lab uses only y = ax². Playback traces the curve within the fixed integration interval from 0 to x; it does not estimate numerical error or change the chosen point. Current readings: y at chosen x: 0.608; Tangent slope · 2ax: 1.35; Signed area · ax³/3: 0.182. All parameters are adjustable with the labeled controls below.−2.4−1.201.22.4−9−4.504.59xy(x, ax²)
y = ax²TangentSigned integral
y at chosen x
0.608
Tangent slope · 2ax
1.35
Signed area · ax³/3
0.182
t = 0 s

This lab uses only y = ax². Playback traces the curve within the fixed integration interval from 0 to x; it does not estimate numerical error or change the chosen point. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forCheck assumptions and use several mechanisms: one analytic family or a passing adjoint identity cannot certify a general derivative implementation.

Check your understanding

Why can an adjoint dot check pass even when a custom JVP and VJP are both wrong?

Try it yourself

At the kink of |x| at zero, a central difference with symmetric nonzero h returns zero. Does that establish an ordinary derivative zero? Explain alongside the function's one-sided slopes.

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Compare the two directional limits; a symmetric quotient can cancel despite a missing derivative.

Compare with the solution

No. The left slope is minus one and the right slope plus one, so |x| has no ordinary derivative at zero. The symmetric quotient cancels to zero because |h|=|−h|; it does not override the mismatch or validate every framework's chosen subgradient convention.

Take it with you

  • Finite differences require a valid smooth deterministic target and a scale-aware step.
  • Adjoint dot checks verify consistency without proving primal agreement.
  • Passing evidence must name its inputs, shapes, conventions, runtime state, and limits.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.