The full ConvNeXt-T — [3,3,9,3], forward + whole-net VJP + graph + faithfulness #
The real ConvNeXt-T spec, beside the two-block scalar-LN net of ConvNeXt.lean:
4×4/s4 patchify stem (3→96, 224→56) → stem-LN → stage1 (3 blocks @96/56²) → downsample (LN + 2×2/s2 conv 96→192) → stage2 (3 @192/28²) → ds (192→384) → stage3 (9 @384/14²) → ds (384→768) → stage4 (3 @768/7²) → GAP → head LN → dense.
- Depth-k within a stage —
CnxBlockParamsChbundles the block 10-tuple;convNextStageChK (k) (ps : Fin k → CnxBlockParamsCh …)folds blocks head-first with VJP by induction — the ViT depth-k recipe, simpler here (same-shape blocks within a stage). - Downsample boundaries —
cnxDownChW=flatConvStride2(2×2) ∘ channel-LN; both VJPs existed. - 4×4/s4 patchify stem —
flatConvStride4(= decimate ∘ decimateOdd ∘ stride-1 SAME conv,StridedConv.lean: the left-aligned windowx[4i..4i+3]of the paper's pad-0Conv2d(4, s=4)) + the.flatConvStride4Fgraph node.
GELU/LN/conv are smooth, so the whole-net VJP convNextForwardTChHasVJP is global, under the 23
LN positivities (1 stem + 18 block + 3 downsample + head) and no other hypothesis — as are
efficientnetForwardBFullHasVJP and vitForwardKVHasVJP. The ConvNeXtFold/ConvNeXtChainClose
param bridges are dim-generic and cover all 18 blocks verbatim; the downsample conv W/b reuse the
proven stride-2 bridges.
References #
- Liu et al. 2022, A ConvNet for the 2020s (ConvNeXt). https://arxiv.org/abs/2201.03545
ConvNeXt specifies channel_layer_norm — h·w statistics per example, each over the c
channels at one spatial position, per-channel [c] affine. See ChannelLN.lean for the
primitive and for why Route A needs no new op and no new VJP.
The two-block scalar-LN net in ConvNeXt.lean (convNextForward, convNextBlock,
convNextBlockBody) is a different net: it backs the comparator and a book chapter. The LN
sites here are 1 stem + 18 block + 3 downsample (all channel-LN) + the head LN after GAP.
The ConvNeXt block body with the LN left as a parameter. Written once and instantiated at
chanLNTensor3, so the channel-LN world costs one definition rather than a second copy of
convNextBlockBody's six-piece vjpComp chain.
Equations
- Proofs.cnxBodyWith gf LN Wdw bdw Wex bex Wpr bpr γls = Proofs.layerScale γls ∘ Proofs.flatConv Wpr bpr ∘ gf.map (cExp * h * w) ∘ Proofs.flatConv Wex bex ∘ LN ∘ Proofs.depthwiseFlat Wdw bdw
Instances For
The body VJP, given the LN's. Only the LN carries a hypothesis — gelu is smooth and
conv/layerScale are linear, so this is global exactly as convNextBlockBodyHasVJP is.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The per-channel layer-scale expanded to the flat map.
Equations
- Proofs.cnxGlsCh p k = p.γls (Proofs.StableHLO.chanIdx c h w k)
Instances For
The packaged ConvNeXt block: residual of the shared body at chanLNTensor3.
Equations
- Proofs.cnxBlockChW gf p = Proofs.residual (Proofs.cnxBodyWith gf (Proofs.chanLNTensor3 c h w p.εn p.γn p.βn) p.Wdw p.bdw p.Wex p.bex p.Wpr p.bpr (Proofs.cnxGlsCh p))
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Depth-k channel-LN stage fold (head recursion — block 0 runs first).
Equations
- Proofs.convNextStageChK gf 0 x_2 = fun (v : Proofs.Vec (c * h * w)) => v
- Proofs.convNextStageChK gf k.succ ps = (Proofs.convNextStageChK gf k fun (i : Fin k) => ps i.succ) ∘ Proofs.cnxBlockChW gf (ps 0)
Instances For
A three-block stage, unrolled.
A nine-block stage, unrolled.
Equations
- One or more equations did not get rendered due to their size.
- Proofs.convNextStageChKHasVJP gf 0 x_3 x_4 = Proofs.identityHasVJP (c * h * w)
Instances For
Stage-boundary downsample: 2×2/s2 conv ∘ channel-LN (cin@2h×2w → cout@h×w).
Equations
- Proofs.cnxDownChW h w p = Proofs.flatConvStride2 p.W p.b ∘ Proofs.chanLNTensor3 cin (2 * h) (2 * w) p.ε p.γ p.β
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
All ConvNeXt-T parameters. Every LN affine is a Vec, and BOTH the stem LN (sγ/sβ : Vec 96) and the head LN (hγ/hβ : Vec 768) are present — the paper's forward is
patchify → channel_layer_norm → stages → GAP → LN → dense. The official implementation and
timm both have the stem and head LNs:
facebookresearch/ConvNeXt does self.norm(x.mean([-2,-1])) with
nn.LayerNorm(dims[-1], eps=1e-6), and timm's convnext_tiny head is
NormMlpClassifierHead(global_pool → LayerNorm2d(768) → flatten → fc).
- sW : Kernel4 96 3 4 4
- sb : Vec 96
- sε : ℝ
- sγ : Vec 96
- sβ : Vec 96
- s1 : Fin 3 → CnxBlockParamsCh 96 384 56 56 7 7
- d1 : CnxDownParamsCh 96 192
- s2 : Fin 3 → CnxBlockParamsCh 192 768 28 28 7 7
- d2 : CnxDownParamsCh 192 384
- s3 : Fin 9 → CnxBlockParamsCh 384 1536 14 14 7 7
- d3 : CnxDownParamsCh 384 768
- s4 : Fin 3 → CnxBlockParamsCh 768 3072 7 7 7 7
- hε : ℝ
Head LayerNorm, between GAP and the classifier: ε, then the
Vec 768affine. PlainlayerNormVec, notchanLNTensor3: after GAP the tensor is[768], one row, so the channel LN and the vector LN are the same function and this is the cheaper spelling — it is alsorowLNVecFlat 1 768, i.e. ViT's per-token LN at one row, whoserowLNVecFlat_differentiableandHasVJPare already proven and whose graph mirror isrowLN_affine_eq. - hγ : Vec 768
- hβ : Vec 768
- Wd : Mat 768 nC
- bd : Vec nC
Instances For
The channel-LN ConvNeXt-T forward (3×224² → nC). Nested-application form, so the graph
faithfulness convNextFwdGraphTCh_faithful closes stage by stage. nC is a binder: the
Imagenette artifacts run it at 10 and the convnextin_* ImageNet artifacts at 1000. It has no
drop-path; the *drop* artifacts compute another function.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The channel-LN ConvNeXt-T has a (correct) VJP — at every input. 23 LayerNorm
positivities: stem + 18 blocks (via the per-stage ∀ i) + 3 downsamples + the head LN,
which this statement composes as rowLNVecFlat 1 768 w.hε w.hγ w.hβ and takes hhε for.
Chain-stated to keep the blocks opaque.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The chain is differentiable everywhere (the 23 LayerNorm positivities only) — the
Differentiable peer of convNextForwardTChHasVJP, on the same twelve-factor chain, which
batchMapHasVJP asks for beside the HasVJP when the net is lifted over a batch
(ConvNeXtWholeBackCertifiedTieB.lean).
The nested↔chain bridge: convNextForwardTCh w x equals the twelve-factor ∘ chain
convNextForwardTChHasVJP is stated on.
Correctness on convNextForwardTCh itself (via the bridge).
One channel-LN forward site, mirroring cnxLnFwdSite at chLN := true
op-for-op: transpose to [h·w, c], normalise each spatial row over its channels at the
scalar identities %one/%zero, apply the real [c] affine, transpose back. The two
transports are the reassoc / unassoc casts the render uses; den_reassocS
(ConvNeXtChannelLN.lean) is what makes them the math's Mat-split bridge.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The head LN forward site — the paper's norm(x.mean([-2,-1])).
It is chanLNGraph with the transposes deleted, and that is not a shortcut: after GAP the
tensor is a single [768] row, so "normalise each spatial row over its channels" and
"normalise the feature vector" are the same function — m = 1. The render emits exactly these
three ops, which is what makes cnxHeadLnFwdSite a mirror rather than a peer.
Note: indexed SHlo (1 * c); c is the literal 768 at every call site, so 1 * c reduces
and no transport is needed. Do not generalise c to a variable without adding one — that is the
trap convNextBackAll's Vec (1 * nClasses) annotations already record.
Equations
- Proofs.StableHLO.headLNGraph gN btN epsStr ε γ β e = Proofs.StableHLO.SHlo.rowBiasF btN β (Proofs.StableHLO.SHlo.rowScaleF gN γ (Proofs.StableHLO.SHlo.lnRowF "%one" "%zero" epsStr ε 1 0 e))
Instances For
The ConvNeXt block graph — the [3,3,9,3] block segment, with chanLNGraph at its LN
site.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Depth-k channel-LN stage graph fold — block base+1 first, prefixes b{base+1}_.
Equations
- One or more equations did not get rendered due to their size.
- Proofs.StableHLO.cnxStageChGraphK gf epsStr x✝¹ 0 x_5 x✝ = x✝
Instances For
Channel-LN downsample graph: channel-LN → 2×2/s2 widening conv.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The channel-LN ConvNeXt-T forward graph (3×224² → nC): patchify stem → stem
channel-LN → the [3,3,9,3] stages with 3 channel-LN + 2×2/s2 downsample boundaries →
GAP → head LN → dense. 23 LN sites: 1 stem + 18 block + 3 downsample + head.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Channel-LN forward faithfulness — the [3,3,9,3] channel-LN graph denotes
convNextForwardTCh. One rw per stage: cnxStageChGraphK_den / cnxDownChGraphW_faithful
at the stages and downsamples, chanLNGraph_faithful at the stem LN and headLNGraph_faithful
at the head.