micrograd

  • 写一个 class Value
  • 定义各种运算(加减乘除幂指等等)
  • Value 应当记录‘prev’和’操作名’,也就是 previous value 经过什么样的操作得到了这个 Value
  • 对于每个运算的重载,都要实现一个 _backward() 函数,对于每种运算,实现对应的计算相对梯度的公式。(self.grad = `??? prev.grad’)
class Value:
 
	def __init__(self, data, _children=(), _op='', label=''):
	self.data = data
	
	self.grad = 0.0
	
	self._backward = lambda: None
	
	self._prev = set(_children)
	
	self._op = _op
	
	self.label = label
def __add__(self, other): # exactly as in the video
 
	other = other if isinstance(other, Value) else Value(other)
	
	out = Value(self.data + other.data, (self, other), '+')
 
	def _backward():
	
		self.grad += 1.0 * out.grad
		
		other.grad += 1.0 * out.grad
		
		out._backward = _backward
	
	return out
  • 再实现一个循环算梯度的 backward()
def backward(self): # exactly as in video
 
	topo = []
	
	visited = set()
	
	def build_topo(v):
	
		if v not in visited:
	
			visited.add(v)
	
		for child in v._prev:
		
			build_topo(child)
	
			topo.append(v)
	
	build_topo(self)
	
	self.grad = 1.0
	
	for node in reversed(topo):
	
	node._backward()