Skip to content

Norm ​

norm.batch_norm ​

batch_norm eval mode: (x − μ)/√(σ²+ε)·γ+β per channel, spelled

exactly as the Rust impl — g = γ·(1/√(σ²+ε)), shift = β − μ·g, out = x·g + shift — so the f64 expression tree matches bit-for-bit, not just mathematically. eps is null/absent → 1e-5. input [N, C, H, W]; gamma/beta/mean/var rank-1 [C].

Signature: norm.batch_norm((input, gamma, beta, mean, var, ...rest))

norm.batch_norm_backward ​

tensor.batch_norm_backward — the adjoint DERIV_PAIRS registers

for tensor.batch_norm: primal args + upstream grad_out → {"input": dx, "gamma": dγ, "beta": dβ}. Per channel, with inv_std = 1/√(σ²+ε), scale = γ·inv_std, x̂ = (x−μ)·inv_std: dβ += g, dγ += g·x̂, dx = g·scale (sums over batch+spatial).

Signature: norm.batch_norm_backward((input, gamma, beta, mean, var, grad_out, ...rest))

norm.derive ​

tensor.derive — the registered-pairs table, not autodiff: the

adjoint op name for name, or null. A bare local name qualifies to tensor.<name>; eleven pairs are registered — the elementwise four, matmul, conv2d, max_pool, reshape, transpose, concat, and batch_norm — mirroring DERIV_PAIRS in host-tensor's ops/derive.rs. (A non-string argument flows through as null here — the host op raises a TypeMismatch instead; the divergence is documented.)

Signature: norm.derive((name))