Human–Machine Convergence

Calculus, chain rules and credit assignment

Rajesh Ranjan Mahapatra

© 2026 Rajesh Ranjan Mahapatra. 32 min read

Calculus, chain rules and credit assignmentAll Human–Machine Convergence

Inference, dynamics and causality

Calculus, chain rules and credit assignment

The chain rule makes distant learning tractable by factorising a global loss sensitivity into local pullbacks, but the resulting gradient becomes defensible credit only after path, scale and intervention checks.

TLDR

  1. The chain rule turns a distant effect into products and sums of local sensitivities.
  2. Reverse-mode differentiation reuses one backward sweep to obtain many parameter gradients from one scalar loss.
  3. The same multiplication that enables learning can make gradients vanish, explode, cancel or shatter.
  4. A raw gradient is coordinate-dependent local sensitivity, not causal blame or global importance.
  5. Before changing a component, verify the derivative and test finite interventions, paths and equivalent parameterisations.

The camera setting that the gradient barely notices

Consider Trellis, a synthetic inspection model that turns a camera signal into a defect probability. One internal gate receives the value z = 8, so its sigmoid output is 0.9997. The desired output for this example is 0.5. With squared error, the loss is about 0.1248.

Ask backpropagation how the loss changes if z moves. It returns a gradient of roughly 0.00017. That looks like an instruction to ignore the gate. Yet resetting z from 8 to 0 makes the output exactly 0.5 and removes the loss.

Nothing is inconsistent. The gradient answered a narrow question: what happens under an infinitesimal move from 8? The reset asked a different question: what happens under a large intervention that crosses a saturated region? A gradient is a local sensitivity in a declared computation, not a universal measure of what caused the failure.

The error that does not travel backwards

“Backpropagating the error” invites a misleading picture. It sounds as if the wrong answer is packaged at the output and carried backwards, layer by layer, until every parameter receives its share of blame. That story is useful for orientation, but it hides the mathematical object doing the work.

The backward quantity is not the error itself. It is the sensitivity of the chosen scalar loss to an intermediate value. At each operation, the system asks: if this input changed by a tiny amount while the rest of the local calculation stayed fixed, how much would the final loss change? The answer is then translated through the next operation, and the next, until it reaches a parameter.

This is why calculus matters. A derivative is a disciplined local comparison. For a scalar function y = f(x), the derivative at x is the limiting ratio between a small output change and the small input change that produced it. It says nothing by itself about large moves, alternative mechanisms, bad labels, missing variables or whether the intervention is physically available.

Make the comparison more explicit. Let a system have two adjustable quantities, θ₁ and θ₂, and let its loss be L(θ₁, θ₂). At one operating point, the gradient might be (4, 1). This does not mean that the first quantity caused four times as much harm. It means that, under the chosen units and while making an infinitesimal move parallel to one coordinate axis, loss changes four times as quickly along θ₁ as along θ₂.

The available action may point elsewhere. If a physical constraint permits only the joint move d = (1, −1), then the relevant first-order change is the directional derivative ∇L · d = 3. If the permitted move is d = (1, −4), the first-order change is zero even though neither coordinate gradient is zero. Credit becomes actionable only after the candidate direction of change is named. A component score without an action model quietly assumes that every coordinate can move independently, by the same unit, at negligible cost.

A gradient watershed flowing from a loss basin back towards parameters Forward computations descend from three parameter ridges into one loss basin. Backward sensitivity follows the same channels in reverse, becoming narrower or wider according to each local slope. scalar loss one question at the outlet θ₁ θ₂ θ₃ forward values backward sensitivity Channel width represents local amplification; a dry channel represents zero local derivative.
The gradient watershed. A single loss creates a backward sensitivity field over the paths that produced it. The geometry emphasises the central mechanism: local slopes control how much signal each upstream route receives. Illustrative.

The watershed picture also exposes a hidden assumption. We often speak as though a component owns a fixed amount of responsibility. In fact, its derivative depends on the current point, the route to the loss and the coordinates used to describe the component. Change any of those, and the number can change even when the forward behaviour does not.

Thought experiment: the saturated gate

Return to Trellis. At z = 8, the sigmoid is nearly flat. Move z by 0.001 and the output barely changes, so the derivative is correctly tiny. Now allow one different intervention: replace the gate setting with z = 0. That move crosses the plateau and reaches a region with a steep slope. The loss disappears.

Which answer is right? Both, because they answer different counterfactuals. The derivative describes an infinitesimal perturbation within the present regime. The reset describes a finite, feasible action. Local credit becomes actionable only when the intervention scale matches the decision you can actually make.

The same boundary applies to the loss. Suppose Trellis is trained against an incorrect label. Backpropagation can be mathematically flawless and still push every parameter in the wrong practical direction. Suppose the loss omits energy use, false-negative cost or a policy constraint. No chain rule will smuggle those concerns into the gradient. It differentiates the objective provided, not the objective intended.

Worked example: a zero gradient made from two strong demands

Consider the one-parameter predictor ŷ = θx with squared loss ½(ŷ − t)². At θ = 0, use two records with the same input x = 1. The first target is t = 2, so its gradient is −2. The second target is t = −2, so its gradient is +2. The mean gradient is exactly zero.

The parameter is not irrelevant to either record. The selected batch objective asks it to satisfy incompatible local demands and then averages them away. A different weighting, subgroup slice or loss would return a different credit signal.

This cancellation is common enough to deserve its own diagnostic. Record the reduction operation, not just the final scalar. A mean over examples, time steps or tasks determines which positive and negative sensitivities meet before the backward pass begins. Per-example gradients can reveal conflict that the aggregate gradient conceals. They still remain local sensitivities, but they expose which parts of the declared objective are supplying them.

Evidence status: the calculus is established mathematics. The claim that gradients should be treated as proposals rather than causal verdicts is a practitioner synthesis developed in this paper.
The argument in one pass
Chart · flow
flowchart TD
  A["The error that does not travel<br/>backwards"] --> B["One global question, many<br/>local answers"]
  B --> C["When the path changes the credit"]
  C --> D["From sensitivity to a change<br/>you can defend"]
  D -. "re-test" .-> A
  classDef first fill:#0a1424,stroke:#B96D00,stroke-width:2px,color:#e6f3ff
  classDef step fill:#0a1424,stroke:#3f7da0,stroke-width:1px,color:#e6f3ff
  class A first
  class B,C,D step
A structural route through Calculus, chain rules and credit assignment: from The error that does not travel backwards to Use gradients to propose and…. Reading use: follow the relation, then return to the surrounding argument for evidence and limits.

One global question, many local answers

The chain rule earns its importance by making a distant question decomposable. Begin with a calculation small enough to hold in working memory.

Worked example: a four-step scalar model

Let the input be x = 2, a weight be w = 2, and a bias be b = 1. The model computes a = wx + b = 5, then y = a² = 25. The target is t = 20, and the loss is L = ½(y − t)² = 12.5.

The local derivatives are simple: ∂L/∂y = 5, ∂y/∂a = 10, and ∂a/∂w = 2. Multiply them and ∂L/∂w = 100. A small move Δw = −0.01 therefore predicts ΔL ≈ −1. The actual loss change is about −0.978, close because the move is small.

Annotated forward and backward passes for a scalar chain The top row shows forward values from weight and input to loss. The bottom row shows local derivatives multiplying backwards to produce a weight gradient of one hundred. FORWARD VALUES w = 2x = 2, b = 1 a = 5wx + b y = 25a² L = 12.5½(y − 20)² BACKWARD SENSITIVITIES ∂L/∂y = 5loss slope × ∂y/∂a = 10square slope × ∂a/∂w = 2affine slope ∂L/∂w = 100product
A derivative assembled from local slopes. No node needs to know the whole formula. Each contributes one local derivative, and the chain rule composes them. Illustrative worked example.

In scalar notation, if z₀ = θ, z₁ = f₁(z₀), and so on until L = zₖ, then the derivative is the product of local derivatives along the chain.

∂L/∂θ = (∂L/∂zk−1) (∂zk−1/∂zk−2) ⋯ (∂z1/∂θ) Each factor measures one local sensitivity at the values produced by the forward pass. The equation assumes differentiability at those values.

Vectors change the notation, not the idea. Each operation has a Jacobian, a linear map that approximates how a small input displacement changes the output. Reverse mode starts with sensitivity one at the scalar loss and repeatedly applies transposed Jacobians. In automatic-differentiation language, it computes vector-Jacobian products, or pullbacks, from output cotangents to input cotangents (JAX authors).

z̄i−1 = Jfᵢ(zi−1)T z̄i z̄ᵢ means ∂L/∂zᵢ. The Jacobian translates output sensitivity into input sensitivity. It is evaluated at the cached forward value.

Read the transpose in that expression as a pullback. Suppose a local operation maps a three-number input into a two-number output. Its Jacobian has two rows and three columns. The backward pass does not need every entry of that matrix as a standalone object. It receives a two-number sensitivity from downstream and multiplies by the transposed Jacobian, producing the three-number sensitivity required upstream. Automatic-differentiation systems call this a vector–Jacobian product or, depending on orientation, a Jacobian-transpose–vector product. The operation answers one targeted question without materialising a potentially enormous Jacobian.

A concrete linear node makes this visible. Let z = Aθ, where θ contains three parameters, z has two outputs and A is a two-by-three matrix. If downstream computation supplies g = ∂L/∂z, then the parameter gradient is Aᵀg. Each column of A tells how one parameter moves both outputs. Multiplication by g weights those movements by what the loss currently cares about. The result is credit for this loss and this downstream state, not a permanent property of the parameter.

What reverse mode actually stores

During the forward pass, each primitive operation records or makes recoverable the values needed by its local derivative rule. During the reverse pass, it receives an output cotangent, applies its pullback and accumulates the result at its parents. When a value is reused, contributions from every executed use are added. When control flow skips a branch, that unexecuted branch contributes nothing to that run.

This local contract is the source of both efficiency and inspectability. For straight-line arithmetic programs, Baur and Strassen (1983) showed that all first partial derivatives of a scalar result can be obtained with only constant-factor arithmetic overhead relative to evaluating the program. Modern systems complicate the accounting with memory traffic, parallel kernels, control flow and recomputation, but the structural bargain remains: one scalar question can be pulled back to many inputs by reusing local work.

This direction is computationally decisive. A training loss usually has millions or billions of parameter inputs and one scalar output. Forward mode would carry one input perturbation through the graph at a time. Reverse mode shares the forward calculation, then obtains all parameter sensitivities in one reverse traversal. Automatic differentiation is broader than neural-network backpropagation, but backprop is its most visible machine-learning use (Baydin et al., 2018). The efficient reverse accumulation idea also predates its neural-network popularisation (Baur and Strassen, 1983).

Mechanism

Reverse mode works because every local derivative can be reused by every upstream parameter that flows through it. The forward pass records values. The backward pass composes local linear maps in the opposite order. Shared subcomputations are differentiated once, not re-expanded separately for every parameter.

Automatic differentiation is therefore neither symbolic differentiation nor finite differencing. Symbolic differentiation rewrites an expression and can expand it into unwieldy formulae. Finite differencing reruns the program after perturbing an input and suffers from truncation and floating-point error. Automatic differentiation executes derivative rules alongside the original primitives, so its result is exact up to ordinary numerical arithmetic for the graph that actually ran. It can still be wrong for the intended system if the graph omits a path, detaches a state, uses an unsuitable surrogate derivative or encodes the wrong objective.

The computational advantage also explains why scalar losses dominate training interfaces. If a system has many outputs and one wants the complete Jacobian with respect to many parameters, no single reverse sweep contains every possible output question. Each seed at the output selects a different linear combination. A scalar loss compresses those questions before differentiation. That compression is a modelling decision: it determines which errors, examples and desiderata become commensurable enough to share one backward signal.

Real computational graphs branch and merge. At a fork, one value influences several descendants. Its total gradient is the sum of the contributions returning through every child. This sum is as important as the pathwise products.

Worked example: two active paths that partly cancel

Let p = ab, q = ac, s = p + q, and L = ½(s − 1)². Choose a = 2, b = 3 and c = −1. Then s = 4 and ∂L/∂s = 3. The path through p contributes 3 × b = 9 to ∂L/∂a. The path through q contributes 3 × c = −3. The total is 6.

Neither branch owns the final answer. Credit is a signed path sum. If b + c = 0, the gradient to a becomes zero even though both branches are active and individually sensitive.

Fork and merge graph showing pathwise gradient contributions Parameter a forks into products ab and ac. Their gradient contributions of positive nine and negative three merge into total gradient six. a = 2 shared input p = ab = 6 b = 3 q = ac = −2 c = −1 s = 4 p + q L = 4.5 ½(s − 1)² +9 −3 ∂L/∂a = 9 − 3 = 6
Credit is a signed sum over paths. Branches can reinforce or cancel. A zero total gradient can hide large opposing sensitivities. Illustrative worked example.
MethodWhat it computesBest fitMain failure or cost
Symbolic differentiationTransforms an expression into another expressionSmall closed-form formulaeExpressions can expand and duplicate work
Finite differenceApproximates change by evaluating nearby pointsBlack-box checks and small parameter setsOne or more evaluations per direction; step-size and rounding trade-offs
Forward modePushes an input perturbation through Jacobian-vector productsFew inputs, many outputsRepeated work when inputs greatly outnumber outputs
Reverse modePulls an output sensitivity through vector-Jacobian productsMany inputs, one scalar lossStores or recomputes forward intermediates; inherits graph and differentiability assumptions

Rumelhart, Hinton and Williams showed how repeated weight adjustments derived this way can make hidden units acquire task-relevant representations (1986). The achievement was not that calculus suddenly discovered hidden layers. It was that a global training error could be translated into local update directions for every weight without separately solving a new optimisation problem for each one.

When the path changes the credit

The chain rule does more than transmit sensitivity. It reshapes it. Products govern a single path, sums govern competing paths, and the graph determines which paths exist. These operations create predictable failure modes.

Thought experiment: the hundred-room corridor

Imagine a message crossing a corridor of identical rooms. Each room multiplies it by a gain α. After T rooms, both the forward influence and the backward sensitivity contain the factor αᵀ. With α = 0.9 and 60 rooms, the factor is about 0.0018. With α = 1.1, it is about 304.

No individual room is dramatic. The apparent phase change belongs to repeated multiplication. Depth turns modest local bias into exponential attenuation or amplification.

Illustrative chart of gradient magnitude across depth Logarithmic gradient magnitude falls for local gain zero point nine, stays flat for gain one, and rises for gain one point one over sixty layers. 10³10²10¹110⁻¹10⁻²10⁻³ 0102030405060 depth T |αᵀ| on a log scale α = 0.9, vanishing α = 1.0, preserved α = 1.1, exploding
Repetition creates the cliff. The plot is synthetic and scalar, but it shows why seemingly small deviations in local gain become severe with depth. Matrix-valued networks add direction and alignment effects. Illustrative; values are αᵀ.

In recurrent networks, the same parameters are applied over time, so credit to an early state contains a product of many transition Jacobians. Pascanu, Mikolov and Bengio analysed vanishing and exploding gradients through analytical, geometric and dynamical lenses, and proposed gradient clipping for explosion (2013). Clipping controls the size of an update after the fact. It does not reconstruct information already erased by a near-zero product.

Forward state and backward sensitivity across a six-step recurrent chain Forward states shrink from one to zero point two six under gain zero point eight. Backward sensitivity mirrors the same powers from the final loss towards the initial state. FORWARD STATE: hₜ = 0.8 hₜ₋₁ BACKWARD SENSITIVITY: ∂h₆/∂hₜ = 0.8⁶⁻ᵗ 1.000h₀0.262credit 0.800h₁0.328credit 0.640h₂0.410credit 0.512h₃0.512credit 0.410h₄0.640credit 0.328h₅0.800credit 0.262h₆1.000loss seed
Time reverses the bookkeeping, not the dynamics. The backward pass asks how the final state depends on each earlier state. Repeated contraction makes early credit faint. Illustrative scalar recurrence.

The scalar corridor hides a more selective effect. In a vector system, every room applies a Jacobian matrix rather than one gain. A matrix can stretch one direction, shrink another and rotate both. Products of such matrices may preserve the overall norm while erasing the particular direction needed to solve the task. Conversely, a large norm may be concentrated in an irrelevant direction. Monitoring only the average gradient magnitude can therefore miss directional loss of credit.

Singular values provide the local lens. For one Jacobian, a singular value above one amplifies its associated direction and a value below one contracts it. Across depth, the singular directions themselves can rotate, so multiplying average gains is only a rough warning. The exact signal depends on the ordered product encountered along the executed trajectory. This is why initialization, normalisation, gating and architecture alter trainability even when they compute families of similar functions.

Residual connections change that product in a specific way. A plain layer hₖ₊₁ = Fₖ(hₖ) contributes the Jacobian Jₖ. A residual layer hₖ₊₁ = hₖ + Fₖ(hₖ) contributes I + Jₖ, where I is the identity map. The identity term supplies a direct route for both forward state and backward sensitivity. It does not guarantee stable training, but it changes the default from repeatedly replacing a signal to repeatedly perturbing it. The empirical success of residual networks and the analysis of shattered gradients support this path-based explanation within the architectures studied by He and colleagues (2016) and Balduzzi and colleagues (2017).

Feed-forward depth has an additional problem. Even when gradient magnitudes remain controlled, gradients for nearby inputs can become poorly correlated and resemble noise. Balduzzi and colleagues called this gradient shattering and showed that skip connections resist it better than plain deep networks (2017). Residual architectures provide identity routes through which signals and gradients can travel more directly, one reason they made much deeper networks easier to optimise (He et al., 2016).

Thought experiment: the tenfold twin

Take the ReLU model y = v ReLU(wx) with x = 1, w = 2, v = 3 and target 5. It outputs 6. The gradients are ∂L/∂w = 3 and ∂L/∂v = 2.

Now replace the parameters with w′ = 20 and v′ = 0.3. Because ReLU is positively homogeneous, the function is unchanged for every input: 0.3 ReLU(20x) = 3 ReLU(2x). Yet the gradients become 0.3 and 20. The apparent ranking flips.

Function-preserving reparameterisation with different raw gradients Two ReLU networks compute the same output six for every input under positive rescaling, but their raw parameter gradients swap from three and two to zero point three and twenty. Original coordinates Tenfold rescaling x ReLUw = 2 y = 6v = 3 x ReLUw′ = 20 y = 6v′ = 0.3 same function Raw gradients∂L/∂w = 3∂L/∂v = 2 Raw gradients∂L/∂w′ = 0.3∂L/∂v′ = 20 The model behaviour is invariant; Euclidean parameter gradients are not.
Same function, different apparent credit. Raw gradient magnitude depends on the coordinate system. Path-normalised methods were proposed partly to respect function-preserving rescalings in ReLU networks (Neyshabur et al., 2015). Illustrative calculation.

The reparameterisation example reveals a geometric choice hidden inside ordinary gradient descent. A derivative is a covector: it converts a proposed displacement into a first-order loss change. To turn that covector into an update vector, an optimiser needs a rule for measuring distance in parameter space. Plain gradient descent uses the Euclidean geometry of the current coordinates. Rescale those coordinates and the same function receives a different update.

Methods such as path-normalised optimisation try to remove part of this arbitrariness for positively homogeneous networks. Neyshabur, Salakhutdinov and Srebro (2015) designed Path-SGD so that function-preserving node rescalings do not change its geometry in the same way. This is not a universal solution. Different invariances suit different model classes, and function-space change can still interact with data and loss. The useful lesson is narrower: a ranking becomes stronger when it survives transformations that leave the relevant behaviour unchanged.

This is not a numerical curiosity. If an engineer ranks modules by raw gradient magnitude, equivalent parameterisations can suggest opposite priorities. The gradient is a covector: it transforms when coordinates change. A step direction also depends on the metric used to turn that covector into a parameter displacement. Ordinary gradient descent silently chooses Euclidean geometry in the current coordinates.

Thought experiment: the severed backward wire

Build two programs with the same forward calculation y = f(g(x)). In the second, insert a stop-gradient operation after g. Both programs produce exactly the same output for every input. During learning, however, the first sends credit into g and the second sends none.

The forward function does not uniquely determine the learning graph. Freezing a module, detaching a state, using a non-differentiable tool or replacing a value with a cached constant changes who can receive credit without changing the current prediction.

Two identical forward graphs with different backward boundaries Both upper and lower systems compute the same output. The lower graph contains a stop-gradient barrier, so backward sensitivity does not reach the upstream module. Same forward behaviour x module gtrainable module ftrainable losssame value x module gdetached module ftrainable losssame value stop-gradient boundary
Learning has a boundary distinct from inference. A component can participate in the forward answer yet receive no gradient. The training graph, not output behaviour alone, defines credit routes. Illustrative.

The strongest alternative to exact backpropagation is not that credit can be ignored. It is that useful teaching signals may be approximate. Feedback alignment replaces exact transposed forward weights with fixed random feedback pathways, yet can train several linear and nonlinear networks because the forward weights adapt towards useful alignment (Lillicrap et al., 2016). Direct feedback alignment goes further by sending output error directly to hidden layers (Nøkland, 2016).

These results weaken any claim that the exact chain-rule gradient is the only possible learning signal. They do not show that all approximate signals work, that biological brains implement those algorithms, or that gradient correctness is irrelevant. For a fixed smooth graph and scalar objective, reverse mode still computes the precise local derivative. The alternative algorithms change the learning rule and accept a different guarantee.

Sigmoid saturation separating local slope from finite intervention A sigmoid curve is nearly flat at z equals eight, where the local gradient is tiny. A long arrow to z equals zero shows a finite reset that reaches the target output and removes the loss. target = 0.5 z = 8, p ≈ 0.9997 local slope ≈ 0 finite reset crosses the plateau −10010gate input zsigmoid output
A correct derivative can still be a poor guide to a large action. At saturation, the local slope is tiny. A finite intervention can cross into a different regime and produce a large effect. Illustrative; sigmoid values are exact.
Worked edge case: zero first-order credit at a movable point

Let L(θ) = θ³. At θ = 0, the gradient is zero, yet any small negative move lowers the loss and any small positive move raises it. The tangent is flat because the leading local change is cubic, not because the point is an optimum. In several dimensions, saddles and flat plateaux create richer versions of the same warning.

A finite update asks more than the gradient can answer. For a parameter displacement Δθ, the second-order approximation is ΔL ≈ gᵀΔθ + ½ΔθᵀHΔθ. Here g is the gradient, H is the Hessian and the quadratic term records local curvature along the proposed move. The approximation assumes sufficient smoothness and a displacement small enough for neglected higher-order terms to remain minor. Hessian–vector products can estimate the curvature term without constructing the full matrix, as shown by Pearlmutter (1994).

Curvature improves a step forecast, not the meaning of credit. It can reveal that a large gradient points into a sharply curved wall, or that a modest gradient lies in a broad productive valley. It still inherits the chosen loss, graph, data and coordinates. Second-order optimisation narrows the gradient-to-action gap for local moves; it does not turn optimisation sensitivity into historical causation.

Nonsmooth activations add another boundary. A ReLU has zero derivative throughout its inactive region and no unique classical derivative at zero. Software chooses a convention at the kink. A dead unit can therefore receive no local gradient even when a sufficiently large bias change would reactivate it. Gradient checking near such points must distinguish a coding error from a genuine lack of smoothness.

Gradient-based explanations create a related warning. Input attribution is not the same problem as assigning parameter updates, so the fields should not be equated. Still, implementation invariance and model-randomisation tests show why a visually plausible gradient-derived explanation is not automatically faithful (Sundararajan et al., 2017) (Adebayo et al., 2018). The lesson transfers as a design discipline: test the claimed meaning, rather than only the arithmetic.

How the claim changes under pressure
Chart · state
stateDiagram-v2
  [*] --> Claim
  state "An autodiff-free<br/>credit-assignment audit" as Claim
  state "Frame the claim" as Test
  state "Test the mechanism" as Revision
  Claim --> Test: expose mechanism
  Test --> Decision: evidence survives
  Test --> Revision: rival survives
  Revision --> Claim: narrow or rebuild
  Decision --> [*]
The revision loop begins with An autodiff-free credit-assignment audit and keeps counterexamples inside the reasoning path. Reading use: follow the relation, then return to the surrounding argument for evidence and limits.

From sensitivity to a change you can defend

Return to Trellis as a configured system rather than a bare equation. It contains a sensor setting, a clipping preprocessor, a trainable encoder, a calibration layer, a decision threshold and a labelled dataset. Only some of these objects lie inside the differentiable graph. Only some are allowed to change. Only the declared loss contributes a learning signal.

A large encoder gradient may identify a locally effective parameter update. It does not prove that the encoder created the bad label, that changing it is safer than changing exposure, or that the policy threshold should move. A zero sensor gradient may mean saturation, a detached path, cancellation across examples or a genuinely insensitive operating point. The number needs a typed interpretation.

A new causal distinction

Optimisation credit is the local derivative of the selected loss in the current coordinates. Intervention credit is the observed or estimated effect of a bounded feasible change. Mechanism credit is the part of that effect that remains stable when alternative paths, equivalent parameterisations and relevant data slices are tested.

The three can agree, but they need not. Treating them as one concept is the gradient-to-action gap.

The practical object should therefore be a credit-assignment assay, not a leaderboard of components. Its manifest records the scalar objective, the data slice and reduction, the candidate variable, its units, the executed path, the allowed intervention, the numerical tolerance and the invariances that matter. Without those fields, two teams can report “the gradient” while answering different questions.

The burden should match the decision. A reversible optimiser step may need only a verified derivative and a line-search check. Freezing a module for a month should also test data slices, alternative paths and nearby operating points. Replacing a sensor, changing a policy threshold or blaming a team requires evidence outside the differentiable model. Do not demand every rung for every update, but do not spend higher-stakes authority on lower-rung evidence.

This distinction suggests a ladder rather than a verdict. Each rung permits a stronger decision while retaining the limits of the previous one.

The Credit Assignment Ladder Five ascending steps move from a derivative existing in the graph to numerical verification, finite intervention, path stability and representation stability. A side boundary warns that the ladder does not establish real-world causality outside the model. 1. Graph creditA differentiable path exists 2. VerifiedFinite difference agrees 3. FeasibleBounded move improves 4. Path-stableEffect survives path tests 5. Stable creditRanking survives re-expression Decision strength rises Boundary: still conditional on loss, data, graph and intervention set No rung alone proves real-world causality, safety, fairness or moral responsibility.
The Credit Assignment Ladder. Move upward only when the next test passes. A gradient can guide local optimisation at level two; prioritising a module for consequential change should usually require the higher rungs. Practitioner synthesis proposed in this paper.
RungTestPositive result permitsNegative result means
Graph creditTrace the exact path from parameter to loss, including detachments, reuse and aggregationInterpret the derivative within that graphNo gradient claim is available for the severed component
Verified local sensitivityCompare the hand or automatic derivative with a central finite difference away from kinksTrust the local implementation to numerical toleranceSuspect a bug, unstable step size or nonsmooth point
Feasible interventionApply a bounded change that respects the allowed operating rangeUse the gradient sign as an update proposal at that scaleThe linear approximation is too local, or interactions dominate
Path stabilityAblate, hold fixed or separately measure competing routes and data slicesAttribute the effect to a more specific mechanism within the modelCancellation, redundancy or confounding paths control the result
Representation stabilityRepeat under function-preserving rescaling or compare function-space changePrioritise the component with less coordinate arbitrarinessRaw magnitude is a property of parameterisation, not stable importance
Configured-system example: auditing Trellis

Declare the question. Trellis uses squared calibration loss on a named synthetic batch. The candidate is the pre-sigmoid gate value z, measured in the encoder’s internal units. A small optimiser update is allowed; a direct reset is available only as a diagnostic intervention.

Verify the local calculation. At z = 8, the hand derivative and central finite difference agree near 0.00017. This supports graph credit and numerical correctness at that point. It does not yet support ignoring the gate.

Vary intervention scale. A change of −0.001 produces the tiny loss reduction predicted by the tangent. Changes of −0.1, −1 and the reset to zero increasingly depart from that prediction as they cross the sigmoid’s curved shoulder. The gate therefore has weak local optimisation credit at the saturated point but strong finite intervention credit over an available diagnostic range.

Test the path. Repeat after removing clipping, detaching the calibration layer and evaluating records separately. If the effect disappears only when one route is severed, that route carries model-internal mechanism credit. If subgroup gradients oppose one another, the aggregate score was hiding a trade-off. If the ranking changes under an equivalent rescaling of adjacent ReLU layers, raw parameter magnitude is not representation-stable.

The defensible conclusion is deliberately typed: the gate is locally saturated under the declared loss; finite changes can materially alter that loss; and the strength of any module-level attribution depends on the tested path and representation. Nothing in the assay establishes why the real camera produced a signal, whether the label is correct or whether changing the deployed sensor is safe.

A comparative test of the ladder can be small and decisive. Generate families of two-layer networks that implement the same input-output function through different positive rescalings. Add controlled saturation, redundant paths and mixtures of examples with cancelling gradients. Rank candidate components once by raw gradient magnitude and once by the highest ladder rung passed. Then apply predeclared bounded interventions and measure realised loss change, ranking stability across batches and sensitivity to equivalent parameterisations.

The main prediction is not that higher rungs always produce larger gains. It is that they reduce false confidence: fewer high-ranked components should fail to improve under the permitted intervention, and fewer priorities should reverse under behaviour-preserving re-expression. A null result would be useful. It would show that the additional assay cost does not buy better decisions for that model family, loss and intervention range.

Open research hypothesis

The ladder should predict which gradient-ranked component changes produce stable improvement better than raw gradient magnitude alone. Evidence would strengthen the proposal if rankings that survive finite interventions, path tests and rescaling generalise across batches and nearby operating points. It would weaken it if the extra tests add no predictive value or merely inject noise.

A rival explanation is that any improvement comes from generic robustness testing rather than the specific distinction among optimisation, intervention and mechanism credit. The framework should not be used to infer real-world causality outside the declared system. Its smallest useful test is a scalar or two-layer network with one saturation case, one fork and one equivalent rescaling.

Executable lab

An autodiff-free credit-assignment audit

The lab below exposes the local products that a framework normally hides. The interactive controls show depth amplification and saturation. The Python program computes a two-layer network by hand, checks every gradient with central differences, compares first-order predictions with finite moves, and reproduces the reparameterisation example.

Python · standard library only
"""Autodiff-free credit-assignment lab for Paper 17.

Uses only Python's standard library. It compares hand-derived gradients with
central finite differences, then exposes saturation, depth and reparameterisation
failure cases.
"""
from __future__ import annotations

from dataclasses import dataclass, replace
import math
from typing import Dict, Tuple


@dataclass(frozen=True)
class Params:
    w1: float = 0.8
    b1: float = -0.1
    w2: float = 1.2
    b2: float = 0.05


def forward(p: Params, x: float, target: float) -> Dict[str, float]:
    """Two-layer scalar network: affine -> tanh -> affine -> squared loss."""
    a = p.w1 * x + p.b1
    h = math.tanh(a)
    y = p.w2 * h + p.b2
    loss = 0.5 * (y - target) ** 2
    return {"a": a, "h": h, "y": y, "loss": loss}


def manual_gradient(p: Params, x: float, target: float) -> Dict[str, float]:
    """Reverse pass written explicitly from local derivatives."""
    cache = forward(p, x, target)
    dloss_dy = cache["y"] - target
    dloss_dw2 = dloss_dy * cache["h"]
    dloss_db2 = dloss_dy
    dloss_dh = dloss_dy * p.w2
    dloss_da = dloss_dh * (1.0 - cache["h"] ** 2)
    dloss_dw1 = dloss_da * x
    dloss_db1 = dloss_da
    return {
        "w1": dloss_dw1,
        "b1": dloss_db1,
        "w2": dloss_dw2,
        "b2": dloss_db2,
    }


def central_difference(
    p: Params, x: float, target: float, name: str, eps: float = 1e-6
) -> float:
    """Black-box local check. It is approximate and sensitive to eps."""
    plus = replace(p, **{name: getattr(p, name) + eps})
    minus = replace(p, **{name: getattr(p, name) - eps})
    return (forward(plus, x, target)["loss"] - forward(minus, x, target)["loss"]) / (
        2.0 * eps
    )


def bounded_effect(
    p: Params, x: float, target: float, name: str, delta: float
) -> Tuple[float, float]:
    """Return actual loss change and first-order predicted loss change."""
    changed = replace(p, **{name: getattr(p, name) + delta})
    actual = forward(changed, x, target)["loss"] - forward(p, x, target)["loss"]
    predicted = manual_gradient(p, x, target)[name] * delta
    return actual, predicted


def sigmoid(z: float) -> float:
    if z >= 0:
        e = math.exp(-z)
        return 1.0 / (1.0 + e)
    e = math.exp(z)
    return e / (1.0 + e)


def saturation_case(z: float = 8.0, target: float = 0.5) -> Dict[str, float]:
    p = sigmoid(z)
    loss = 0.5 * (p - target) ** 2
    local_gradient = (p - target) * p * (1.0 - p)
    reset_p = sigmoid(0.0)
    reset_loss = 0.5 * (reset_p - target) ** 2
    return {
        "probability": p,
        "loss": loss,
        "local_gradient": local_gradient,
        "loss_change_if_reset_to_zero": reset_loss - loss,
    }


def relu_pair(w: float, v: float, x: float, target: float) -> Dict[str, float]:
    pre = w * x
    h = max(0.0, pre)
    y = v * h
    loss = 0.5 * (y - target) ** 2
    active = 1.0 if pre > 0.0 else 0.0
    return {
        "y": y,
        "loss": loss,
        "dw": (y - target) * v * active * x,
        "dv": (y - target) * h,
    }


def reparameterisation_case(c: float = 10.0) -> Dict[str, Dict[str, float]]:
    """Positive rescaling preserves y = v ReLU(w x) but changes raw gradients."""
    original = relu_pair(w=2.0, v=3.0, x=1.0, target=5.0)
    rescaled = relu_pair(w=2.0 * c, v=3.0 / c, x=1.0, target=5.0)
    return {"original": original, "rescaled": rescaled}


def depth_case(gain: float, depth: int) -> float:
    """Sensitivity through a scalar chain h_t = gain * h_(t-1)."""
    if depth < 0:
        raise ValueError("depth must be non-negative")
    return gain**depth


def run_audit() -> None:
    p = Params()
    x, target = 1.7, 0.4
    analytic = manual_gradient(p, x, target)

    print("Manual gradient versus central finite difference")
    for name, value in analytic.items():
        numeric = central_difference(p, x, target, name)
        scale = max(1.0, abs(value), abs(numeric))
        rel_error = abs(value - numeric) / scale
        print(f"  {name}: manual={value:+.8f}  finite={numeric:+.8f}  error={rel_error:.2e}")

    print("\nBounded intervention on w1")
    for delta in (-0.50, -0.05, -0.005):
        actual, predicted = bounded_effect(p, x, target, "w1", delta)
        print(f"  delta={delta:+.3f}  actual={actual:+.8f}  linear prediction={predicted:+.8f}")

    print("\nSaturation case")
    for key, value in saturation_case().items():
        print(f"  {key}: {value:+.8f}")

    print("\nFunction-preserving ReLU rescaling")
    twins = reparameterisation_case()
    for name, values in twins.items():
        print(f"  {name}: y={values['y']:.2f}, dw={values['dw']:.2f}, dv={values['dv']:.2f}")

    print("\nDepth sensitivity")
    for gain in (0.9, 1.0, 1.1):
        print(f"  gain={gain:.1f}, depth=60, product={depth_case(gain, 60):.6g}")


if __name__ == "__main__":
    run_audit()

How to run it

  1. Save the embedded program as paper17_credit_assignment_lab.py.
  2. Run it with:
    python paper17_credit_assignment_lab.py
  3. No package installation is required. The first output block should report tiny relative errors between the manual derivatives and central finite differences.

A positive gradient check permits confidence that the local derivative was implemented correctly at the tested point. Agreement between predicted and actual loss change for small steps permits using the gradient as a local proposal. Divergence at larger steps reveals curvature, saturation or path interactions. The rescaling output demonstrates why raw gradient magnitude is not stable credit.

What the lab cannot establish

It does not prove convergence to a global optimum, validate a real dataset, identify the true cause of an observed failure, or authorise a consequential action. It tests mathematical consistency and decision stability inside a synthetic model.

Optional depth: why central differences are a check, not a replacement

A central difference estimates ∂L/∂θ using [L(θ + ε) − L(θ − ε)] / 2ε. Large ε introduces truncation error because curvature matters. Tiny ε subtracts nearly equal floating-point numbers and amplifies rounding error. Directional checks scale better than checking every coordinate, but they still provide approximate evidence at selected points. Reverse-mode differentiation uses the program’s local derivative rules and is exact up to floating-point arithmetic for the executed smooth branch.

Optional depth: second-order information changes the question again

The gradient gives the first-order slope. The Hessian describes how that slope changes with direction. A Hessian-vector product can reveal curvature without materialising the full Hessian, following the method developed by Pearlmutter (1994). Curvature can improve step selection, but it remains conditional on the same loss, graph and coordinates. More derivatives do not automatically produce broader causal meaning.

The evidence conversation
Chart · sequence
sequenceDiagram
  participant Q as Question
  participant M as Mechanism
  participant E as Evidence
  participant D as Decision
  Q->>M: The error that does not travel backwards
  M->>E: An autodiff-free credit-assignment audit
  E-->>M: compare rival explanations
  E->>D: Use gradients to propose and interventions to authorise
  D-->>Q: revise scope or act
Question, mechanism, evidence and decision exchange the burdens developed in Calculus, chain rules and credit assignment. Reading use: follow the relation, then return to the surrounding argument for evidence and limits.

Use gradients to propose and interventions to authorise

When a model fails, do not ask which parameter or module is “to blame” and then sort by gradient magnitude. Ask what derivative was actually computed. Name the scalar loss, the data aggregation, the executed path, the coordinate system and the intervention scale.

Then separate the decisions. If you are debugging derivative code, a central finite-difference check may be enough. If you are choosing a small optimiser step, a verified local gradient may be enough. If you are deciding which module to redesign, freeze, replace or govern, demand finite intervention evidence, path tests and representation stability.

The chain rule remains one of the most powerful compression devices in machine intelligence. It converts one remote objective into local update information across a composite system. Its limitation is the mirror image of that power: it can only speak through the graph, loss and coordinates it has been given.

This creates a simple release discipline. Store gradients as decision receipts with the objective version, sample identifiers, aggregation rule, model state, graph boundaries and proposed step. For any change that is difficult to reverse, add the finite intervention result and at least one structural challenge. The receipt should state what passed, what failed and which inference remains prohibited. A naked heat map or component ranking is not a receipt.

The same discipline improves scientific claims. Saying that a parameter “matters” should specify whether it has a non-zero derivative, changes behaviour when intervened on, carries a unique path or retains its ranking across equivalent implementations. Those are different observations. Their separation makes negative results interpretable rather than embarrassing.

Use gradients to propose a change. Use bounded interventions and structural checks to authorise the change. When those disagree, the right response is not to average the numbers. It is to identify which assumption in the credit path failed.

That decision discipline changes architecture as well as diagnosis. Preserve useful gradient routes with appropriate scaling and skip paths. Expose detachments and nondifferentiable boundaries. Report per-path or per-example cancellation where averages hide it. Compare changes in function space when parameter coordinates are arbitrary. Above all, keep optimisation credit distinct from causal responsibility.

Glossary

Adjoint or cotangent
The backward sensitivity of a scalar loss to an intermediate value, often written as a barred variable.
Automatic differentiation
Programmatic evaluation of derivatives by composing local derivative rules over executed operations.
Backpropagation
Reverse-mode differentiation applied to a learning objective and used to update model parameters.
Credit assignment
The problem of connecting a distant outcome to the internal states, actions or parameters that should change.
Jacobian
The local linear map from small input changes to small output changes for a vector-valued function.
Pullback or VJP
A vector-Jacobian product that maps output sensitivity backwards to input sensitivity.
Saturation
A region where an activation changes very little despite changes in its input, producing a small local derivative.
Stop-gradient
An operation that preserves a value in the forward pass while blocking its backward derivative path.

References

  1. Rumelhart, D. E., Hinton, G. E. and Williams, R. J. (1986). Learning representations by back-propagating errors. Nature 323, 533–536. Publisher page.
  2. Baydin, A. G., Pearlmutter, B. A., Radul, A. A. and Siskind, J. M. (2018). Automatic differentiation in machine learning: a survey. Journal of Machine Learning Research 18(153), 1–43. JMLR.
  3. Baur, W. and Strassen, V. (1983). The complexity of partial derivatives. Theoretical Computer Science 22, 317–330. DOI.
  4. JAX authors. The Autodiff Cookbook. Official JAX documentation. Documentation.
  5. Pascanu, R., Mikolov, T. and Bengio, Y. (2013). On the difficulty of training recurrent neural networks. Proceedings of the 30th International Conference on Machine Learning. PMLR.
  6. He, K., Zhang, X., Ren, S. and Sun, J. (2016). Deep residual learning for image recognition. CVPR. CVF Open Access.
  7. Balduzzi, D., Frean, M., Leary, L., Lewis, J. P., Ma, K. W. D. and McWilliams, B. (2017). The shattered gradients problem: if ResNets are the answer, then what is the question? ICML. PMLR.
  8. Neyshabur, B., Salakhutdinov, R. and Srebro, N. (2015). Path-SGD: path-normalized optimization in deep neural networks. NeurIPS. NeurIPS proceedings.
  9. Lillicrap, T. P., Cownden, D., Tweed, D. B. and Akerman, C. J. (2016). Random synaptic feedback weights support error backpropagation for deep learning. Nature Communications 7, 13276. Publisher page.
  10. Nøkland, A. (2016). Direct feedback alignment provides learning in deep neural networks. NeurIPS. NeurIPS proceedings.
  11. Sundararajan, M., Taly, A. and Yan, Q. (2017). Axiomatic attribution for deep networks. ICML. PMLR.
  12. Adebayo, J., Gilmer, J., Muelly, M., Goodfellow, I., Hardt, M. and Kim, B. (2018). Sanity checks for saliency maps. NeurIPS. NeurIPS proceedings.
  13. Pearlmutter, B. A. (1994). Fast exact multiplication by the Hessian. Neural Computation 6(1), 147–160. MIT Press.