Documentation

LeanMlir.Proofs.Nets.MobileNet.MobileNetV2FullB

MobileNetV2 at TRUE BATCH-NORM — the whole net's forward and graph (T1-forward, T2) #

The MobileNetV2 peer of ResNet34FullB.lean, and the first half of planning/archive/proofs_tier_to_paper_nets.md section 4.2's MobileNetV2 column.

MobileNetV2FullPaper.lean states this net's whole-net ℝ forward and typed graph at per-example BatchNorm (bnPerChannelTensor3, reduce [2,3]). That was the world of mobilenetv2_fwd.mlir and the Imagenette SGD trainer mobilenetv2_train_step.mlir, and every tier built on it is true and was correctly paired with those bytes. It is NOT the world of mobilenetv2_adam_train_step.mlir, mobilenetv2_rms_train_step.mlir or any ImageNet artifact — including mobilenetv2in_rmsdp64, whose accuracy the book quotes — all of which reduce [0,2,3]: one mu/var per channel across the batch, the one op that couples examples.

MobileNetV2's two renderers did not overlap, so this was not a flag away. MobileNetV2Render.lean was SGD-inline and per-example only; MobileNetV2RenderB is AdamW/RMSProp-only, at the batched index and at batch BatchNorm. This file re-states the ladder at bnBatchLA (= the proven bnBatchTensor4 at the network's left-assoc index), which is that renderer's world. ⭐ Since 4c leg 2 (2026-09-06) it is the ONLY renderer: the per-example one and its train step are retired and mobilenetv2_fwd.mlir comes from the batched chain too, so this file's world is now the whole net's.

What is new here, and what is not #

⭐⭐ Nothing about the blocks is new. MobileNetV2BackB0.lean already carries the batched relu6 stages (cbrB, dwbrB, dwbrBstrided, and projB from EfficientNetRenderPC.lean), their _at VJPs and their backward-graph faithfulness, all at bnBatchLA. What was missing is the level above: a net-level ℝ forward, a net-level forward graph, and the faithfulness tying them. This file is that enumeration.

The weight bundles are reused, not re-declared. IVW / IVWNoExp (MobileNetV2FullPaper.lean) hold kernels, epsilons, gammas and betas — nothing that knows which BatchNorm world reduces them — so the batched net binds the same records the per-example one does. Only the top-level bundle is new, because it is generic in the class count where the retired per-example record was pinned at 10.

Padding is XLA-SAME at all five stride-2 sites — the stem 3x3/s2 conv and the four stride-2 depthwises (b2, b4, b7, b14). These are flatConvStride2Xla / depthwiseStride2FlatXla, NOT r34's symmetric flatConvStride2 peers; the two families have identical types and identical emitted shapes, so only the certificate distinguishes them, and MobileNetV2 is the TF-origin net. scripts/convention_audit.py sees this at the artifact tier and nothing sees it here, so it is stated.

There is no max-pool. MobileNetV2's stem is conv-BN-relu6 and downsamples once; r34's stem is conv-BN-relu, then a 3x3/s2 pool. That is why this net needs no batchMap_has_vjp_at.

Conventions this net runs at #

depth17 bottlenecks, the paper [t,c,n,s] table, stem 32 to head 1280
BatchNormbatch (bnBatchLA, reduce [0,2,3], width N*h*w), 52 sites
activationrelu6 (TWO kinks, at 0 and at 6); 35 sites, none after a project
stride-2 paddingXLA-SAME at all five sites
stem3x3/s2 conv-bn-relu6, 3 to 32, 224 to 112 (NO pool)
head1x1 conv-bn-relu6 320 to 1280, then GAP and dense, generic in the class count
artifactsmobilenetv2_fwd and every train step — this net now has ONE chain (4c leg 2)

⭐ The head is generic in nCls, so one statement covers the 10-class Imagenette artifacts and the 1000-class mobilenetv2in ones.

N stays a variable throughout. T1 and T2 carry no numerals, so the batch size does not need pinning here; it is pinned only where a Maps envelope turns a width into a rational (T4/T5), and the artifacts' N is the PER-REPLICA batch (64 on the data-parallel runs) because the collectives average gradients and no BatchNorm statistic is all-reduced.

The bias operand names are the render's DEFAULT convBias := false ones%zb{c}, the shared zero constant each conv, depthwise and project bias is bound to once its real bias has been folded into the BatchNorm that follows it. That is what makes the shipped parameter census 158 and not 210. Every graph below is -quantified over the bias VALUE, so it covers the convBias := true render too; only the name would differ there.

structure Proofs.MNV2BWeights (nCls : ) :

Every paper-spec MobileNetV2 parameter: stem (3x3/s2, 3 to 32) + the 17 bottlenecks of the [t,c,n,s] table + the 1x1 head (320 to 1280) + the dense classifier. Generic in nCls — the retired per-example record was pinned at 10, and the lesson MobileNetV2FullPaperEval.lean and B0's eval twin both paid for is that the head's envelope depends on the fan-in and never on the output count.

Instances For
    @[reducible]
    noncomputable def Proofs.mnv2StemB (N h w : ) {ic oc kH kW : } (Ws : Kernel4 oc ic kH kW) (bs : Vec oc) (εs : ) (γs βs : Vec oc) :
    Vec (N * (ic * (2 * h) * (2 * w)))Vec (N * (oc * h * w))

    Batched stem: 3x3/s2 XLA-SAME conv -> batch BN -> relu6. MobileNetV2 has no stem pool.

    Equations
    Instances For
      @[reducible]
      noncomputable def Proofs.mnv2NoExpB (N h w : ) {ic oc : } (p : IVWNoExp ic oc) :
      Vec (N * (ic * h * w))Vec (N * (oc * h * w))

      Batched t = 1 first bottleneck (b1): depthwise-bn-relu6 then the linear-bottleneck project. No expand conv, no skip. The one block shape with no mnv2*BodyB lemma to delegate to.

      Equations
      Instances For
        @[reducible]
        noncomputable def Proofs.mnv2ExpOnlyB (N h w : ) {ic mid oc : } (p : IVW ic mid oc) :
        Vec (N * (ic * h * w))Vec (N * (oc * h * w))

        Batched stride-1 inverted-residual BODY, no skip (ic ≠ oc; b11, b17): projB ∘ dwbrB ∘ cbrB.

        Equations
        Instances For
          @[reducible]
          noncomputable def Proofs.mnv2ResidB (N h w : ) {c mid : } (p : IVW c mid c) :
          Vec (N * (c * h * w))Vec (N * (c * h * w))

          Batched stride-1 inverted residual WITH the identity skip (s = 1 ∧ ic = oc). ⭐ The residual add IS the block output — unlike ResNet, there is no relu after it, which is why a MobileNetV2 block carries two kink clauses and not three.

          Equations
          Instances For
            @[reducible]
            noncomputable def Proofs.mnv2StridedB (N h w : ) {ic mid oc : } (p : IVW ic mid oc) :
            Vec (N * (ic * (2 * h) * (2 * w)))Vec (N * (oc * h * w))

            Batched stride-2 downsampling bottleneck (no skip): expand at 2h x 2w, the XLA-SAME strided depthwise halving spatial, then project at h x w.

            Equations
            Instances For
              @[reducible]
              noncomputable def Proofs.mnv2HeadB (N h w : ) {ic oc nCls : } (Wh : Kernel4 oc ic 1 1) (bh : Vec oc) (εh : ) (γh βh : Vec oc) (Wd : Mat oc nCls) (bd : Vec nCls) :
              Vec (N * (ic * h * w))Vec (N * nCls)

              Batched head: 1x1 conv-bn-relu6 (ic to oc), global average pool, dense classifier.

              Equations
              • One or more equations did not get rendered due to their size.
              Instances For
                noncomputable def Proofs.mobilenetv2ForwardB_full (N : ) {nCls : } (w : MNV2BWeights nCls) (x : Vec (N * (3 * (2 * 112) * (2 * 112)))) :
                Vec (N * nCls)

                The full batch-BN MobileNetV2 forward, N*(3*224*224) -> N*nCls. The batched peer of the retired per-example forward; nested-application form, as resnet34ForwardB_full and efficientnetForwardB_full both are, so a T6 tie can peel it one block at a time.

                Equations
                • One or more equations did not get rendered due to their size.
                Instances For
                  def Proofs.StableHLO.mnv2StemGraphB (epsStr : String) (N h w : ) {ic oc kH kW : } (Ws : Kernel4 oc ic kH kW) (bs : Vec oc) (εs : ) (γs βs : Vec oc) (e : SHlo (N * (ic * (2 * h) * (2 * w)))) :
                  SHlo (N * (oc * h * w))

                  Stem graph: 3x3/s2 XLA-SAME conv -> batch BN -> relu6.

                  Equations
                  • One or more equations did not get rendered due to their size.
                  Instances For
                    theorem Proofs.StableHLO.mnv2StemGraphB_faithful (epsStr : String) (N h w : ) {ic oc kH kW : } (Ws : Kernel4 oc ic kH kW) (bs : Vec oc) (εs : ) (γs βs : Vec oc) (e : SHlo (N * (ic * (2 * h) * (2 * w)))) :
                    den (mnv2StemGraphB epsStr N h w Ws bs εs γs βs e) = mnv2StemB N h w Ws bs εs γs βs (den e)
                    def Proofs.StableHLO.mnv2NoExpGraphB (pfx epsStr : String) (N h w : ) {ic oc : } (p : IVWNoExp ic oc) (e : SHlo (N * (ic * h * w))) :
                    SHlo (N * (oc * h * w))

                    t = 1 bottleneck graph (b1): depthwise -> BN -> relu6 -> project 1x1 -> BN.

                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For
                      theorem Proofs.StableHLO.mnv2NoExpGraphB_faithful (pfx epsStr : String) (N h w : ) {ic oc : } (p : IVWNoExp ic oc) (e : SHlo (N * (ic * h * w))) :
                      den (mnv2NoExpGraphB pfx epsStr N h w p e) = mnv2NoExpB N h w p (den e)
                      def Proofs.StableHLO.mnv2ExpOnlyGraphB (pfx epsStr : String) (N h w : ) {ic mid oc : } (p : IVW ic mid oc) (e : SHlo (N * (ic * h * w))) :
                      SHlo (N * (oc * h * w))

                      Stride-1 no-skip bottleneck graph (b11, b17): expand -> depthwise -> project, batch BN after each, relu6 after the first two.

                      Equations
                      • One or more equations did not get rendered due to their size.
                      Instances For
                        theorem Proofs.StableHLO.mnv2ExpOnlyGraphB_faithful (pfx epsStr : String) (N h w : ) {ic mid oc : } (p : IVW ic mid oc) (e : SHlo (N * (ic * h * w))) :
                        den (mnv2ExpOnlyGraphB pfx epsStr N h w p e) = mnv2ExpOnlyB N h w p (den e)
                        def Proofs.StableHLO.mnv2ResidGraphB (pfx epsStr : String) (N h w : ) {c mid : } (p : IVW c mid c) (e : SHlo (N * (c * h * w))) :
                        SHlo (N * (c * h * w))

                        Stride-1 skip bottleneck graph: the body plus the addVB identity skip, the block-input subtree e shared between both arms as the render emits it.

                        Equations
                        Instances For
                          theorem Proofs.StableHLO.mnv2ResidGraphB_faithful (pfx epsStr : String) (N h w : ) {c mid : } (p : IVW c mid c) (e : SHlo (N * (c * h * w))) :
                          den (mnv2ResidGraphB pfx epsStr N h w p e) = mnv2ResidB N h w p (den e)
                          def Proofs.StableHLO.mnv2StridedGraphB (pfx epsStr : String) (N h w : ) {ic mid oc : } (p : IVW ic mid oc) (e : SHlo (N * (ic * (2 * h) * (2 * w)))) :
                          SHlo (N * (oc * h * w))

                          Stride-2 downsampling bottleneck graph: expand at 2h x 2w, XLA-SAME strided depthwise, project at h x w.

                          Equations
                          • One or more equations did not get rendered due to their size.
                          Instances For
                            theorem Proofs.StableHLO.mnv2StridedGraphB_faithful (pfx epsStr : String) (N h w : ) {ic mid oc : } (p : IVW ic mid oc) (e : SHlo (N * (ic * (2 * h) * (2 * w)))) :
                            den (mnv2StridedGraphB pfx epsStr N h w p e) = mnv2StridedB N h w p (den e)
                            def Proofs.StableHLO.mnv2HeadGraphB (epsStr : String) (N h w : ) {ic oc nCls : } (Wh : Kernel4 oc ic 1 1) (bh : Vec oc) (εh : ) (γh βh : Vec oc) (Wd : Mat oc nCls) (bd : Vec nCls) (e : SHlo (N * (ic * h * w))) :
                            SHlo (N * nCls)

                            Head graph: 1x1 conv -> batch BN -> relu6 -> GAP -> dense.

                            Equations
                            • One or more equations did not get rendered due to their size.
                            Instances For
                              theorem Proofs.StableHLO.mnv2HeadGraphB_faithful (epsStr : String) (N h w : ) {ic oc nCls : } (Wh : Kernel4 oc ic 1 1) (bh : Vec oc) (εh : ) (γh βh : Vec oc) (Wd : Mat oc nCls) (bd : Vec nCls) (e : SHlo (N * (ic * h * w))) :
                              den (mnv2HeadGraphB epsStr N h w Wh bh εh γh βh Wd bd e) = mnv2HeadB N h w Wh bh εh γh βh Wd bd (den e)
                              def Proofs.StableHLO.mobilenetv2FwdGraphB_full (N : ) (epsStr : String) {nCls : } (w : MNV2BWeights nCls) (e : SHlo (N * (3 * (2 * 112) * (2 * 112)))) :
                              SHlo (N * nCls)

                              The full batch-BN MobileNetV2 forward graph. Block prefixes are the render's (b1b17, each parameter %b{k}{e,d,p}{W,g,bt}), so the typed graph diffs against mobilenetv2_adam_train_step's forward half name for name.

                              Equations
                              • One or more equations did not get rendered due to their size.
                              Instances For
                                theorem Proofs.StableHLO.mobilenetv2FwdGraphB_full_faithful (N : ) (epsStr : String) {nCls : } (w : MNV2BWeights nCls) (e : SHlo (N * (3 * (2 * 112) * (2 * 112)))) :

                                T2 for MobileNetV2 at batch BN: the typed graph denotes the whole-net forward. One rw per block over the six per-kind faithfulness lemmas.