- Je berekent en controleert de gradiënten van een lineaire regressie.
- Je traint met gradient descent en vergelijkt de eindparameters met een bekende oplossing.
Je kunt de beste rechte lijn direct uitrekenen. Maar bij een groter model bestaat vaak geen bruikbare gesloten formule. Daarom trainen we dezelfde lijn nu met kleine verbeterstappen: een aanpak die je later ook voor een neuraal netwerk gebruikt.
Je kent de gradiënt als richting van sterkste lokale stijging. Hier zijn de twee instellingen helling w en intercept b; de hoogte van het landschap is de MSE. Beide knoppen beïnvloeden dezelfde voorspellingen, dus hun gevoeligheden moeten bij dezelfde oude instellingen horen.
1. Van een voorspelfout naar twee gevoeligheden
Neem twee trainingsparen: x = [−1, 1] en y = [−1, 3]. Ze liggen op de lijn met w = 2 en b = 1. Start echter bij w = b = 0: beide voorspellingen zijn nul en de MSE is (1 + 9)/2 = 5.
Voor de afgeleide schrijven we de fout nu als voorspelling min doel, het omgekeerde teken van het residu. Het kwadraat verandert daardoor niet. Noem deze fout e en het gemiddelde verlies L:
i wijst een meetpaar aan en n is het aantal paren. De afgeleide van een kwadraat geeft 2e. De kettingregel vermenigvuldigt dat voor w met x, en voor b met 1; de factor 1/n blijft staan.
Het teken ∂ benoemt een partiële afgeleide: verander één instelling terwijl de andere vast blijft. Bij ons startpunt is e = [1, −3]. De producten x maal e zijn [−1, −3], dus dw = −4 en db = −2.
def lijn_gradient(xs, ys, w, b):
if not xs or len(xs) != len(ys):
raise ValueError("Ongeldige paren")
sw = 0
sb = 0
for i in range(len(xs)):
e = w * xs[i] + b - ys[i]
sw = sw + xs[i] * e
sb = sb + e
return (2 * sw / len(xs),
2 * sb / len(xs))
xs = [-1, 1]
ys = [-1, 3]
print(lijn_gradient(xs, ys, 0, 0))
# (-4.0, -2.0)
Maak deze functie voor kleine eindige waarden; lege of ongelijk lange lijsten geven ValueError. Gebruik dezelfde foutconventie in beide componenten. De controle vergelijkt je gradiënt ook met centrale verschillen, zoals in de eerdere gradiëntenles.
012. Eén gezamenlijk vertrekpunt
Trek een klein deel van iedere afgeleide af. Met leersnelheid eta = 0.1 wordt w gelijk aan 0 − 0.1 × (−4) = 0.4, en b aan 0 − 0.1 × (−2) = 0.2. De negatieve gevoeligheden betekenen hier dat verhogen het verlies lokaal verlaagt.
η is de Griekse letter eta; dw en db zijn de twee zojuist berekende gevoeligheden. Veelgemaakte fout: eerst w wijzigen en daarna db opnieuw berekenen. Dan gebruik je twee verschillende vertrekpunten en voer je een ander algoritme uit.
def lijn_stap(xs, ys, w, b, eta):
dw, db = lijn_gradient(xs, ys, w, b)
return (w - eta * dw, b - eta * db)
w, b = lijn_stap(xs, ys, 0, 0, 0.1)
print(w, b) # 0.4 0.2
De toewijzing dw, db = ... pakt de twee waarden uit het teruggegeven paar. Maak lijn_stap met één gradiëntberekening. Bewaar de invoerlijsten; alleen het nieuwe parameterpaar wordt teruggegeven.
3. Controleer verbetering met het echte verlies
Met de nieuwe lijn zijn de voorspellingen −0.2 en 0.6, dus e = [0.8, −2.4]. De MSE is (0.64 + 5.76)/2 = 3.2. Bereken het verlies zelf, zodat je niet alleen naar bewegende parameters kijkt.
def lijn_loss(xs, ys, w, b):
totaal = 0
for i in range(len(xs)):
e = w * xs[i] + b - ys[i]
totaal = totaal + e ** 2
return totaal / len(xs)
print(lijn_loss(xs, ys, w, b)) # 3.2
wg, bg = lijn_stap(xs, ys, 0, 0, 1.1)
print(lijn_loss(xs, ys, wg, bg)) # 7.2
Een stap met eta = 1.1 verhoogt het verlies naar 7.2: de juiste richting garandeert geen goede stapgrootte. Verander eta tijdens onderzoek, maar vergelijk steeds dezelfde begininstellingen en trainingsdata.
Maak train_lijn(xs,ys,eta,stappen). Start bij w = b = 0 en geef (w,b,history) terug; history bevat eerst het beginverlies en daarna één waarde per update. Weiger lege/ongelijke lijsten en een negatief aantal stappen met ValueError; stappen is een geheel getal.
w = 0.0
b = 0.0
history = [lijn_loss(xs, ys, w, b)]
for i in range(2):
w, b = lijn_stap(xs, ys, w, b, 0.1)
history.append(lijn_loss(xs, ys, w, b))
print(w, b) # ongeveer 0.72, 0.36
print(history) # ongeveer [5, 3.2, 2.048]
Bij nul stappen blijft history één lang. Meer kleine stappen brengen deze lijn richting (2, 1), maar een dalende trainingsloss bewijst nog geen goede voorspellingen op onbekende data.
03Wat neem je mee?
- De kettingregel geeft één gevoeligheid voor helling en één voor intercept.
- Beide updates gebruiken hetzelfde oude parameterpaar.
- Bewaar het werkelijk berekende verlies, inclusief het beginpunt, en controleer de stapgrootte.
Hierna vergelijk je je eigen regressie met een bibliotheekmodel op apart gehouden testdata.