COE 592Lecture 02Part 05
Batch, layer, instance and group normalization
Why nicely scaled activations make optimization easier, how batch normalization computes, scales and shifts, how it changes at inference, and the axes each normalization variant averages over.
- Concepts
- 5
- Slides
- 27-38
- Reading
- 30 min
Why this part matters
Every network you will compress, quantize or deploy in this course carries normalization layers. Batch normalization is a large part of why deep CNNs train at all, and it is also the first optimization you get for free on a microcontroller: at inference it folds into the layer before it and costs nothing.
This part builds the normalization family from one question: which numbers are averaged together to make one mean? Answer it for the batch axis and you have batch norm; answer it for the feature axis and you have layer norm, the block inside every transformer in part 06. Along the way you meet the exam staples of this lecture: tensor shapes, the train versus test difference, fusing BN into a linear layer, and computing BN on a tiny batch by hand.
By the end you can
- Explain why uncentered or unevenly scaled inputs make y = Wx hard to optimize.
- Write the batch norm transform with the shape of every tensor and say which parts are learned.
- State why BN differs between training and inference and derive the fused W' and b'.
- Name the axes each of BN, LN, IN and GN averages over and read off the resulting mu shape.
- Compute BN on a small mini-batch by hand and self-check with mean = beta and variance = gamma squared.
Feed a linear layer y = Wx two raw features: a pixel intensity somewhere in 0 to 255 and a binary flag in 0 to 1. For both features to have a similar influence on y, the two corresponding entries of W must differ by about two orders of magnitude. And because neither feature is centered at zero, the layer needs a large Bias just to bring its outputs near zero, where the next activation function does useful work.
Those are the two troubles every layer faces. Inputs that are not centered force a large bias, and inputs with different scales per element force the entries of W to vary a lot. Both make gradient descent slow, because one learning rate has to serve directions of very different steepness, so the update zig-zags along the steep direction while creeping along the shallow one. Goodfellow, Bengio and Courville motivate the same problem with a deep chain of layers: every update to an early layer changes the statistics that every later layer sees, so the layers keep re-adapting to each other.
The idea, due to Ioffe and Szegedy in 2015, is to stop hoping the inputs are nice and to force them to be. For each dimension k, subtract the mean and divide by the standard deviation, so that the dimension has zero mean and unit variance:
The part that makes this a layer rather than a preprocessing step is that the map is differentiable. It sits inside the network, at any hidden layer, and gradients flow through it exactly as through a convolution. The CS231n notes call it differentiable preprocessing built into the network itself. On slide 27 this is why Normalization appears as the fifth component of a CNN, beside convolution, pooling, fully connected layers and activations, and slide 39 later returns to the same map with the activation function circled instead.
Recall
Give the two properties of an input x that make y = Wx hard to optimize, and what each forces the layer to do.
Start with one column of numbers. Take the mini-batch from slide 38 after its ReLU, and look only at feature 1 across the four samples: (3, 1, 3, 2). Standardizing that column is the entire batch norm computation in miniature.
Worked example
One feature, four samples
Mean over the batch
mu = (3 + 1 + 3 + 2) / 4 = 2.25Variance over the batch
sigma squared = ((0.75) squared + (-1.25) squared + (0.75) squared + (-0.25) squared) / 4 = 0.6875Normalize each value
Divide each deviation by sqrt(0.6875 + eps), about 0.829: x_hat = (0.905, -1.508, 0.905, -0.302)Result
One mean and one variance for the feature, computed across the samples. Every feature gets its own pair.
Now the general rule. The input to a batch norm layer after a fully connected layer is a matrix x of shape N x D: N samples in the mini-batch (the Batch size) by D features. Every average runs down the N axis, and that is the whole story of the axes: one statistic per feature column, averaged over the sample rows.
Shape of every tensor in batch norm for a fully connected layer
- x
- N x D
- mu_j
- D
- sigma_j squared
- D
- x_hat
- N x D
- gamma, beta
- D
- y
- N x D
The epsilon under the root is a tiny constant, 1e-5 by default in PyTorch, that prevents division by zero when a feature happens to be constant across the batch. It changes nothing numerically otherwise, but it appears in every formula and in every fusion derivation, so keep it.
Why gamma and beta exist
Is forcing zero mean and unit variance always good? It is a hard constraint, and a network is not always best served by activations pinned to a standard distribution. So the layer gets two learnable vectors of shape D, gamma and beta, and outputs y = gamma x_hat + beta. Ioffe and Szegedy point out that setting gamma = sqrt(Var[x]) and beta = E[x] recovers the original activations, if that were the optimal thing to do. The network can therefore undo normalization entirely, which means normalization can never make the model less expressive; it can only change what is easy to learn.
Goodfellow, Bengio and Courville explain why the new parametrization learns more easily even though it can represent the same functions. In the original network the mean of a hidden unit is set by a long chain of interacting weights in all the layers below. After BN the mean is set by beta alone and the scale by gamma alone, two parameters with a direct, local effect on the quantity gradient descent needs to move.
The tanh plot on slide 31 makes the point concrete. The derivative 1 - tanh squared (x) peaks at 1 at the origin and falls below 0.1 once |x| exceeds about 1.8. If normalized values feed a tanh, then gamma decides how far they reach into the flat, saturated tails and beta decides where the center of the band sits. A small gamma keeps the layer almost linear; a large one lets it saturate on purpose. The model chooses the amount of saturation instead of inheriting it from whatever scale the previous layer produced.
Recall
For x of shape N x D, write the four BN equations and the shape of each of mu, sigma squared, x_hat, gamma, beta and y.
Quick check
For a fully connected layer with input of shape N x D, over which axis does batch normalization average to get one mean?
A keyword-spotting model on a microcontroller hears one audio clip at a time. A batch of one has zero variance, so the statistics of the "batch" are meaningless, and even a batch of ten would make the answer for one clip depend on which nine clips happened to arrive with it. Ioffe and Szegedy state the requirement plainly: at inference the output should depend only on the input, deterministically.
So the layer changes its source of statistics. During training it keeps a running average of the mini-batch means and variances it has seen. At inference it uses those stored values and ignores the batch entirely. PyTorch updates the buffers as running = (1 - momentum) running + momentum x_batch with momentum 0.1, normalizes with the biased variance during training, and stores the unbiased variance (divide by N - 1) in running_var, following the paper's m/(m - 1) correction. Goodfellow, Bengio and Courville note the payoff: with running averages the model can be evaluated on a single example.
Frozen statistics turn BN into an affine map
Once mu and sigma squared are constants, batch norm on feature j is nothing more than multiply by one number and add another. And if the layer before it is a linear layer z = Wx + b, two affine maps in a row are one affine map. Write it out:
Read the first formula per output row j: the whole row of W is multiplied by the scalar gamma_j / sqrt(sigma_j squared + eps), and the bias becomes that scalar times (b_j - mu_j), plus beta_j. The same holds for a convolution: each output filter is scaled by its channel's factor. Ioffe and Szegedy already say this in the paper: the normalization is a linear transform that may be composed with the scaling by gamma and shift by beta into a single linear transform. PyTorch ships it as torch.nn.utils.fusion.fuse_conv_bn_eval, which requires both modules in eval mode with their running buffers computed. This is Batch norm fusion.
Worked example
Fusing BN into the slide 38 linear layer
Take the linear layer and frozen statistics
W = [[1, 0, 1], [1, 1, 0], [0, 2, -1]], b = (0, -1, 0), gamma = (2, 3, -1), beta = (0, 0, 1). For frozen statistics use the batch statistics of z = Wx + b itself (BN sits directly on the linear output, no ReLU in between): mu = (2.25, 1.25, 1.25), sigma squared = (0.6875, 1.6875, 6.6875).Compute one scale factor per output row
s_j = gamma_j / sqrt(sigma_j squared + eps), so s = (2.412, 2.309, -0.387).Scale each row of W and rebuild the bias
Row j gamma_j / sqrt(var_j + eps) Row j of W' b'_j 1 2 / 0.829 = 2.412 (2.412, 0, 2.412) 2.412 (0 - 2.25) + 0 = -5.427 2 3 / 1.299 = 2.309 (2.309, 2.309, 0) 2.309 (-1 - 1.25) + 0 = -5.196 3 -1 / 2.586 = -0.387 (0, -0.773, 0.387) -0.387 (0 - 1.25) + 1 = 1.483 One linear layer replaces two
W'x + b' agrees with BN(Wx + b) to floating-point precision on all four slide 38 samples, which you will meet in full in the last concept. The deployed model holds only W' and b'; gamma, beta, the running mean and the running variance vanish from the binary.
For embedded deployment this is the reason the slide says zero overhead at test time. A fused network runs no extra multiply-accumulate operations, moves no extra activations through memory, launches one fewer kernel per layer, and stores four fewer vectors per layer in flash. In later lectures on pruning, the very gamma factors that get fused away are also what network slimming reads to decide which channels matter.
What BN buys during training, and the one way it bites
- Much easier training and higher learning rates: normalizing each layer's input stops small parameter changes from amplifying into large, suboptimal changes in activations and gradients as they pass through many layers (Ioffe and Szegedy, section 3.3). On ImageNet the paper reaches the same accuracy as its baseline in 14 times fewer training steps.
- Better gradient flow: the tanh argument from the previous concept applies at every layer. Activations are kept out of the saturated tails unless the model wants them there, so derivatives stay usable.
- Robustness to initialization: scaling the weights of a layer by a constant scales its output by the same constant, and normalization divides that constant back out. The scale of the initial weights largely stops mattering.
- Regularization during training, the "How?" on slide 33: each sample is normalized with statistics that depend on the other random samples in its mini-batch, so the network no longer produces deterministic values for a given training example (section 3.4). That injected noise acts like a mild regularizer, and the paper reports that dropout can be removed or reduced in strength. Dive into Deep Learning notes that batch sizes around 50 to 100 inject roughly the right amount of noise.
The red line on slide 33 is the hazard that follows from everything above. The layer computes something different in training mode (batch statistics) and evaluation mode (running statistics). Forget to call model.eval() and your deployed model's answer for one input depends on the other inputs in the batch and degrades silently; for a batch of one, x_hat is 0 by construction so every feature collapses to beta (PyTorch's BatchNorm1d refuses to run at all in that case). It is one of the most common bugs in deep learning code precisely because, for any larger batch, nothing crashes.
| Variance | Feature 1 | Feature 2 | Feature 3 |
|---|---|---|---|
| Biased (training) | 0.6875 | 1.6875 | 4.1875 |
| Unbiased (running_var) | 0.917 | 2.25 | 5.583 |
Recall
Why does BN behave differently at train and test time, and what does PyTorch store to make test time work?
Recall
Derive W' and b' when BN with frozen statistics directly follows y = Wx + b.
Quick check
During inference, which mean does a batch normalization layer subtract from its input?
Take one activation tensor from a convolution layer, N x C x H x W = 8 x 64 x 32 x 32. It holds about half a million numbers. Every normalization in this part does the same arithmetic, subtract a mean and divide by a standard deviation, then scale and shift. The only thing that distinguishes them is the answer to one question: which of those numbers are averaged together to make one mean?
| Normalization | Values per mean | Number of means |
|---|---|---|
| Batch norm for convolutions | 8 x 32 x 32 = 8192 | 64 |
| Layer norm | 64 x 32 x 32 = 65536 | 8 |
| Instance norm, per Feature map per sample | 32 x 32 = 1024 | 512 |
| Group norm | 2 x 1024 = 2048 | 256 |
Wu and He write all four as one formula. Each value x_i is normalized with a mean and standard deviation computed over a set S_i, and different normalizations simply use different definitions of that set:
| Normalization | Averages over | mu, sigma shape | gamma, beta shape | Same at train and test? |
|---|---|---|---|---|
| BN, fully connected | N | 1 x D | 1 x D | No |
| BN, convolution (BatchNorm2d) | N, H, W | 1 x C x 1 x 1 | 1 x C x 1 x 1 | No |
| Layer norm | D (or C, H, W) | N x 1 x 1 x 1 (N x 1 on slide 35) | 1 x D on slide 35; 1 x C x 1 x 1 in Wu and He | Yes |
| Instance norm | H, W | N x C x 1 x 1 | 1 x C x 1 x 1 | Yes |
| Group norm | H, W and C/G channels | N x G x 1 x 1 | 1 x C x 1 x 1 | Yes |
Two patterns in that table carry most of the marks. First, the shape of mu is the tensor shape with a 1 wherever you averaged and the full size everywhere else. Batch norm averages over N, H, W and leaves 1 x C x 1 x 1; instance norm averages over H, W only and leaves N x C x 1 x 1. Second, gamma and beta do not follow the mu shape: they are per channel for BN, IN and GN. Ioffe and Szegedy learn a pair per feature map rather than per activation, and Wu and He write that BN, LN, IN and GN all learn a per-channel linear transform, the convention the table and the explorer below use. A BatchNorm2d over 64 channels therefore holds 128 learnable values, whatever the image size.
C/G = 1 (G = C) is instance norm and C/G = C (G = 1) is layer norm
Only the three visible faces are drawn. Lit cells share one mean with the anchor cell (teal column). Sample index runs into the depth, channel runs along the front edge.
Why the batch-free variants exist
Layer norm was introduced by Ba, Kiros and Hinton for exactly the cases where a batch is awkward. Its statistics come from all of the summed inputs to the neurons in a layer on a single training case, so it performs exactly the same computation at training and test time and is straightforward to apply to recurrent networks by computing the statistics separately at each time step. Slide 35 lists both facts. Because it never looks at another sample, it also works at batch size one, and the Transformer block in part 06 uses it in every Add and Norm step: Vaswani and colleagues define each sub-layer output as LayerNorm(x + Sublayer(x)).
Instance norm came from style transfer. Ulyanov, Vedaldi and Lempitsky found that replacing batch norm with instance norm, applied both at training and testing, sharply improved stylization, because the per-image contrast statistics are exactly what a style transfer network needs to discard. PyTorch's InstanceNorm2d defaults to no affine parameters and no running statistics.
Group norm is the embedded and detection story. Wu and He show that batch norm's error increases rapidly when the batch size becomes smaller: a ResNet-50 on ImageNet at batch size 2 reaches 34.7 percent error with BN and 24.1 percent with GN, while GN's computation is independent of batch size. With G = 32 as the default, GN becomes LN when G = 1 and IN when G = C, which is what the explorer's two slider ends show: one channel per group is instance norm, all channels in one group is layer norm. When you fine-tune a model on a device with a memory budget that allows one or two samples per step, a batch-free normalization is the difference between a model that trains and one that does not. Wu and He note that dropping the batch size constraint can free considerably more memory, sixteen times or more.
Recall
A conv output is 8 x 64 x 32 x 32. Give the mu shape for BN, LN, IN and GN with 32 groups, and how many values each mean averages.
Quick check
A BatchNorm2d layer follows a convolution with 64 output channels of size 32 x 32. How many learnable parameters does it hold?
Quick check
Which normalization gives identical outputs at training and test time and never depends on other samples in the batch?
Tom Yeh's batch norm worksheet runs a mini-batch of four samples with three features each passes through a linear layer, a ReLU, then batch norm. Filling in every cell is the single best preparation for the computational question on this topic, so here is every number, recomputed rather than copied from the heavily rounded original.
The layout hides two conventions. The mini-batch is written as columns x1 = (1, 0, 2), x2 = (0, 3, 1), x3 = (3, 1, 0), x4 = (0, 1, 2) with a row of ones appended, so the red 3 x 4 "Linear Layer" block is [W | b] with W = [[1, 0, 1], [1, 1, 0], [0, 2, -1]] and b = (0, -1, 0). Likewise the "Scale and Shift" block is [diag(gamma) | beta] with gamma = (2, 3, -1) and beta = (0, 0, 1), applied to the normalized matrix with its own row of ones. The small two-column "Trainable Parameters" box (drawn as a 2 x 2 grid in the blank template) stands for the columns [gamma | beta]; for this three-feature layer it holds a 3 x 2 matrix.
Worked example
Batch norm on the slide 38 mini-batch
Linear layer z = Wx + b
Row 1 of W is (1, 0, 1) with bias 0, so for x1 it gives 1 + 2 = 3. Doing this for every row and sample: row 1 is (3, 1, 3, 2), row 2 is (0, 2, 3, 0), row 3 is (-2, 5, 2, 0).ReLU
Only one value is negative. The -2 in row 3 becomes 0, so the batch norm input is (3, 1, 3, 2), (0, 2, 3, 0), (0, 5, 2, 0).Batch statistics, one per feature row
Quantity Feature 1 Feature 2 Feature 3 After ReLU 3, 1, 3, 2 0, 2, 3, 0 0, 5, 2, 0 Sum 9 5 7 Mean (divide by N = 4) 2.25 1.25 1.75 Variance (biased, divide by N) 0.6875 1.6875 4.1875 Standard deviation about 0.829 about 1.299 about 2.046 Normalize
Subtract the row mean, divide by the row standard deviation (with eps = 1e-5 under the root). For feature 1: (3 - 2.25) / 0.829 = 0.905, (1 - 2.25) / 0.829 = -1.508, and so on.Scale and shift with gamma = (2, 3, -1), beta = (0, 0, 1)
Row Feature 1 Feature 2 Feature 3 x_hat 0.905, -1.508, 0.905, -0.302 -0.962, 0.577, 1.347, -0.962 -0.855, 1.588, 0.122, -0.855 gamma, beta 2, 0 3, 0 -1, 1 y = gamma x_hat + beta 1.81, -3.02, 1.81, -0.60 -2.89, 1.73, 4.04, -2.89 1.86, -0.59, 0.88, 1.86 Mean of y (should be beta) 0 0 1 Variance of y (should be gamma squared) 4 9 1 Self-check in ten seconds
Each output row has mean beta_j and variance gamma_j squared: means 0, 0, 1 and variances 4, 9, 1. If your rows do not satisfy this, the arithmetic slipped somewhere. Output values are rounded to two decimals, so treat them as approximate.
| x1 | x2 | x3 | x4 | |
|---|---|---|---|---|
| f1 | 1 | 0 | 3 | 0 |
| f2 | 0 | 3 | 1 | 1 |
| f3 | 2 | 1 | 0 | 2 |
| w1 | w2 | w3 | b | |
|---|---|---|---|---|
| f1 | 1 | 0 | 1 | 0 |
| f2 | 1 | 1 | 0 | -1 |
| f3 | 0 | 2 | -1 | 0 |
| x1 | x2 | x3 | x4 | |
|---|---|---|---|---|
| f1 | 3 | 1 | 3 | 2 |
| f2 | 0 | 2 | 3 | 0 |
| f3 | -2 | 5 | 2 | 0 |
| x1 | x2 | x3 | x4 | |
|---|---|---|---|---|
| f1 | 3 | 1 | 3 | 2 |
| f2 | 0 | 2 | 3 | 0 |
| f3 | 0 | 5 | 2 | 0 |
| f1 | f2 | f3 | |
|---|---|---|---|
| sum | 9 | 5 | 7 |
| mean | 2.2500 | 1.2500 | 1.7500 |
| var | 0.6875 | 1.6875 | 4.1875 |
| std | 0.829 | 1.299 | 2.046 |
| x1 | x2 | x3 | x4 | |
|---|---|---|---|---|
| f1 | 0.905 | -1.508 | 0.905 | -0.302 |
| f2 | -0.962 | 0.577 | 1.347 | -0.962 |
| f3 | -0.855 | 1.588 | 0.122 | -0.855 |
| x1 | x2 | x3 | x4 | |
|---|---|---|---|---|
| f1 | 1.809 | -3.015 | 1.809 | -0.603 |
| f2 | -2.887 | 1.732 | 4.041 | -2.887 |
| f3 | 1.855 | -0.588 | 0.878 | 1.855 |
| x1 | x2 | x3 | x4 | |
|---|---|---|---|---|
| train | 1.809 | -3.015 | 1.809 | -0.603 |
| eval | 4.000 | 0.000 | 4.000 | 2.000 |
Sample x1 gives 1.81 with batch statistics and 4.00 with the running ones. A model left in train mode at deployment produces the first number and its value depends on which other samples share the batch.
Switch the simulator to eval mode and the same four inputs produce different outputs with the simulator's placeholder running mean and variance of one (PyTorch itself starts running_mean at 0 and running_var at 1): sample 1, feature 1 gives 4.00 instead of 1.81. That gap is the slide 33 bug made visible. To reproduce the fusion table of the previous concept, switch the placement to the paper order, press "load this batch's statistics" so the running mean becomes 2.25, 1.25, 1.25 and the running variance 0.6875, 1.6875, 6.6875, then press fuse: W' and b' appear computed live, with the check that they reproduce BN(Wx + b). With the placeholder running values of one you get a different, equally valid fused layer with scales 2, 3, -1, because the fused weights depend on whatever statistics training froze.
Recall
Feature values after ReLU are (0, 2, 3, 0). Compute mu, sigma squared and x_hat with epsilon negligible.
Recall
Which of mu, sigma squared, gamma and beta are learned by backpropagation, and which are computed?
Recap
If you remember nothing else
- Normalization exists because y = Wx is hard to optimize when inputs are off-center (a large bias is needed) or differently scaled (W entries must span very different magnitudes).
- BN works per feature over the batch: mu and sigma squared have shape D, x_hat = (x - mu)/sqrt(sigma squared + eps), y = gamma x_hat + beta. gamma and beta are learned, mu and sigma are computed.
- gamma = sqrt(sigma squared + eps) and beta = mu recover the identity; before tanh they decide how far activations reach into the saturated tails.
- At inference mu and sigma squared are running averages, so BN is an affine map that folds into the previous FC or conv: W' = diag(gamma/sqrt(sigma squared + eps)) W, b' = gamma (b - mu)/sqrt(sigma squared + eps) + beta, at zero test-time cost.
- Benefits: easier training, better gradient flow, higher learning rates, robustness to initialization, regularization from batch noise. Hazard: train and eval mode behave differently.
- BN for conv averages over N, H, W (mu is 1 x C x 1 x 1); LN over features per sample (N x 1); IN over H, W per sample and channel (N x C x 1 x 1); GN over H, W and C/G channels. gamma and beta are per channel (1 x C x 1 x 1) for BN, IN and GN; LN on an N x D input has them 1 x D on slide 35, per channel in Wu and He.
- LN, IN and GN need no batch and behave the same at train and test, which is why LN runs in RNNs and transformers and GN wins at batch size 2.
- Slide 38 batch: means 2.25, 1.25, 1.75; variances 0.6875, 1.6875, 4.1875; every output row has mean beta and variance gamma squared.
Sources
- Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate ShiftPaperIoffe and Szegedy, ICML 2015Algorithm 1, identity recovery via gamma and beta, inference with population statistics, regularization (3.4), higher learning rates (3.3), per-feature-map parameters, 14x fewer steps.(opens in a new tab)
- Layer NormalizationPaperBa, Kiros and Hinton, 2016Statistics from a single training case, same computation at train and test, application to recurrent networks.(opens in a new tab)
- Instance Normalization: The Missing Ingredient for Fast StylizationPaperUlyanov, Vedaldi and Lempitsky, 2016Replacing batch norm with instance norm at training and test time for style transfer.(opens in a new tab)
- Improved Texture Networks: Maximizing Quality and Diversity in Feed-forward Stylization and Texture SynthesisPaperUlyanov, Vedaldi and Lempitsky, CVPR 2017The instance normalization reference cited on slide 36.(opens in a new tab)
- Group NormalizationPaperWu and He, ECCV 2018Unified S_i formulation, G = 32 default, LN at G = 1 and IN at G = C, per-channel gamma and beta, 24.1 vs 34.7 percent error at batch size 2, memory remark.(opens in a new tab)
- Attention Is All You NeedPaperVaswani et al., NeurIPS 2017Section 3.1: each sub-layer output is LayerNorm(x + Sublayer(x)).(opens in a new tab)
- How Does Batch Normalization Help Optimization?PaperSanturkar, Tsipras, Ilyas and Madry, NeurIPS 2018BN smooths the optimization landscape; internal covariate shift is not the cause of its success.(opens in a new tab)
- Deep Learning, chapter 8.7.1: Batch NormalizationBookGoodfellow, Bengio and Courville, MIT PressAdaptive reparametrization, why beta and gamma make the mean and scale easy to learn, running averages at test time.(opens in a new tab)
- MIT 6.5940 TinyML and Efficient Deep Learning Computing, Lecture 2DocsMIT HAN LabSlide 41: normalization makes optimization faster, unified S_i definition, per-channel linear transform.(opens in a new tab)
- torch.nn.BatchNorm2dDocsPyTorch documentationeps 1e-5, momentum 0.1, biased variance in training and unbiased running variance, running estimates in eval mode, gamma and beta of size C.(opens in a new tab)
- torch.nn.LayerNormDocsPyTorch documentationStatistics over the last D dimensions, identical in training and evaluation modes.(opens in a new tab)
- torch.nn.GroupNormDocsPyTorch documentationEach group holds num_channels / num_groups channels; same statistics at train and eval.(opens in a new tab)
- torch.nn.InstanceNorm2dDocsPyTorch documentationInstance statistics at train and eval, affine and track_running_stats off by default.(opens in a new tab)
- torch.nn.utils.fusion.fuse_conv_bn_evalDocsPyTorch documentationFuses a convolution and a batch norm in eval mode into a single convolution.(opens in a new tab)
- CS231n notes: Setting up the data and the modelDocsStanford UniversityBatch norm as differentiable preprocessing, inserted after FC or conv layers and before nonlinearities.(opens in a new tab)
- Dive into Deep Learning, section 8.5: Batch NormalizationBookZhang, Lipton, Li and SmolaTraining versus prediction mode, batch noise as regularization at batch sizes of 50 to 100, epsilon, per-channel BN for convolutions.(opens in a new tab)
- Batch Normalization by HandArticleTom Yeh, byhand.aiSource of the slide 38 worksheet. The full sheet is paywalled; values here were recomputed.(opens in a new tab)