MobileNetV2 rendered from the verified AST, at the BATCHED index — the SOLE renderer #
This file writes every MobileNetV2 artifact. @mobilenetv2_fwd and @mobilenetv2in_fwd come
from mnv2FwdChainB, the ONE traversal every train step below differentiates, so the net that
scores and the net that trains are one graph by construction. The EVAL forwards are rendered from
the per-example chain: bnPerChannelEvalF reads frozen statistics and reduces nothing, so they are
BatchNorm-world-agnostic.
The whole graph sits at N := B, so every batch-coupled den is honest: bnBatchF,
bnBatchBack and the whole *GradB family reduce over the batch, and at N = 1 each would
describe a one-example function while the emitted text reduces over all B.
The ops this net needed that no other did: BatchableOp.relu6 — mnv2 is the only ReLU6 net
in the kit, EfficientNet being all-swish — and selectMidB, its two-sided backward mask, which
reads the saved per-example pre-activation and therefore CANNOT be a BatchableOp descriptor. Plus
depthwise{,Strided}BiasGradB: enet's depthwise convs are followed by BN so their bias is folded
into it, mnv2's are not.
The optimizer is the proven adamMNextF/adamVNextF/adamWParamF triple applied to the un-fused
*GradB gradients. The cotangent is composed from kit ops (softmaxRow → subB → scaleB → addVB → shiftB → divConstB, α = 0.1, K = nClasses). %loss is report-only and stays outside the AST,
exactly as resnet34/cifar8's does.
The Proofs tier this file's train steps are tied at is the batch-BN one:
MobileNetV2FullB (the batched forward and its typed graph), MobileNetV2FullBVJP (its VJP),
GradNodesB (the un-fused gradient-node folds) and MobileNetV2StepTieB (the whole-net tie).
Render is value-independent (skel erases values), so placeholder zeros and ε := 0 are passed;
the emitted literals carry the real values.
Saved forward SSA names a block's backward + gradient passes reference. ec/en/er are the
block input for the no-expand block (b1), which has no expand conv.
- code : String
- o : String
- ec : String
- en : String
- er : String
- dc : String
- dn : String
- dr : String
- pc : String
- stE : String
- stD : String
- stP : String
Instances For
Equations
STRIDED inverted-residual forward: expand at the input 2hh×2ww, depthwise downsamples
2hh×2ww → hh×ww, project 1×1 at hh×ww. NO skip.
Equations
- One or more equations did not get rendered due to their size.
Instances For
STRIDE-1 inverted-residual forward with the identity skip (ic = oc): everything at
hh×ww, block output = addVB (project-BN out) (block input). The bottleneck is LINEAR — no
relu6 after the add.
Equations
- One or more equations did not get rendered due to their size.
Instances For
EXPAND-NO-SKIP stride-1 forward (b11/b17): as irFwdSkipB but ic ≠ oc, so the block
output is the project-BN output directly.
Equations
- One or more equations did not get rendered due to their size.
Instances For
NO-EXPAND forward (b1, the canonical t = 1 block): depthwise(stride-1, on ic channels)
→ BN → relu6 → project(1×1 ic→oc) → BN. No expand conv, no skip. er is the depthwise INPUT
(= the block input), which is what the depthwise weight gradient reads.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The 210 parameters of the 17-block paper-spec net, in func-arg order. stem (4) + b1
no-expand (8) + b2..b17 (16 × 12 = 192) + head (4) + dense (2) = 210 — the same decomposition
paperSig uses, at the names the committed AdamW artifact presents.
Instances For
The 104 BN running-statistic slots = 52 BN layers × (μ, var): stem 1, b1 two (no expand
BN), b2..b17 three each (48), head 1. Both an input (…i) and an output slot.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The driver's variant slug for a given (B, replicas): the artifact is
verified_mlir/mobilenetv2_<variant>_train_step.mlir, the entry point is
@mobilenetv2_<variant>_train_step, and LEAN_MLIR_VARIANT selects it. All three must agree —
the shim checks the entry name and refuses a mismatch outright ("entry mismatch") rather than
running the wrong graph. B = 32 is deliberately unsuffixed so the committed artifact keeps its
name. The #guards at the bottom pin the literal #eval paths against this.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The forward record mnv2FwdChainB hands to its two consumers: the emitted code, the stem's
three activations, the seventeen block records, the head's three, and the GAP/logits names.
- code : String
- stc : String
- stn : String
- str : String
- hc : String
- hn : String
- hr : String
- gap : String
- log : String
- sst : String
- hst : String
- cin : String
Instances For
Equations
Stem forward: 3×3/s2 XLA-SAME conv (3→32, 224→112) → batch BN → relu6 (no max-pool).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Head forward: 1×1 conv (320→1280) → batch BN → relu6 → GAP(7×7) → [dropout] → dense, on
block 17's output xName.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The MobileNetV2 forward chain at the BATCHED index — one traversal, consumed by both
@mobilenetv2_fwd and every train step that differentiates it.
This exists so @mobilenetv2_fwd and the batch-BN train steps cannot be different nets:
a forward built from a PER-EXAMPLE chain (bnPerChannelF, reduce [2,3], divisor H·W) next
to batch-BN train steps (reduce [0,2,3], divisor B·H·W) is a different function. This is
ResNet34RenderB.r34FwdChainB's shape, for ResNet50RenderB.r50FwdChainB's reason.
The EVAL forward is deliberately NOT moved onto this chain, exactly as ResNet-34's and
ResNet-50's are not: bnPerChannelEvalF reads frozen per-channel statistics and reduces
nothing, so mobilenetv2_fwd_eval.mlir is BatchNorm-world-agnostic and correct against both
chains; moving it buys nothing.
Extracting the traversal is byte-neutral for the train step: pretty's SSA counter follows
the call SEQUENCE, and the sequence is unchanged.
Equations
- One or more equations did not get rendered due to their size.
Instances For
@mobilenetv2_fwd rendered from the BATCHED chain — the same traversal every batch-BN
train step in this file differentiates, so the net that scores and the net that trains are one
graph by construction. The writer of verified_mlir/mobilenetv2_fwd.mlir.
Takes %x plus the parameters in mnv2SigList order — 159 inputs at the shipped
convBias := false — and returns logits [B, nClasses].
It normalises over the BATCH, as the AdamW and RMSProp steps whose accuracies the book quotes
do. Parameter names come from mnv2SigList, this file's single source; the driver binds
positionally.
Equations
- One or more equations did not get rendered due to their size.
Instances For
MobileNetV2 (17-block paper spec) AdamW train step, batch BN, rendered from the verified AST
at N := B. 739 inputs (%x, 210 θ, 210 m, 210 v, %lr/%bc1/%bc2, 104 running-stat
slots, %onehot) and 737 outputs (210 θ', 210 m', 210 v', %loss/%bc1/%bc2, 104 batch
stats) — the interface the committed hand-written artifact already presents, so the driver is
unchanged. Parameter ORDER comes from mnv2SigList and stat order from mnv2StatSigList, the
single sources, so the arity/order contract cannot drift.
Stem 3×3/s2 (3→32, 224→112, NO maxpool) → b1 (no-expand t=1, 32→16) → b2..b17 (4 stride-2
downsamples, 10 identity skips, 2 stage-first widenings) → 1×1 conv-BN-relu6 head (320→1280) →
GAP → dense (1280→nClasses).
Instances For
- code : String
- o : String
The block's BN layers in forward order,
(stat prefix, channels, spatial side). The eval forward turns each into a%{prefix}mu/%{prefix}varinput pair;MobileNetV2RenderB's AdamW step hands the matching batch μ/var back in the SAME order (it walks the same block list). Order is expand-BN → depthwise-BN → project-BN, with the expand entry ABSENT for the no-expand block b1 — the layoutmobilenetv2Verified.bnChannelsis listed in, which is how the driver packsrunningBnStats. A misaligned slot is SILENT: the arities still match and the wrong layer's statistics simply flow into the wrong site.
Instances For
Equations
STRIDED inverted-residual forward (b1/b3/b5/b6): expand at the input 2hh×2ww, depthwise
downsamples 2hh×2ww → hh×ww, project 1×1 at hh×ww. NO skip.
Equations
- One or more equations did not get rendered due to their size.
Instances For
STRIDE-1 inverted-residual forward (b2/b4): everything at hh×ww, with an addV skip on the
block input (ic = oc).
Equations
- One or more equations did not get rendered due to their size.
Instances For
NO-EXPAND inverted-residual forward (b1): depthwise(stride-1, on ic channels)→BN→relu6
→ project(1×1 ic→oc)→BN. NO expand, NO skip. f.er = the depthwise INPUT (= block input
xName), f.dr = the project input. (ec/en are unused for this block kind.)
Equations
- One or more equations did not get rendered due to their size.
Instances For
EXPAND-NO-SKIP stride-1 forward (b11/b17): expand(1×1)→BN→relu6 → depthwise(3×3)→BN→relu6
→ project(1×1)→BN. Everything at hh×ww; ic ≠ oc so NO skip (block output = project-BN out).
Equations
- One or more equations did not get rendered due to their size.
Instances For
The 17-block MobileNetV2 eval forward: its code, the logits name the eval function returns,
and the 52-entry BN stat layout. (The train step walks the batched mnv2FwdChainB instead.)
- code : String
- logits : String
The 52 BN layers as
(stat prefix, channels, spatial side), stem -> blocks in forward order -> head. Single source for the eval signature and the eval BN sites.
Instances For
Equations
The eval forward's stem: 3x3/s2 XLA-SAME conv (3->32, 224->112) -> BN (stn) -> relu6, on
%x. Returns the code and the relu6 output's name.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The eval forward's head: 1x1 conv (320->1280) -> BN (hn) -> relu6 -> GAP(7x7) ->
dense(1280->nClasses), on block 17's output xin. Returns the code and the logits' name.
Equations
- One or more equations did not get rendered due to their size.
Instances For
@mobilenetv2_fwd_eval rendered ENTIRELY from the verified AST — the inference forward,
every BN site consuming frozen per-channel running stats (bnPerChannelEvalF) instead of
reducing statistics out of its activation. Same 210 params in the same order, plus the 104 stat
inputs (52 BN layers × μ/var, interleaved per layer in bnChannels order): 315 inputs.
Its train-step partner is the batch-BN mobilenetv2_adam_train_step in MobileNetV2RenderB,
whose returned batch μ/var the driver EMAs into exactly these slots. Being frozen-stat affine,
this graph is the same in either BN world — which is why it can live beside the per-example
chain: bnPerChannelEvalF performs no reduction, so there is no batch to be honest about.
Equations
- One or more equations did not get rendered due to their size.