diff --git a/norch/__pycache__/tensor.cpython-38.pyc b/norch/__pycache__/tensor.cpython-38.pyc index ab543df..058017d 100644 Binary files a/norch/__pycache__/tensor.cpython-38.pyc and b/norch/__pycache__/tensor.cpython-38.pyc differ diff --git a/norch/autograd/__pycache__/functions.cpython-38.pyc b/norch/autograd/__pycache__/functions.cpython-38.pyc index 4169576..0df507a 100644 Binary files a/norch/autograd/__pycache__/functions.cpython-38.pyc and b/norch/autograd/__pycache__/functions.cpython-38.pyc differ diff --git a/norch/autograd/functions.py b/norch/autograd/functions.py index 67bc301..bbd8907 100644 --- a/norch/autograd/functions.py +++ b/norch/autograd/functions.py @@ -1,20 +1,20 @@ class AddBackward: def __init__(self, x, y): - self.tensors = [x, y] + self.input = [x, y] def backward(self, gradient): return [gradient, gradient] class SubBackward: def __init__(self, x, y): - self.tensors = [x, y] + self.input = [x, y] def backward(self, gradient): return [gradient, -gradient] class ScalarMulBackward: def __init__(self, x, scalar): - self.tensors = [x] + self.input = [x] self.scalar = scalar def backward(self, gradient): @@ -23,17 +23,17 @@ class ScalarMulBackward: class ElementwiseMulBackward: def __init__(self, x, y): - self.tensors = [x, y] + self.input = [x, y] def backward(self, gradient): - return [gradient * self.tensors[1], gradient * self.tensors[0]] + return [gradient * self.input[1], gradient * self.input[0]] class SumBackward: def __init__(self, x): - self.tensor = x + self.input = [x] def backward(self, gradient): # Since sum reduces a tensor to a scalar, gradient is broadcasted to match the original shape. - return self.tensor.ones_like() * float(gradient.tensor.contents.data.value) + return [float(gradient.tensor.contents.data[0]) * self.input[0].ones_like()] diff --git a/norch/tensor.py b/norch/tensor.py index 5103ec1..b615808 100644 --- a/norch/tensor.py +++ b/norch/tensor.py @@ -133,27 +133,22 @@ class Tensor: return if gradient is None: - if self.shape != [1]: + if self.shape == [1]: + gradient = Tensor([1]) + else: raise RuntimeError("Gradient argument must be specified for non-scalar tensors.") - gradient = self.ones_like() - - if self.shape != [1]: - raise RuntimeError("Only scalar tensors can be used to trigger backward propagation.") - + if self.grad is None: self.grad = gradient + else: self.grad += gradient - if self.grad_fn is not None: + if self.grad_fn is not None: # not a leaf grads = self.grad_fn.backward(gradient) - if len(grads) == 1: - self.grad = grads[0] - else: - for tensor, grad in zip(self.grad_fn.tensors, grads): - tensor.backward(grad) + for tensor, grad in zip(self.grad_fn.input, grads): + tensor.backward(grad) - def zero_grad(self): self.grad = None diff --git a/test.py b/test.py index 56e4173..93aa5c7 100644 --- a/test.py +++ b/test.py @@ -29,10 +29,11 @@ if __name__ == "__main__": #d = b-c - c = a.sum() - c.backward() - print(a.grad) - print(b.grad) + c = a*b + + d = c.sum() + d.backward() + print(c.grad) #print(a ** 2) """#print(a)