Machine Learning Academy · Les

Batchnormalisatie: stabieler en sneller trainen

Cursisten voegen nn.BatchNorm1d toe tussen lagen, observeren snellere convergentie in een diep netwerk en begrijpen hoe BatchNorm activaties binnen elke minibatch normaliseert.

Les 2 van 413 stappen

Batchnormalisatie: stabieler en sneller trainen is een gratis Machine Learning Academy-les op CoddyKit. Dit is les 2 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Machine Learning Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Machine Learning Academy bevat in totaal 4 lessen.

Het probleem dat Batch Norm oplost

Diepe neurale netwerken hebben last van interne covariate shift — de verdeling van de invoer van elke laag verandert tijdens het trainen wanneer de gewichten van de vorige laag worden bijgewerkt. Hierdoor moet elke laag zich voortdurend aanpassen aan een verschuivende invoerverdeling, waardoor het trainen langzamer verloopt. Batchnormalisatie (Batch Norm), geïntroduceerd door Ioffe en Szegedy in 2015, lost dit op door de invoer van lagen binnen elke mini-batch te normaliseren. Dit versnelt het trainen aanzienlijk en maakt het minder gevoelig voor de initialisatie van gewichten.

# Without batch norm: deep networks train slowly and
# require very careful weight init and LR tuning.

# With batch norm: can use higher learning rates,
# less sensitive to initialisation, acts as regulariser.

# Batch norm normalises each feature to:
# mean=0, std=1 within the batch, then
# applies learnable scale (gamma) and shift (beta).
print('Batch Norm: normalize -> scale -> shift')

Hoe Batch Norm wiskundig werkt

Voor elke kenmerkdimensie berekent Batch Norm het gemiddelde en de variantie over de huidige mini-batch en normaliseert vervolgens elke waarde. Na de normalisatie past het twee leerbare parameters toe: gamma (schaal) en beta (verschuiving). Hierdoor kan het netwerk de normalisatie indien nodig ongedaan maken — de identiteits transformatie kan worden teruggewonnen. Er wordt een kleine constante epsilon aan de variantie toegevoegd om delen door nul te voorkomen.

import torch

def batch_norm_manual(x, gamma, beta, eps=1e-5):
    # x shape: (batch_size, features)
    mu = x.mean(dim=0)           # mean per feature
    var = x.var(dim=0, unbiased=False)  # var per feature
    x_norm = (x - mu) / (var + eps).sqrt()
    return gamma * x_norm + beta  # scale and shift

x = torch.randn(32, 8)  # batch=32, 8 features
gamma = torch.ones(8)
beta = torch.zeros(8)

out = batch_norm_manual(x, gamma, beta)
print('Mean near 0:', out.mean(dim=0).abs().max().item() < 0.01)
print('Std near 1:', (out.std(dim=0) - 1).abs().max().item() < 0.01)

nn.BatchNorm1d voor volledig verbonden lagen

nn.BatchNorm1d wordt gebruikt na lineaire lagen in feedforwardnetwerken. De laag neemt num_features (de grootte van de uitvoer van de vorige laag) als argument. Batch Norm wordt meestal na de lineaire laag maar vóór de activatiefunctie geplaatst, al is er nog steeds discussie over de vraag of plaatsing vóór of na de activatie beter is. De module houdt een voortschrijdend gemiddelde en een voortschrijdende variantie bij voor gebruik tijdens inferentie.

import torch
import torch.nn as nn

model = nn.Sequential(
    nn.Linear(16, 64),
    nn.BatchNorm1d(64),   # after linear, before activation
    nn.ReLU(),
    nn.Linear(64, 32),
    nn.BatchNorm1d(32),
    nn.ReLU(),
    nn.Linear(32, 10)
)

x = torch.randn(32, 16)   # batch of 32
out = model(x)
print(out.shape)           # torch.Size([32, 10])

Gedrag tijdens trainen en inferentie

Batch Norm gedraagt zich verschillend tijdens het trainen en tijdens inferentie. Tijdens het trainen gebruikt het de statistieken van de mini-batch (het gemiddelde en de variantie van de huidige batch). Tijdens inferentie gebruikt het voortschrijdende statistieken (een exponentieel voortschrijdend gemiddelde dat tijdens het trainen is opgebouwd), zodat voorspellingen deterministisch zijn en niet afhangen van de batchgrootte. Daarom moet je tijdens inferentie model.eval() aanroepen — hiermee schakel je BatchNorm over op het gebruik van de voortschrijdende statistieken.

import torch
import torch.nn as nn

bn = nn.BatchNorm1d(4)

# Training mode: uses batch statistics, updates running stats
bn.train()
x = torch.randn(8, 4)
out_train = bn(x)

# After training, running_mean and running_var are populated
print('Running mean:', bn.running_mean)

# Eval mode: uses running statistics (deterministic)
bn.eval()
x_new = torch.randn(1, 4)   # single sample -- works!
out_eval = bn(x_new)
print(out_eval.shape)         # torch.Size([1, 4])

Leerbare parameters: gamma en beta

Batch Norm heeft per kenmerk twee leerbare parameters: weight (gamma, geïnitialiseerd op 1) en bias (beta, geïnitialiseerd op 0). Hiermee kan het netwerk leren om de genormaliseerde waarden opnieuw te schalen en te verschuiven als dat de taak verbetert. Ze worden net als gewone gewichtsmatrices bijgewerkt door de optimizer. Als je Batch Norm-lagen tijdens fine-tuning wilt bevriezen, stel je requires_grad=False in voor deze parameters.

import torch.nn as nn

bn = nn.BatchNorm1d(8)
print('gamma (weight):', bn.weight.data)   # all 1s
print('beta (bias):', bn.bias.data)         # all 0s
print('gamma requires_grad:', bn.weight.requires_grad)  # True
print('beta requires_grad:', bn.bias.requires_grad)     # True

# Total trainable params in this BN layer:
# 2 * 8 = 16 (gamma and beta for 8 features)
params = sum(p.numel() for p in bn.parameters())
print('Params:', params)   # 16

Snellere convergentie waarnemen

Een van de duidelijkste voordelen van Batch Norm is snellere convergentie. Netwerken met Batch Norm bereiken doorgaans dezelfde validatienauwkeurigheid in minder epochs en kunnen grotere learning rates gebruiken zonder instabiliteit. De normalisatie houdt activaties tijdens het trainen binnen een gezond bereik en voorkomt verzadiging, waardoor het leren vertraagt in netwerken met sigmoid- of tanh-activaties. Het effect is het duidelijkst in diepe netwerken met veel lagen.

import torch
import torch.nn as nn
import torch.optim as optim

def make_model(use_bn):
    layers = [nn.Linear(16, 64)]
    if use_bn: layers.append(nn.BatchNorm1d(64))
    layers.append(nn.ReLU())
    layers.append(nn.Linear(64, 2))
    return nn.Sequential(*layers)

X = torch.randn(200, 16)
y = torch.randint(0, 2, (200,))

for use_bn in [False, True]:
    model = make_model(use_bn)
    opt = optim.SGD(model.parameters(), lr=0.1)
    crit = nn.CrossEntropyLoss()
    for _ in range(20):
        opt.zero_grad(); loss = crit(model(X), y)
        loss.backward(); opt.step()
    print(f'BN={use_bn}: final_loss={loss.item():.4f}')

Batch Norm als regularisator

Batch Norm werkt als een lichte regularisator, omdat elk trainingsvoorbeeld wordt genormaliseerd ten opzichte van de andere voorbeelden in de mini-batch. Dit introduceert een vorm van stochastiek die vergelijkbaar is met Dropout. Daardoor hebben netwerken met Batch Norm vaak minder Dropout nodig. Het regularisatie-effect neemt af bij grotere batchgroottes, omdat de batchstatistieken deterministischer worden, de werkelijke populatiestatistieken benaderen en het stochastische element verdwijnt.

# Key insight: batch norm introduces noise proportional to
# 1/sqrt(batch_size) because batch statistics are noisy
# estimates of population statistics.

# Small batch (e.g., 8): high noise -> more regularisation
# Large batch (e.g., 512): low noise -> less regularisation

# Common pattern: use batch norm AND a small dropout
# for strong regularisation in deep networks
model = __import__('torch').nn.Sequential(
    __import__('torch').nn.Linear(32, 128),
    __import__('torch').nn.BatchNorm1d(128),
    __import__('torch').nn.ReLU(),
    __import__('torch').nn.Dropout(0.2)  # mild dropout
)
print('BN + light Dropout: balanced regularisation')

nn.BatchNorm2d voor convolutionele netwerken

In convolutionele netwerken normaliseert nn.BatchNorm2d voor elk kanaal afzonderlijk over de batch- en ruimtelijke dimensies. De laag neemt num_channels als argument (overeenkomstig met het aantal uitvoerkanalen van de voorafgaande Conv2d-laag). Het standaardpatroon is Conv2d -> BatchNorm2d -> ReLU. Dit wordt gebruikt in vrijwel elke moderne CNN-architectuur, waaronder ResNet, VGG en EfficientNet.

import torch
import torch.nn as nn

# Standard CNN block: Conv -> BN -> ReLU
conv_block = nn.Sequential(
    nn.Conv2d(3, 64, kernel_size=3, padding=1),
    nn.BatchNorm2d(64),    # 64 = number of output channels
    nn.ReLU(inplace=True)
)

# Input: batch of 8 RGB images, 32x32 pixels
x = torch.randn(8, 3, 32, 32)
out = conv_block(x)
print(out.shape)   # torch.Size([8, 64, 32, 32])

Layer Norm versus Batch Norm

Laagnormalisatie (gebruikt in Transformers) normaliseert over de kenmerken binnen één enkel voorbeeld, in plaats van over de batch. Hierdoor is deze normalisatie onafhankelijk van de batchgrootte, wat essentieel is voor reeksen met variabele lengte en kleine batches. Batch Norm normaliseert voor elk kenmerk over de batch en is ideaal voor CNN's en trainen met grote batches. De verkeerde keuze kan nadelig zijn: Batch Norm gebruiken in een Transformer of Layer Norm in een CNN is een veelgemaakte architectuurfout.

import torch
import torch.nn as nn

x = torch.randn(4, 8)  # batch=4, features=8

# Batch Norm: normalise across batch for each feature
bn = nn.BatchNorm1d(8)
bn_out = bn(x)   # statistics computed over 4 samples

# Layer Norm: normalise across features for each sample
ln = nn.LayerNorm(8)
ln_out = ln(x)   # statistics computed over 8 features

print('BN output shape:', bn_out.shape)   # (4, 8)
print('LN output shape:', ln_out.shape)   # (4, 8)
# Same shape, different normalisation axes

Batch Norm bevriezen tijdens fine-tuning

Wanneer je een vooraf getraind model finetunet op een kleine dataset, zijn de voortschrijdende statistieken in de Batch Norm-lagen geschat op basis van de oorspronkelijke grote dataset. Als je deze statistieken laat bijwerken met een kleine fine-tuningbatch, kunnen ze vervormd raken en kunnen de prestaties verslechteren. Een gebruikelijke strategie is om Batch Norm-lagen te bevriezen door ze permanent in de eval-modus te zetten. In PyTorch doe je dit door model.apply aan te roepen met een aangepaste functie die elke BN-laag bevriest.

import torch.nn as nn

def freeze_bn(module):
    '''Keep BN in eval mode during fine-tuning.'''
    if isinstance(module, (nn.BatchNorm1d,
                           nn.BatchNorm2d,
                           nn.BatchNorm3d)):
        module.eval()  # use running stats, not batch stats
        module.weight.requires_grad_(False)
        module.bias.requires_grad_(False)

model = nn.Sequential(
    nn.Linear(4, 8),
    nn.BatchNorm1d(8),
    nn.ReLU()
)
model.apply(freeze_bn)
print('BN frozen for fine-tuning')

Beperkingen en alternatieven van Batch Norm

Batch Norm heeft bekende beperkingen: er is een minimale batchgrootte nodig (meestal 16 of meer) voor betrouwbare statistieken; bij zeer kleine batches is de methode ineffectief of schadelijk; en er ontstaat een afhankelijkheid tussen voorbeelden in een batch, wat parallellisatie ingewikkelder maakt. Alternatieven zijn onder andere Group Norm (kanalen in groepen verdelen), Instance Norm (normaliseren per voorbeeld en kanaal, gebruikt voor stijloverdracht) en Layer Norm (gebruikt in Transformers). De juiste normalisatie kiezen is afhankelijk van de architectuur.

import torch
import torch.nn as nn

x = torch.randn(4, 16, 10)  # (batch, channels, seq_len)

# GroupNorm: 4 groups of 4 channels each
gn = nn.GroupNorm(num_groups=4, num_channels=16)
print('GroupNorm:', gn(x).shape)

# InstanceNorm: normalise each sample+channel independently
ins = nn.InstanceNorm1d(16)
print('InstanceNorm:', ins(x).shape)

# LayerNorm: normalise across last N dimensions
ln = nn.LayerNorm([16, 10])
print('LayerNorm:', ln(x).shape)

Korte kennistest

Test je begrip van de concepten uit deze les over Machine Learning met Python.

Samenvatting van de les

In deze les heb je geleerd dat Batchnormalisatie de invoer van lagen binnen elke mini-batch normaliseert om het trainen te stabiliseren en te versnellen, dat nn.BatchNorm1d en nn.BatchNorm2d respectievelijk voor volledig verbonden en convolutionele lagen worden gebruikt, en dat model.eval() BN overschakelt op voortschrijdende statistieken die tijdens het trainen zijn verzameld voor deterministische inferentie. Hierna voegen we Dropout-regularisatie toe om overfitting te voorkomen.

Gratis beginnen

Leer Python met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
30
Lessen
120

Veelgestelde vragen

Is de les “Batchnormalisatie: stabieler en sneller trainen” gratis?

Ja — de volledige tekst van “Batchnormalisatie: stabieler en sneller trainen” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Machine Learning Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Machine Learning Academy bevat in totaal 4 lessen.

Wat leer ik in “Batchnormalisatie: stabieler en sneller trainen”?

Cursisten voegen nn.BatchNorm1d toe tussen lagen, observeren snellere convergentie in een diep netwerk en begrijpen hoe BatchNorm activaties binnen elke minibatch normaliseert. Je oefent met Machine Learning Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Machine Learning Academy te beginnen?

Ervaring vooraf is niet nodig. Machine Learning Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 2 van 4.

Hoe lang duurt de les “Batchnormalisatie: stabieler en sneller trainen”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Machine Learning Academy?

Ja. Elke les over Machine Learning Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Learning rate: de belangrijkste hyperparameter
  2. Batchnormalisatie: stabieler en sneller trainen
  3. Dropout-regularisatie om overfitting te voorkomen
  4. Gewichtsinitialisatie: Xavier- en He-initialisatie
← Terug naar Machine Learning Academy