67 lines
1.9 KiB
Python
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
|