Documentation

LeanMlir.Proofs.Float.MlpFloatBridge

The MNIST MLP and E4M3 linear-net float chains #

FloatBridge's per-op bounds, assembled for two nets: the MNIST MLP (784→512→512→10), as the forward (mlp_float_close, mlp_float_close_uniform), its binary32 numeric instance (mnist_mlp_float_budget), the six float SGD steps (mlp_{w,b}{0,1,2}_step_float_close) with the W₂ instance (mnist_w2_step_float_budget) and the loss-head instance (mnist_cot_budget); and the depth-1 fp8 linear net (linear_e4m3_logit_budget, linear_e4m3_argmax_preserved). Each theorem is stated over any FloatModel; Binary32Instance instantiates the E4M3 one. The ResNet-34 peer is ResNet34FloatBridge.

noncomputable def Proofs.FloatModel.mlpF (M : FloatModel) {d₀ d₁ d₂ d₃ : ℕ} (W₀ : Mat d₀ d₁) (b₀ : Vec d₁) (W₁ : Mat d₁ d₂) (b₁ : Vec d₂) (W₂ : Mat d₂ d₃) (b₂ : Vec d₃) (x : Vec d₀) :
Vec d₃

Rounded MLP forward — the float peer of the dense W₂ b₂ ∘ relu ∘ dense W₁ b₁ ∘ relu ∘ dense W₀ b₀ composition (MlpTrainStep.lean). relu appears bare: max-with-0 is exact in floating point.

Equations
Instances For
    theorem Proofs.FloatModel.mlp_float_close (M : FloatModel) {d₀ d₁ d₂ d₃ : ℕ} (W₀ : Mat d₀ d₁) (b₀ : Vec d₁) (W₁ : Mat d₁ d₂) (b₁ : Vec d₂) (W₂ : Mat d₂ d₃) (b₂ : Vec d₃) (x : Vec d₀) (e₀ e₁ : ℝ) (he₀ : 0 ≤ e₀) (he₁ : 0 ≤ e₁) (h₀ : ∀ (j : Fin d₁), M.denseErr W₀ b₀ x 0 j ≤ e₀) (h₁ : ∀ (j : Fin d₂), M.denseErr W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x)) e₀ j ≤ e₁) (k : Fin d₃) :
    |M.mlpF W₀ b₀ W₁ b₁ W₂ b₂ x k - Proofs.dense W₂ b₂ (relu d₂ (Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x)))) k| ≤ M.denseErr W₂ b₂ (relu d₂ (Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x)))) e₁ k

    MLP forward extraction (Chapter 2). The rounded 3-layer MLP is within the layer-2 denseErr budget (at inherited error e₁) of the real MLP — the same dense/relu composition whose train step is certified in MlpTrainStep.lean. The hypotheses h₀/h₁ uniformize the per-coordinate layer-0/1 budgets into e₀/e₁; at any concrete net they are discharged by finite max over the d₁ (resp. d₂) coordinates.

    theorem Proofs.FloatModel.mlp_float_close_uniform (M : FloatModel) {d₀ d₁ d₂ d₃ : ℕ} {W₀ : Mat d₀ d₁} {b₀ : Vec d₁} {W₁ : Mat d₁ d₂} {b₁ : Vec d₂} {W₂ : Mat d₂ d₃} {b₂ : Vec d₃} {x : Vec d₀} {w₀ β₀ w₁ β₁ w₂ β₂ a : ℝ} (hw₀ : 0 ≤ w₀) (hβ₀ : 0 ≤ β₀) (hw₁ : 0 ≤ w₁) (hβ₁ : 0 ≤ β₁) (hw₂ : 0 ≤ w₂) (ha : 0 ≤ a) (hW₀ : ∀ (i : Fin d₀) (j : Fin d₁), |W₀ i j| ≤ w₀) (hb₀ : ∀ (j : Fin d₁), |b₀ j| ≤ β₀) (hW₁ : ∀ (i : Fin d₁) (j : Fin d₂), |W₁ i j| ≤ w₁) (hb₁ : ∀ (j : Fin d₂), |b₁ j| ≤ β₁) (hW₂ : ∀ (i : Fin d₂) (j : Fin d₃), |W₂ i j| ≤ w₂) (hb₂ : ∀ (j : Fin d₃), |b₂ j| ≤ β₂) (hx : ∀ (i : Fin d₀), |x i| ≤ a) (k : Fin d₃) :
    |M.mlpF W₀ b₀ W₁ b₁ W₂ b₂ x k - Proofs.dense W₂ b₂ (relu d₂ (Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x)))) k| ≤ layerBudget M.u d₂ w₂ β₂ (layerAct d₁ w₁ β₁ (layerAct d₀ w₀ β₀ a)) (layerBudget M.u d₁ w₁ β₁ (layerAct d₀ w₀ β₀ a) (layerBudget M.u d₀ w₀ β₀ a 0))

    MLP forward extraction, uniform-magnitude budgets. mlp_float_close with the e₀/e₁ uniformization discharged once and for all from coordinatewise magnitude bounds |Wᵢ| ≤ wᵢ, |bᵢ| ≤ βᵢ, |x| ≤ a. The budget is a closed form in the dims and magnitudes — evaluable by norm_num at a concrete net.

    theorem Proofs.FloatModel.mnist_mlp_float_budget (M : FloatModel) (hMu : M.u ≤ u32) (W₀ : Mat 784 512) (b₀ : Vec 512) (W₁ : Mat 512 512) (b₁ : Vec 512) (W₂ : Mat 512 10) (b₂ : Vec 10) (x : Vec 784) (hW₀ : ∀ (i : Fin 784) (j : Fin 512), |W₀ i j| ≤ 3 / 5) (hb₀ : ∀ (j : Fin 512), |b₀ j| ≤ 1) (hW₁ : ∀ (i j : Fin 512), |W₁ i j| ≤ 3 / 5) (hb₁ : ∀ (j : Fin 512), |b₁ j| ≤ 1) (hW₂ : ∀ (i : Fin 512) (j : Fin 10), |W₂ i j| ≤ 3 / 5) (hb₂ : ∀ (j : Fin 10), |b₂ j| ≤ 1) (hx : ∀ (i : Fin 784), |x i| ≤ 1) (k : Fin 10) :
    |M.mlpF W₀ b₀ W₁ b₁ W₂ b₂ x k - Proofs.dense W₂ b₂ (relu 512 (Proofs.dense W₁ b₁ (relu 512 (Proofs.dense W₀ b₀ x)))) k| ≤ 5100

    Numeric capstone at the committed MNIST-MLP dims and TRAINED magnitudes (the MainMnistMlpVerified.lean net: 784→512→512→10; |W| ≤ 3/5 covers the measured max|W| = 0.52 of a real 12-epoch 97.8% run — He init already exceeds the prettier 1/32 in its tails). For any rounding model at binary32 accuracy (u ≤ 2⁻²⁴), every rounded logit is within 5100 of the exact-real logit — the worst-case logit magnitude at these bounds is ≈4.5·10⁷, so ≈10⁻⁴ relative, the same relative scale as at small weights. All three layer budgets discharge by norm_num through the γ-form; no big-power evaluation.

    Measured on the live run (scripts/certs/margin_probe.py): actual logit drift ≤ 1.6·10⁻⁵ — the ≈3·10⁸ gap between the worst-case bound and reality is the worst-case-composition blow-up (307·e Lipschitz amplification per layer at these magnitudes), the quantitative case for a-posteriori certificates past toy depth.

    theorem Proofs.FloatModel.mlp_l1_close (M : FloatModel) {d₀ d₁ d₂ : ℕ} {W₀ : Mat d₀ d₁} {b₀ : Vec d₁} {W₁ : Mat d₁ d₂} {b₁ : Vec d₂} {x : Vec d₀} {w₀ β₀ w₁ β₁ a : ℝ} (hw₀ : 0 ≤ w₀) (hβ₀ : 0 ≤ β₀) (hw₁ : 0 ≤ w₁) (ha : 0 ≤ a) (hW₀ : ∀ (i : Fin d₀) (j : Fin d₁), |W₀ i j| ≤ w₀) (hb₀ : ∀ (j : Fin d₁), |b₀ j| ≤ β₀) (hW₁ : ∀ (i : Fin d₁) (j : Fin d₂), |W₁ i j| ≤ w₁) (hb₁ : ∀ (j : Fin d₂), |b₁ j| ≤ β₁) (hx : ∀ (i : Fin d₀), |x i| ≤ a) :
    (∀ (j : Fin d₁), |M.dense W₀ b₀ x j - Proofs.dense W₀ b₀ x j| ≤ layerBudget M.u d₀ w₀ β₀ a 0) ∧ (∀ (j : Fin d₁), |relu d₁ (M.dense W₀ b₀ x) j - relu d₁ (Proofs.dense W₀ b₀ x) j| ≤ layerBudget M.u d₀ w₀ β₀ a 0) ∧ (∀ (i : Fin d₁), |relu d₁ (Proofs.dense W₀ b₀ x) i| ≤ layerAct d₀ w₀ β₀ a) ∧ ∀ (j : Fin d₂), |M.dense W₁ b₁ (relu d₁ (M.dense W₀ b₀ x)) j - Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x)) j| ≤ layerBudget M.u d₁ w₁ β₁ (layerAct d₀ w₀ β₀ a) (layerBudget M.u d₀ w₀ β₀ a 0)

    The MLP's first two rounded layers from a fresh input: layer 0's pre-activation (and its ReLU) within E₀ = layerBudget … a 0, the real layer-0 activation within A₁ = layerAct d₀ w₀ β₀ a, and layer 1's pre-activation within layerBudget … A₁ E₀ — the forward prefix every step capstone below starts from.

    theorem Proofs.FloatModel.mlp_w2_step_float_close (M : FloatModel) {d₀ d₁ d₂ d₃ : ℕ} {W₀ : Mat d₀ d₁} {b₀ : Vec d₁} {W₁ : Mat d₁ d₂} {b₁ : Vec d₂} (W₂ : Mat d₂ d₃) {x : Vec d₀} {gt g : Vec d₃} {lr w₀ β₀ w₁ β₁ a G eg : ℝ} (hw₀ : 0 ≤ w₀) (hβ₀ : 0 ≤ β₀) (hw₁ : 0 ≤ w₁) (hβ₁ : 0 ≤ β₁) (ha : 0 ≤ a) (hlr : 0 ≤ lr) (hW₀ : ∀ (i : Fin d₀) (j : Fin d₁), |W₀ i j| ≤ w₀) (hb₀ : ∀ (j : Fin d₁), |b₀ j| ≤ β₀) (hW₁ : ∀ (i : Fin d₁) (j : Fin d₂), |W₁ i j| ≤ w₁) (hb₁ : ∀ (j : Fin d₂), |b₁ j| ≤ β₁) (hx : ∀ (i : Fin d₀), |x i| ≤ a) (hG : ∀ (j : Fin d₃), |g j| ≤ G) (hg : ∀ (j : Fin d₃), |gt j - g j| ≤ eg) (i : Fin d₂) (j : Fin d₃) :
    |M.sub (W₂ i j) (M.mul lr (M.mul (relu d₂ (M.dense W₁ b₁ (relu d₁ (M.dense W₀ b₀ x))) i) (gt j))) - (W₂ i j - lr * (relu d₂ (Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x))) i * g j))| ≤ sgdErr M.u lr |W₂ i j| (layerAct d₁ w₁ β₁ (layerAct d₀ w₀ β₀ a) * G) (mulErr M.u (layerAct d₁ w₁ β₁ (layerAct d₀ w₀ β₀ a)) G (layerBudget M.u d₁ w₁ β₁ (layerAct d₀ w₀ β₀ a) (layerBudget M.u d₀ w₀ β₀ a 0)) eg)

    Rounded output-layer weight update (W₂). The float update fl(W₂ᵢⱼ − fl(lr·fl(ã₂ᵢ·gtⱼ))) — outer-product gradient from the stored float forward activation, as the rendered trainer computes it — is within an explicit budget of the real step W₂ᵢⱼ − lr·(a₂ᵢ·gⱼ). The real target is Mat.outer a₂ g i j = emitWeightGrad's entry, the quantity mlp_layer2_weight_grad_bridge proves equal to the pdiv-Jacobian contraction — so this chains the float step to the certified gradient. Takes the output cotangent gt ≈ g as a hypothesis; softmax_ce_cot_close discharges it with eg := cotErr u eexp δ n.

    theorem Proofs.FloatModel.mlp_b2_step_float_close (M : FloatModel) {d₃ : ℕ} (b₂ : Vec d₃) {gt g : Vec d₃} {lr G eg : ℝ} (hlr : 0 ≤ lr) (hG : ∀ (j : Fin d₃), |g j| ≤ G) (hg : ∀ (j : Fin d₃), |gt j - g j| ≤ eg) (j : Fin d₃) :
    |M.sub (b₂ j) (M.mul lr (gt j)) - (b₂ j - lr * g j)| ≤ sgdErr M.u lr |b₂ j| G eg

    Rounded output-layer bias update (b₂) — the bias gradient is the cotangent (emitBiasGrad), so this is sgd_step_close directly.

    theorem Proofs.FloatModel.mlp_w1_step_float_close (M : FloatModel) {d₀ d₁ d₂ d₃ : ℕ} {W₀ : Mat d₀ d₁} {b₀ : Vec d₁} (W₁ : Mat d₁ d₂) {b₁ : Vec d₂} {W₂ : Mat d₂ d₃} {x : Vec d₀} {gt g : Vec d₃} {lr w₀ β₀ w₁ β₁ w₂ a G eg : ℝ} (hw₀ : 0 ≤ w₀) (hβ₀ : 0 ≤ β₀) (hw₁ : 0 ≤ w₁) (hw₂ : 0 ≤ w₂) (ha : 0 ≤ a) (hlr : 0 ≤ lr) (hG0 : 0 ≤ G) (heg : 0 ≤ eg) (hW₀ : ∀ (i : Fin d₀) (j : Fin d₁), |W₀ i j| ≤ w₀) (hb₀ : ∀ (j : Fin d₁), |b₀ j| ≤ β₀) (hW₁ : ∀ (i : Fin d₁) (j : Fin d₂), |W₁ i j| ≤ w₁) (hb₁ : ∀ (j : Fin d₂), |b₁ j| ≤ β₁) (hW₂ : ∀ (i : Fin d₂) (j : Fin d₃), |W₂ i j| ≤ w₂) (hx : ∀ (i : Fin d₀), |x i| ≤ a) (hG : ∀ (j : Fin d₃), |g j| ≤ G) (hg : ∀ (j : Fin d₃), |gt j - g j| ≤ eg) (hmargin : ∀ (i' : Fin d₂), layerBudget M.u d₁ w₁ β₁ (layerAct d₀ w₀ β₀ a) (layerBudget M.u d₀ w₀ β₀ a 0) < |Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x)) i'|) (i : Fin d₁) (j : Fin d₂) :
    |M.sub (W₁ i j) (M.mul lr (M.mul (relu d₁ (M.dense W₀ b₀ x) i) (reluMask (M.dense W₁ b₁ (relu d₁ (M.dense W₀ b₀ x))) (M.dense (fun (j' : Fin d₃) (i' : Fin d₂) => W₂ i' j') (fun (x : Fin d₂) => 0) gt) j))) - (W₁ i j - lr * (relu d₁ (Proofs.dense W₀ b₀ x) i * reluMask (Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x))) (Proofs.dense (fun (j' : Fin d₃) (i' : Fin d₂) => W₂ i' j') (fun (x : Fin d₂) => 0) g) j))| ≤ sgdErr M.u lr |W₁ i j| (layerAct d₀ w₀ β₀ a * layerAct d₃ w₂ 0 G) (mulErr M.u (layerAct d₀ w₀ β₀ a) (layerAct d₃ w₂ 0 G) (layerBudget M.u d₀ w₀ β₀ a 0) (layerBudget M.u d₃ w₂ 0 G eg))

    Rounded hidden-layer weight update (W₁), through the backward chain. The float cotangent ct₁ = mask(pt₁, W₂ᵀ·gt) — computed from the rendered pre-activation and the rounded transposed matvec, exactly the structure of the rendered backward — is within layerBudget of the real c₁ = mask(p₁, W₂ᵀ·g) (the mlpCotOut1 closed form), given the quantitative margin E₁ < |p₁ᵢ| at every layer-1 pre-activation: the forward rounding error must not flip a ReLU. Then the update is within sgdErr of the real W₁ᵢⱼ − lr·(a₁ᵢ·c₁ⱼ), the quantity mlp_layer1_weight_grad_bridge certifies. W₀/b₁/b₀ are the same instantiation one mask deeper.

    theorem Proofs.FloatModel.mlp_b1_step_float_close (M : FloatModel) {d₀ d₁ d₂ d₃ : ℕ} {W₀ : Mat d₀ d₁} {b₀ : Vec d₁} {W₁ : Mat d₁ d₂} (b₁ : Vec d₂) {W₂ : Mat d₂ d₃} {x : Vec d₀} {gt g : Vec d₃} {lr w₀ β₀ w₁ β₁ w₂ a G eg : ℝ} (hw₀ : 0 ≤ w₀) (hβ₀ : 0 ≤ β₀) (hw₁ : 0 ≤ w₁) (hw₂ : 0 ≤ w₂) (ha : 0 ≤ a) (hlr : 0 ≤ lr) (hG0 : 0 ≤ G) (heg : 0 ≤ eg) (hW₀ : ∀ (i : Fin d₀) (j : Fin d₁), |W₀ i j| ≤ w₀) (hb₀ : ∀ (j : Fin d₁), |b₀ j| ≤ β₀) (hW₁ : ∀ (i : Fin d₁) (j : Fin d₂), |W₁ i j| ≤ w₁) (hb₁ : ∀ (j : Fin d₂), |b₁ j| ≤ β₁) (hW₂ : ∀ (i : Fin d₂) (j : Fin d₃), |W₂ i j| ≤ w₂) (hx : ∀ (i : Fin d₀), |x i| ≤ a) (hG : ∀ (j : Fin d₃), |g j| ≤ G) (hg : ∀ (j : Fin d₃), |gt j - g j| ≤ eg) (hmargin : ∀ (i' : Fin d₂), layerBudget M.u d₁ w₁ β₁ (layerAct d₀ w₀ β₀ a) (layerBudget M.u d₀ w₀ β₀ a 0) < |Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x)) i'|) (j : Fin d₂) :
    |M.sub (b₁ j) (M.mul lr (reluMask (M.dense W₁ b₁ (relu d₁ (M.dense W₀ b₀ x))) (M.dense (fun (j' : Fin d₃) (i' : Fin d₂) => W₂ i' j') (fun (x : Fin d₂) => 0) gt) j)) - (b₁ j - lr * reluMask (Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x))) (Proofs.dense (fun (j' : Fin d₃) (i' : Fin d₂) => W₂ i' j') (fun (x : Fin d₂) => 0) g) j)| ≤ sgdErr M.u lr |b₁ j| (layerAct d₃ w₂ 0 G) (layerBudget M.u d₃ w₂ 0 G eg)

    Rounded hidden bias update (b₁) — the gradient is the layer-1 cotangent itself (emitBiasGrad), so this is the cotangent chain followed by sgd_step_close.

    theorem Proofs.FloatModel.mlp_w0_step_float_close (M : FloatModel) {d₀ d₁ d₂ d₃ : ℕ} (W₀ : Mat d₀ d₁) {b₀ : Vec d₁} {W₁ : Mat d₁ d₂} {b₁ : Vec d₂} {W₂ : Mat d₂ d₃} {x : Vec d₀} {gt g : Vec d₃} {lr w₀ β₀ w₁ β₁ w₂ a G eg : ℝ} (hw₀ : 0 ≤ w₀) (hβ₀ : 0 ≤ β₀) (hw₁ : 0 ≤ w₁) (hw₂ : 0 ≤ w₂) (ha : 0 ≤ a) (hlr : 0 ≤ lr) (hG0 : 0 ≤ G) (heg : 0 ≤ eg) (hW₀ : ∀ (i : Fin d₀) (j : Fin d₁), |W₀ i j| ≤ w₀) (hb₀ : ∀ (j : Fin d₁), |b₀ j| ≤ β₀) (hW₁ : ∀ (i : Fin d₁) (j : Fin d₂), |W₁ i j| ≤ w₁) (hb₁ : ∀ (j : Fin d₂), |b₁ j| ≤ β₁) (hW₂ : ∀ (i : Fin d₂) (j : Fin d₃), |W₂ i j| ≤ w₂) (hx : ∀ (i : Fin d₀), |x i| ≤ a) (hG : ∀ (j : Fin d₃), |g j| ≤ G) (hg : ∀ (j : Fin d₃), |gt j - g j| ≤ eg) (hmargin₁ : ∀ (i' : Fin d₂), layerBudget M.u d₁ w₁ β₁ (layerAct d₀ w₀ β₀ a) (layerBudget M.u d₀ w₀ β₀ a 0) < |Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x)) i'|) (hmargin₀ : ∀ (i' : Fin d₁), layerBudget M.u d₀ w₀ β₀ a 0 < |Proofs.dense W₀ b₀ x i'|) (i : Fin d₀) (j : Fin d₁) :
    |M.sub (W₀ i j) (M.mul lr (M.mul (x i) (reluMask (M.dense W₀ b₀ x) (M.dense (fun (j' : Fin d₂) (i' : Fin d₁) => W₁ i' j') (fun (x : Fin d₁) => 0) (reluMask (M.dense W₁ b₁ (relu d₁ (M.dense W₀ b₀ x))) (M.dense (fun (j' : Fin d₃) (i' : Fin d₂) => W₂ i' j') (fun (x : Fin d₂) => 0) gt))) j))) - (W₀ i j - lr * (x i * reluMask (Proofs.dense W₀ b₀ x) (Proofs.dense (fun (j' : Fin d₂) (i' : Fin d₁) => W₁ i' j') (fun (x : Fin d₁) => 0) (reluMask (Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x))) (Proofs.dense (fun (j' : Fin d₃) (i' : Fin d₂) => W₂ i' j') (fun (x : Fin d₂) => 0) g))) j))| ≤ sgdErr M.u lr |W₀ i j| (a * layerAct d₂ w₁ 0 (layerAct d₃ w₂ 0 G)) (mulErr M.u a (layerAct d₂ w₁ 0 (layerAct d₃ w₂ 0 G)) 0 (layerBudget M.u d₂ w₁ 0 (layerAct d₃ w₂ 0 G) (layerBudget M.u d₃ w₂ 0 G eg)))

    Rounded input-layer weight update (W₀) — the cotangent crosses BOTH masks, so both quantitative margins are required; the activation operand is the raw input x, identical in both nets (zero inherited error). The real target W₀ᵢⱼ − lr·(xᵢ·c₀ⱼ) is the certified layer-0 step (mlp_layer0_weight_grad_bridge).

    theorem Proofs.FloatModel.mlp_b0_step_float_close (M : FloatModel) {d₀ d₁ d₂ d₃ : ℕ} {W₀ : Mat d₀ d₁} (b₀ : Vec d₁) {W₁ : Mat d₁ d₂} {b₁ : Vec d₂} {W₂ : Mat d₂ d₃} {x : Vec d₀} {gt g : Vec d₃} {lr w₀ β₀ w₁ β₁ w₂ a G eg : ℝ} (hw₀ : 0 ≤ w₀) (hβ₀ : 0 ≤ β₀) (hw₁ : 0 ≤ w₁) (hw₂ : 0 ≤ w₂) (ha : 0 ≤ a) (hlr : 0 ≤ lr) (hG0 : 0 ≤ G) (heg : 0 ≤ eg) (hW₀ : ∀ (i : Fin d₀) (j : Fin d₁), |W₀ i j| ≤ w₀) (hb₀ : ∀ (j : Fin d₁), |b₀ j| ≤ β₀) (hW₁ : ∀ (i : Fin d₁) (j : Fin d₂), |W₁ i j| ≤ w₁) (hb₁ : ∀ (j : Fin d₂), |b₁ j| ≤ β₁) (hW₂ : ∀ (i : Fin d₂) (j : Fin d₃), |W₂ i j| ≤ w₂) (hx : ∀ (i : Fin d₀), |x i| ≤ a) (hG : ∀ (j : Fin d₃), |g j| ≤ G) (hg : ∀ (j : Fin d₃), |gt j - g j| ≤ eg) (hmargin₁ : ∀ (i' : Fin d₂), layerBudget M.u d₁ w₁ β₁ (layerAct d₀ w₀ β₀ a) (layerBudget M.u d₀ w₀ β₀ a 0) < |Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x)) i'|) (hmargin₀ : ∀ (i' : Fin d₁), layerBudget M.u d₀ w₀ β₀ a 0 < |Proofs.dense W₀ b₀ x i'|) (j : Fin d₁) :
    |M.sub (b₀ j) (M.mul lr (reluMask (M.dense W₀ b₀ x) (M.dense (fun (j' : Fin d₂) (i' : Fin d₁) => W₁ i' j') (fun (x : Fin d₁) => 0) (reluMask (M.dense W₁ b₁ (relu d₁ (M.dense W₀ b₀ x))) (M.dense (fun (j' : Fin d₃) (i' : Fin d₂) => W₂ i' j') (fun (x : Fin d₂) => 0) gt))) j)) - (b₀ j - lr * reluMask (Proofs.dense W₀ b₀ x) (Proofs.dense (fun (j' : Fin d₂) (i' : Fin d₁) => W₁ i' j') (fun (x : Fin d₁) => 0) (reluMask (Proofs.dense W₁ b₁ (relu d₁ (Proofs.dense W₀ b₀ x))) (Proofs.dense (fun (j' : Fin d₃) (i' : Fin d₂) => W₂ i' j') (fun (x : Fin d₂) => 0) g))) j)| ≤ sgdErr M.u lr |b₀ j| (layerAct d₂ w₁ 0 (layerAct d₃ w₂ 0 G)) (layerBudget M.u d₂ w₁ 0 (layerAct d₃ w₂ 0 G) (layerBudget M.u d₃ w₂ 0 G eg))

    Rounded input bias update (b₀) — the layer-0 cotangent directly.

    theorem Proofs.FloatModel.mnist_w2_step_float_budget (M : FloatModel) (hMu : M.u ≤ u32) (W₀ : Mat 784 512) (b₀ : Vec 512) (W₁ : Mat 512 512) (b₁ : Vec 512) (W₂ : Mat 512 10) (x : Vec 784) (g : Vec 10) (hW₀ : ∀ (i : Fin 784) (j : Fin 512), |W₀ i j| ≤ 3 / 5) (hb₀ : ∀ (j : Fin 512), |b₀ j| ≤ 1) (hW₁ : ∀ (i j : Fin 512), |W₁ i j| ≤ 3 / 5) (hb₁ : ∀ (j : Fin 512), |b₁ j| ≤ 1) (hW₂ : ∀ (i : Fin 512) (j : Fin 10), |W₂ i j| ≤ 3 / 5) (hx : ∀ (i : Fin 784), |x i| ≤ 1) (hG : ∀ (j : Fin 10), |g j| ≤ 1) (i : Fin 512) (j : Fin 10) :
    |M.sub (W₂ i j) (M.mul (1 / 10) (M.mul (relu 512 (M.dense W₁ b₁ (relu 512 (M.dense W₀ b₀ x))) i) (g j))) - (W₂ i j - 1 / 10 * (relu 512 (Proofs.dense W₁ b₁ (relu 512 (Proofs.dense W₀ b₀ x))) i * g j))| ≤ 5 / 4

    Numeric gradient capstone at the committed dims and TRAINED magnitudes (784→512→512→10, |W| ≤ 3/5 covering the measured max|W| = 0.52): binary32 accuracy (u ≤ 2⁻²⁴), lr = 1/10, |b|, |x| ≤ 1, |g| ≤ 1 (a softmax−onehot cotangent is always in [−1,1]), cotangent taken exact — then every rounded W₂ SGD entry is within 5/4 of the certified real step.

    The budget decomposes honestly: ~1.2 of it is lr·E₁·|g| — the forward budget riding through the gradient at learning-rate scale — while fresh backward rounding contributes only ~2·10⁻³. The gradient step is as accurate as the forward pass, no worse. Measured on the live run (scripts/certs/margin_probe.py): actual W₂ step deviation ≤ 7.5·10⁻⁹ — the worst-case-vs-measured gap is the a-posteriori case in numbers.

    theorem Proofs.FloatModel.mnist_cot_budget (M : FloatModel) (hMu : M.u ≤ u32) (fexp : ℝ → ℝ) {eexp : ℝ} (heexp0 : 0 ≤ eexp) (heexp : eexp ≤ 1 / 1000000) (hfexp : ∀ (t : ℝ), |fexp t - Real.exp t| ≤ eexp * Real.exp t) (zt z : Vec 10) (label : Fin 10) (hz : ∀ (k' : Fin 10), |zt k' - z k'| ≤ 1 / 100) (k : Fin 10) :
    |M.softmaxCECotF fexp zt label k - (softmax 10 z k - oneHot 10 label k)| ≤ 21 / 1000

    Numeric head budget at the committed MNIST output (n = 10): for any model at binary32 accuracy, exp accurate to eexp ≤ 10⁻⁶ (an assumed accuracy for GPU exp, not measured in the repo), and float logits within δ = 1/100 of real, the rounded softmax−onehot cotangent is within 21/1000 of the certified gradient — almost all of it the e^(2δ) − 1 ≈ 2δ logit-perturbation term; the head's own rounding contributes < 4·10⁻⁶.

    δ = 1/100 is an a-posteriori-style hypothesis: the worst-case forward logit budget (≈5100 at trained magnitudes) makes e^(2δ) − 1 vacuous, so a useful head budget needs the measured logit error — exactly the hand-off point from worst-case to a-posteriori analysis. Empirically validated (scripts/certs/margin_probe.py): measured drift on a real 12-epoch run is ≤ 1.6·10⁻⁵, 600× inside the 1/100 hypothesis.

    theorem Proofs.FloatModel.linear_e4m3_logit_budget (M L : FloatModel) (hMu : M.u ≤ u32) (hLu : L.u ≤ uE4M3) :
    denseMixedBudget M.u L.u 784 (3 / 5) 1 1 ≤ 61

    The worst-case E4M3 per-logit budget at the MNIST-linear dims (784→n; E4M3 leaf u_leaf ≤ 2⁻⁴, fp32 accumulate u_acc ≤ 2⁻²⁴; pixels |x| ≤ 1, trained |W| ≤ 3/5, |b| ≤ 1): every E4M3-mixed logit is within 61 of the exact-ℝ logit. The leaf term (2·2⁻⁴ ≈ 12.5%)·∑|xW| dominates (the fp32 fan-in γ at 784 is ≈5·10⁻⁵, negligible) — this is the worst-case, all-errors- aligned figure. The demo (scripts/demos/mnist_e4m3_demo.py) measures the actual drift at max|Δlogit| = 0.38 (errors cancel), the a-posteriori B; both feed argmax_preserved.

    theorem Proofs.FloatModel.linear_e4m3_argmax_preserved (M L : FloatModel) (hMu : M.u ≤ u32) (hLu : L.u ≤ uE4M3) {n : ℕ} {W : Mat 784 n} {b : Vec n} {x : Vec 784} (hW : ∀ (i : Fin 784) (j : Fin n), |W i j| ≤ 3 / 5) (hb : ∀ (j : Fin n), |b j| ≤ 1) (hx : ∀ (i : Fin 784), |x i| ≤ 1) (k : Fin n) (hmargin : ∀ (i : Fin n), i ≠ k → 122 < Proofs.dense W b x k - Proofs.dense W b x i) (i : Fin n) :
    i ≠ k → M.denseMixed L W b x i < M.denseMixed L W b x k

    Verified E4M3 MNIST-linear argmax preservation. For the certified linear classifier at E4M3 leaf precision / fp32 accumulate, pixels |x| ≤ 1, trained |W| ≤ 3/5, |b| ≤ 1: whenever the exact-ℝ logit margin at the top class k exceeds 2·61 = 122, the E4M3-mixed forward keeps k as the strict argmax — provably the same prediction. Depth-1 makes the single-matmul bound the end-to-end bound, so this is the one realistic fp8 case with an honest accuracy guarantee (no vacuous depth compounding). The 122 is the worst-case threshold; with the demo's measured B = 0.38 the same argmax_preserved covers the >0.76-margin inputs — empirically 92.89% of the MNIST test set (scripts/demos/mnist_e4m3_demo.py). fp32 ≈ exact-ℝ (within u_acc), so the demo's fp32 margins are the relevant quantity.