PoC: the full-16 EfficientNet-B0 train step §1a TIE (whole-net thread) — DONE (capstone efficientnet_net_tied, all 262 params, 3-axiom clean; only the optional dense-head fold below remains) #
The EfficientNet-B0 §1a tie (its batched, un-fused peer is EnetTiePoCG.efficientnet_net_tiedG). The §1 fold
(EfficientNetFold) gives every batched param-SGD op den = certified ∀ cotangent; this
file pins each cotangent to the actual loss-driven backward chain of the rendered net — threading
the real forward activations through every param op and composing the backward cotangent from the
loss down through all 16 MBConv blocks (with the residual fan-in at every stride-1 skip AND the SE
gate fan-in), so each output's den = certified becomes a single composed theorem with the forward
= the proven efficientnetForwardB_full.
What is NEW vs mnv2's tie (the harder content, hence a dedicated effort):
- swish masks instead of relu6 — the cotangent crosses
swishBack(smooth, no two-kinkselectMid) at every conv-bn-swish / depthwise-bn-swish stage. - the SE multiplicative gate fan-in — the cotangent at an SE input is
gate ⊙ dyOut(the fusedseBackBatchedvalue) and the SE dense param cotangents come fromseReduceB(the gate cotangentΣ_{h,w}(x⊙dy)) threaded back throughsigmoidBack → denseRowBack(W₂) → swishBack. - true batch-norm backward (
bnBatchBack) — batch-coupled, vs mnv2's per-example BN. EfficientNetChainClose's whole-net backward is HasVJP-composition style (vjp_compof the per-block_has_vjp), NOT explicit cotangent-vector defs like mnv2'sinvresCot*— so the tie must BUILD explicit chain-cot constructors (the bulk of the remaining work).
Landed so far (all 3-axiom clean — [propext, Classical.choice, Quot.sound]) #
All five per-block-type tie lemmas — every one of the 262 params' SGD ops denotes the certified batched
Σ_nloss-descent step at the REAL loss-driven backward cotangent:enet_exp_tied(16 params) — stride-1 expand block; covers the 9 residual blocks (ic=oc) AND the 2 no-skip widenings (ic≠oc, b9/b16); the param ops are skip-agnostic (the fan-in lives in the thread).enet_strided_tied(16) — strided downsample (b2/4/6/12): expand at2h×2w, strided depthwise.enet_noexp_tied(12) — b1 (t=1, no expand; depthwise onic→ SE → project).enet_stem_tied(4) — 3×3/s2 conv-bn-swish stem.enet_head_tied(6) — 1×1 conv-bn-swish head + dense (Wfc/bfc tied at the loss cotangentg).
The genuinely-new content vs mnv2 is PROVEN here: swish masks (
swBackB), the SE gate fan-in (gateCotB=den seReduceB→sigBackB→rowDenseBackFlat→swBackB→ SE dense ops), true batch-norm backward (bnBackB=bnBatchLAVJP), the strided depthwise back (dStridedInB), all at the batched indexN·(c·h·w).reassocBbridges the conv/swish(oc·h·w)↔ BN(oc·(h·w))index. Each per-block tie is a pure delegation to the §1-fold genericsEnetPoC.*at the chain cotangents.The whole-net thread
efficientnet_net_tied(DONE, 3-axiom clean) — all 262 params tied through the REALefficientnetForwardB_full: block inputs are its forward prefixes (a0..a16), the per-block output cotangents (dy0..dy16) composed top-down by the proven block VJPs (headFwdB_has_vjp,mb{Exp,Resid,Strided,NoExp}W_has_vjp) from the loss cotangentg.@[irreducible]*TiedAtwrappers keep the 16-deep thread opaque (the r34/mnv2 heartbeat lesson). The residual fan-in at the 9 identity skips is folded intombResidW's own VJP (it includes the+ x), so it is automatic — the whole 262-param train step is den-composed forward→loss→backward, no free activations, no symbolic cot.
Remaining (optional refinement) #
- The dense-head total-loss fold (
Wfc → ∂CE/∂Wfc) — the batched-Σ_nanalogue ofmlp_output_total_loss_grad; today the head dense ties at the loss cotangentgdirectly.
Chain-cotangent helpers — the per-op batched backward steps (built fresh, HasVJP-style) #
EfficientNetChainClose proves the per-block VJPs by vjp_comp of the per-op VJPs but exposes no
explicit cotangent-vector defs (unlike mnv2's invresCot*). So the tie BUILDS the chain cotangents
from the proven per-op backwards: bnBackB (true-BN, the batch-coupled bnBatchLA VJP), swBackB
(swish, smooth), cInB/dInB (the batched conv/depthwise input-VJP = den convBackBatched/
depthwiseBackBatched), seInB (the fused SE input-cot = den seBackBatched), gateCotB (the SE
gate cotangent = den seReduceB), sigBackB, rowDenseBackFlat (the SE excite/reduce backs). Every
helper IS a .backward of a proven VJP (or the exact den of the emitted backward op), so the
cotangents are the genuine loss-driven backward, not a free ∀c. reassocB bridges the conv/swish
index (oc·h·w) to the BN param-op index (oc·(h·w)).
(oc·h·w) → (oc·(h·w)) batched reassociation reindex — bridges the conv/swish chain index to the
BN γ/β + conv-bias op index (EnetPoC.bn{Gamma,Beta}B_den consume Vec (N·(oc·(h·w)))).
Equations
- Proofs.EnetTiePoC.reassocB N oc h w v i = v (Fin.cast ⋯ i)
Instances For
Batched true-BN input-cotangent (bnBatchLA VJP — batch-coupled).
Equations
- Proofs.EnetTiePoC.bnBackB N oc h w ε hε γ β x dy = (Proofs.bnBatchLA_has_vjp N oc h w ε hε γ β).backward x dy
Instances For
⭐ The tie's BN node and the emitted BN node denote one map. Every batched render emits
.bnBatchBack, typed at N·(oc·(h·w)); the ties state the BN input cotangent at
.bnBatchLABack, its network-layout N·(oc·h·w) twin (ResNet34TieB.bnInB). The two print
the same text, and their dens differ only by the associativity relabelling reassocB: the
two scatters inside bnBatchLABack's den collapse because Fin.cast is a bijection.
The certified BN input cotangent every batched T3 tie threads IS the emitted bnBatchBack
node's den, read back through reassocB. This is the missing half of
bnBatchLABack_faithful: that lemma certifies the tie's node, this one says the render's node
computes the same numbers.
Batched swish mask-back (smooth, no kink).
Equations
- Proofs.EnetTiePoC.swBackB n x dy = (Proofs.swish_has_vjp n).backward x dy
Instances For
Batched sigmoid back (the SE gate excite-dense output cotangent).
Equations
- Proofs.EnetTiePoC.sigBackB n x dy = (Proofs.sigmoid_has_vjp n).backward x dy
Instances For
Batched 1×1/conv input-VJP (= den convBackBatched; conv is linear, x unused).
Equations
- Proofs.EnetTiePoC.cInB N W b dy = Proofs.StableHLO.batchMap N (fun (d : Proofs.Vec (oc * h * w)) => (Proofs.flatConv_has_vjp W b).backward (fun (x : Fin (ic * h * w)) => 0) d) dy
Instances For
Batched depthwise input-VJP (= den depthwiseBackBatched).
Equations
- Proofs.EnetTiePoC.dInB N W b dy = Proofs.StableHLO.batchMap N (fun (d : Proofs.Vec (c * h * w)) => (Proofs.depthwiseFlat_has_vjp W b).backward (fun (x : Fin (c * h * w)) => 0) d) dy
Instances For
Batched strided depthwise input-VJP (= den depthwiseStridedBackBatched; upsamples h→2h).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Batched GAP input-VJP (= den gapBackBatched; the head's GAP backward, broadcast÷(h·w)).
Equations
- Proofs.EnetTiePoC.gapInB N c h w dy = Proofs.StableHLO.batchMap N (fun (d : Proofs.Vec c) => (Proofs.globalAvgPoolFlat_has_vjp c h w).backward (fun (x : Fin (c * h * w)) => 0) d) dy
Instances For
Batched fused SE input-cotangent (= den seBackBatched, the x⊙gate VJP).
Equations
- Proofs.EnetTiePoC.seInB N W₁ b₁ W₂ b₂ x dy = (Proofs.seB_has_vjp N W₁ b₁ W₂ b₂).backward x dy
Instances For
Batched SE gate cotangent dgate[n,c] = Σ_{h,w}(x⊙dy) (= den seReduceB, the broadcast-adjoint
of x ⊙ dy — the FIRST step of the SE gate backward, feeding the SE dense param grads).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Residual stride-1 MBConv block — all 16 params tied (expand → dw → SE → project + skip) #
The centerpiece: exercises the genuinely-new content vs mnv2 — swish masks (smooth), the SE gate
fan-in (gateCotB → sigBackB → {zW₂,zb₂} → rowDenseBackFlat → swBackB → {zW₁,zb₁}), and true
batch-norm backward (bnBackB), all at the batched index N·(c·h·w). Backward from dyOut (cot at
project-BN out): project-BN-back → project-conv-back (cot at SE out) → SE backward (fused dx for the
depthwise side; un-fused gate-cot for the SE params) → depthwise swish/BN/conv backs → expand
swish/BN/conv backs. Residual (ic=oc=c): the block-input cotangent fan-in + dyOut lives in the
whole-net thread, not here (the param ops are skip-agnostic — identical to the no-skip widenings).
Residual stride-1 MBConv block, tied. All 16 params (expand/project 1×1 conv W+b, depthwise
W+b, SE reduce/excite dense W₁/b₁/W₂/b₂, three true-BN γ/β) denote the certified batched Σ_n
loss-descent step at the real block forward activations + the chain cotangents driven by dyOut.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Strided downsampling MBConv block — all 16 params tied (b2/b4/b6/b12) #
Same as the expand block EXCEPT the expand stage lives at the block-input grid 2h×2w and the
depthwise is strided (depthwiseStridedWeightSgdB, the expand-side cotangent cotEr upsamples h→2h
via dStridedInB). No skip (spatial+channels change).
Strided downsampling MBConv block, tied. All 16 params at the real forward (expand at 2h×2w,
strided depthwise 2h→h) + the chain cotangents driven by dyOut.
Equations
- One or more equations did not get rendered due to their size.
Instances For
No-expand MBConv block (b1, t=1) — all 12 params tied (depthwise on ic → SE → project) #
NO expand conv: the depthwise runs directly on the block input (ic channels). 12 params (4 depthwise+BN,
4 SE, 4 project). The SE squeeze/excite is on ic channels (ic → r → ic).
No-expand MBConv block, tied. All 12 params at the real forward + chain cotangents.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Stem — the 3×3/s2 conv-bn-swish (4 params), feeding block 1 #
swish(bn(convStride2Xla Ws bs x)), 3→32 at 224→112, at the XLA-SAME phase the shipped stem
uses. The cotangent block 1 delivers at the stem swish output (dyStem) lifts through swish-back
- true-BN-back to the conv-out cotangent (the
convStridedXlaWeightSgdBconsumes it; NO conv-back past%x). 4 params.
Stem, tied. The 3×3/s2 conv (Ws/bs) + its true-BN (γs/βs) at the real stem forward +
the cotangent through the stem swish (no maxpool, no conv-back).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Head — the 1×1 conv-bn-swish (4 params) → GAP → dense (Wfc/bfc), + the loss cotangent #
dense(GAP(swish(bn(conv Wh bh))))) (320→1280 conv, GAP, 1280→nClasses dense), then the batched
per-row softmax-CE gradient g = rowSoftmax(logits) − onehot. The head conv params tie at the chain
cotangent (loss → dense-back → GAP-back → swish/BN-back); the dense Wfc/bfc tie at the loss cotangent
g directly.
Head, tied. The 4 head conv-bn params + the 2 dense params (Wfc/bfc) denote the certified step
at the real head forward + the loss-driven cotangent g = rowSoftmax(logits) − onehot.
Equations
- One or more equations did not get rendered due to their size.
Instances For
@[irreducible] bundle-taking *TiedAt wrappers — one per block type, for the whole-net thread #
Each takes the B0Weights block bundle (MBW/MBWNoExp) + its ε-positivity + the block input + the
downstream cotangent dyOut, and delegates to the per-block-type tie. @[irreducible] keeps the
16-deep capstone thread opaque to the elaborator (the r34/mnv2 heartbeat lesson).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
The whole-net thread — all 262 params tied through the REAL efficientnetForwardB_full #
The capstone: efficientnetForwardB_full's prefixes are the block inputs (a0..a16 = stem, then the
16 MBConv blocks), and the per-block output cotangents (dy0..dy16) are composed TOP-DOWN by the
proven block VJPs (headFwdB_has_vjp, mb{Exp,Resid,Strided,NoExp}W_has_vjp) from the loss cotangent
g = rowSoftmax(logits) − onehot. Each block's tie then holds at its real input + threaded dyOut.
The full §1a tie: the WHOLE 16-MBConv (262-param) EfficientNet-B0 train step is den-composed
forward→loss→backward, no free activations, no symbolic cotangent. The residual fan-in at the 9
identity skips is folded into mbResidW's own VJP (it includes the + x), so it is automatic.
The whole 16-MBConv EfficientNet-B0 train step, tied. Threading the real batched (true-BN + SE)
forward efficientnetForwardB_full and the loss-driven backward cotangent chain (swish masks, SE
gate fan-in, true-BN backs, the residual fan-in folded into the block VJPs), the stem, all 16
MBConv blocks, the conv-bn-swish head, and the dense head all denote the certified batched Σ_n
loss-descent step.