Closing the ConvNeXt render — the parameter-gradient close (two small new families) #
planning/archive/convnext_close.md Item C, applied to the representative 2-block ConvNeXt
(tests/TestConvNeXtTrain.lean; convNextForward, the proven whole-net VJP convnext_has_vjp).
The close is generic in the cotangent dy the backward chain delivers at each layer's output
(pinning that cotangent to the actual block chain is the optional Item D), batch-1 — LayerNorm is
per-example separable, so no batched apparatus (the EfficientNet contrast).
| family (render SSA) | forward fn | certified by |
|---|---|---|
| stem/expand/project 1×1 conv W/b | conv2d (stride 1) | cnn_render_conv{W,b}_certified (M3, reuse) |
| depthwise 7×7 W/b | depthwiseConv2d | cnx_render_dw7{W,b}_certified (kernel-general — pinned below) |
dense head Wd/bd | matmul / +bias | M2 weight/bias_grad_bridge (reuse) |
layer-scale γ (layerScaleF) | γ ⊙ x | cnx_render_lsgamma_certified (new): ∂(γⱼxⱼ)/∂γᵢ = xᵢδᵢⱼ ⇒ dγ = x ⊙ dy |
scalar-LN γ/β (the bnF sites) | layerNormForward | cnx_render_ln{gamma,beta}_certified (new): the Vec 1 embedding |
| gelu | — | no parameters |
Two genuinely-new bridge families:
- Layer-scale
γ—layerScale γ x = γ ⊙ xis symmetric in(γ, x), so the γ-Jacobian is the same diagonal as the input-Jacobian with the roles swapped:∂(γⱼxⱼ)/∂γᵢ = xᵢ·δᵢⱼ(pdiv_layerScale_gamma, the mirror ofpdiv_layerScale), giving the rendereddγ = x ⊙ dy. - Scalar-LN
γ/β— the proof's LayerNorm (layerNormForward = bnForward) has scalarγ β : ℝ, andBatchNorm.leandeliberately leftbn_grad_gamma/bn_grad_betaas definitions ("scalar params don't fit thepdiv/HasVJPframework cleanly"). This file closes that gap by embedding the scalar asVec 1: as a function ofγ' : Vec 1, LN is affine —γ' ↦ fun k => x̂ₖ · γ'(0) + β— so its Jacobian collapses throughpdiv_add/pdiv_mul/pdiv_const/pdiv_reindex(theCifarBnCloserecipe with the constant channel mapFin n → Fin 1) to∂yₖ/∂γ = x̂ₖ(resp.1for β), certifying the rendered whole-nreducesdγ = Σ dy·x̂,dβ = Σ dy(bn_grad_gamma/bn_grad_beta— now bridged, not just defined). Affine in the params, so no0 < εneeded (ε only enters the constant x̂).
The 7×7 depthwise is the only kernel size to pin (prior nets used 3×3/5×5; the generic
mnv2_render_depthwise{W,b}_certified is kernel-general — stride-1 only, ConvNeXt blocks don't
downsample). The 1×1 convs (stem/expand/project) and the dense head are verbatim M3/M2 reuse at the
ConvNeXt shapes. 3-axiom clean by inheritance.
7×7 depthwise weight output, certified. The generic depthwise weight bridge at kH=kW=7;
covers every ConvNeXt block's depthwise (stride-1 — ConvNeXt blocks keep resolution).
7×7 depthwise bias output, certified.
The rendered layer-scale γ gradient: dγ_i = x_i · dy_i (elementwise multiply of the
saved layer input with the cotangent — the layerScaleF-shaped backward).
Equations
- Proofs.layerScale_grad_gamma x dy i = x i * dy i
Instances For
Layer-scale γ-gradient bridge. The rendered dγ = x ⊙ dy equals the certified Jacobian
of layerScale (as a function of γ) contracted with the cotangent dy.
Layer-scale γ output, certified. γⁿ = γ − lr·(x ⊙ dy) denotes
γ − lr·(certified ∂(layerScale)/∂γ · cotangent). The multiplicative-bias peer of
cnn_render_convb_certified.
Scalar-LN γ-gradient bridge. The rendered whole-n reduce dγ = Σ_j dy_j·x̂_j
(bn_grad_gamma) equals the certified Jacobian of scalar-LN (as a function of γ, embedded
Vec 1) contracted with the cotangent dy. Closes the gap BatchNorm.lean documented —
bn_grad_gamma is now bridged, not just defined.
Scalar-LN β-gradient bridge. Likewise the rendered dβ = Σ_j dy_j (bn_grad_beta) is
the certified scalar-LN ∂/∂β contraction.
Scalar-LN γ output, certified. γⁿ = γ − lr·(Σ dy·x̂) denotes
γ − lr·(certified ∂(layerNormForward)/∂γ · cotangent). Covers the stem-LN, both block-LNs,
and the head-LN of the representative ConvNeXt (each at its own n).