Recommended resources
The freely available resources this lesson will direct you to.
Hello! Let's get started on our next lesson.
Introduction
In our last lesson, we explored two powerful regularization techniques, L2 regularization and dropout, to combat overfitting. These methods help our models generalize better by penalizing large weights or deactivating neurons during training.
Today, we'll dive into another fundamental technique for training deep neural networks: Batch Normalization (BN). While the primary goal of BN isn't regularization, it often has a beneficial regularizing side effect. Its main purpose is to stabilize and accelerate the training process, which can sometimes feel like a dark art. By normalizing the inputs to each layer, Batch Normalization makes the learning process more predictable and efficient.
By the end of this lesson, you will be able to explain how Batch Normalization works and apply it to a neural network in PyTorch to stabilize and accelerate training.
1. The Problem: Unstable Training
Imagine you're training a deep neural network. As the network learns, the weights in the early layers are constantly being updated. Since you have a background in calculus, you know that via the chain rule, these small changes have a cascading effect on the activations in later layers. This means that from the perspective of a specific layer deep in the network, the distribution of its inputs is constantly shifting. This phenomenon is called internal covariate shift.
This constant shifting makes training difficult. It's like trying to hit a moving target. The layer is continuously trying to adapt to a new input distribution, which slows down learning and makes the training process unstable.
To get an intuition for how Batch Normalization helps, let's start with a video that uses a great analogy.
Batch Normalization in neural networks - EXPLAINED!
This video from CodeEmporium visualizes the loss landscape. Without Batch Normalization, the landscape can be stretched and difficult to navigate. With Batch Normalization, it becomes smoother, making it much easier for the optimizer to find the minimum.
Watch the section from 00:56 to 03:47. Focus on the contour plot analogy and how it represents the training process becoming more stable and quicker.
Now, for a more formal explanation of internal covariate shift, let's turn to a classic video from Andrew Ng.
Why Does Batch Norm Work? (C2W3L06)
This video explains how Batch Norm makes later layers in the network more robust to changes in the earlier layers, directly addressing the problem of internal covariate shift.
Watch the segment from 00:42 to 07:32. Pay attention to how changes in the distribution of one layer's activations (A[2]) affect the learning process of the next layer (which sees A[2] as its input).
2. The Mechanism: How Batch Normalization Works
Batch Normalization addresses internal covariate shift by normalizing the output of a layer before it's passed to the next. This is done for each mini-batch during training. The process involves four steps for each feature (or neuron activation):
- Calculate Batch Mean (μ): Compute the mean of the activations across all samples in the current mini-batch.
- Calculate Batch Variance (σ²): Compute the variance of the activations across the mini-batch.
- Normalize: Use the batch mean and variance to normalize each activation to have a mean of 0 and a standard deviation of 1.
- Scale and Shift: Multiply the normalized value by a learnable parameter (gamma) and add another learnable parameter (beta).
This process is summarized by the following equation:
Where:
- is an activation from the mini-batch .
- and are the mean and variance of the mini-batch.
- is a small constant for numerical stability (to avoid division by zero).
- and are learnable parameters that allow the network to scale and shift the normalized distribution. This is crucial because it gives the network the flexibility to decide the optimal mean and variance for each layer's activations, rather than being forced into a standard normal distribution.
This diagram provides an excellent visual walkthrough of the entire process.

To solidify your understanding of the math and the role of and , please read the following short text.
Batch normalization in 3 levels of understanding
The article 'Batch normalization in 3 levels of understanding' provides a concise explanation of the training-time calculations.
Read the section 'B.1.1) Training'. It presents the formulas clearly and explains the purpose of the learnable parameters γ and β.
3. Training vs. Evaluation
A critical detail of Batch Normalization is that it behaves differently during training and evaluation (inference).
- During training (
model.train()): BN uses the mean and variance of the current mini-batch to normalize activations. It also updates running estimates of the overall dataset's mean and variance using an exponential moving average. - During evaluation (
model.eval()): We might be making a prediction on a single sample, so calculating a "batch" mean and variance is not possible or meaningful. Instead, the BN layer uses the fixed running estimates of mean and variance that it computed during training.
This ensures that the model's output is deterministic during inference. PyTorch handles this switch for you automatically when you call model.train() or model.eval().
Batch normalization in 3 levels of understanding
Let's revisit the 'Batch normalization in 3 levels of understanding' article to see how the evaluation phase is handled.
Read the short section 'B.1.2) Evaluation'. This explains the use of estimated population statistics (μ_pop, σ_pop) during the evaluation phase.
4. Benefits of Batch Normalization
Applying Batch Normalization brings several significant benefits:
- Faster Convergence: By stabilizing the input distributions, BN smooths the optimization landscape, allowing the model to train faster.
- Allows Higher Learning Rates: Normalization reduces the model's sensitivity to the scale of weights, which often allows you to use higher learning rates without causing the training to diverge.
- Slight Regularization: The mean and variance are calculated on a mini-batch, so they are slightly noisy estimates of the true dataset statistics. This noise adds a minor regularizing effect, similar to dropout. As the batch size increases, this effect diminishes.
Let's watch the final part of Andrew Ng's video, where he discusses this regularization effect.
Why Does Batch Norm Work? (C2W3L06)
This clip explains the unintended but useful regularization side-effect of Batch Normalization.
Watch from 07:47 to 10:50. He explains how the noise from mini-batch statistics acts as a form of regularization.
5. Applying Batch Normalization in PyTorch
In PyTorch, Batch Normalization is added as a layer, just like nn.Linear or nn.ReLU. It is most commonly placed between the linear (or convolutional) layer and the non-linear activation function.
There are different versions of the BN layer depending on the dimensionality of your data:
nn.BatchNorm1d: For 1D data, such as the output of ann.Linearlayer (i.e., a batch of vectors).nn.BatchNorm2d: For 2D data, such as the output of ann.Conv2dlayer (i.e., a batch of images with channels).nn.BatchNorm3d: For 3D data.
The most important parameter for these layers is num_features, which must be equal to the number of channels or features of the layer's input. For a nn.Linear layer, this is its out_features.
machine-learning-articles/batch-normalization-with-pytorch.md
This article gives a very clear explanation of the difference between nn.BatchNorm1d and nn.BatchNorm2d.
Read the subsection 'Differences between BatchNorm2d and BatchNorm1d'. It breaks down the expected input shapes ([N, C, L] vs. [N, C, H, W]) and makes it clear when to use each.
Here is an example of how to add nn.BatchNorm1d to a simple MLP:
import torch.nn as nn
class MLP_with_BN(nn.Module):
def __init__(self):
super().__init__()
self.layers = nn.Sequential(
nn.Flatten(),
# Block 1
nn.Linear(3072, 64), # 3072 for CIFAR-10 images (32*32*3)
nn.BatchNorm1d(64), # Applied to the 64 features from the linear layer
nn.ReLU(),
# Block 2
nn.Linear(64, 32),
nn.BatchNorm1d(32), # Applied to the 32 features
nn.ReLU(),
# Output Layer
nn.Linear(32, 10)
)
def forward(self, x):
return self.layers(x)
Now, let's watch a complete practical example where a network is trained with and without Batch Normalization to see the difference in performance.
Batch Normalization in neural networks - EXPLAINED!
The CodeEmporium video provides a full, hands-on demonstration in PyTorch, building a model and comparing its training performance with and without Batch Normalization.
Watch the final section from 09:15 to 15:32. This will walk you through the code for defining, training, and evaluating a network with BN layers, tying everything together.
Conclusion
You've now added another crucial tool to your deep learning toolkit. Batch Normalization is a standard component in most modern deep learning architectures for a reason—it makes training faster, more stable, and more robust.
Key Takeaways:
- Internal Covariate Shift: The change in the distribution of layer inputs during training, which slows down and destabilizes learning.
- Batch Normalization (BN): A technique that normalizes layer inputs for each mini-batch to have a controlled mean and variance.
- Mechanism: BN calculates the mean/variance of a mini-batch, normalizes the activations, and then applies a learnable scale () and shift ().
- Training vs. Evaluation: BN uses mini-batch statistics during training and fixed, pre-computed population statistics during evaluation.
- Benefits: Leads to faster and more stable training, allows for higher learning rates, and provides a slight regularization effect.
- PyTorch Implementation: Use
nn.BatchNorm1dfor outputs of dense layers andnn.BatchNorm2dfor outputs of convolutional layers.
In our next and final lesson of this module, we will cover Early Stopping, a simple yet effective technique for preventing overfitting by monitoring validation performance and stopping the training process at the right time.