Hoppa till innehållet
AI-grafen
E· Universitetmatematik· ca 60 min· utvecklande· verifierad 2026-09-20

Kedjeregeln i flera variabler

Kunna tillämpa kedjeregeln på sammansatta funktioner av vektorer — det som backpropagation bygger på.

Förkunskaper

Intuition

I en variabel: om y = f(g(x)) så är dy/dx = f′(g(x)) · g′(x). Derivatorna multipliceras längs kedjan.

I flera variabler gäller samma sak, fast med matriser. Ett nät är en kedja:

x → z₁ = W₁x → a₁ = σ(z₁) → z₂ = W₂a₁ → … → L

För att veta hur L ändras när W₁ ändras multipliceras alla mellanledens derivator ihop, bakifrån. Det är backpropagation — inte en separat algoritm, utan kedjeregeln tillämpad effektivt.

Härledning

För f:Rn→Rmf:\mathbb R^n\to\mathbb R^m är jacobianen JfJ_f en m×nm\times n-matris med [Jf]ij=∂fi/∂xj[J_f]_{ij} = \partial f_i/\partial x_j.

Kedjeregeln: för h=f∘gh = f\circ g gäller Jh(x)=Jf(g(x)) Jg(x)J_h(x) = J_f(g(x))\, J_g(x) — matrisprodukt, i den ordningen.

För en skalär förlust LL arbetar man med gradienter (rader) i stället för fulla jacobianer. Ett lager z=Wa+bz = Wa + b, a′=σ(z)a' = \sigma(z):

∂L∂z=∂L∂a′⊙σ′(z),∂L∂W=∂L∂z a⊤,∂L∂a=W⊤∂L∂z\frac{\partial L}{\partial z} = \frac{\partial L}{\partial a'}\odot \sigma'(z), \qquad \frac{\partial L}{\partial W} = \frac{\partial L}{\partial z}\,a^\top, \qquad \frac{\partial L}{\partial a} = W^\top\frac{\partial L}{\partial z}

Varför bakifrån? Med nn indata och en skalär utdata kostar framåtdifferentiering (en riktning i taget) nn genomgångar; bakåtdifferentiering ger alla partiella derivator i en genomgång. Med miljontals parametrar är skillnaden avgörande — det är hela skälet till att reverse-mode AD dominerar i deep learning.

Konsekvensen för djupa nät: gradienten till lager 1 är en produkt av många faktorer. Är de systematiskt < 1 försvinner den; är de > 1 exploderar den. Residualkopplingar ger en «genväg» där faktorn är 1, vilket är varför de gör mycket djupa nät tränbara.

Kod

import numpy as np

def framat(x, W1, b1, W2, b2):
    z1 = W1 @ x + b1
    a1 = np.tanh(z1)
    z2 = W2 @ a1 + b2
    return z1, a1, z2

def bakat(x, y, W1, b1, W2, b2):
    z1, a1, z2 = framat(x, W1, b1, W2, b2)
    dL_dz2 = 2 * (z2 - y)                       # L = ||z2 - y||²
    dL_dW2 = np.outer(dL_dz2, a1)
    dL_da1 = W2.T @ dL_dz2                      # kedjeregeln bakåt
    dL_dz1 = dL_da1 * (1 - np.tanh(z1) ** 2)    # tanh' = 1 - tanh²
    dL_dW1 = np.outer(dL_dz1, x)
    return dL_dW1, dL_dz1, dL_dW2, dL_dz2

# Numerisk kontroll — gör alltid detta när du implementerat backprop själv
rng = np.random.default_rng(0)
x, y = rng.normal(size=4), rng.normal(size=2)
W1, b1 = rng.normal(size=(3, 4)) * 0.3, np.zeros(3)
W2, b2 = rng.normal(size=(2, 3)) * 0.3, np.zeros(2)
dW1 = bakat(x, y, W1, b1, W2, b2)[0]

eps = 1e-6; num = np.zeros_like(W1)
for i in range(W1.shape[0]):
    for j in range(W1.shape[1]):
        Wp = W1.copy(); Wp[i, j] += eps
        Wm = W1.copy(); Wm[i, j] -= eps
        Lp = ((framat(x, Wp, b1, W2, b2)[2] - y) ** 2).sum()
        Lm = ((framat(x, Wm, b1, W2, b2)[2] - y) ** 2).sum()
        num[i, j] = (Lp - Lm) / (2 * eps)
print(np.abs(dW1 - num).max() < 1e-6)     # True

Behärskning innebär

  • Tillämpar kedjeregeln på sammansatta vektorfunktioner
  • Skriver gradienten som en produkt av jacobianer
  • Kopplar till backpropagation

Logga in för att göra övningarna och bygga upp din behärskning.

Källor

Alla källor och licenser