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

Bygg en mini-autograd

Kunna implementera en skalär autograd-motor (micrograd-stil) och träna ett nät med den.

Förkunskaper

Intuition

En autograd-motor behöver förvånansvärt lite:

  1. En Value-klass som bär ett tal, sin gradient, sina «barn» och en lokal _backward-funktion.
  2. Varje operation (+, ·, tanh …) skapar en ny Value, kopplar den till sina operander och definierar hur gradienten ska propageras bakåt genom just den operationen.
  3. backward() sorterar grafen topologiskt och kör _backward i omvänd ordning.

Det är allt. PyTorch gör samma sak, fast på tensorer och med tusen optimeringar.

Nyckelinsikten: gradienter ackumuleras (+=). En variabel som används två gånger får bidrag från båda vägarna — det är kedjeregelns summaregel.

Kod

import math

class Value:
    def __init__(self, data, barn=(), op=""):
        self.data, self.grad = float(data), 0.0
        self._backward = lambda: None
        self._prev, self._op = set(barn), op

    def __add__(self, other):
        other = other if isinstance(other, Value) else Value(other)
        ut = Value(self.data + other.data, (self, other), "+")
        def _backward():
            self.grad += ut.grad                      # += , inte =
            other.grad += ut.grad
        ut._backward = _backward
        return ut

    def __mul__(self, other):
        other = other if isinstance(other, Value) else Value(other)
        ut = Value(self.data * other.data, (self, other), "*")
        def _backward():
            self.grad += other.data * ut.grad
            other.grad += self.data * ut.grad
        ut._backward = _backward
        return ut

    def tanh(self):
        t = math.tanh(self.data)
        ut = Value(t, (self,), "tanh")
        def _backward():
            self.grad += (1 - t ** 2) * ut.grad
        ut._backward = _backward
        return ut

    def backward(self):
        ordning, besokta = [], set()
        def bygg(v):
            if v not in besokta:
                besokta.add(v)
                for b in v._prev:
                    bygg(b)
                ordning.append(v)
        bygg(self)
        self.grad = 1.0
        for v in reversed(ordning):                   # topologisk ordning, baklänges
            v._backward()

    __radd__ = __add__; __rmul__ = __mul__
    def __neg__(self): return self * -1
    def __sub__(self, o): return self + (-o)

# Kontroll: f = (a*b + a).tanh(),  a=2, b=-3  →  f = tanh(-4)
a, b = Value(2.0), Value(-3.0)
f = (a * b + a).tanh()
f.backward()
print(round(f.data, 4), round(a.grad, 4), round(b.grad, 4))
# -0.9993  -0.0013  -0.0007

Verifiera alltid numeriskt: ändra a.data med ±1e-6, räkna om f, och jämför differenskvoten med a.grad. Stämmer de är motorn korrekt.

Behärskning innebär

  • Implementerar en skalär autograd-motor
  • Bygger beräkningsgrafen och topologisk ordning
  • Tränar ett litet nät med sin egen motor

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

Källor

Alla källor och licenser