Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Implementering af Backpropagation | Neuralt Netværk fra Bunden
Introduktion til neurale netværk

bookImplementering af Backpropagation

Generel tilgang

Ved fremadpropagering tager hvert lag ll outputtet fra det forrige lag, al1a^{l-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 tilbagepropagering behøver hvert lag ll kun dalda^l for at beregne de respektive gradienter og returnere dal1da^{l-1}, så backward()-metoden tager dalda^l-vektoren som sin parameter. Resten af den nødvendige information er allerede gemt i Layer-klassen.

Afledte af aktiveringsfunktioner

Da afledte af aktiveringsfunktioner er nødvendige for tilbagepropagering, bør aktiveringsfunktioner som ReLU og sigmoid struktureres som klasser i stedet for selvstændige funktioner. Dette gør det muligt at definere både:

  1. Selve aktiveringsfunktionen (implementeret via __call__()-metoden), så den kan anvendes direkte i Layer-klassen ved brug af self.activation(z);
  2. Dens afledte (implementeret via derivative()-metoden), hvilket muliggør effektiv tilbagepropagering og bruges i Layer-klassen som self.activation.derivative(z).

Ved at strukturere aktiveringsfunktioner som objekter kan de nemt videregives til Layer-klassen og bruges dynamisk.

ReLu

Den afledte af ReLU-aktiveringsfunktionen er som følger, hvor ziz_i er et element i vektoren af pre-aktiveringer zz:

f(zi)={1,zi>00,zi0f'(z_i) = \begin{cases} 1, z_i > 0\\ 0, z_i \le 0 \end{cases}
class ReLU:
    def __call__(self, z):
        return np.maximum(0, z)

    def derivative(self, z):
        return (z > 0).astype(float)

Sigmoid

Afledte af sigmoid aktiveringsfunktion er som følger:

f(zi)=f(zi)(1f(zi))f'(z_i) = f(z_i) \cdot (1 - f(z_i))
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 disse aktiveringsfunktioner anvendes de på hele vektoren zz, og det samme gælder for deres afledte. NumPy anvender internt operationen på hvert element i vektoren. For eksempel, hvis vektoren zz indeholder 3 elementer, er udledningen som følger:

f(z)=f([z1z2z3])=[f(z1)f(z2)f(z3)]f'(z) = f'( \begin{bmatrix} z_1\\ z_2\\ z_3 \end{bmatrix} ) = \begin{bmatrix} f'(z_1)\\ f'(z_2)\\ f'(z_3) \end{bmatrix}

Metoden backward()

Metoden backward() er ansvarlig for beregning af gradienterne ved hjælp af formlerne nedenfor:

dzl=dalfl(zl)dWl=dzl(al1)Tdbl=dzldal1=(Wl)Tdzl\begin{aligned} dz^l &= da^l \odot f'^l(z^l)\\ dW^l &= dz^l \cdot (a^{l-1})^T\\ db^l &= dz^l\\ da^{l-1} &= (W^l)^T \cdot dz^l \end{aligned}

a^{l-1} og zlz^l gemmes som henholdsvis attributterne inputs og outputs i klassen Layer. Aktiveringsfunktionen ff gemmes som attributten activation.

Når alle nødvendige gradienter er beregnet, kan vægte og biaser opdateres, da de ikke længere er nødvendige for yderligere beregning:

Wl=WlαdWlbl=blαdbl\begin{aligned} W^l &= W^l - \alpha \cdot dW^l\\ b^l &= b^l - \alpha \cdot db^l \end{aligned}

Derfor er learning_rate (α\alpha) 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
Note
Bemærk

Operatoren * udfører elementvis multiplikation, mens funktionen np.dot() udfører dot-produkt i NumPy. Attributten .T transponerer et array.

question mark

Hvilket af følgende beskriver bedst rollen for metoden backward() i Layer-klassen under backpropagation?

Select the correct answer

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 2. Kapitel 8

Spørg AI

expand

Spørg AI

ChatGPT

Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat

Awesome!

Completion rate improved to 4

bookImplementering af Backpropagation

Stryg for at vise menuen

Generel tilgang

Ved fremadpropagering tager hvert lag ll outputtet fra det forrige lag, al1a^{l-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 tilbagepropagering behøver hvert lag ll kun dalda^l for at beregne de respektive gradienter og returnere dal1da^{l-1}, så backward()-metoden tager dalda^l-vektoren som sin parameter. Resten af den nødvendige information er allerede gemt i Layer-klassen.

Afledte af aktiveringsfunktioner

Da afledte af aktiveringsfunktioner er nødvendige for tilbagepropagering, bør aktiveringsfunktioner som ReLU og sigmoid struktureres som klasser i stedet for selvstændige funktioner. Dette gør det muligt at definere både:

  1. Selve aktiveringsfunktionen (implementeret via __call__()-metoden), så den kan anvendes direkte i Layer-klassen ved brug af self.activation(z);
  2. Dens afledte (implementeret via derivative()-metoden), hvilket muliggør effektiv tilbagepropagering og bruges i Layer-klassen som self.activation.derivative(z).

Ved at strukturere aktiveringsfunktioner som objekter kan de nemt videregives til Layer-klassen og bruges dynamisk.

ReLu

Den afledte af ReLU-aktiveringsfunktionen er som følger, hvor ziz_i er et element i vektoren af pre-aktiveringer zz:

f(zi)={1,zi>00,zi0f'(z_i) = \begin{cases} 1, z_i > 0\\ 0, z_i \le 0 \end{cases}
class ReLU:
    def __call__(self, z):
        return np.maximum(0, z)

    def derivative(self, z):
        return (z > 0).astype(float)

Sigmoid

Afledte af sigmoid aktiveringsfunktion er som følger:

f(zi)=f(zi)(1f(zi))f'(z_i) = f(z_i) \cdot (1 - f(z_i))
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 disse aktiveringsfunktioner anvendes de på hele vektoren zz, og det samme gælder for deres afledte. NumPy anvender internt operationen på hvert element i vektoren. For eksempel, hvis vektoren zz indeholder 3 elementer, er udledningen som følger:

f(z)=f([z1z2z3])=[f(z1)f(z2)f(z3)]f'(z) = f'( \begin{bmatrix} z_1\\ z_2\\ z_3 \end{bmatrix} ) = \begin{bmatrix} f'(z_1)\\ f'(z_2)\\ f'(z_3) \end{bmatrix}

Metoden backward()

Metoden backward() er ansvarlig for beregning af gradienterne ved hjælp af formlerne nedenfor:

dzl=dalfl(zl)dWl=dzl(al1)Tdbl=dzldal1=(Wl)Tdzl\begin{aligned} dz^l &= da^l \odot f'^l(z^l)\\ dW^l &= dz^l \cdot (a^{l-1})^T\\ db^l &= dz^l\\ da^{l-1} &= (W^l)^T \cdot dz^l \end{aligned}

a^{l-1} og zlz^l gemmes som henholdsvis attributterne inputs og outputs i klassen Layer. Aktiveringsfunktionen ff gemmes som attributten activation.

Når alle nødvendige gradienter er beregnet, kan vægte og biaser opdateres, da de ikke længere er nødvendige for yderligere beregning:

Wl=WlαdWlbl=blαdbl\begin{aligned} W^l &= W^l - \alpha \cdot dW^l\\ b^l &= b^l - \alpha \cdot db^l \end{aligned}

Derfor er learning_rate (α\alpha) 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
Note
Bemærk

Operatoren * udfører elementvis multiplikation, mens funktionen np.dot() udfører dot-produkt i NumPy. Attributten .T transponerer et array.

question mark

Hvilket af følgende beskriver bedst rollen for metoden backward() i Layer-klassen under backpropagation?

Select the correct answer

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 2. Kapitel 8
some-alt