MobileNetV2 — end-to-end inverted-residual VJP (flattened Vec space) #
Builds a representative MobileNetV2 forward and proves its end-to-end
vector–Jacobian product correct, analogous to cnn_has_vjp_at for the
ResNet basic block. Everything lives in flattened Vec space and reuses
the foundation rules from CNN.lean, Depthwise.lean, BatchNorm.lean,
MLP.lean, and Residual.lean through vjp_comp_at chaining.
What's new here #
relu6— the clamped activationmin (max x 0) 6. Unlikerelu, the saturated branch is the constant 6 (not linear-through-origin), so the local-linearization trick matchesrelu6against an affine surrogateg(proj on the active region, constant 0 below, constant 6 above) whose fderiv is the diagonal indicator1_{0<x<6}. Smoothness is the two-sidedx k ≠ 0 ∧ x k ≠ 6.Inverted-residual body —
project ∘ depthwise ∘ expand:- expand : 1×1 conv → bn → relu6 (
ic → mid, mid = t·ic) - depthwise: depthwise conv → bn → relu6 (
mid → mid) - project : 1×1 conv → bn (linear bottleneck, no activation;
mid → oc) With a stride-1 /ic = ocskip it becomesresidual body(no final activation — MobileNetV2's linear-bottleneck design).
- expand : 1×1 conv → bn → relu6 (
End-to-end — stem (3×3 conv-bn-relu6) → skip inverted-residual → no-skip inverted-residual (channel change) → global average pool → dense head. Fixed block counts; generic channel/kernel dims; spatial
h wpreserved throughout (SAME convs).
Padding convention #
The strided sites — the 6-block mobilenetv2Forward_full's stem and its four downsample
depthwises — read flatConvStride2Xla / depthwiseStride2FlatXla, the XLA-SAME (odd)
phase every MobileNetV2 artifact emits, re-spelled 2026-09-05 with the rest of the Proofs
tier. This net is the scalar-BN stepping stone mobilenetv2Forward_full_pc replaced: no
artifact and no float number rests on it, and it moved so the whole MobileNetV2 cone reads
one phase. The 2-block generic mobilenetv2Forward below has a stride-1 stem and is not
affected either way.
All new defs/theorems certify to exactly [propext, Classical.choice, Quot.sound].
Equations
- Proofs.relu6 n x i = min (max (x i) 0) 6
Instances For
ReLU6's local linear part at a smooth point: projects to y k when
0 < x k < 6, otherwise zero.
Equations
- Proofs.relu6LinearPart n x = ContinuousLinearMap.pi fun (k : Fin n) => if 0 < x k ∧ x k < 6 then ContinuousLinearMap.proj k else 0
Instances For
1×1 conv → bn → relu6 (expand stage / stem). Mirror of
convBnRelu_has_vjp_at with relu6 in place of relu.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Depthwise → bn → relu6 (depthwise stage of an inverted residual).
Channels & spatial dims preserved: Vec (c*h*w) → Vec (c*h*w).
Equations
- One or more equations did not get rendered due to their size.
Instances For
conv → bn (no activation) — the project (linear bottleneck) stage.
Everywhere differentiable, global HasVJP.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The expand stage as a flat map.
Equations
- Proofs.ivExpand We be εe γe βe = Proofs.relu6 (mid * h * w) ∘ Proofs.bnForward (mid * h * w) εe γe βe ∘ Proofs.flatConv We be
Instances For
The depthwise stage as a flat map.
Equations
- Proofs.ivDepthwise Wd bd εd γd βd = Proofs.relu6 (mid * h * w) ∘ Proofs.bnForward (mid * h * w) εd γd βd ∘ Proofs.depthwiseFlat Wd bd
Instances For
The project (linear bottleneck) stage as a flat map.
Equations
- Proofs.ivProject Wp bp εp γp βp = Proofs.bnForward (oc * h * w) εp γp βp ∘ Proofs.flatConv Wp bp
Instances For
Inverted-residual body = project ∘ depthwise ∘ expand. Flat
Vec (ic*h*w) → Vec (oc*h*w).
Equations
- Proofs.invresBody We be εe γe βe Wd bd εd γd βd Wp bp εp γp βp = Proofs.ivProject Wp bp εp γp βp ∘ Proofs.ivDepthwise Wd bd εd γd βd ∘ Proofs.ivExpand We be εe γe βe
Instances For
Inverted-residual body VJP at a smooth point. Two vjp_comp_at
chains: (1) depthwise ∘ expand over the two relu6 smoothness families,
(2) project (everywhere) on top.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Inverted-residual block WITH skip (stride 1, ic = oc = c):
residual (invresBody) — body(x) + x. No final activation
(MobileNetV2 uses linear bottleneck; the project stage has no relu6,
and the residual add is the block output).
Equations
- One or more equations did not get rendered due to their size.
Instances For
The forward MobileNetV2.
Equations
- One or more equations did not get rendered due to their size.
Instances For
MobileNetV2 end-to-end VJP at a smooth point. Chains the stem,
a skip inverted-residual, a no-skip inverted-residual, global avg
pool, and dense head with vjp_comp_at under one bundled smoothness
family (one ≠0∧≠6 hypothesis per relu6 site, evaluated at the
running activation).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Public correctness theorem for mobilenetv2_has_vjp_at — exposes
the witness's .correct field: the full MobileNetV2 backward equals
the pdiv-contracted Jacobian (Jacobian-transpose applied to the
cotangent). MobileNetV2 analogue of cnn_has_vjp_at_correct.
Stride-2 conv → bn → relu6 (the strided stem). Strided mirror of
convBnRelu6_has_vjp_at with flatConvStride2Xla; input spatial halves
(2h×2w → h×w).
Equations
- One or more equations did not get rendered due to their size.
Instances For
The strided depthwise stage as a flat map (Vec (mid*(2h)*(2w)) → Vec (mid*h*w)).
Equations
- Proofs.ivDepthwiseStrided Wd bd εd γd βd = Proofs.relu6 (mid * h * w) ∘ Proofs.bnForward (mid * h * w) εd γd βd ∘ Proofs.depthwiseStride2FlatXla Wd bd
Instances For
Stride-2 depthwise → bn → relu6 (downsampling depthwise stage). Strided
mirror of dwBnRelu6_has_vjp_at with depthwiseStride2FlatXla.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Strided inverted-residual body = project ∘ depthwiseStrided ∘ expand.
Expand is SAME at the input resolution (2h×2w); the stride-2 depthwise
halves spatial (2h×2w → h×w); project is SAME at the output resolution.
Flat Vec (ic*(2h)*(2w)) → Vec (oc*h*w). (No skip: strided blocks change
spatial / channels, so MobileNetV2 never wraps them in a residual.)
Equations
- Proofs.invresBodyStrided We be εe γe βe Wd bd εd γd βd Wp bp εp γp βp = Proofs.ivProject Wp bp εp γp βp ∘ Proofs.ivDepthwiseStrided Wd bd εd γd βd ∘ Proofs.ivExpand We be εe γe βe
Instances For
Strided inverted-residual body VJP at a smooth point. Strided mirror of
invresBody_has_vjp_at: expand SAME (at 2h×2w) → depthwise-strided → project.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The full MobileNetV2 forward (ch7 render): stem-s2 → 6 inverted-residual
blocks (b1/b3/b5/b6 stride-2 downsample, b2/b4 stride-1 skip) → 1×1
conv-bn-relu6 head → global-avg-pool → dense. Scalar BN; faithful topology.
Equations
- One or more equations did not get rendered due to their size.
Instances For
BN of a constant vector is the (constant) shift β — centering zeroes
the normalized term, killing the √. Keystone for discharging ReLU6
smoothness on a constant-activation net.
Equations
- Proofs.MobileNetV2Concrete.Ws x✝³ x✝² x✝¹ x✝ = 0
Instances For
Equations
Instances For
Equations
- Proofs.MobileNetV2Concrete.We₁ x✝³ x✝² x✝¹ x✝ = 0
Instances For
Equations
Instances For
Equations
- Proofs.MobileNetV2Concrete.Wd₁ x✝² x✝¹ x✝ = 0
Instances For
Equations
Instances For
Equations
- Proofs.MobileNetV2Concrete.Wp₁ x✝³ x✝² x✝¹ x✝ = 0
Instances For
Equations
Instances For
Equations
- Proofs.MobileNetV2Concrete.We₂ x✝³ x✝² x✝¹ x✝ = 0
Instances For
Equations
Instances For
Equations
- Proofs.MobileNetV2Concrete.Wd₂ x✝² x✝¹ x✝ = 0
Instances For
Equations
Instances For
Equations
- Proofs.MobileNetV2Concrete.Wp₂ x✝³ x✝² x✝¹ x✝ = 0
Instances For
Equations
Instances For
Equations
- Proofs.MobileNetV2Concrete.Wh x✝¹ x✝ = 0
Instances For
Equations
Instances For
Equations
Instances For
Whole-network VJP for a concrete MobileNetV2 — every ReLU6
smoothness hypothesis (bn ≠ 0 ∧ bn ≠ 6 at the five relu6 sites)
discharged: every BN input is the zero vector (zero kernels), so each
BN output is its shift β = 1 ∈ (0,6) via bnForward_const.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Public unconditional correctness theorem — the concrete MobileNetV2's
backward equals the pdiv-Jacobian VJP, no hypotheses.
With γ=1, β=3 and length n ≤ 8, every BN output is in (0,6) — for
an arbitrary input z and arbitrary ε>0. No constant-collapse, no
sqrt computed: the bound reduces to (zₖ−μ)² < 9(σ²+ε).
BN rescales every deviation by istd (the γ=1 case). Over any
index set S, the BN-output deviation-sum is the input deviation-sum
scaled by the positive bnIstd. This is what carries a stem-planted
cross-channel asymmetry through the four BN layers undamped.
Instances For
Equations
- Proofs.Mnv2Live.We₁ x✝³ x✝² x✝¹ x✝ = 0
Instances For
Equations
- Proofs.Mnv2Live.Wd₁ x✝² x✝¹ x✝ = 0
Instances For
Equations
- Proofs.Mnv2Live.Wp₁ x✝³ x✝² x✝¹ x✝ = 0
Instances For
block2 expand: identity channel map.
Instances For
block2 depthwise: identity (single 1×1 tap).
Equations
- Proofs.Mnv2Live.Wd₂ x✝² x✝¹ x✝ = 1
Instances For
block2 project: identity channel map.
Instances For
identity dense head ⇒ output = per-channel GAP.
Instances For
Unconditional whole-network VJP on a nonzero, non-collapsed MobileNetV2.
Every ReLU6 smoothness hypothesis of mobilenetv2_has_vjp_at is discharged
by win (the window lemma) — not by a constant collapse. No side
conditions; three-axiom closure.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Public unconditional correctness theorem — the nonzero-weight
MobileNetV2's backward equals the pdiv-Jacobian VJP, no hypotheses.
The 1×1 unit depthwise conv (W = 1, b = 0) is the identity.
GAP of a constant vector is that constant.
Flat index of channel-0 spatial position p (matches globalAvgPoolFlat_as_sum).
Equations
- Proofs.Mnv2Live.ι p = finProdFinEquiv (finProdFinEquiv (0, p.1), p.2)
Instances For
Sum of channel-0 deviations from the (full-vector) mean.
Equations
- Proofs.Mnv2Live.chSum z = ∑ p : Fin 2 × Fin 2, (z (Proofs.Mnv2Live.ι p) - Proofs.bnMean (2 * 2 * 2) z)
Instances For
Σ over the four channel-0 positions of the input is 6 (= 0+1+2+3).
The X-forward reduces to four BN layers on a constant-shifted stem output.
The live witness is non-degenerate: its forward computes a non-trivial
function of the input — forward X ≠ forward 0. So the Jacobian is not
identically zero, unlike MobileNetV2Concrete.