In de vorige lessen heb je gezien dat neurale netwerken gewichten hebben, en dat training die gewichten aanpast. Maar hoe weet het netwerk welke gewichten het moet veranderen, en met hoeveel? Het antwoord is backpropagation - het allerbelangrijkste algoritme in moderne deep learning.
Andrej Karpathy noemt het "het belangrijkste dat je moet begrijpen over neurale netwerken." Laten we kijken waarom.
Tijdens een forward pass stroomt data van links naar rechts door het netwerk:
De voorspelling wordt vervolgens vergeleken met het juiste antwoord via een verliesfunctie (behandeld in de volgende les). Het verlies is één enkel getal dat zegt: "Dit is hoe fout je zit."
Stel je voor dat je een taart bakt en die vreselijk smaakt. Je hebt vijf ingrediënten gebruikt. De vraag is: welk ingrediënt droeg het meest bij aan de slechte smaak, en in welke mate?
Backpropagation beantwoordt precies deze vraag voor neurale netwerken. Het wijst schuld toe aan elk afzonderlijk gewicht door te vragen: "Als ik dit gewicht een klein beetje verschuif, hoeveel verandert het verlies dan?"
Die mate van verandering wordt een gradiënt genoemd, en die komt uit de calculus - meer specifiek de afgeleide.
Geoffrey Hinton, een van de "peetvaders van AI," heeft gezegd dat backpropagation het kernidee is dat deep learning praktisch toepasbaar maakte. Zonder dit zou het trainen van netwerken met miljoenen parameters rekenkundig onmogelijk zijn.
Neurale netwerken zijn ketens van eenvoudige bewerkingen die samen worden gecombineerd. De kettingregel uit de calculus vertelt ons hoe we samengestelde functies moeten differentiëren:
Sign in to join the discussion
Als
y = f(g(x)), dandy/dx = f'(g(x)) × g'(x).
Alledaagse analogie: Je rijdt naar een winkel. Je snelheid hangt af van hoe hard je het gaspedaal indrukt. De stand van het gaspedaal hangt af van het verkeer. Om te weten hoe het verkeer je snelheid beïnvloedt, vermenigvuldig je: (snelheid per gaspedaalindrukking) × (gaspedaalindrukking per verkeerssituatie). Dat is de kettingregel - het vermenigvuldigen van lokale veranderingssnelheden langs een keten.
Backpropagation werd gepopulariseerd in een baanbrekend artikel uit 1986 door Rumelhart, Hinton en Williams, maar het kernidee van reverse-mode automatische differentiatie dateert uit de jaren zestig.
Moderne frameworks zoals PyTorch bouwen een berekeningsgraaf op tijdens de forward pass. Elke bewerking - optellen, vermenigvuldigen, ReLU - wordt een knooppunt. Backpropagation doorloopt deze graaf vervolgens in omgekeerde richting, waarbij de kettingregel bij elk knooppunt wordt toegepast om gradiënten te berekenen.
Zie het als een rivierenstelsel. Het verlies is de oceaan aan het einde. Backprop volgt elke zijrivier stroomopwaarts om te achterhalen hoeveel elke bron (gewicht) heeft bijgedragen aan de uiteindelijke stroom.
Stel L = (w × x - y)² met w = 2, x = 3, y = 10.
w × x = 6, dan 6 - 10 = -4, dan (-4)² = 16. Verlies = 16.dL/d(diff) = 2 × (-4) = -8, dan d(diff)/d(wx) = 1, dus dL/d(wx) = -8.d(wx)/dw = x = 3, dus dL/dw = -8 × 3 = -24.De gradiënt van −24 vertelt ons: het verhogen van w zal het verlies snel doen afnemen. Dat is precies het signaal dat we nodig hebben om te verbeteren.
Wat doen we bij de kettingregel met de lokale afgeleiden bij elk knooppunt?
In een diep netwerk moeten gradiënten door veel lagen reizen. Elke laag vermenigvuldigt de gradiënt met zijn lokale afgeleide. Dit creëert twee gevaarlijke faalmodi:
Als lokale afgeleiden klein zijn (bijv. de sigmoid-functie verzadigt dicht bij 0 of 1), maakt herhaalde vermenigvuldiging de gradiënten steeds kleiner richting nul. Vroege lagen leren nauwelijks - ze ontvangen bijna geen signaal. Dit was een groot probleem bij vroege diepe netwerken.
Als lokale afgeleiden groot zijn, groeien gradiënten exponentieel. Gewichten krijgen enorme updates en het netwerk wordt instabiel, wat NaN-waarden oplevert.
De afgeleide van ReLU is ofwel 0 of 1 - het verkleint de gradiënt nooit wanneer het actief is. Waarom zou deze eenvoudige eigenschap revolutionair zijn geweest voor het trainen van diepe netwerken?
Moderne oplossingen zijn onder meer:
Zodra backprop elke gradiënt heeft berekend, werkt de optimalisator (volgende les) elk gewicht bij:
w_nieuw = w_oud - leersnelheid × gradiënt
De leersnelheid bepaalt de stapgrootte. Te groot en je schiet door; te klein en het trainen duurt eindeloos. De gradiënt geeft de richting aan; de leersnelheid bepaalt hoe ver je stapt.
Wat veroorzaakt verdwijnende gradiënten in diepe netwerken?
Elke keer dat ChatGPT zijn volgend-woord-voorspelling verbetert, elke keer dat een zelfrijdende auto zijn besturing verfijnt, draait backpropagation op de achtergrond. Het is het algoritme dat leren van fouten wiskundig nauwkeurig maakt.
Zonder backprop zouden we geen efficiënte manier hebben om netwerken met miljoenen - of miljarden - parameters te trainen.
Wat vertelt een gradiënt ons over een gewicht?
Karpathy benadrukt dat backprop "gewoon een herhaalde toepassing van de kettingregel" is. Als je de kettingregel en berekeningsgrafen begrijpt, begrijp je backprop. Welke andere complexe systemen zouden begrepen kunnen worden door ze op te splitsen in eenvoudige, samenvoegbare onderdelen?