ℝ→Float32 bridge: the composition backbone (whole-net certificate) #
A whole-net float certificate is a fold of the per-op budgets. FloatClose
packages exactly what's needed to fold: on inputs within magnitude A, the float
fF is within an error modulus L e of the real f (per coordinate, at input
error e), and both real and float outputs are within B (so the next layer's
magnitude precondition is met). FloatClose.comp proves this composes — the
moduli compose as Lg ∘ Lf, magnitudes thread A → B → C — so a whole net is
FloatClose with the composed modulus, no per-net re-proof.
Instances proved here: relu (exact in float, modulus id) and flatConv
(modulus = the conv-fan-in layerBudget). The remaining r34 ops are already
*_close lemmas and slot in the same way: BN→relu via bnRelu_close (use the
operating-point bnIstd_close_at for the eistd, else the budget is vacuous),
maxpool via maxPoolFlat_close, the skip via reluAdd_close. The whole-net
certificate is then .comp folded over the layer list.
A-posteriori-magnitude, proved-error float closeness, built to compose.
A bounds the inputs (both real va and float vt), B both outputs;
L is the input-error → output-error modulus.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Float-closeness composes — the whole-net certificate backbone. Magnitudes
thread A → B → C, error moduli compose Lg ∘ Lf.
ReLU is FloatClose with modulus id — exact in float (real = float map),
1-Lipschitz on the inherited error, never grows magnitudes.
Convolution is FloatClose with modulus the conv-fan-in layerBudget.
Real output ≤ layerAct; float output ≤ layerAct + layerBudget(e=0) (the
extra rounding) — that sum is the propagated magnitude B.
Dense layer is FloatClose with modulus the fan-in layerBudget (the dense
analogue of floatClose_flatConv). Real output ≤ layerAct; float output ≤ that
- the fresh-input rounding
layerBudget(e=0). The SE excite/reduce denses and the classifier head are this instance; the ViT MLP denses reuse it too.
Demo: a conv→relu unit is FloatClose — (conv).comp (relu) folds the
conv layerBudget modulus and ReLU's id. A 2-conv chain
relu∘conv∘relu∘conv is two more .comps; the whole r34 net is this fold
over its layer list (with the BN/maxpool/skip instances slotted in).
MaxPool is FloatClose with modulus id — exact in float, 1-Lipschitz,
never grows magnitudes (maxPoolFlat_close / maxPoolFlat_abs_le).
⭐ He et al.'s 3×3/s2 stem pool is FloatClose — the peer of floatClose_maxPool, and
identical in shape: a max is EXACT (it selects an existing cell, so the modulus is id and the
magnitude is unchanged) whatever the window size. The overlap that makes the backward
accumulate is invisible here, because the forward at one output still reads one cell.
planning/archive/rsb_a3_r50_verified.md §4b.
Global-average-pool is FloatClose — Vec (c·h·w) → Vec c, the SE squeeze.
GAP is a per-channel bnMean (globalAvgPoolFlat_eq_bnMean), so the real output
never exceeds the input magnitude A (bnMean_abs_le) and is 1-Lipschitz in the
input (bnMean_input_close, the spatial mean averages the per-coordinate error
back to e); the float roundoff is gapFlat_close's budget gb. Output magnitude
A + gb, modulus e ↦ gb + e.
THE FOLD: a whole CIFAR stage is FloatClose. conv→relu→conv→relu→maxpool
folded through .comp into a single certificate — there exist a propagated
magnitude B and an error modulus L (the composition of the two conv
layerBudgets through the three id moduli) with the whole float stage within
L e of the real stage at input error e. No bespoke proof: the five per-op
FloatClose facts chained. The whole r34 net is this same fold at scale (with
the BN/skip instances slotted in). ⚠ The ∃ B L closes the modulus, so on its own
this statement says only that both maps are bounded on the box.
Residual block relu(F(x) + x) is FloatClose — the branching combinator
(the skip reuses the input, so it's not a plain .comp). Given the body F
FloatClose A B, the block's float (rounded skip-add) is within
reluAdd_close's budget of the real relu(F(x)+x); output magnitude
(1+u)(B+A). The defining ResNet op.
Additive residual F(x) + x (no trailing activation) is FloatClose — the
MBConv / transformer skip, the no-ReLU cousin of floatClose_residualBlock. The
rounded skip-add fl(FF(x) ⊕ x) is within add_close's budget of the real
F(x) + x; output magnitude (1+u)(B+A).
THE RESIDUAL FOLD: a (no-BN) ResNet basic block is FloatClose. Body
conv₂ → relu → conv₁ folded via .comp, then wrapped by the residual
combinator into relu(F(x) + x) — one certificate for the whole block,
skip included. The r34 identity block is this with BN inserted (the BN→relu
FloatClose instance is the remaining wrap). ⚠ Same caveat as floatClose_cifarStage.
BN→relu is FloatClose (per-example, training-mode). The float BN computes
its stats from the input via the supplied fμ/fistdv (within emean/eistd
of the true stats on the magnitude domain — discharged by bnMean_close /
bnVar_close + bnIstd_close_at when instantiated). Error from bnRelu_close
(rounding + input-shift); float-output magnitude from bnForward_close_of.
With this + floatClose_flatConv + the residual combinator, the r34 identity
block folds entirely through .comp.
BN alone (no activation) is FloatClose — floatClose_bnRelu with the
trailing ReLU dropped, error from bnStep_close (rounding bnForward_close_of
- input-shift
bnForward_input_close), samebnReluBudgetmodulus (ReLU only shrinks, so removing it leaves the budget unchanged). The BN-before-swish steps in EfficientNet's MBConv (and BN-before-GELU positions generally) are this instance.
The identity map is FloatClose (modulus id).
THE FINAL FOLD: a magnitude-stable block iterated n times is FloatClose.
A dim-preserving block that is FloatClose A A f fF L (its activations stay
within the a-posteriori bound A — BN keeps them O(1), as the probe confirms)
composes with itself to any depth: f^[n] is FloatClose A A with modulus
L^[n]. This is r34's within-stage depth (n = 3,4,6,3); the whole net is
these iterates .comp-joined with the stem / downsamples / GAP / dense. The
depth-generic whole-net certificate — no per-depth re-proof.
r34's four stages, folded. Given an identity block that is magnitude-stable
FloatClose A A (the a-posteriori-bounded regime), the [3,4,6,3] block stack
of each stage is FloatClose A A — the four floatClose_iterate instances at
r34's depths. The full r34_float_close is these .comp the stem / strided
downsamples / GAP / dense (each its own FloatClose instance).
Additive residual residual f = f(x) + x is FloatClose — the MBConv /
transformer skip in the Residual.lean API (residual = biPath f id, defeq to
floatClose_addResidual's fun v j => F v j + v j).