Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Implementering av Backpropagation | Nevralt Nettverk fra Bunnen Av
Introduksjon til nevrale nettverk

bookImplementering av Backpropagation

Generell tilnærming

Ved fremoverpropagering tar hvert lag ll utdataene fra forrige lag, al1a^{l-1}, som input og beregner sine egne utdata. Derfor tar forward()-metoden i Layer-klassen vektoren av forrige utdata som eneste parameter, mens resten av nødvendig informasjon lagres i klassen.

Ved bakoverpropagering trenger hvert lag ll kun dalda^l for å beregne de respektive gradientene og returnere dal1da^{l-1}, så backward()-metoden tar dalda^l-vektoren som parameter. Resten av nødvendig informasjon er allerede lagret i Layer-klassen.

Derivater av aktiveringsfunksjoner

Siden derivater av aktiveringsfunksjoner er nødvendige for bakoverpropagering, bør aktiveringsfunksjoner som ReLU og sigmoid struktureres som klasser i stedet for frittstående funksjoner. Dette gjør det mulig å definere både:

  1. Selve aktiveringsfunksjonen (implementert via __call__()-metoden), slik at den kan brukes direkte i Layer-klassen med self.activation(z);
  2. Dens derivat (implementert via derivative()-metoden), som gir effektiv bakoverpropagering og brukes i Layer-klassen som self.activation.derivative(z).

Ved å strukturere aktiveringsfunksjoner som objekter kan vi enkelt sende dem til Layer-klassen og bruke dem dynamisk.

ReLu

Derivatet av ReLU-aktiveringsfunksjonen er som følger, der ziz_i er et element i vektoren av 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

Den deriverte av sigmoid-aktiveringsfunksjonen 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 aktiveringsfunksjonene anvendes de på hele vektoren zz, og det samme gjelder for deres deriverte. NumPy anvender operasjonen på hvert element i vektoren internt. For eksempel, hvis vektoren zz inneholder 3 elementer, er derivasjonen 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 å beregne gradientene ved å bruke følgende formler:

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 lagres som henholdsvis inputs og outputs attributter i Layer-klassen. Aktiveringsfunksjonen ff lagres som attributtet activation.

Når alle nødvendige gradienter er beregnet, kan vektene og biasene oppdateres siden de ikke lenger trengs for videre 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}

Dermed er learning_rate (α\alpha) en annen parameter for denne metoden.

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
Merk

Operatoren * utfører elementvis multiplikasjon, mens funksjonen np.dot() utfører prikkprodukt i NumPy. Attributtet .T transponerer et array.

question mark

Hvilket av følgende beskriver best rollen til backward()-metoden i Layer-klassen under backpropagation?

Select the correct answer

Alt var klart?

Hvordan kan vi forbedre det?

Takk for tilbakemeldingene dine!

Seksjon 2. Kapittel 8

Spør AI

expand

Spør AI

ChatGPT

Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår

Suggested prompts:

Can you explain how the backward() method uses the stored attributes in the Layer class?

What is the purpose of the activation function's derivative in backpropagation?

Could you provide an example of how to use these activation function classes in a neural network layer?

Awesome!

Completion rate improved to 4

bookImplementering av Backpropagation

Sveip for å vise menyen

Generell tilnærming

Ved fremoverpropagering tar hvert lag ll utdataene fra forrige lag, al1a^{l-1}, som input og beregner sine egne utdata. Derfor tar forward()-metoden i Layer-klassen vektoren av forrige utdata som eneste parameter, mens resten av nødvendig informasjon lagres i klassen.

Ved bakoverpropagering trenger hvert lag ll kun dalda^l for å beregne de respektive gradientene og returnere dal1da^{l-1}, så backward()-metoden tar dalda^l-vektoren som parameter. Resten av nødvendig informasjon er allerede lagret i Layer-klassen.

Derivater av aktiveringsfunksjoner

Siden derivater av aktiveringsfunksjoner er nødvendige for bakoverpropagering, bør aktiveringsfunksjoner som ReLU og sigmoid struktureres som klasser i stedet for frittstående funksjoner. Dette gjør det mulig å definere både:

  1. Selve aktiveringsfunksjonen (implementert via __call__()-metoden), slik at den kan brukes direkte i Layer-klassen med self.activation(z);
  2. Dens derivat (implementert via derivative()-metoden), som gir effektiv bakoverpropagering og brukes i Layer-klassen som self.activation.derivative(z).

Ved å strukturere aktiveringsfunksjoner som objekter kan vi enkelt sende dem til Layer-klassen og bruke dem dynamisk.

ReLu

Derivatet av ReLU-aktiveringsfunksjonen er som følger, der ziz_i er et element i vektoren av 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

Den deriverte av sigmoid-aktiveringsfunksjonen 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 aktiveringsfunksjonene anvendes de på hele vektoren zz, og det samme gjelder for deres deriverte. NumPy anvender operasjonen på hvert element i vektoren internt. For eksempel, hvis vektoren zz inneholder 3 elementer, er derivasjonen 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 å beregne gradientene ved å bruke følgende formler:

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 lagres som henholdsvis inputs og outputs attributter i Layer-klassen. Aktiveringsfunksjonen ff lagres som attributtet activation.

Når alle nødvendige gradienter er beregnet, kan vektene og biasene oppdateres siden de ikke lenger trengs for videre 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}

Dermed er learning_rate (α\alpha) en annen parameter for denne metoden.

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
Merk

Operatoren * utfører elementvis multiplikasjon, mens funksjonen np.dot() utfører prikkprodukt i NumPy. Attributtet .T transponerer et array.

question mark

Hvilket av følgende beskriver best rollen til backward()-metoden i Layer-klassen under backpropagation?

Select the correct answer

Alt var klart?

Hvordan kan vi forbedre det?

Takk for tilbakemeldingene dine!

Seksjon 2. Kapittel 8
some-alt