Implementatie van Backpropagation
Algemene aanpak
Bij voorwaartse propagatie neemt elke laag l de uitvoer van de vorige laag, al−1, als invoer en berekent zijn eigen uitvoer. Daarom neemt de forward()-methode van de Layer-klasse de vector van vorige uitkomsten als enige parameter, terwijl de overige benodigde informatie binnen de klasse wordt opgeslagen.
Bij achterwaartse propagatie heeft elke laag l alleen dal nodig om de respectievelijke gradiënten te berekenen en dal−1 terug te geven, dus de backward()-methode neemt de dal-vector als parameter. De overige benodigde informatie is al opgeslagen in de Layer-klasse.
Afgeleiden van activatiefuncties
Omdat de afgeleiden van activatiefuncties vereist zijn voor achterwaartse propagatie, moeten activatiefuncties zoals ReLU en sigmoid als klassen worden geïmplementeerd in plaats van als losse functies. Deze structuur maakt het mogelijk beide componenten duidelijk te definiëren:
- De activatiefunctie zelf — geïmplementeerd met de
__call__()-methode, zodat deze direct kan worden toegepast in deLayer-klasse metself.activation(z); - De afgeleide ervan — geïmplementeerd met de
derivative()-methode, waardoor efficiënte berekening tijdens achterwaartse propagatie mogelijk is viaself.activation.derivative(z).
Het representeren van activatiefuncties als objecten maakt het eenvoudig om ze aan verschillende lagen door te geven en dynamisch toe te passen tijdens zowel voorwaartse als achterwaartse propagatie.
ReLu
De afgeleide van de ReLU-activatiefunctie is als volgt, waarbij zi een element is van de vector van pre-activaties z:
f′(zi)={1,zi>00,zi≤0class ReLU:
def __call__(self, z):
return np.maximum(0, z)
def derivative(self, z):
return (z > 0).astype(float)
Sigmoid
De afgeleide van de sigmoid activatiefunctie is als volgt:
f′(zi)=f(zi)⋅(1−f(zi))class Sigmoid:
def __call__(self, x):
return 1 / (1 + np.exp(-z))
def derivative(self, z):
sig = self(z)
return sig * (1 - sig)
Voor beide activatiefuncties wordt de bewerking toegepast op de volledige vector z, evenals op de afgeleide daarvan. NumPy voert de berekening elementgewijs uit, wat betekent dat elk element van de vector onafhankelijk wordt verwerkt.
Als de vector z bijvoorbeeld drie elementen bevat, wordt de afgeleide als volgt berekend:
f′(z)=f′z1z2z3=f′(z1)f′(z2)f′(z3)De backward()-methode
De backward()-methode is verantwoordelijk voor het berekenen van de gradiënten met behulp van de onderstaande formules:
a^{l-1} en zl worden respectievelijk opgeslagen als de attributen inputs en outputs in de Layer-klasse. De activatiefunctie f wordt opgeslagen als het attribuut activation.
Zodra alle benodigde gradiënten zijn berekend, kunnen de gewichten en biases worden bijgewerkt, aangezien ze niet langer nodig zijn voor verdere berekeningen:
Wlbl=Wl−α⋅dWl=bl−α⋅dblDaarom is learning_rate (α) een andere parameter van deze methode.
def backward(self, da, learning_rate):
dz = ...
d_weights = ...
d_biases = ...
da_prev = ...
self.weights -= learning_rate * d_weights
self.biases -= learning_rate * d_biases
return da_prev
De *-operator voert elementgewijze vermenigvuldiging uit, terwijl de functie np.dot() een dotproduct uitvoert in NumPy. Het attribuut .T transponeert een array.
Bedankt voor je feedback!
Vraag AI
Vraag AI
Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.
Awesome!
Completion rate improved to 4
Implementatie van Backpropagation
Veeg om het menu te tonen
Algemene aanpak
Bij voorwaartse propagatie neemt elke laag l de uitvoer van de vorige laag, al−1, als invoer en berekent zijn eigen uitvoer. Daarom neemt de forward()-methode van de Layer-klasse de vector van vorige uitkomsten als enige parameter, terwijl de overige benodigde informatie binnen de klasse wordt opgeslagen.
Bij achterwaartse propagatie heeft elke laag l alleen dal nodig om de respectievelijke gradiënten te berekenen en dal−1 terug te geven, dus de backward()-methode neemt de dal-vector als parameter. De overige benodigde informatie is al opgeslagen in de Layer-klasse.
Afgeleiden van activatiefuncties
Omdat de afgeleiden van activatiefuncties vereist zijn voor achterwaartse propagatie, moeten activatiefuncties zoals ReLU en sigmoid als klassen worden geïmplementeerd in plaats van als losse functies. Deze structuur maakt het mogelijk beide componenten duidelijk te definiëren:
- De activatiefunctie zelf — geïmplementeerd met de
__call__()-methode, zodat deze direct kan worden toegepast in deLayer-klasse metself.activation(z); - De afgeleide ervan — geïmplementeerd met de
derivative()-methode, waardoor efficiënte berekening tijdens achterwaartse propagatie mogelijk is viaself.activation.derivative(z).
Het representeren van activatiefuncties als objecten maakt het eenvoudig om ze aan verschillende lagen door te geven en dynamisch toe te passen tijdens zowel voorwaartse als achterwaartse propagatie.
ReLu
De afgeleide van de ReLU-activatiefunctie is als volgt, waarbij zi een element is van de vector van pre-activaties z:
f′(zi)={1,zi>00,zi≤0class ReLU:
def __call__(self, z):
return np.maximum(0, z)
def derivative(self, z):
return (z > 0).astype(float)
Sigmoid
De afgeleide van de sigmoid activatiefunctie is als volgt:
f′(zi)=f(zi)⋅(1−f(zi))class Sigmoid:
def __call__(self, x):
return 1 / (1 + np.exp(-z))
def derivative(self, z):
sig = self(z)
return sig * (1 - sig)
Voor beide activatiefuncties wordt de bewerking toegepast op de volledige vector z, evenals op de afgeleide daarvan. NumPy voert de berekening elementgewijs uit, wat betekent dat elk element van de vector onafhankelijk wordt verwerkt.
Als de vector z bijvoorbeeld drie elementen bevat, wordt de afgeleide als volgt berekend:
f′(z)=f′z1z2z3=f′(z1)f′(z2)f′(z3)De backward()-methode
De backward()-methode is verantwoordelijk voor het berekenen van de gradiënten met behulp van de onderstaande formules:
a^{l-1} en zl worden respectievelijk opgeslagen als de attributen inputs en outputs in de Layer-klasse. De activatiefunctie f wordt opgeslagen als het attribuut activation.
Zodra alle benodigde gradiënten zijn berekend, kunnen de gewichten en biases worden bijgewerkt, aangezien ze niet langer nodig zijn voor verdere berekeningen:
Wlbl=Wl−α⋅dWl=bl−α⋅dblDaarom is learning_rate (α) een andere parameter van deze methode.
def backward(self, da, learning_rate):
dz = ...
d_weights = ...
d_biases = ...
da_prev = ...
self.weights -= learning_rate * d_weights
self.biases -= learning_rate * d_biases
return da_prev
De *-operator voert elementgewijze vermenigvuldiging uit, terwijl de functie np.dot() een dotproduct uitvoert in NumPy. Het attribuut .T transponeert een array.
Bedankt voor je feedback!