ICT Horse Logo

iCt Horse

connecting the dots

Email: info@icthorse.nl

Telefoon: +31610323432

KvK: 96787112 | BTW: NL002996606B14

Module 2 van 8

Gradient Descent

Hoe vindt een AI de juiste gewichten? Het geheim achter machine learning: afdalen naar het dal van de minste fouten.

1. Het probleem: hoe leert een machine?

In Module 1 zagen we dat een perceptron gewichten en een bias nodig heeft om te werken. We gebruikten een simpele leerregel: als het antwoord fout is, schuif de gewichten een beetje. Maar bij complexere problemen werkt dat niet meer.

De vraag is: hoe vind je systematisch de beste gewichten?

Analogie: Stel je voor dat je geblinddoekt op een berg staat en het dal moet bereiken. Je kunt niet zien, maar je kunt wél voelen welke kant het afloopt. Elke stap neem je in de richting waar het het steilst naar beneden gaat. Dat is gradient descent — afdalen langs de steilste helling.

De "berg" is de loss function (foutfunctie) — een formule die meet hoe ver je model ernaast zit. De "hoogte" is de fout. Het "dal" is het punt waar de fout het kleinst is. Gradient descent helpt je daar te komen.

2. Loss functions: fouten meten

Voordat je kunt leren, moet je kunnen meten hoe fout je model is. Dat doet een loss function. De twee meest gebruikte:

Mean Squared Error (MSE)

MSE = gemiddelde van (verwacht - voorspeld)²

Je neemt het verschil tussen wat je verwacht en wat het model voorspelt, kwadreert dat (zodat negatieve fouten ook meetellen), en neemt het gemiddelde over alle voorbeelden.

Verwacht Voorspeld Verschil Kwadraat
10.70.30.09
00.2-0.20.04
10.90.10.01
MSE = (0.09 + 0.04 + 0.01) / 3 = 0.047
Waarom kwadrateren? Twee redenen: (1) negatieve en positieve fouten tellen allebei mee, en (2) grote fouten worden extra bestraft. Een fout van 0.5 weegt 6.25x zwaarder dan een fout van 0.2.

Mean Absolute Error (MAE)

MAE = gemiddelde van |verwacht - voorspeld|

Simpeler — neem gewoon de absolute waarde van elk verschil. Minder gevoelig voor uitschieters, maar lastiger om mee te rekenen bij gradient descent.

3. De gradient: welke kant op?

Nu je weet hoe je fouten meet, is de volgende vraag: hoe pas je de gewichten aan zodat de fout kleiner wordt?

Hier komt de afgeleide (derivative) om de hoek kijken. De afgeleide van de loss function ten opzichte van een gewicht vertelt je:

wnieuw = woud - learning_rate × ∂Loss / ∂w

Het minteken is cruciaal: je gaat de tegenovergestelde richting van de gradient op. Als de helling omhoog gaat (positieve gradient), verklein je het gewicht. Als de helling omlaag gaat (negatieve gradient), vergroot je het.

Analogie: De gradient is als een kompas op de berg. Het wijst altijd bergopwaarts. Jij wilt naar beneden, dus je loopt de tegenovergestelde kant op.

De afgeleide van MSE

Voor een enkel neuron met één gewicht en MSE als loss:

Loss = (verwacht - voorspeld)²

voorspeld = w × x + b

∂Loss / ∂w = -2 × (verwacht - voorspeld) × x

∂Loss / ∂b = -2 × (verwacht - voorspeld)

In de praktijk laten we de factor 2 vaak weg (het is toch maar een constante die de learning rate absorbeert).

4. Learning rate: de stapgrootte

De learning rate (leertempo) bepaalt hoe groot elke stap is. Dit is een van de belangrijkste keuzes in machine learning.

Learning rate Effect Risico
Te klein (0.0001) Hele kleine stapjes, zeer langzaam Duurt eeuwen, kan vastlopen in lokaal minimum
Goed (0.01 - 0.1) Stabiele convergentie
Te groot (1.0+) Grote sprongen, overschiet het dal Stuitert heen en weer, convergeert nooit
Analogie: Terug naar de geblinddoekte bergbeklimmer. Een te kleine learning rate is alsof je babystapjes neemt — je komt er wel, maar het duurt uren. Een te grote learning rate is alsof je reuzensprongen maakt — je springt over het dal heen en landt aan de andere kant, weer bergop.

5. Varianten van gradient descent

Het basis-algoritme heeft drie varianten, afhankelijk van hoeveel data je per stap gebruikt:

Variant Data per stap Eigenschap
Batch GD Alle data Stabiel maar langzaam bij grote datasets
Stochastic GD (SGD) 1 voorbeeld Snel maar onrustig (veel ruis)
Mini-batch GD Klein groepje (16-256) Beste van beide werelden — dit wordt het meest gebruikt
In de praktijk: Bijna alle moderne AI-systemen (inclusief ChatGPT en Claude) zijn getraind met mini-batch gradient descent, vaak met geavanceerde varianten zoals Adam — een optimizer die de learning rate automatisch per gewicht aanpast.

6. Python code: gradient descent in actie

We trainen een enkel neuron om een simpele functie te leren: y = 2x + 1

import random

# --- Data genereren: y = 2x + 1 ---
data = []
for _ in range(100):
    x = random.uniform(0, 10)
    y = 2 * x + 1 + random.gauss(0, 0.5)  # beetje ruis
    data.append((x, y))

# --- Neuron parameters ---
w = random.uniform(-1, 1)   # gewicht (we zoeken: 2)
b = random.uniform(-1, 1)   # bias    (we zoeken: 1)
lr = 0.001                    # learning rate

# --- Training loop ---
for epoch in range(200):
    total_loss = 0

    for x, y_true in data:
        # Forward pass
        y_pred = w * x + b

        # Loss (MSE per punt)
        loss = (y_true - y_pred) ** 2
        total_loss += loss

        # Gradient berekenen
        dw = -2 * (y_true - y_pred) * x   # dLoss/dw
        db = -2 * (y_true - y_pred)       # dLoss/db

        # Gewichten updaten
        w -= lr * dw
        b -= lr * db

    avg_loss = total_loss / len(data)
    if epoch % 20 == 0:
        print(f"Epoch {epoch:3d} | Loss: {avg_loss:.4f} | w={w:.4f}, b={b:.4f}")

print(f"\nGeleerd: y = {w:.2f}x + {b:.2f}")
print(f"Werkelijk: y = 2.00x + 1.00")

Verwachte output (ongeveer):

Epoch   0 | Loss: 45.2310 | w=0.8321, b=-0.1234
Epoch  20 | Loss:  1.3456 | w=1.7823, b=0.6543
Epoch  40 | Loss:  0.2891 | w=1.9567, b=0.9234
...
Epoch 180 | Loss:  0.2501 | w=2.0012, b=0.9987

Geleerd: y = 2.00x + 1.00
Werkelijk: y = 2.00x + 1.00

Interactieve demo 1: De bal die het dal zoekt

Versleep de bal naar een startpositie en klik Start. De bal daalt af langs de loss-curve via gradient descent. Experimenteer met de learning rate!

0.050
Positie (w)
0.00
Loss
0.00
Gradient
0.00
Stap
0

Interactieve demo 2: Een lijn leren

Het neuron probeert een rechte lijn te fitten door de datapunten. Klik Train en kijk hoe de lijn (en de loss) zich aanpast. Je kunt ook eigen punten klikken op het linkervlak.

0.0050
w (helling)
0.00
b (snijpunt)
0.00
Loss (MSE)
0.00
Epoch
0

7. Valkuilen: lokale minima en zadelpunten

Bij een simpele functie zoals x² is er maar één dal — het globale minimum. Maar bij complexe neurale netwerken is het landschap vol heuvels en dalen.

Probeer in Demo 1 het "Hobbelig landschap" en start de bal op verschillende posities. Je zult zien dat hij soms in een lokaal minimum landt, niet in het diepste dal.

Oplossingen in de praktijk:
  • Momentum — geef de bal "snelheid" zodat hij over kleine heuvels heen rolt
  • Random restarts — begin meerdere keren op verschillende plekken
  • Adam optimizer — past learning rate automatisch per gewicht aan
  • Stochastic noise — de ruis van SGD helpt om uit lokale minima te ontsnappen

8. Vooruitblik: backpropagation

Gradient descent werkt prima voor één neuron. Maar wat als je honderden neuronen in meerdere lagen hebt? Hoe bereken je dan de gradient voor elk gewicht?

Het antwoord is backpropagation — een slim algoritme dat de chain rule uit de wiskunde gebruikt om de fout "terug te propageren" van de output naar elke laag. In Module 3 gaan we dit in detail behandelen.

Chain rule: ∂Loss/∂w1 = ∂Loss/∂output × ∂output/∂hidden × ∂hidden/∂w1

Elke schakel in de keten vertelt hoe gevoelig de uiteindelijke fout is voor die specifieke weight. Zo kan elk gewicht in het netwerk individueel worden bijgestuurd.

Samenvatting

← Module 1: Neuronen Module 3: Neural Networks →

Een gratis cursus van iCt Horse — Connecting the dots