Diepe Netwerken Trainen

Je begrijpt nu wat neurale netwerken zijn—of het nu feedforward, CNNs, RNNs of Transformers zijn—maar hoe leren ze eigenlijk? Hoe gaat een netwerk van willekeurige voorspellingen naar het herkennen van handgeschreven cijfers, het begrijpen van taal, of het identificeren van objecten in foto’s?

Het antwoord ligt in twee onderling verbonden processen: backpropagation en gradient descent. Deze algoritmen werken samen om systematisch miljoenen of miljarden gewichten aan te passen, waardoor een willekeurig geïnitialiseerd netwerk verandert in een intelligent systeem. Dit is waar de wiskundige concepten uit Hoofdstuk 2—met name afgeleiden—essentieel worden om moderne AI te begrijpen.

Laten we verkennen hoe neurale netwerken transformeren van willekeurige gokkers naar geavanceerde patroonherkenningssystemen.


Miljoenen Gewichten Aanpassen

Overweeg de schaal van wat we proberen te bereiken. Een (vrij klein) diep netwerk kan hebben:

  • Inputlaag: 784 neuronen (voor 28×2828×28 pixelafbeeldingen).
  • Verborgen laag 1: 512 neuronen.
  • Verborgen laag 2: 256 neuronen.
  • Outputlaag: 10 neuronen (voor cijferclassificatie 0-9).

Dit creëert ongeveer 784×512+512×256+256×10=534.016784 \times 512 + 512 \times 256 + 256 \times 10 = 534.016 gewichten die geleerd moeten worden! Elk van deze gewichten beïnvloedt de uiteindelijke voorspelling, maar hun effecten zijn indirect—ze vloeien door meerdere lagen en activatiefuncties. De fundamentele vraag wordt: wanneer het netwerk een fout maakt, welke gewichten moeten we aanpassen en met hoeveel?

Traditionele optimalisatiebenaderingen falen hier omdat:

  • We elk gewicht niet afzonderlijk kunnen testen (dat zou miljoenen experimenten vergen).
  • Gewichten op complexe manieren met elkaar interageren.
  • Kleine veranderingen grote effecten kunnen hebben door niet-lineaire activatiefuncties.

Hier biedt backpropagation een elegante wiskundige oplossing.


Voorwaartse Pass: Een Voorspelling Maken

Voordat we van fouten kunnen leren, moeten we een voorspelling doen. Deze "forward pass" stuurt inputdata laag voor laag door het netwerk.

✍🏼 Voorbeeld Handgeschreven Cijfer: Laten we een handgeschreven "7" door ons netwerk volgen:

  1. Inputlaag: Ontvangt 784 pixelhelderheidswaarden.
  2. Verborgen laag 1: Elk van de 512 neuronen berekent: activation(weighted sum of inputs+bias)\text{activation}(\text{weighted sum of inputs} + \text{bias}).
  3. Verborgen laag 2: Elk van de 256 neuronen verwerkt outputs van laag 1.
  4. Outputlaag: 10 neuronen produceren scores voor de cijfers 0-9.

Voor elk neuron is de berekening:

output=σ(w1x1+w2x2+...+wnxn+b)\text{output} = \sigma (w_1 x_1 + w_2 x_2 + ... + w_n x_n + b)

In deze functie gebruiken we σ\sigma om de activatiefunctie aan te duiden. We “trekken” de inmiddels bekende formule dus door de activatiefunctie. Dit gebeurt miljoenen keren terwijl informatie voorwaarts door het netwerk stroomt.

Network diagram showing data flowing forward through layers with activations

Na het maken van een voorspelling kan het netwerk enkele scores outputten. Onthoud dat we één score per klasse krijgen:

[0.1,0.05,0.2,0.05,0.1,0.1,0.05,0.8,0.1,0.15][0.1, 0.05, 0.2, 0.05, 0.1, 0.1, 0.05, 0.8, 0.1, 0.15]

De hoogste score (0.8) komt overeen met positie 7, dus het netwerk voorspelt "7"—correct! Maar wat als het fout is?


Fouten Meten: Loss Functions

Wanneer ons netwerk een verkeerde voorspelling doet, moeten we precies kwantificeren hoe verkeerd die was. Hier komen loss functions in beeld—ze geven één getal dat de fout van het netwerk vertegenwoordigt. We hebben deze eerder gezien tijdens Machine Learning, weet je nog?

Voor onze cijferherkenningstaak gebruiken we iets dat cross-entropy loss heet, dat zelfverzekerde foute voorspellingen zwaar bestraft:

Loss=log(predicted probability of correct class)\text{Loss} = - \text{log} (\text{predicted probability of correct class})

Laten we enkele voorbeelden doornemen:

  • Correct en zelfverzekerd: Voorspelt 0.9 voor het juiste cijfer → Loss=log(0.9)=0.05\text{Loss} = - \log(0.9) = 0.05 (lage straf).
  • Correct maar onzeker: Voorspelt 0.6 voor het juiste cijfer → Loss=log(0.6)=0.22\text{Loss} = - \log(0.6) = 0.22 (middelmatige straf).
  • Verkeerd en zelfverzekerd: Voorspelt 0.9 voor een verkeerd cijfer → Loss=log(0.1)=2.3\text{Loss} = - \log(0.1) = 2.3 (hoge straf).

Deze loss function moedigt het netwerk aan om zowel accuraat als zelfverzekerd te zijn in correcte voorspellingen.

Voor problemen met continue waarden (zoals huizenprijzen) gebruiken we vaak de Mean Squared Error (MSE). Dit is een functie die we eerder zagen—zie je hoe deze ML-technieken ons helpen in Deep Learning?

Loss=(predicted valueactual value)2\text{Loss} = (\text{predicted value} - \text{actual value})^2

De keuze van loss function bepaalt hoe het netwerk leert. Cross-entropy duwt het netwerk richting zelfverzekerde, correcte classificaties, terwijl MSE aanmoedigt om voorspellingen dicht bij doelwaarden te houden.


Backpropagation: Verantwoordelijkheid Traceren

Hier gebeurt de magie. Backpropagation lost het toewijzingsprobleem van krediet op: welke gewichten zijn verantwoordelijk voor de fout, en in welke mate?

Weet je nog afgeleiden uit Hoofdstuk 2? Backpropagation gebruikt de kettingregel uit de calculus om te volgen hoe elk gewicht de uiteindelijke loss beïnvloedt door alle tussenliggende lagen heen. Het proces, conceptueel, is als volgt:

  1. Outputlaag: Bereken hoeveel elk outputneuron bijdroeg aan de loss.
  2. Verborgen laag 2: Gebruik de outputlaaggradiënten om gradiënten voor verborgen laag 2 te berekenen.
  3. Verborgen laag 1: Gebruik de gradiënten van verborgen laag 2 om gradiënten voor verborgen laag 1 te berekenen.
  4. Ga achterwaarts door: Totdat we de inputlaag bereiken.
Network diagram showing error gradients flowing backward through layers

Wiskundig, voor een gewicht dat neuron ii met neuron jj verbindt:

(how loss changes with neuron j)×(how neuron j changes with weight)(\text{how loss changes with neuron j}) × (\text{how neuron j changes with weight})

Dit laat ons de gradiënt voor elk afzonderlijk gewicht in het netwerk efficiënt berekenen.


Gradient Descent: Het Gewichtsupdateproces

Zodra backpropagation ons vertelt hoe elk gewicht de loss beïnvloedt, gebruikt gradient descent deze informatie om de gewichten te verbeteren. De techniek volgt een eenvoudige updateregel:

new weight=old weightlearning rate×gradient\text{new weight} = \text{old weight} - \text{learning rate} \times \text{gradient}

Laten we dit opsplitsen:

  • Gradiënt: De afgeleide die aangeeft in welke richting de loss toeneemt.
  • Negatieve gradiënt: De richting waarin de loss afneemt (waar we heen willen).
  • Learning rate: Hoe groot de stap is die we in die richting zetten.

De learning rate is wat we een hyperparameter noemen, een keuze die je vooraf instelt—het model leert deze niet. Het definieert hoe groot de stap moet zijn die we zetten om de loss te verlagen.

Line plots showing loss curves for different learning rates over training steps
  • Te laag (0.001): Zeer traag leren, mogelijk nooit optimale prestaties.
  • Precies goed (0.01): Gestage verbetering richting optimale gewichten.
  • Te hoog (0.1): Netwerk stuitert rond en vestigt zich niet op goede gewichten.

De juiste learning rate vinden kan wat trial-and-error vergen, maar er zijn enkele vuistregels:

  • Begin met gangbare waarden (0.01, 0.001).
  • Monitor de trainingsloss; die zou gestaag moeten dalen.
  • Pas aan op basis van netwerkgedrag en probleemcomplexiteit.

In de praktijk is het kiezen van een geschikte learning rate een van de belangrijkste beslissingen om stabiele en efficiënte training te waarborgen.


Stochastic Gradient Descent

Het hele dataset verwerken voor elke gewichtsupdate (batch gradient descent) is computationeel duur en vaak onnodig. In plaats daarvan gebruiken de meeste neurale netwerken varianten die gewichten vaker bijwerken.

In plaats van alle trainingsvoorbeelden te gebruiken, gebruiken we een techniek genaamd Mini-Batch Gradient Descent. Hierbij gebruiken we kleine batches (typisch 32-256 voorbeelden):

  1. Forward pass: Verwerk een batch voorbeelden.
  2. Loss berekenen: Gemiddelde loss over de batch.
  3. Backpropagation: Bereken gradiënten op basis van de batch.
  4. Gewichten updaten: Pas de gradient descent-stap toe.
  5. Herhaal: Ga naar de volgende batch.

Batchen heeft veel voordelen, net zoals berekeningen in matrixvorm (weet je nog toen we dit deden in Hoofdstuk 2?); waaronder:

  • Computationele efficiëntie: Gevectoriseerde operaties zijn sneller.
  • Geheugenbeheer: Hele datasets passen niet in het geheugen.
  • Regularisatie-effect: Ruis van verschillende batches helpt overfitting te vermijden.
  • Snellere convergentie: Frequentere updates leiden vaak tot sneller leren.

Deze balans van efficiëntie, schaalbaarheid en regularisatie is waarom mini-batch stochastic gradient descent de standaard optimalisatiemethode in deep learning is geworden.


De Complete Trainingslus

Laten we alles samenbrengen in de context van het trainen van ons cijferherkenningsnetwerk en bekijken hoe een volledige trainingslus eruitziet. Tijdens training lopen we door de gehele dataset; dit noemen we een "epoch". Voor elke epoch gebeurt het volgende:

  1. Forward Pass:

    • Voer een batch afbeeldingen door het netwerk.
    • Verkrijg voorspellingen voor elke afbeelding.
  2. Loss-Berekening:

    • Vergelijk voorspellingen met correcte labels.
    • Bereken cross-entropy loss.
  3. Backpropagation:

    • Bereken gradiënten voor alle gewichten.
    • Traceer de fout achterwaarts door alle lagen.
  4. Gewichtsupdate:

    • Pas gradient descent toe op alle gewichten.
    • new_weight = old_weight - lr × gradient.
  5. Herhaal:

    • Ga naar de volgende batch.

Naarmate de loss afneemt, neemt de nauwkeurigheid van het model toe:

Line plot showing decreasing loss and increasing accuracy over training epochs

Een typische trainingstijdlijn kan er ongeveer zo uitzien:

  • Epoch 1: 30% nauwkeurigheid, hoge loss (netwerk leert basispatronen).
  • Epoch 5: 70% nauwkeurigheid, dalende loss (herkenning van veelvoorkomende cijferfeatures).
  • Epoch 10: 85% nauwkeurigheid, lage loss (fijnslijpen van moeilijke gevallen).
  • Epoch 20: 92% nauwkeurigheid, zeer lage loss (bijna optimale prestaties).

Door dit iteratieve proces verfijnt het netwerk geleidelijk zijn parameters totdat het cijfers betrouwbaar met hoge nauwkeurigheid kan herkennen.


Geavanceerde Optimalisatietechnieken

Hoewel basis-gradient descent werkt, gebruikt modern deep learning geavanceerdere optimizers die het leerproces aanpassen.

Momentum: Onthoudt eerdere gradiënten om updates te vervlakken en leren te versnellen in consistente richtingen.

Adam Optimizer: Past learning rates per parameter individueel aan op basis van historische gradiënten. Combineert voordelen van momentum met adaptieve learning rates. Meest populaire optimizer voor deep learning.

Geavanceerde optimizers convergeren sneller en bereiken effectievere oplossingen sneller dan traditionele methoden. Ze zijn ook robuuster, minder gevoelig voor de learning rate, en kunnen hun gedrag tijdens training dynamisch aanpassen om beter bij het probleem te passen.


Training Monitoren: Hoe Weet Je Dat Het Werkt

Het trainen van neurale netwerken vereist zorgvuldige monitoring om te verzekeren dat het proces correct verloopt:

  • Trainingsloss: Zou gestaag in de loop van de tijd moeten dalen.
  • Validatienauwkeurigheid: Zou moeten stijgen en redelijk sporen met training.
  • Leercurves: Grafieken die voortgang in de tijd tonen.

Tekenen van gezonde training zijn:

  • Loss daalt soepel (met wat ruis).
  • Validatieprestaties verbeteren samen met trainingsprestaties.
  • Het netwerk doet steeds zinvollere voorspellingen.

We zullen enkele waarschuwingen voor slechte training in het volgende hoofdstuk verkennen!


Belangrijkste Inzichten

Het trainen van diepe neurale netwerken combineert backpropagation en gradient descent om systematisch miljoenen parameters aan te passen van willekeurige initiatie naar intelligent gedrag. De forward pass genereert voorspellingen door data door lagen van gewogen verbindingen en activatiefuncties te laten stromen. Loss functions kwantificeren voorspellingsfouten op manieren die het leren richting gewenste uitkomsten sturen. Backpropagation gebruikt de kettingregel uit de calculus om efficiënt gradiënten voor elk gewicht te berekenen en te bepalen hoe elke parameter bijdraagt aan de totale fout.

Gradient descent gebruikt deze gradiënten om gewichten bij te werken in richtingen die de loss verminderen, waarbij de learning rate de stapgrootte bepaalt. Moderne optimizers bouwen voort op basis-gradient descent door learning rates aan te passen. Het begrijpen van dit trainingsproces onthult hoe neurale netwerken transformeren van willekeurige functies naar geavanceerde patroonherkenningssystemen via systematische wiskundige optimalisatie.