Implementering af Backpropagation
Stryg for at vise menuen
Generel tilgang
Ved fremadpropagering tager hvert lag l outputtet fra det forrige lag, al−1, som input og beregner sit eget output. Derfor tager forward()-metoden i Layer-klassen vektoren af forrige output som sin eneste parameter, mens resten af den nødvendige information er gemt i klassen.
Ved bagudpropagering behøver hvert lag l kun dal for at beregne de respektive gradienter og returnere dal−1, så backward()-metoden tager dal-vektoren som parameter. Resten af den nødvendige information er allerede gemt i Layer-klassen.
Afledte aktiveringsfunktioner
Da afledte aktiveringsfunktioner er nødvendige for bagudpropagering, bør aktiveringsfunktioner som ReLU og sigmoid implementeres som klasser i stedet for selvstændige funktioner. Denne struktur gør det muligt at definere begge komponenter tydeligt:
- Selve aktiveringsfunktionen — implementeret med
__call__()-metoden, så den kan anvendes direkte iLayer-klassen medself.activation(z); - Dens afledte — implementeret med
derivative()-metoden, hvilket muliggør effektiv beregning under bagudpropagering viaself.activation.derivative(z).
Repræsentation af aktiveringsfunktioner som objekter gør det nemt at videregive dem til forskellige lag og anvende dem dynamisk under både fremad- og bagudpropagering.
ReLu
Afledte af ReLU-aktiveringsfunktionen er som følger, hvor zi er et element i vektoren af præ-aktiveringer 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
Afledte af sigmoid-aktiveringsfunktionen er som følger:
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)
For begge aktiveringsfunktioner anvendes operationen på hele vektoren z, samt på dens afledte. NumPy udfører automatisk beregningen elementvist, hvilket betyder, at hvert element i vektoren behandles uafhængigt.
For eksempel, hvis vektoren z indeholder tre elementer, beregnes den afledte som:
f′(z)=f′z1z2z3=f′(z1)f′(z2)f′(z3)backward()-metoden
Metoden backward() er ansvarlig for beregning af gradienterne ved hjælp af formlerne nedenfor:
a^{l-1} og zl gemmes som attributterne inputs og outputs i klassen Layer, henholdsvis. Aktiveringsfunktionen f gemmes som attributten activation.
Når alle nødvendige gradienter er beregnet, kan vægte og bias opdateres, da de ikke længere er nødvendige for yderligere beregning:
Wlbl=Wl−α⋅dWl=bl−α⋅dblDerfor er learning_rate (α) en anden parameter for denne metode.
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
Operatoren * udfører elementvis multiplikation, mens funktionen np.dot() udfører dot-produkt i NumPy. Attributten .T transponerer et array.
Tak for dine kommentarer!
Spørg AI
Spørg AI
Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat
Implementering af Backpropagation
Generel tilgang
Ved fremadpropagering tager hvert lag l outputtet fra det forrige lag, al−1, som input og beregner sit eget output. Derfor tager forward()-metoden i Layer-klassen vektoren af forrige output som sin eneste parameter, mens resten af den nødvendige information er gemt i klassen.
Ved bagudpropagering behøver hvert lag l kun dal for at beregne de respektive gradienter og returnere dal−1, så backward()-metoden tager dal-vektoren som parameter. Resten af den nødvendige information er allerede gemt i Layer-klassen.
Afledte aktiveringsfunktioner
Da afledte aktiveringsfunktioner er nødvendige for bagudpropagering, bør aktiveringsfunktioner som ReLU og sigmoid implementeres som klasser i stedet for selvstændige funktioner. Denne struktur gør det muligt at definere begge komponenter tydeligt:
- Selve aktiveringsfunktionen — implementeret med
__call__()-metoden, så den kan anvendes direkte iLayer-klassen medself.activation(z); - Dens afledte — implementeret med
derivative()-metoden, hvilket muliggør effektiv beregning under bagudpropagering viaself.activation.derivative(z).
Repræsentation af aktiveringsfunktioner som objekter gør det nemt at videregive dem til forskellige lag og anvende dem dynamisk under både fremad- og bagudpropagering.
ReLu
Afledte af ReLU-aktiveringsfunktionen er som følger, hvor zi er et element i vektoren af præ-aktiveringer 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
Afledte af sigmoid-aktiveringsfunktionen er som følger:
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)
For begge aktiveringsfunktioner anvendes operationen på hele vektoren z, samt på dens afledte. NumPy udfører automatisk beregningen elementvist, hvilket betyder, at hvert element i vektoren behandles uafhængigt.
For eksempel, hvis vektoren z indeholder tre elementer, beregnes den afledte som:
f′(z)=f′z1z2z3=f′(z1)f′(z2)f′(z3)backward()-metoden
Metoden backward() er ansvarlig for beregning af gradienterne ved hjælp af formlerne nedenfor:
a^{l-1} og zl gemmes som attributterne inputs og outputs i klassen Layer, henholdsvis. Aktiveringsfunktionen f gemmes som attributten activation.
Når alle nødvendige gradienter er beregnet, kan vægte og bias opdateres, da de ikke længere er nødvendige for yderligere beregning:
Wlbl=Wl−α⋅dWl=bl−α⋅dblDerfor er learning_rate (α) en anden parameter for denne metode.
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
Operatoren * udfører elementvis multiplikation, mens funktionen np.dot() udfører dot-produkt i NumPy. Attributten .T transponerer et array.
Tak for dine kommentarer!