Machine Learning Academy · Lektion

Autograd: Automatisk derivering för backpropagation

Ni kommer att definiera en skalär beräkningsgraf, anropa .backward() och granska .grad på lövtensorer för att förstå hur gradienter flödar genom nätverket.

Lektion 2 av 413 steg

Autograd: Automatisk derivering för backpropagation är en gratis lektion i Machine Learning Academy på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Machine Learning Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Machine Learning Academy innehåller totalt 4 lektioner.

Vad är automatisk differentiering?

Automatisk differentiering (autograd) är den motor som beräknar gradienter i PyTorch utan att programmeraren behöver härleda dem för hand. Till skillnad från numerisk differentiering (ändliga differenser) eller symbolisk differentiering (algebra) fungerar autograd genom att registrera operationer på tensorer under körning och spela upp dem baklänges. Det gör det möjligt att träna modeller med valfri arkitektur effektivt och korrekt.

import torch

# A simple differentiable computation
x = torch.tensor(3.0, requires_grad=True)
y = x ** 2 + 2 * x + 1   # y = (x+1)^2

# Compute gradient dy/dx
y.backward()
print(x.grad)   # tensor(8.) because dy/dx = 2x+2 = 2*3+2 = 8

requires_grad: aktivera gradientspårning

Gradientspårning är inaktiverad som standard. Om du anger requires_grad=True instrueras PyTorch att registrera alla operationer på den tensorn, så att gradienter kan beräknas senare. Lövtensorer (parametrar) kräver gradienter, och mellanliggande tensorer ärver automatiskt gradientspårningen från sina föräldrar. Modellparametrar som skapas av nn.Module får automatiskt requires_grad=True.

import torch

# Leaf tensor with gradient tracking
w = torch.tensor(2.0, requires_grad=True)
b = torch.tensor(0.5, requires_grad=True)

# Forward pass
x = torch.tensor(3.0)   # input, no grad needed
y_pred = w * x + b      # y = wx + b = 6.5

print(y_pred.requires_grad)  # True (inherited)
print(w.is_leaf)              # True
print(y_pred.is_leaf)         # False

Beräkningsgrafen

När du utför operationer på tensorer med requires_grad=True bygger PyTorch en dynamisk beräkningsgraf (en riktad acyklisk graf över operationer). Varje nod lagrar operationen och referenser till sina indata. När .backward() anropas går PyTorch igenom grafen baklänges (från utdata till indata) med hjälp av kedjeregeln för att beräkna partiella derivator för varje lövtensor. Grafen byggs om från grunden vid varje forward pass, vilket möjliggör dynamiska arkitekturer.

import torch

a = torch.tensor(2.0, requires_grad=True)
b = torch.tensor(3.0, requires_grad=True)

# Build computation graph
c = a * b          # c = 6
d = c + a          # d = 8
e = d ** 2         # e = 64

# Inspect graph node
print(e.grad_fn)          # <PowBackward0 object>
print(e.grad_fn.next_functions)  # parents in the graph

Anropa .backward(): beräkna gradienter

Om du anropar .backward() på en skalär tensor startar backpropagation genom hela beräkningsgrafen och gradienter lagras i attributet .grad för varje lövtensor. Om utdatan inte är skalär måste du ange en gradienttensor med samma form (den inkommande gradienten). Gradienter ackumuleras som standard — anropa alltid optimizer.zero_grad() (eller tensor.grad.zero_()) före nästa backward pass för att undvika felaktiga uppdateringar.

import torch

x = torch.tensor(4.0, requires_grad=True)
loss = (x - 1) ** 2   # minimum at x=1

loss.backward()
print(x.grad)   # tensor(6.) = 2*(x-1) = 2*3 = 6

# Gradients accumulate! Reset before next pass
x.grad.zero_()
new_loss = (x - 2) ** 2
new_loss.backward()
print(x.grad)   # tensor(4.) = 2*(x-2) = 2*2 = 4

Gradientflöde genom flera operationer

Kedjeregeln säger att derivatan av en sammansättning av funktioner är produkten av derivatorna. Autograd tillämpar detta mekaniskt genom varje operation i grafen. Om du förstår hur gradienter flödar blir det lättare att felsöka problem som försvinnande gradienter (produkter nära noll) och exploderande gradienter (produkter större än 1 som multipliceras många gånger). Valet av aktiveringsfunktion (ReLU kontra sigmoid) påverkar gradienternas storlek direkt.

import torch

# Chain: z = sigmoid(wx + b), loss = (z - y_true)^2
def sigmoid(x):
    return 1 / (1 + torch.exp(-x))

w = torch.tensor(0.5, requires_grad=True)
b = torch.tensor(0.0, requires_grad=True)
x = torch.tensor(2.0)
y_true = torch.tensor(1.0)

z = sigmoid(w * x + b)
loss = (z - y_true) ** 2
loss.backward()

print(f'dL/dw = {w.grad:.4f}')  # gradient w.r.t. weight
print(f'dL/db = {b.grad:.4f}')  # gradient w.r.t. bias

torch.no_grad(): inaktivera gradientspårning

Under inferens (förutsägelse på nya data) behöver du inte gradienter — att beräkna dem slösar tid och minne. Om du omsluter inferenskoden med torch.no_grad() inaktiveras beräkningsgrafen helt, vilket snabbar upp forward passes och minskar minnesanvändningen med upp till 50 %. Detta används även i utvärderingsslingor för att få valideringsmått utan att påverka träningen.

import torch

x = torch.randn(100, requires_grad=True)

# With gradient tracking (training)
out = x ** 2
print(out.requires_grad)   # True

# Without gradient tracking (inference)
with torch.no_grad():
    out_no_grad = x ** 2
    print(out_no_grad.requires_grad)  # False

# Also used as a decorator
@torch.no_grad()
def predict(model, data):
    return model(data)

Problem med gradientackumulering och zero_grad

PyTorch ackumulerar (lägger till) gradienter i .grad varje gång .backward() anropas. Detta är avsiktligt för vissa avancerade tekniker, men under normal träning innebär det att du måste nollställa gradienterna före varje backward pass. Det vanliga idiomet använder optimerarens metod zero_grad(), som rensar gradienterna för alla parametrar som optimeraren hanterar. Om du glömmer detta steg växer gradienterna obegränsat, vilket förstör uppdateringarna.

import torch
import torch.nn as nn
import torch.optim as optim

model = nn.Linear(2, 1)
optimizer = optim.SGD(model.parameters(), lr=0.01)

for epoch in range(3):
    optimizer.zero_grad()         # clear old gradients
    x = torch.randn(4, 2)
    y_pred = model(x)
    loss = y_pred.sum()
    loss.backward()               # compute new gradients
    optimizer.step()              # update weights
    print(f'Epoch {epoch}: loss={loss.item():.3f}')

Inspektera gradientvärden för felsökning

Att inspektera gradientvärden är avgörande för att diagnostisera träningsproblem. Du kan komma åt dem via tensor.grad efter att du har anropat backward. Om du plottar gradientnormen för olika lager ser du om gradienterna försvinner (nära noll) eller exploderar (mycket stora) i djupa nätverk. En vanlig felsöknings-hook är att skriva ut gradientstatistik efter var N:te batch för att upptäcka instabilitet tidigt under träningen.

import torch
import torch.nn as nn

model = nn.Sequential(
    nn.Linear(4, 8),
    nn.ReLU(),
    nn.Linear(8, 1)
)

x = torch.randn(16, 4)
y_pred = model(x)
loss = y_pred.mean()
loss.backward()

# Inspect gradients of each parameter
for name, param in model.named_parameters():
    if param.grad is not None:
        norm = param.grad.norm().item()
        print(f'{name}: grad_norm={norm:.4f}')

Koppla bort tensorer från grafen

Ibland vill du använda en beräknad tensor som en konstant indata till en annan beräkning — utan att låta gradienter flöda genom den. .detach() returnerar en ny tensor som delar data men har kopplats bort från beräkningsgrafen. Detta används i target-nätverk (förstärkningsinlärning), för att stoppa gradientflödet i specifika grenar av ett nätverk och för att konvertera tensorer till NumPy-arrayer för plottning.

import torch

a = torch.tensor(3.0, requires_grad=True)
b = a * 2             # b depends on a
c = b.detach()        # c is a constant copy of b's value

d = c * 5             # gradient does NOT flow back to a
d.backward()

# a.grad is None because c severed the graph
print(a.grad)         # None

# Detach before converting to NumPy
np_val = b.detach().numpy()
print(np_val)         # [6.0] (as NumPy array)

Andragradens gradienter med create_graph

PyTorch stöder derivering av högre ordning. Om du skickar create_graph=True till .backward() behålls beräkningsgrafen för själva gradientberäkningen, så att du kan derivera med avseende på gradienter. Detta används i meta-inlärning (MAML), regularisering med gradientstraff (Wasserstein GAN) och alla tekniker som optimerar med avseende på gradienter.

import torch

x = torch.tensor(2.0, requires_grad=True)
y = x ** 3           # y = x^3

# First derivative dy/dx = 3x^2
dy = torch.autograd.grad(y, x, create_graph=True)[0]
print(dy)            # tensor(12., grad_fn=...)

# Second derivative d^2y/dx^2 = 6x
d2y = torch.autograd.grad(dy, x)[0]
print(d2y)           # tensor(6.)

Autograd i träningspipeline

Autograd utgör grunden för varje träningsslinga för neurala nätverk. Det vanliga mönstret består av fyra steg: (1) nollställ gradienterna med optimizer.zero_grad(), (2) forward pass för att beräkna förutsägelser och förlust, (3) backward pass med loss.backward() för att beräkna gradienter och (4) optimizer step med optimizer.step() för att uppdatera parametrarna. När du förstår att autograd utför det omfattande kalkylarbetet kan du fokusera på modellarkitektur och hyperparametrar.

import torch
import torch.nn as nn
import torch.optim as optim

model = nn.Linear(1, 1)
optimizer = optim.SGD(model.parameters(), lr=0.1)
criterion = nn.MSELoss()

# Synthetic data: y = 3x + 1
X = torch.randn(20, 1)
y = 3 * X + 1 + 0.1 * torch.randn(20, 1)

for epoch in range(5):
    optimizer.zero_grad()       # (1) zero grads
    y_pred = model(X)           # (2) forward
    loss = criterion(y_pred, y) # (2) loss
    loss.backward()             # (3) backward
    optimizer.step()            # (4) update
    print(f'Epoch {epoch}: loss={loss.item():.4f}')

Snabbtest

Testa dina kunskaper om begrepp inom maskininlärning med Python från den här lektionen.

Sammanfattning av lektionen

I den här lektionen lärde du dig att autograd bygger en dynamisk beräkningsgraf som registrerar varje operation på tensorer med requires_grad=True, att .backward() beräknar gradienter med hjälp av kedjeregeln och lagrar dem i .grad, samt att gradienter ackumuleras och därför måste nollställas före varje träningssteg. Härnäst utforskar vi hur du bygger ett feedforward-nätverk med nn.Module.

Gratis att börja

Lär dig Python med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
30
Lektioner
120

Vanliga frågor

Är lektionen ”Autograd: Automatisk derivering för backpropagation” gratis?

Ja – hela texten till ”Autograd: Automatisk derivering för backpropagation” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Machine Learning Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Machine Learning Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Autograd: Automatisk derivering för backpropagation”?

Ni kommer att definiera en skalär beräkningsgraf, anropa .backward() och granska .grad på lövtensorer för att förstå hur gradienter flödar genom nätverket. Ni övar på Machine Learning Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Machine Learning Academy?

Du behöver inga förkunskaper. Utbildningen i Machine Learning Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.

Hur lång tid tar lektionen ”Autograd: Automatisk derivering för backpropagation”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Machine Learning Academy-lektionen?

Ja. Varje Machine Learning Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. PyTorch-tensorer: Skapa, bearbeta och överföra till GPU
  2. Autograd: Automatisk derivering för backpropagation
  3. Bygga ett feedforward-nätverk med nn.Module
  4. Träningsloop: Förlust, optimerare och epoker
← Tillbaka till Machine Learning Academy