Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lära Implementering av Backpropagation | Neuronnätverk Från Grunden
Introduktion till neurala nätverk

bookImplementering av Backpropagation

Allmän metod

Vid framåtriktad spridning tar varje lager ll utdata från föregående lager, al1a^{l-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 spridning behöver varje lager ll endast dalda^l för att beräkna respektive gradienter och returnera dal1da^{l-1}, så metoden backward() tar vektorn dalda^l som sin parameter. Övrig nödvändig information är redan lagrad i klassen Layer.

Derivator av aktiveringsfunktioner

Eftersom derivator av aktiveringsfunktioner behövs för bakåtriktad spridning, bör aktiveringsfunktioner som ReLU och sigmoid struktureras som klasser istället för fristående funktioner. Detta gör det möjligt att definiera både:

  1. Själva aktiveringsfunktionen (implementerad via metoden __call__()), vilket möjliggör direkt användning i klassen Layer med self.activation(z);
  2. Dess derivata (implementerad via metoden derivative()), vilket möjliggör effektiv bakåtriktad spridning och används i klassen Layer som self.activation.derivative(z).

Genom att strukturera aktiveringsfunktioner som objekt kan de enkelt överföras till klassen Layer och användas dynamiskt.

ReLu

Derivatan av ReLU-aktiveringsfunktionen är följande, där ziz_i är ett element i vektorn av pre-aktiveringar 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

Derivatan av sigmoidaktiveringsfunktionen är följande:

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)

För båda dessa aktiveringsfunktioner tillämpar vi dem på hela vektorn zz, och detsamma gäller för deras derivator. NumPy tillämpar internt operationen på varje element i vektorn. Till exempel, om vektorn zz innehåller 3 element, är derivatan enligt följande:

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}

backward()-metoden

Metoden backward() ansvarar för beräkning av gradienter med hjälp av formlerna nedan:

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} och zlz^l lagras som attributen inputs respektive outputs i klassen Layer. Aktiveringsfunktionen ff lagras som attributet activation.

När alla nödvändiga gradienter har beräknats kan vikter och bias uppdateras eftersom de inte längre behövs för ytterligare beräkningar:

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}

Därför är learning_rate (α\alpha) 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
Note
Notera

*-operatorn utför elementvis multiplikation, medan funktionen np.dot() utför skalärprodukt i NumPy. Attributet .T transponerar en array.

question mark

Vilket av följande beskriver bäst rollen för metoden backward() i klassen Layer under backpropagation?

Select the correct answer

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 2. Kapitel 8

Fråga AI

expand

Fråga AI

ChatGPT

Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal

Awesome!

Completion rate improved to 4

bookImplementering av Backpropagation

Svep för att visa menyn

Allmän metod

Vid framåtriktad spridning tar varje lager ll utdata från föregående lager, al1a^{l-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 spridning behöver varje lager ll endast dalda^l för att beräkna respektive gradienter och returnera dal1da^{l-1}, så metoden backward() tar vektorn dalda^l som sin parameter. Övrig nödvändig information är redan lagrad i klassen Layer.

Derivator av aktiveringsfunktioner

Eftersom derivator av aktiveringsfunktioner behövs för bakåtriktad spridning, bör aktiveringsfunktioner som ReLU och sigmoid struktureras som klasser istället för fristående funktioner. Detta gör det möjligt att definiera både:

  1. Själva aktiveringsfunktionen (implementerad via metoden __call__()), vilket möjliggör direkt användning i klassen Layer med self.activation(z);
  2. Dess derivata (implementerad via metoden derivative()), vilket möjliggör effektiv bakåtriktad spridning och används i klassen Layer som self.activation.derivative(z).

Genom att strukturera aktiveringsfunktioner som objekt kan de enkelt överföras till klassen Layer och användas dynamiskt.

ReLu

Derivatan av ReLU-aktiveringsfunktionen är följande, där ziz_i är ett element i vektorn av pre-aktiveringar 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

Derivatan av sigmoidaktiveringsfunktionen är följande:

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)

För båda dessa aktiveringsfunktioner tillämpar vi dem på hela vektorn zz, och detsamma gäller för deras derivator. NumPy tillämpar internt operationen på varje element i vektorn. Till exempel, om vektorn zz innehåller 3 element, är derivatan enligt följande:

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}

backward()-metoden

Metoden backward() ansvarar för beräkning av gradienter med hjälp av formlerna nedan:

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} och zlz^l lagras som attributen inputs respektive outputs i klassen Layer. Aktiveringsfunktionen ff lagras som attributet activation.

När alla nödvändiga gradienter har beräknats kan vikter och bias uppdateras eftersom de inte längre behövs för ytterligare beräkningar:

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}

Därför är learning_rate (α\alpha) 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
Note
Notera

*-operatorn utför elementvis multiplikation, medan funktionen np.dot() utför skalärprodukt i NumPy. Attributet .T transponerar en array.

question mark

Vilket av följande beskriver bäst rollen för metoden backward() i klassen Layer under backpropagation?

Select the correct answer

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 2. Kapitel 8
some-alt