Skip to content

Neural Models Do Not Respect Accounting Identities

A model can fit every component of an allocation and still fail the only test that matters — whether the parts sum to the whole. Four places to enforce that, and what each one costs.

16 min read3,177 words

An allocation model splits a shared cost pool across five business units. By every measure anyone asked for, it is a good model. Each unit's allocation lands within a tenth of a per cent of the held-out target. The residuals are unbiased. The error distribution is boring in the way you want error distributions to be.

Then it goes to a reviewer, who adds up the five numbers. The pool was 4,812,600.00. The allocations come to 4,812,617.31.

Seventeen point three one, against four point eight million. As a share of the pool that is 0.00036 per cent, well inside every tolerance in the model's own evaluation report. As an accounting statement it is not a small error, because the sum of the parts here is not approximately the whole — it is definitionally the whole. There is no line on the statement called difference. The reviewer's first question is not how large the error is. It is which of the five numbers is wrong, and the model has no answer to that, because from the model's point of view nothing went wrong.

Run it again on next month's pool and it misses by a different amount in a different direction. This is not a bug in the sense of something that can be found and removed. It is the absence of a property the model was never built to have.

Synthetic dataFigures below are generated, not observed. No employer data appears on this site.

The pool, the five units and the table further down are constructed. The arithmetic on them is exact; the model behind them does not exist.

Why the penalty term does not fix it

The obvious response is to tell the model about the constraint. Write the identity in matrix form: for an output vector xRnx \in \mathbb{R}^{n} and a set of mm linear identities, the requirement is Ax=bAx = b with ARm×nA \in \mathbb{R}^{m \times n} and m<nm < n. Then add a term to the loss:

L(x)  =  (x)  +  λAxb22\mathcal{L}(x) \;=\; \ell(x) \;+\; \lambda \lVert Ax - b \rVert_2^2

This works, in the sense that the measured violation falls as λ\lambda rises. It never reaches zero, and the reason is structural rather than a matter of tuning. At a stationary point of the penalised objective, (x)+2λA(Axb)=0\nabla \ell(x) + 2\lambda A^{\top}(Ax - b) = 0. Left-multiply by AA, assume AA has full row rank, and solve for the residual:

Axb  =  12λ(AA)1A(x)Ax - b \;=\; -\frac{1}{2\lambda}\,(AA^{\top})^{-1} A \, \nabla \ell(x)

The violation shrinks as 1/λ1/\lambda and vanishes only when A(x)=0A\nabla \ell(x) = 0 — that is, only when the unconstrained fit already satisfies the identity, which is exactly the case where the penalty was unnecessary. For any finite λ\lambda and any objective that is still pulling somewhere, there is a residual, and it is the model's own gradient that puts it there.

Two practical problems sit underneath the algebra. Raising λ\lambda starves the accuracy term, so the components get worse in order to make the total slightly better. And whatever residual you measure is an average over the evaluation set; nothing in the construction bounds the violation on the next input. A penalty is a statement about the expected behaviour of a fitted function. It is not a property of the function.

That distinction is the whole problem, because the acceptance test on the other side is binary. A control tester does not grade a balance on a curve, and the evidence that satisfies one is not the evidence a model card provides. "It usually balances" is not a mitigating detail. It is the finding.

The reframe

How small the violation can be made is the wrong question. Where it can be made impossible is the right one, and that question has only four candidate answers: the training objective, the raw output vector, whatever happens downstream before a number reaches the ledger, and the forward pass itself. Each site yields a different kind of guarantee — statistical, algebraic, procedural, structural — and the kinds are not interchangeable.

A constraint in the loss function is a preference. A constraint in the parameterisation is a fact.

Nothing in that sentence is original as mathematics. What goes under-appreciated in applied work is how often the choice between the four sites is made implicitly, by whoever wrote the training loop. It surfaces six months later, when a statement fails to tie and nobody in the room can say which of the four was meant to be holding the line.

Four places to put a constraint

The identity, written properly

Almost every hard identity in a financial system is affine. Components summing to a total, debits equalling credits, opening balance plus movements equalling closing balance, a cross-foot across a grid of subtotals — all of them are rows of Ax=bAx = b. Some are hierarchies rather than a single sum, and the same algebra covers those too; the structure of AA is a graph of correspondences rather than a flat constraint list. What follows applies wherever the identity is affine and known at inference time.

1. The training objective

Discussed above: a penalty buys a small violation and no guarantee. The honest upgrade is an augmented Lagrangian, which adds an explicit multiplier estimate alongside the quadratic term and drives the residual to zero without sending λ\lambda to infinity — the method of Hestenes and Powell, and the standard answer to this exact deficiency in the optimisation literature. It helps. It also only helps at convergence, on the training distribution, for a stationary point you have no way of certifying you reached. What the objective can enforce is a tendency.

2. Inference-time projection

Take the raw output and project it onto the affine set {x:Ax=b}\{x : Ax = b\}. The Euclidean projection has a closed form:

x  =  xA(AA)1(Axb)x' \;=\; x - A^{\top}(AA^{\top})^{-1}(Ax - b)

Check it: Ax=AxAA(AA)1(Axb)=bAx' = Ax - AA^{\top}(AA^{\top})^{-1}(Ax - b) = b. Exactly, for every input, whatever the model did. AA is fixed, so you factor AAAA^{\top} once and each inference costs a matrix-vector product.

The cost is not compute. It is that the correction lands on every component. For a single sum constraint, A=1A = \mathbf{1}^{\top}, and the formula collapses to subtracting 1n(1xb)\frac{1}{n}(\mathbf{1}^{\top}x - b) from each line. If one component carried all the error and the other four were exactly right, the projection makes four correct numbers wrong to make one wrong number less wrong. Total absolute error, in that case, is multiplied by 2(n1)/n2(n-1)/n, which exceeds one for every n>2n > 2. Error goes up. The statement starts balancing.

There is a fix, and it is not mine. The weighted projection

x  =  xWA(AWA)1(Axb)x' \;=\; x - W A^{\top}(A W A^{\top})^{-1}(Ax - b)

minimises (xx)W1(xx)(x'-x)^{\top}W^{-1}(x'-x) subject to Ax=bAx' = b, so choosing WW as the component-wise error covariance sends the correction to the components you trust least. This is precisely the hierarchical forecast reconciliation problem, and the covariance-weighted solution is the MinT estimator of Wickramasuriya, Athanasopoulos and Hyndman. The catch travels with it: you now need an error covariance, estimated from data, and a badly estimated WW redistributes the correction confidently in the wrong direction.

3. Post-processing repair

Let the model produce whatever it produces, compute the residual, and put it somewhere: a designated line, the largest line, a rounding-differences account. This is exact, trivially cheap, deterministic, and by far the most common approach in practice — usually undocumented, often in a spreadsheet downstream of everything anyone reviewed.

What it costs is auditability, in a specific and literal sense. The number in the repaired line was not produced by the model. It is a plug: the amount required to make the other numbers tie. If a reviewer asks for the provenance of that figure, the honest answer is that it is a residual, and a residual is not an allocation. Repair converts a model error into an accounting entry, which is either the most defensible option or the least, depending entirely on whether the plug is labelled as one.

4. Architectural guarantee

Parameterise the output so it cannot violate the identity. For a single total, emit shares through a softmax and multiply by the known total, x=bσ(z)x = b \cdot \sigma(z), and 1x=b\mathbf{1}^{\top}x = b holds by construction. In general, take any particular solution xpx_p with Axp=bAx_p = b and a basis NN for the null space of AA, and emit

x  =  xp+Nu,Ax  =  Axp+ANu  =  b+0  =  bx \;=\; x_p + N u, \qquad Ax \;=\; Ax_p + ANu \;=\; b + 0 \;=\; b

for every uu the network can produce, because AN=0AN = 0 is what makes NN a null space basis. This is the only one of the four where the guarantee is a property of the function class rather than of the training run, the data, or a downstream step. It costs one matrix multiply at inference, and it is differentiable, so the model trains against the constraint rather than around it.

What it costs is expressiveness, and the cost is exactly measurable: the output is confined to an affine subspace of dimension nmn - m. The model cannot represent the hypothesis "line 3 is high and the other four are right", because that hypothesis is off the subspace. Errors become zero-sum by construction — every overstatement is somebody else's understatement. Whether that is a feature depends on whether the identity is true of the world or merely true of the report. The softmax version smuggles in a second constraint as well, since every component comes out positive, which is wrong the moment a legitimate allocation can be a credit.

The arithmetic the guarantee holds in

Projection and architecture are exact over the reals. A ledger is not kept over the reals; it is kept over a lattice of cents. Round a vector that sums exactly to the total, and the rounded vector generally does not. The set of representable outputs is not a subspace, and no continuous parameterisation lands on it by construction.

So the last operation before posting has to be a lattice-aware allocation — the largest-remainder method or a cousin of it — which drags in the apportionment paradoxes Balinski and Young catalogued for legislative seats. Nothing proved above the rounding step promises anything about what lands below it.

The four sites compose

Nothing above says pick one. The sites act at different moments — training, the forward pass, inference, posting — so they stack, and the interesting question is which stack still holds when one step is skipped.

Two of the four are exact only over the reals, and neither survives rounding on its own; both want a lattice-aware allocation underneath them. What separates them is fragility. A projection is a separate piece of code, and a separate piece of code can be disabled for one batch, retried after a failure, or applied after the wrong transform, and the guarantee leaves with it. A parameterisation cannot be switched off without changing the model that was signed off. Repair is the mirror image: exact in the ledger's own arithmetic by construction, and exact about a figure that has stopped being an allocation. The objective composes with all three and guarantees nothing in any combination, which is the argument for treating it as regularisation rather than as a control.

A worked example

A pool of 4,812,600.00 is allocated across five units. The true allocation is known by construction. The raw model reproduces four components exactly and overstates the third by 17.31 — an error deliberately concentrated in one line, so that the distributional side-effects are visible rather than smeared.

1 · OBJECTIVE2 · PROJECTION3 · REPAIR4 · ARCHITECTURETRAIN LOSSOUTPUT LAYERRAW VECTORPOST-PROCESSLEDGER+ λ ||Ax - b||^2x - A^T(AA^T)^-1(Ax - b)plug into one lineb · softmax(z)GUARANTEESPRICERESIDUAL, REALRESIDUAL, CENTSviolation small, never 0no bound at test timeexact in real arithmeticevery line is movedexact in the ledger itselfone line absorbs the restexact by constructionholds for every inputcorrectnessa solve, and distortionauditabilityexpressiveness2.140.0000.000.0002.14+0.010.00-0.01COLOURED FIGURES ARE VIOLATIONS THAT SURVIVE THE INTERVENTION
Fig. 01The four injection points as a pipeline. Rows are stages a prediction passes through; each column intervenes at exactly one of them, and the thin rules mark the stages it leaves untouched. The lower block reports what each intervention guarantees and the residual it leaves on the synthetic allocation below — first in exact arithmetic, then after rounding to cents, which is the only arithmetic the ledger has. The residual under the objective column is stipulated, not trained; the other three are arithmetic on the table that follows.

The penalty column is stipulated rather than trained: assume a penalised model that leaves a residual of 2.14 on this pool. I have not run the training, and the size of that number is illustrative — the only claim being made is that it is not zero and that nothing in the method makes it zero. Every other column is arithmetic, and it is exact.

LineTrueRaw modelProjectedRepairedArchitecture
BU-11,204,300.001,204,300.001,204,296.541,204,300.001,204,293.81
BU-2962,540.00962,540.00962,536.54962,540.00962,535.05
BU-31,443,760.001,443,777.311,443,773.851,443,777.311,443,777.31
BU-4721,900.00721,900.00721,896.54721,900.00721,896.29
BU-5480,100.00480,100.00480,096.54480,082.69480,097.53
Sum4,812,600.004,812,617.314,812,600.014,812,600.004,812,599.99

Four things in that table are worth pausing on.

The projection worked and made the answer worse. Before it, one line was wrong by 17.31 and four were exactly right; after it, all five are wrong, and total absolute error has gone from 17.31 to 27.69. The statement now balances, and the number of defensible lines on it has dropped from four to zero. A weighted projection with a well-estimated covariance would have sent most of the correction to BU-3 and left the others alone, which is the entire argument for bothering with WW.

The repaired column has two wrong lines instead of one. BU-3 keeps its 17.31 overstatement and BU-5 absorbs the offset, so the pool ties, one line is overstated, one is understated, and neither figure is a model output any more. The books are correct and the allocation is fiction in two places.

The architecture column shows what zero-sum error looks like. The share head holds the same view of BU-3, so the softmax has no way to express it except by taking the 17.31 out of the other four in proportion to their size. The constraint did not remove the error. It reshaped it into something that balances.

And then the last row. The unrounded projection sums to exactly 4,812,600.000; rounded to cents it sums to 4,812,600.01. The architecture output sums exactly in the reals and to 4,812,599.99 in cents. Only the repaired column ties in the arithmetic the ledger actually uses, because it is the only one that was computed in that arithmetic. A guarantee proved over R\mathbb{R} and applied after a rounding step is not a guarantee.

Limits

Three honest ones.

Most of this is not new. The projection is standard constrained least squares, the weighted version is hierarchical forecast reconciliation and the covariance-weighted solution is MinT. Soft penalties for physical constraints are the core of the physics-informed neural network literature of Raissi, Perdikaris and Karniadakis; differentiable constrained layers belong to Amos and Kolter and the deep declarative networks line, and their logical analogue to the semantic loss and DeepProbLog work. What I claim is the mapping onto ledger arithmetic, not the methods.

The framing only covers affine, known-at-inference constraints. A tolerance that applies to one class of item and not another is conditional, not affine. An inequality is a cone, not a subspace. A total that is itself predicted rather than given breaks the architectural option, which needs bb to construct the output. Real close processes have all three.

And I have not measured the accuracy cost of the architectural option. The hypothesis is that confining the output to an (nm)(n-m)-dimensional subspace costs less held-out accuracy than the penalty costs in violations you cannot ship, and that the trade improves as m/nm/n falls. It is a hypothesis with a clean experimental design and no experiment behind it.

Where this goes

Constraints that are not affine come next in this pillar — conditional rules, tolerances, inequalities — where the four-site map still applies but only one site survives it. After that, the harder question: what a control tester should be shown before accepting a structural guarantee, which is a problem in evidence rather than modelling. The rest of the pillar is laid out on the research page.

Before accepting that a model respects an identity, find out which of the four sites is holding it and in which arithmetic that proof was written. If the answer is the loss function, there is no proof — only a preference that has so far behaved itself.