Documentation

LeanMlir.Proofs.Nets.ResNet.ResNet50ParamGrad

ResNet-50 — every parameter gradient node IS the loss's derivative in that parameter #

r50_net_tiedB says each of the 161 parameter gradient nodes denotes its layer's parameter Jacobian contracted with the cotangent the emitted backward chain threads to it, from a loss cotangent g it takes as a binder; the r50*CotIn_eq_vjp lemmas say the block-input cotangents are certified VJP backwards. r50_net_lossGrad composes them: for any loss L of the logits whose gradient at the net's output is g, every node is ∂L/∂θ of the WHOLE net with that one parameter varied. The two losses the artifacts ship discharge hL:

Scope. One replica, at either precision: every conv weight node is stated on the renderers' switch (convWeightGradBAt bf16 id …, Foundation.GradNodesBAt), so bf16 := true is the bf16 kind resnet50in_momdp64bf16 and resnet50in160_lambaccdp4x128wxclipbcebf16, the book's ImageNet runs, emit, read over ℝ at the identity rounding (Bf16Erasure), and bf16 := false the f32 artifacts'. The drop-path forwards (*drop*) are outside this statement. Sync-BN data parallelism is reached by composition: r50_net_syncTiedB says each all-reduced gradient is this net's tied node at N := R·N, which this file's capstone makes the loss's gradient at the global batch.

How. ResNet34ParamGrad's three layers, with R34's stem and head bundles reused verbatim (the stem and head ARE R34's functions at R50's widths):

Hypotheses. R50PosB (every BN ε > 0), R50LossSmoothAtB (every relu off its kink and every stem-pool window dead, or its maximum at one position up to cells reading identical input patches, at the real activations); for the smoothed loss also every example's target summing to one and 0 < nCls. The BCE corollary takes no hypothesis on the target.

The stem pool's clause is stated for the parameters, not the image. Real batches have stem-pool windows whose positive maximum sits at two positions, because two cells read identical input patches (flat image regions). There the net has no derivative in the image, so the input VJP's R50SmoothAtB rejects them, but the tied cells are the same function of the stem's weights, so the loss IS differentiable in the parameters. R50LossSmoothAtB allows exactly those ties (StemPoolTwinAt at StemConvTwin), and the stem's parameter nodes are proved through the argmax gather they reduce to (r34StemPool_param_germ). At a tied window the render's pool backward (select_and_scatter with a GE select) sends the cotangent to the window's first maximal cell, and so does the denotation maxPool3s2BackB (its reindex reads windowArgmax, the first maximum). Every pool selector (IsMaxPool3s2SelectB) gives the same four stem gradients (r34Stem_select_grads_eq): r50_net_lossGrad_stemSelect states the stem's nodes at any of them. The probe script scripts/probes/stem_pool_smooth_probe.py checks the stem's clauses on real batches.

def Proofs.ResNet50TieB.r50IdLossTiedB {N h w mid oc : ℕ} (xN cotN vN epsStr : String) (p : R50IdW mid oc) (bf16 : Bool) (v : Vec (N * (oc * h * w))) (Φ : R50IdW mid oc → Vec 1) (dy : Vec (N * (oc * h * w))) :

Identity bottleneck, every parameter node a loss derivative. With Gn the loss read at the block's output and Φ the loss as a function of the block's weight record (hΦ), each of the nine nodes r50IdTiedB ties — at the same cotangents — is ∂Φ/∂slot with that one slot varied.

Equations
  • One or more equations did not get rendered due to their size.
Instances For
    theorem Proofs.ResNet50TieB.r50_idblock_lossTiedB {N h w mid oc : ℕ} (xN cotN vN epsStr : String) (p : R50IdW mid oc) (bf16 : Bool) (hq : R50IdPos p) (v : Vec (N * (oc * h * w))) (hs : R50IdSmoothAt N h w p v) {Gn : Vec (N * (oc * h * w)) → Vec 1} {dy : Vec (N * (oc * h * w))} (hGn : HasGradAt Gn (r50IdB N h w p v) dy) {Φ : R50IdW mid oc → Vec 1} (hΦ : ∀ (p' : R50IdW mid oc), Φ p' = Gn (r50IdB N h w p' v)) :
    r50IdLossTiedB xN cotN vN epsStr p bf16 v Φ dy
    def Proofs.ResNet50TieB.r50ProjLossTiedB {N h w ic mid oc : ℕ} (xN cotN vN epsStr : String) (p : R50ProjW ic mid oc) (bf16 : Bool) (v : Vec (N * (ic * h * w))) (Φ : R50ProjW ic mid oc → Vec 1) (dy : Vec (N * (oc * h * w))) :

    Stride-1 projection bottleneck, every parameter node a loss derivative — the twelve nodes r50ProjTiedB ties.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      theorem Proofs.ResNet50TieB.r50_projblock_lossTiedB {N h w ic mid oc : ℕ} (xN cotN vN epsStr : String) (p : R50ProjW ic mid oc) (bf16 : Bool) (hq : R50ProjPos p) (v : Vec (N * (ic * h * w))) (hs : R50ProjSmoothAt N h w p v) {Gn : Vec (N * (oc * h * w)) → Vec 1} {dy : Vec (N * (oc * h * w))} (hGn : HasGradAt Gn (r50ProjB N h w p v) dy) {Φ : R50ProjW ic mid oc → Vec 1} (hΦ : ∀ (p' : R50ProjW ic mid oc), Φ p' = Gn (r50ProjB N h w p' v)) :
      r50ProjLossTiedB xN cotN vN epsStr p bf16 v Φ dy
      def Proofs.ResNet50TieB.r50DownLossTiedB {N h w ic mid oc : ℕ} (xN cotN vN epsStr : String) (p : R50ProjW ic mid oc) (bf16 : Bool) (v : Vec (N * (ic * (2 * h) * (2 * w)))) (Φ : R50ProjW ic mid oc → Vec 1) (dy : Vec (N * (oc * h * w))) :

      Strided projection bottleneck, every parameter node a loss derivative — the twelve nodes r50DownTiedB ties: W₁ an ordinary conv node at 2h × 2w, W₂ and Wp strided.

      Equations
      • One or more equations did not get rendered due to their size.
      Instances For
        theorem Proofs.ResNet50TieB.r50_downblock_lossTiedB {N h w ic mid oc : ℕ} (xN cotN vN epsStr : String) (p : R50ProjW ic mid oc) (bf16 : Bool) (hq : R50ProjPos p) (v : Vec (N * (ic * (2 * h) * (2 * w)))) (hs : R50DownSmoothAt N h w p v) {Gn : Vec (N * (oc * h * w)) → Vec 1} {dy : Vec (N * (oc * h * w))} (hGn : HasGradAt Gn (r50DownB N h w p v) dy) {Φ : R50ProjW ic mid oc → Vec 1} (hΦ : ∀ (p' : R50ProjW ic mid oc), Φ p' = Gn (r50DownB N h w p' v)) :
        r50DownLossTiedB xN cotN vN epsStr p bf16 v Φ dy
        theorem Proofs.ResNet50TieB.r50IdB_hasGradAt_comp {N h w mid oc : ℕ} (p : R50IdW mid oc) (hq : R50IdPos p) (v : Vec (N * (oc * h * w))) (hs : R50IdSmoothAt N h w p v) {G : Vec (N * (oc * h * w)) → Vec 1} {dy : Vec (N * (oc * h * w))} (hG : HasGradAt G (r50IdB N h w p v) dy) :
        HasGradAt (fun (y : Vec (N * (oc * h * w))) => G (r50IdB N h w p y)) v (r50IdCotIn N h w p v dy)

        Pull the loss gradient back through an identity bottleneck: the certified block VJP, read at the chain's own fan-in (r50IdCotIn_eq_vjp).

        theorem Proofs.ResNet50TieB.r50ProjB_hasGradAt_comp {N h w ic mid oc : ℕ} (p : R50ProjW ic mid oc) (hq : R50ProjPos p) (v : Vec (N * (ic * h * w))) (hs : R50ProjSmoothAt N h w p v) {G : Vec (N * (oc * h * w)) → Vec 1} {dy : Vec (N * (oc * h * w))} (hG : HasGradAt G (r50ProjB N h w p v) dy) :
        HasGradAt (fun (y : Vec (N * (ic * h * w))) => G (r50ProjB N h w p y)) v (r50ProjCotIn N h w p v dy)

        …through the stride-1 projection bottleneck (r50ProjCotIn_eq_vjp).

        theorem Proofs.ResNet50TieB.r50DownB_hasGradAt_comp {N h w ic mid oc : ℕ} (p : R50ProjW ic mid oc) (hq : R50ProjPos p) (v : Vec (N * (ic * (2 * h) * (2 * w)))) (hs : R50DownSmoothAt N h w p v) {G : Vec (N * (oc * h * w)) → Vec 1} {dy : Vec (N * (oc * h * w))} (hG : HasGradAt G (r50DownB N h w p v) dy) :
        HasGradAt (fun (y : Vec (N * (ic * (2 * h) * (2 * w)))) => G (r50DownB N h w p y)) v (r50DownCotIn N h w p v dy)

        …and through the strided projection bottleneck (r50DownCotIn_eq_vjp).

        noncomputable def Proofs.ResNet50TieB.r50SufS4b2 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
        Vec (N * (2048 * q * q)) → Vec (N * nCls)

        The net after block s4b2 — the head.

        Equations
        Instances For
          noncomputable def Proofs.ResNet50TieB.r50SufS4b1 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
          Vec (N * (2048 * q * q)) → Vec (N * nCls)

          The net after block s4b1: block s4b2, then the rest.

          Equations
          Instances For
            noncomputable def Proofs.ResNet50TieB.r50SufS4b0 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
            Vec (N * (2048 * q * q)) → Vec (N * nCls)

            The net after block s4b0: block s4b1, then the rest.

            Equations
            Instances For
              noncomputable def Proofs.ResNet50TieB.r50SufS3b5 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
              Vec (N * (1024 * (2 * q) * (2 * q))) → Vec (N * nCls)

              The net after block s3b5: block s4b0, then the rest.

              Equations
              Instances For
                noncomputable def Proofs.ResNet50TieB.r50SufS3b4 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                Vec (N * (1024 * (2 * q) * (2 * q))) → Vec (N * nCls)

                The net after block s3b4: block s3b5, then the rest.

                Equations
                Instances For
                  noncomputable def Proofs.ResNet50TieB.r50SufS3b3 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                  Vec (N * (1024 * (2 * q) * (2 * q))) → Vec (N * nCls)

                  The net after block s3b3: block s3b4, then the rest.

                  Equations
                  Instances For
                    noncomputable def Proofs.ResNet50TieB.r50SufS3b2 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                    Vec (N * (1024 * (2 * q) * (2 * q))) → Vec (N * nCls)

                    The net after block s3b2: block s3b3, then the rest.

                    Equations
                    Instances For
                      noncomputable def Proofs.ResNet50TieB.r50SufS3b1 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                      Vec (N * (1024 * (2 * q) * (2 * q))) → Vec (N * nCls)

                      The net after block s3b1: block s3b2, then the rest.

                      Equations
                      Instances For
                        noncomputable def Proofs.ResNet50TieB.r50SufS3b0 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                        Vec (N * (1024 * (2 * q) * (2 * q))) → Vec (N * nCls)

                        The net after block s3b0: block s3b1, then the rest.

                        Equations
                        Instances For
                          noncomputable def Proofs.ResNet50TieB.r50SufS2b3 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                          Vec (N * (512 * (2 * (2 * q)) * (2 * (2 * q)))) → Vec (N * nCls)

                          The net after block s2b3: block s3b0, then the rest.

                          Equations
                          Instances For
                            noncomputable def Proofs.ResNet50TieB.r50SufS2b2 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                            Vec (N * (512 * (2 * (2 * q)) * (2 * (2 * q)))) → Vec (N * nCls)

                            The net after block s2b2: block s2b3, then the rest.

                            Equations
                            Instances For
                              noncomputable def Proofs.ResNet50TieB.r50SufS2b1 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                              Vec (N * (512 * (2 * (2 * q)) * (2 * (2 * q)))) → Vec (N * nCls)

                              The net after block s2b1: block s2b2, then the rest.

                              Equations
                              Instances For
                                noncomputable def Proofs.ResNet50TieB.r50SufS2b0 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                                Vec (N * (512 * (2 * (2 * q)) * (2 * (2 * q)))) → Vec (N * nCls)

                                The net after block s2b0: block s2b1, then the rest.

                                Equations
                                Instances For
                                  noncomputable def Proofs.ResNet50TieB.r50SufS1b2 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                                  Vec (N * (256 * (2 * (2 * (2 * q))) * (2 * (2 * (2 * q))))) → Vec (N * nCls)

                                  The net after block s1b2: block s2b0, then the rest.

                                  Equations
                                  Instances For
                                    noncomputable def Proofs.ResNet50TieB.r50SufS1b1 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                                    Vec (N * (256 * (2 * (2 * (2 * q))) * (2 * (2 * (2 * q))))) → Vec (N * nCls)

                                    The net after block s1b1: block s1b2, then the rest.

                                    Equations
                                    Instances For
                                      noncomputable def Proofs.ResNet50TieB.r50SufS1b0 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                                      Vec (N * (256 * (2 * (2 * (2 * q))) * (2 * (2 * (2 * q))))) → Vec (N * nCls)

                                      The net after block s1b0: block s1b1, then the rest.

                                      Equations
                                      Instances For
                                        noncomputable def Proofs.ResNet50TieB.r50SufStem (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) :
                                        Vec (N * (64 * (2 * (2 * (2 * q))) * (2 * (2 * (2 * q))))) → Vec (N * nCls)

                                        The net after the stem: block s1b0, then the rest.

                                        Equations
                                        Instances For
                                          theorem Proofs.ResNet50TieB.r50_factor_stem (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (W : Kernel4 64 3 7 7) (b γ β : Vec 64) :
                                          resnet50ForwardBFull N q { sW := W, sb := b, sε := w.sε, sγ := γ, sβ := β, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufStem N q w (r34StemB N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) W b w.sε γ β x)

                                          The net with the stem's parameters varied is the suffix after the stem at the varied stem.

                                          theorem Proofs.ResNet50TieB.r50_factor_s1b0 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50ProjW 64 64 256) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := p, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS1b0 N q w (r50ProjB N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) p (r50Pre0 N q w x))

                                          The net with block s1b0's weights varied is the suffix after s1b0 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s1b1 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50IdW 64 256) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := p, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS1b1 N q w (r50IdB N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) p (r50Pre1 N q w x))

                                          The net with block s1b1's weights varied is the suffix after s1b1 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s1b2 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50IdW 64 256) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := p, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS1b2 N q w (r50IdB N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) p (r50Pre2 N q w x))

                                          The net with block s1b2's weights varied is the suffix after s1b2 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s2b0 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50ProjW 256 128 512) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := p, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS2b0 N q w (r50DownB N (2 * (2 * q)) (2 * (2 * q)) p (r50Pre3 N q w x))

                                          The net with block s2b0's weights varied is the suffix after s2b0 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s2b1 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50IdW 128 512) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := p, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS2b1 N q w (r50IdB N (2 * (2 * q)) (2 * (2 * q)) p (r50Pre4 N q w x))

                                          The net with block s2b1's weights varied is the suffix after s2b1 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s2b2 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50IdW 128 512) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := p, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS2b2 N q w (r50IdB N (2 * (2 * q)) (2 * (2 * q)) p (r50Pre5 N q w x))

                                          The net with block s2b2's weights varied is the suffix after s2b2 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s2b3 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50IdW 128 512) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := p, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS2b3 N q w (r50IdB N (2 * (2 * q)) (2 * (2 * q)) p (r50Pre6 N q w x))

                                          The net with block s2b3's weights varied is the suffix after s2b3 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s3b0 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50ProjW 512 256 1024) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := p, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS3b0 N q w (r50DownB N (2 * q) (2 * q) p (r50Pre7 N q w x))

                                          The net with block s3b0's weights varied is the suffix after s3b0 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s3b1 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50IdW 256 1024) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := p, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS3b1 N q w (r50IdB N (2 * q) (2 * q) p (r50Pre8 N q w x))

                                          The net with block s3b1's weights varied is the suffix after s3b1 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s3b2 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50IdW 256 1024) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := p, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS3b2 N q w (r50IdB N (2 * q) (2 * q) p (r50Pre9 N q w x))

                                          The net with block s3b2's weights varied is the suffix after s3b2 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s3b3 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50IdW 256 1024) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := p, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS3b3 N q w (r50IdB N (2 * q) (2 * q) p (r50Pre10 N q w x))

                                          The net with block s3b3's weights varied is the suffix after s3b3 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s3b4 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50IdW 256 1024) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := p, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS3b4 N q w (r50IdB N (2 * q) (2 * q) p (r50Pre11 N q w x))

                                          The net with block s3b4's weights varied is the suffix after s3b4 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s3b5 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50IdW 256 1024) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := p, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS3b5 N q w (r50IdB N (2 * q) (2 * q) p (r50Pre12 N q w x))

                                          The net with block s3b5's weights varied is the suffix after s3b5 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s4b0 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50ProjW 1024 512 2048) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := p, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS4b0 N q w (r50DownB N q q p (r50Pre13 N q w x))

                                          The net with block s4b0's weights varied is the suffix after s4b0 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s4b1 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50IdW 512 2048) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := p, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x = r50SufS4b1 N q w (r50IdB N q q p (r50Pre14 N q w x))

                                          The net with block s4b1's weights varied is the suffix after s4b1 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_s4b2 (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (p : R50IdW 512 2048) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := p, Wd := w.Wd, bd := w.bd } x = r50SufS4b2 N q w (r50IdB N q q p (r50Pre15 N q w x))

                                          The net with block s4b2's weights varied is the suffix after s4b2 at the varied block.

                                          theorem Proofs.ResNet50TieB.r50_factor_head (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (W : Mat 2048 nCls) (b : Vec nCls) :
                                          resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := W, bd := b } x = r34HeadB N q q W b (r50Pre16 N q w x)

                                          The net with the classifier varied is the head at the varied classifier.

                                          def Proofs.ResNet50TieB.R50NetLossTiedB (N q : ℕ) {nCls : ℕ} (xN cotN vN epsStr : String) (w : R50BWeights nCls) (bf16 : Bool) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (L : Vec (N * nCls) → Vec 1) (g : Vec (N * nCls)) :

                                          Every ResNet-50 parameter gradient node is the derivative of L in that parameter, for a loss L of the logits and g the cotangent the chain starts from: the 161 nodes r50_net_tiedB ties, each at the cotangent the emitted chain threads to it, stated against L of resnet50ForwardBFull with that one parameter varied. r50_net_lossGrad proves it whenever g is L's gradient at the logits; the two losses the artifacts ship instantiate it.

                                          Equations
                                          • One or more equations did not get rendered due to their size.
                                          Instances For
                                            structure Proofs.ResNet50TieB.R50LossSmoothAtB (N q : ℕ) {nCls : ℕ} (w : R50BWeights nCls) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) :

                                            The smooth-point bundle a loss gradient needs — R50SmoothAtB with the stem pool's clause weakened to allow ties between cells that read identical input patches, as ResNet34TieB.R34LossSmoothAtB does for ResNet-34 (whose stem this is).

                                            Instances For
                                              theorem Proofs.ResNet50TieB.r50LossSmoothAtB_of_smoothAtB {N q nCls : ℕ} {w : R50BWeights nCls} {x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))} (hx : R50SmoothAtB N q w x) :

                                              The input-VJP bundle implies the loss-gradient one.

                                              theorem Proofs.ResNet50TieB.r50_net_lossGrad (N q : ℕ) {nCls : ℕ} (xN cotN vN epsStr : String) (w : R50BWeights nCls) (hp : R50PosB w) (bf16 : Bool) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (hx : R50LossSmoothAtB N q w x) {L : Vec (N * nCls) → Vec 1} {g : Vec (N * nCls)} (hL : HasGradAt L (resnet50ForwardBFull N q w x) g) :
                                              R50NetLossTiedB N q xN cotN vN epsStr w bf16 x L g

                                              Every ResNet-50 parameter gradient node is the derivative of the loss in that parameter. For any loss L of the logits with gradient g at the net's output, each of the 161 nodes r50_net_tiedB ties — at the same cotangent — is ∂L/∂θ of the WHOLE net, resnet50ForwardBFull with that one parameter varied (a stem field, a block's weight record w.blk := p with one slot changed, or the classifier).

                                              Hypotheses: every BN ε positive (R50PosB), every relu off its kink and every stem-pool window dead or tied only between cells reading identical input patches, at the real activations (R50LossSmoothAtB). The loss enters only through hL; r50_net_lossGrad_smoothedCE and r50_net_lossGrad_bce discharge it for the two losses the artifacts ship. The nodes are the f32 ones on one replica (the module's Scope).

                                              theorem Proofs.ResNet50TieB.r50_net_lossGrad_stemSelect (N q : ℕ) {nCls : ℕ} (xN cotN vN epsStr : String) (w : R50BWeights nCls) (hp : R50PosB w) (bf16 : Bool) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (hx : R50LossSmoothAtB N q w x) {L : Vec (N * nCls) → Vec 1} {g : Vec (N * nCls)} (hL : HasGradAt L (resnet50ForwardBFull N q w x) g) (σ : Fin (N * (64 * (2 * (2 * (2 * q))) * (2 * (2 * (2 * q))))) → Fin (N * (64 * (2 * (2 * (2 * (2 * q)))) * (2 * (2 * (2 * (2 * q))))))) (hσ : IsMaxPool3s2SelectB N 64 (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) (StableHLO.cbReluStridedB N w.sW w.sb w.sε w.sγ w.sβ x) σ) :
                                              have dy16 := ResNet34TieB.r34HeadCotBlk N q q w.Wd w.bd (r50Pre16 N q w x) g; have dy15 := r50IdCotIn N q q w.s4b2 (r50Pre15 N q w x) dy16; have dy14 := r50IdCotIn N q q w.s4b1 (r50Pre14 N q w x) dy15; have dy13 := r50DownCotIn N q q w.s4b0 (r50Pre13 N q w x) dy14; have dy12 := r50IdCotIn N (2 * q) (2 * q) w.s3b5 (r50Pre12 N q w x) dy13; have dy11 := r50IdCotIn N (2 * q) (2 * q) w.s3b4 (r50Pre11 N q w x) dy12; have dy10 := r50IdCotIn N (2 * q) (2 * q) w.s3b3 (r50Pre10 N q w x) dy11; have dy9 := r50IdCotIn N (2 * q) (2 * q) w.s3b2 (r50Pre9 N q w x) dy10; have dy8 := r50IdCotIn N (2 * q) (2 * q) w.s3b1 (r50Pre8 N q w x) dy9; have dy7 := r50DownCotIn N (2 * q) (2 * q) w.s3b0 (r50Pre7 N q w x) dy8; have dy6 := r50IdCotIn N (2 * (2 * q)) (2 * (2 * q)) w.s2b3 (r50Pre6 N q w x) dy7; have dy5 := r50IdCotIn N (2 * (2 * q)) (2 * (2 * q)) w.s2b2 (r50Pre5 N q w x) dy6; have dy4 := r50IdCotIn N (2 * (2 * q)) (2 * (2 * q)) w.s2b1 (r50Pre4 N q w x) dy5; have dy3 := r50DownCotIn N (2 * (2 * q)) (2 * (2 * q)) w.s2b0 (r50Pre3 N q w x) dy4; have dy2 := r50IdCotIn N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) w.s1b2 (r50Pre2 N q w x) dy3; have dy1 := r50IdCotIn N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) w.s1b1 (r50Pre1 N q w x) dy2; have cotPool := r50ProjCotIn N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) w.s1b0 (r50Pre0 N q w x) dy1; ResNet34TieB.r34StemLossTiedAtB xN cotN vN epsStr w.sW w.sb w.sε w.sγ w.sβ bf16 x (fun (W : Kernel4 64 3 7 7) (b γ β : Vec 64) => L (resnet50ForwardBFull N q { sW := W, sb := b, sε := w.sε, sγ := γ, sβ := β, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) (ResNet34TieB.r34StemCotCAt σ w.sW w.sb w.sε w.sγ w.sβ x cotPool) (ResNet34TieB.r34StemCotNAt σ w.sW w.sb w.sε w.sγ w.sβ x cotPool)

                                              The stem's gradient nodes at the render's own pool routing — r50_net_lossGrad's stem bundle read at the cotangents routed along ANY pool selector σ at the stem's post-ReLU activation, the emitted select_and_scatter among them (r34StemLossTiedB.select; the R50 stem is R34's, see ResNet34TieB.r34_net_lossGrad_stemSelect).

                                              theorem Proofs.ResNet50TieB.r50_net_lossGrad_smoothedCE (N q : ℕ) {nCls : ℕ} (hK : 0 < nCls) (xN cotN vN epsStr aStr negAK bStr logN ohN : String) (α B : ℝ) (w : R50BWeights nCls) (hp : R50PosB w) (bf16 : Bool) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (hx : R50LossSmoothAtB N q w x) (t : Vec (N * (1 * nCls))) (ht : ∀ (n : Fin N), ∑ k : Fin nCls, targetRow N nCls t n k = 1) :
                                              R50NetLossTiedB N q xN cotN vN epsStr w bf16 x (smoothedBatchLoss N nCls α B t) (BackLinks.unrowB N nCls (StableHLO.den (smoothedLossCotGraph N nCls α B aStr negAK bStr logN ohN (BackLinks.rowB N nCls (resnet50ForwardBFull N q w x)) t)))

                                              The bce := false artifacts: every node is the derivative of the batched label-smoothed cross-entropy smoothedBatchLoss, g the six-op cotangent the render emits.

                                              theorem Proofs.ResNet50TieB.r50_net_lossGrad_bce (N q : ℕ) {nCls : ℕ} (xN cotN vN epsStr bStr logN ohN : String) (w : R50BWeights nCls) (hp : R50PosB w) (bf16 : Bool) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (hx : R50LossSmoothAtB N q w x) (t : Vec (N * (1 * nCls))) :
                                              R50NetLossTiedB N q xN cotN vN epsStr w bf16 x (bceBatchLoss N nCls t) (BackLinks.unrowB N nCls (StableHLO.den (bceLossCotGraph N nCls (↑N * ↑nCls) bStr logN ohN (BackLinks.rowB N nCls (resnet50ForwardBFull N q w x)) t)))

                                              The bce := true artifacts (resnet50in160_lambaccdp8x64wxclipbce among them): every node is the derivative of the batched BCE-with-logits bceBatchLoss, the mean over B×K, g the three-op cotangent at the committed divisor N·K. No hypothesis on the target.

                                              theorem Proofs.ResNet50TieB.r50_net_tied_lossGrad (N q : ℕ) {nCls : ℕ} (xN cotN vN epsStr : String) (w : R50BWeights nCls) (bf16 : Bool) (x : Vec (N * (3 * (2 * (2 * (2 * (2 * (2 * q))))) * (2 * (2 * (2 * (2 * (2 * q)))))))) (g : Vec (N * nCls)) (hp : R50PosB w) (hx : R50LossSmoothAtB N q w x) {L : Vec (N * nCls) → Vec 1} (hL : HasGradAt L (resnet50ForwardBFull N q w x) g) :
                                              have dy16 := ResNet34TieB.r34HeadCotBlk N q q w.Wd w.bd (r50Pre16 N q w x) g; have dy15 := r50IdCotIn N q q w.s4b2 (r50Pre15 N q w x) dy16; have dy14 := r50IdCotIn N q q w.s4b1 (r50Pre14 N q w x) dy15; have dy13 := r50DownCotIn N q q w.s4b0 (r50Pre13 N q w x) dy14; have dy12 := r50IdCotIn N (2 * q) (2 * q) w.s3b5 (r50Pre12 N q w x) dy13; have dy11 := r50IdCotIn N (2 * q) (2 * q) w.s3b4 (r50Pre11 N q w x) dy12; have dy10 := r50IdCotIn N (2 * q) (2 * q) w.s3b3 (r50Pre10 N q w x) dy11; have dy9 := r50IdCotIn N (2 * q) (2 * q) w.s3b2 (r50Pre9 N q w x) dy10; have dy8 := r50IdCotIn N (2 * q) (2 * q) w.s3b1 (r50Pre8 N q w x) dy9; have dy7 := r50DownCotIn N (2 * q) (2 * q) w.s3b0 (r50Pre7 N q w x) dy8; have dy6 := r50IdCotIn N (2 * (2 * q)) (2 * (2 * q)) w.s2b3 (r50Pre6 N q w x) dy7; have dy5 := r50IdCotIn N (2 * (2 * q)) (2 * (2 * q)) w.s2b2 (r50Pre5 N q w x) dy6; have dy4 := r50IdCotIn N (2 * (2 * q)) (2 * (2 * q)) w.s2b1 (r50Pre4 N q w x) dy5; have dy3 := r50DownCotIn N (2 * (2 * q)) (2 * (2 * q)) w.s2b0 (r50Pre3 N q w x) dy4; have dy2 := r50IdCotIn N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) w.s1b2 (r50Pre2 N q w x) dy3; have dy1 := r50IdCotIn N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) w.s1b1 (r50Pre1 N q w x) dy2; have cotPool := r50ProjCotIn N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) w.s1b0 (r50Pre0 N q w x) dy1; (ResNet34TieB.r34StemTiedB N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) xN cotN vN epsStr w.sW w.sb w.sε w.sγ w.sβ bf16 x cotPool ∧ ResNet34TieB.r34StemLossTiedB xN cotN vN epsStr w.sW w.sb w.sε w.sγ w.sβ bf16 x (fun (W : Kernel4 64 3 7 7) (b γ β : Vec 64) => L (resnet50ForwardBFull N q { sW := W, sb := b, sε := w.sε, sγ := γ, sβ := β, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) cotPool) ∧ (r50ProjTiedB N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) xN cotN vN epsStr w.s1b0 bf16 (r50Pre0 N q w x) dy1 ∧ r50ProjLossTiedB xN cotN vN epsStr w.s1b0 bf16 (r50Pre0 N q w x) (fun (p : R50ProjW 64 64 256) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := p, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy1) ∧ (r50IdTiedB N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) xN cotN vN epsStr w.s1b1 bf16 (r50Pre1 N q w x) dy2 ∧ r50IdLossTiedB xN cotN vN epsStr w.s1b1 bf16 (r50Pre1 N q w x) (fun (p : R50IdW 64 256) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := p, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy2) ∧ (r50IdTiedB N (2 * (2 * (2 * q))) (2 * (2 * (2 * q))) xN cotN vN epsStr w.s1b2 bf16 (r50Pre2 N q w x) dy3 ∧ r50IdLossTiedB xN cotN vN epsStr w.s1b2 bf16 (r50Pre2 N q w x) (fun (p : R50IdW 64 256) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := p, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy3) ∧ (r50DownTiedB N (2 * (2 * q)) (2 * (2 * q)) xN cotN vN epsStr w.s2b0 bf16 (r50Pre3 N q w x) dy4 ∧ r50DownLossTiedB xN cotN vN epsStr w.s2b0 bf16 (r50Pre3 N q w x) (fun (p : R50ProjW 256 128 512) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := p, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy4) ∧ (r50IdTiedB N (2 * (2 * q)) (2 * (2 * q)) xN cotN vN epsStr w.s2b1 bf16 (r50Pre4 N q w x) dy5 ∧ r50IdLossTiedB xN cotN vN epsStr w.s2b1 bf16 (r50Pre4 N q w x) (fun (p : R50IdW 128 512) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := p, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy5) ∧ (r50IdTiedB N (2 * (2 * q)) (2 * (2 * q)) xN cotN vN epsStr w.s2b2 bf16 (r50Pre5 N q w x) dy6 ∧ r50IdLossTiedB xN cotN vN epsStr w.s2b2 bf16 (r50Pre5 N q w x) (fun (p : R50IdW 128 512) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := p, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy6) ∧ (r50IdTiedB N (2 * (2 * q)) (2 * (2 * q)) xN cotN vN epsStr w.s2b3 bf16 (r50Pre6 N q w x) dy7 ∧ r50IdLossTiedB xN cotN vN epsStr w.s2b3 bf16 (r50Pre6 N q w x) (fun (p : R50IdW 128 512) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := p, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy7) ∧ (r50DownTiedB N (2 * q) (2 * q) xN cotN vN epsStr w.s3b0 bf16 (r50Pre7 N q w x) dy8 ∧ r50DownLossTiedB xN cotN vN epsStr w.s3b0 bf16 (r50Pre7 N q w x) (fun (p : R50ProjW 512 256 1024) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := p, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy8) ∧ (r50IdTiedB N (2 * q) (2 * q) xN cotN vN epsStr w.s3b1 bf16 (r50Pre8 N q w x) dy9 ∧ r50IdLossTiedB xN cotN vN epsStr w.s3b1 bf16 (r50Pre8 N q w x) (fun (p : R50IdW 256 1024) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := p, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy9) ∧ (r50IdTiedB N (2 * q) (2 * q) xN cotN vN epsStr w.s3b2 bf16 (r50Pre9 N q w x) dy10 ∧ r50IdLossTiedB xN cotN vN epsStr w.s3b2 bf16 (r50Pre9 N q w x) (fun (p : R50IdW 256 1024) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := p, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy10) ∧ (r50IdTiedB N (2 * q) (2 * q) xN cotN vN epsStr w.s3b3 bf16 (r50Pre10 N q w x) dy11 ∧ r50IdLossTiedB xN cotN vN epsStr w.s3b3 bf16 (r50Pre10 N q w x) (fun (p : R50IdW 256 1024) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := p, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy11) ∧ (r50IdTiedB N (2 * q) (2 * q) xN cotN vN epsStr w.s3b4 bf16 (r50Pre11 N q w x) dy12 ∧ r50IdLossTiedB xN cotN vN epsStr w.s3b4 bf16 (r50Pre11 N q w x) (fun (p : R50IdW 256 1024) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := p, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy12) ∧ (r50IdTiedB N (2 * q) (2 * q) xN cotN vN epsStr w.s3b5 bf16 (r50Pre12 N q w x) dy13 ∧ r50IdLossTiedB xN cotN vN epsStr w.s3b5 bf16 (r50Pre12 N q w x) (fun (p : R50IdW 256 1024) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := p, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy13) ∧ (r50DownTiedB N q q xN cotN vN epsStr w.s4b0 bf16 (r50Pre13 N q w x) dy14 ∧ r50DownLossTiedB xN cotN vN epsStr w.s4b0 bf16 (r50Pre13 N q w x) (fun (p : R50ProjW 1024 512 2048) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := p, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy14) ∧ (r50IdTiedB N q q xN cotN vN epsStr w.s4b1 bf16 (r50Pre14 N q w x) dy15 ∧ r50IdLossTiedB xN cotN vN epsStr w.s4b1 bf16 (r50Pre14 N q w x) (fun (p : R50IdW 512 2048) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := p, s4b2 := w.s4b2, Wd := w.Wd, bd := w.bd } x)) dy15) ∧ (r50IdTiedB N q q xN cotN vN epsStr w.s4b2 bf16 (r50Pre15 N q w x) dy16 ∧ r50IdLossTiedB xN cotN vN epsStr w.s4b2 bf16 (r50Pre15 N q w x) (fun (p : R50IdW 512 2048) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := p, Wd := w.Wd, bd := w.bd } x)) dy16) ∧ ResNet34TieB.r34HeadTiedB N q q xN cotN w.Wd w.bd (r50Pre16 N q w x) g ∧ ResNet34TieB.r34HeadLossTiedB xN cotN w.Wd w.bd (r50Pre16 N q w x) (fun (W : Mat 2048 nCls) (b : Vec nCls) => L (resnet50ForwardBFull N q { sW := w.sW, sb := w.sb, sε := w.sε, sγ := w.sγ, sβ := w.sβ, s1b0 := w.s1b0, s1b1 := w.s1b1, s1b2 := w.s1b2, s2b0 := w.s2b0, s2b1 := w.s2b1, s2b2 := w.s2b2, s2b3 := w.s2b3, s3b0 := w.s3b0, s3b1 := w.s3b1, s3b2 := w.s3b2, s3b3 := w.s3b3, s3b4 := w.s3b4, s3b5 := w.s3b5, s4b0 := w.s4b0, s4b1 := w.s4b1, s4b2 := w.s4b2, Wd := W, bd := b } x)) g

                                              The emitted ResNet-50 step's gradient nodes ARE the loss's gradient, at one chain. For each of the 161 parameter slots, at ONE cotangent chain (the tie's own, from g): the node denotes its layer's Jacobian against the chain cotangent (r50_net_tiedB), and any loss L of the logits with gradient g at the network's output of resnet50ForwardBFull with that one slot varied is differentiable there with the node as its gradient (r50_net_lossGrad). The two theorems each state the chain; this one states it once, so an edit to either chain breaks its proof.