Unary & Reverse Operations
The transcendental functions log, exp, and relu
each have well-known derivatives:
- log(x): derivative is 1/x
- exp(x): derivative is exp(x) (it's its own derivative!)
- relu(x): derivative is 1 if x>0, else 0
The "reverse" dunder methods (__radd__, __rmul__, etc.)
let Python handle expressions like 2 * value where the Value
is on the right side. Subtraction and division are defined in terms of addition,
negation, and power — no new gradient rules needed.
def log(self):
return Value(math.log(self.data),
(self,), (1/self.data,))
def exp(self):
return Value(math.exp(self.data),
(self,), (math.exp(self.data),))
def relu(self):
return Value(max(0, self.data),
(self,), (float(self.data > 0),))
def __neg__(self): return self * -1
def __radd__(self, o): return self + o
def __sub__(self, o): return self + (-o)
def __rsub__(self, o): return o + (-self)
def __rmul__(self, o): return self * o
def __truediv__(self, o):
return self * o ** -1
def __rtruediv__(self, o):
return o * self ** -1