Gradient check for a backward pass
Medium12 min12 hidden tests
A team hand-wrote the backward pass for a new layer. Before they train with it, they compare its gradient with a numerical estimate from finite differences. Write gradient_check(analytic, numeric, tol) that returns the relative error between the two gradients and whether it is small enough to trust. The relative error is norm(a - b) / (norm(a) + norm(b)), where norm is the Euclidean length.
Drag the numeric gradient
error = |a − b| / (|a| + |b|)|a − b| = 1.41e−6 and |a| + |b| = 4.4721, so the relative error is 3.16e−7. That is at most tol 1e−6: ok, trust the backward pass.
Relative error 3.16e−7, ok.
Examples
A tiny gap relative to the gradient's size passes
gradient_check([1.0, -2.0], [1.000001, -2.000001])
returns (3.16228e-07, True)
A flipped sign gives a large error and fails
gradient_check([1.0, -2.0], [1.0, 2.0])
returns (0.894427, False)
Requirements
analyticandnumericare lists or arrays of the same shape, 1-D or 2-D.normtreats all entries of an array as one long vector: the square root of the sum of their squares.- When both gradients are all zeros, they agree exactly and the error is 0.0.
- Return a tuple
(error, ok):erroris a float, andokis True whenerroris at mosttol. The defaulttolis 1e-6.
The idea behind it
A gradient check compares the gradient from your backward pass with an estimate from finite differences: nudge each input, see how the loss moves. The two never match exactly, because the estimate has rounding and truncation error, so you need a measure of how far apart they are. An absolute gap misleads, since gradients can be 1e-6 in one layer and 1e3 in another. The relative error ||a - b|| / (||a|| + ||b||) divides by the size of both, so it falls between 0 and 1: 0 for a perfect match, 1 when one of them is zero and the other is not. Adding both norms in the denominator keeps it defined when either gradient alone is zero. As a rough guide in 64-bit floats with a central difference, errors near 1e-7 or below usually mean the backward pass is right, and errors near 1e-2 or above usually mean a bug.