Implementering av Backpropagation
Svep för att visa menyn
Allmän metod
Vid framåtriktad propagiering tar varje lager l utdata från föregående lager, al−1, som indata och beräknar sina egna utdata. Därför tar metoden forward() i klassen Layer vektorn av föregående utdata som sin enda parameter, medan övrig nödvändig information lagras inom klassen.
Vid bakåtriktad propagiering behöver varje lager l endast dal för att beräkna respektive gradienter och returnera dal−1, så metoden backward() tar vektorn dal som sin parameter. Resterande nödvändig information finns redan lagrad i klassen Layer.
Derivator av aktiveringsfunktioner
Eftersom derivator av aktiveringsfunktioner krävs för bakåtriktad propagiering, bör aktiveringsfunktioner som ReLU och sigmoid implementeras som klasser istället för fristående funktioner. Denna struktur gör det möjligt att tydligt definiera båda komponenterna:
- Själva aktiveringsfunktionen — implementerad med metoden
__call__(), så att den kan användas direkt i klassenLayermedself.activation(z); - Dess derivata — implementerad med metoden
derivative(), vilket möjliggör effektiv beräkning under bakåtriktad propagiering viaself.activation.derivative(z).
Att representera aktiveringsfunktioner som objekt gör det enkelt att överföra dem till olika lager och använda dem dynamiskt under både framåtriktad och bakåtriktad propagiering.
ReLu
Derivatan av ReLU-aktiveringsfunktionen är följande, där zi är ett element i vektorn av pre-aktiveringar 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
Derivatan av sigmoid-aktiveringsfunktionen är följande:
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)
För båda aktiveringsfunktionerna tillämpas operationen på hela vektorn z, samt på dess derivata. NumPy utför automatiskt beräkningen elementvis, vilket innebär att varje element i vektorn behandlas oberoende.
Till exempel, om vektorn z innehåller tre element, beräknas derivatan som:
f′(z)=f′z1z2z3=f′(z1)f′(z2)f′(z3)backward()-metoden
Metoden backward() ansvarar för att beräkna gradienterna med hjälp av formlerna nedan:
a^{l-1} och zl lagras som attributen inputs och outputs i klassen Layer, respektive. Aktiveringsfunktionen f lagras som attributet activation.
När alla nödvändiga gradienter har beräknats kan vikterna och biaserna uppdateras eftersom de inte längre behövs för vidare beräkning:
Wlbl=Wl−α⋅dWl=bl−α⋅dblDärför är learning_rate (α) en annan parameter för denna metod.
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
Operatorn * utför elementvis multiplikation, medan funktionen np.dot() utför skalärprodukt i NumPy. Attributet .T transponerar en array.
Tack för dina kommentarer!
Fråga AI
Fråga AI
Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal