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 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 parameter. Resten af den nødvendige information er allerede gemt i Layer-klassen.

Afledte funktioner for aktiveringsfunktioner

Da afledte funktioner af aktiveringsfunktioner er nødvendige for tilbagepropagering, 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:

  1. Selve aktiveringsfunktionen — implementeret via __call__()-metoden, så den kan anvendes direkte i Layer-klassen med self.activation(z);
  2. Dens afledte funktion — implementeret via derivative()-metoden, hvilket muliggør effektiv beregning under tilbagepropagering via self.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 tilbagepropagering.

ReLu

Den afledte funktion 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 aktiveringsfunktionen 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 aktiveringsfunktioner anvendes operationen på hele vektoren zz samt på dens afledte. NumPy udfører automatisk beregningen elementvist, hvilket betyder, at hvert element i vektoren behandles uafhængigt.

For eksempel, hvis vektoren zz indeholder tre elementer, beregnes den afledte som:

f(z)=f([z1z2z3])=[f(z1)f(z2)f(z3)]f'(z) = f'\left( \begin{bmatrix} z_1\\ z_2\\ z_3 \end{bmatrix} \right) = \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 biases 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 backward()-metoden 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 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 parameter. Resten af den nødvendige information er allerede gemt i Layer-klassen.

Afledte funktioner for aktiveringsfunktioner

Da afledte funktioner af aktiveringsfunktioner er nødvendige for tilbagepropagering, 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:

  1. Selve aktiveringsfunktionen — implementeret via __call__()-metoden, så den kan anvendes direkte i Layer-klassen med self.activation(z);
  2. Dens afledte funktion — implementeret via derivative()-metoden, hvilket muliggør effektiv beregning under tilbagepropagering via self.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 tilbagepropagering.

ReLu

Den afledte funktion 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 aktiveringsfunktionen 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 aktiveringsfunktioner anvendes operationen på hele vektoren zz samt på dens afledte. NumPy udfører automatisk beregningen elementvist, hvilket betyder, at hvert element i vektoren behandles uafhængigt.

For eksempel, hvis vektoren zz indeholder tre elementer, beregnes den afledte som:

f(z)=f([z1z2z3])=[f(z1)f(z2)f(z3)]f'(z) = f'\left( \begin{bmatrix} z_1\\ z_2\\ z_3 \end{bmatrix} \right) = \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 biases 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 backward()-metoden 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