micrograd/micrograd/engine.py

67 lines
1.9 KiB
Python

class Value:
def __init__(self, data, _children=(), _op='', label=''):
self.data = data
self.grad = 0.0
self._prev = set(_children)
self._op = _op
self.label = label
self._backward = lambda: None
def backward(self):
def topological(root):
ordered = []
visited = set()
def build_topo(v):
if v not in visited:
visited.add(v)
for child in v._prev:
build_topo(child)
ordered.append(v)
build_topo(root)
return ordered
ordered = topological(self)
self.grad = 1.0
for node in reversed(ordered):
node._backward()
def __repr__(self):
return f"Value(data={self.data})"
def __add__(self, other):
out = Value(data=self.data + other.data,
_children=(self, other), _op='+')
def _backward():
self.grad += 1.0 * out.grad
other.grad += 1.0 * out.grad
out._backward = _backward
return out
def __sub__(self, other):
out = Value(data=self.data - other.data,
_children=(self, other), _op='-')
return out
def __mul__(self, other):
out = Value(data=self.data * other.data,
_children=(self, other), _op='*')
def _backward():
self.grad += other.data * out.grad
other.grad += self.data * out.grad
out._backward = _backward
return out
def tanh(self):
from math import exp
t = (exp(2 * self.data) - 1) / (exp(2 * self.data) + 1)
out = Value(data=t, _children=(self,),
_op='tanh', label='tanh')
def _backward():
self.grad += (1 - t**2) * out.grad
out._backward = _backward
return out