Compare commits
3 commits
d31a72374d
...
4fb2a16c4c
Author | SHA1 | Date | |
---|---|---|---|
|
4fb2a16c4c | ||
|
45168730e8 | ||
|
b0bb7b523d |
41
pygrad/nn.py
41
pygrad/nn.py
|
@ -1,38 +1,43 @@
|
||||||
# Neural networks from scratch with numpy.
|
# Neural networks from scratch with numpy.
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pygrad.tensor as tensor
|
from pygrad.tensor import tensor, Tensor
|
||||||
|
|
||||||
def mean_absolute_error(x, y):
|
def mean_absolute_error(x, y):
|
||||||
return np.mean(np.abs(x - y))
|
return np.mean(np.abs(x - y))
|
||||||
|
|
||||||
def mean_squared_error(x, y):
|
def mean_squared_error(x: Tensor, y: Tensor):
|
||||||
return np.mean(np.power(x - y, 2))
|
return x.sub(y).expt(2).div(tensor([[2.0]]))
|
||||||
|
|
||||||
def cross_entropy_loss(x, y):
|
def cross_entropy_loss(x: Tensor, y: Tensor):
|
||||||
return -np.log(np.exp(y) / np.sum(np.exp(x)))
|
return y.exp().div(np.sum(x.exp())).log().neg()
|
||||||
|
|
||||||
# prepare inputs and outputs
|
# prepare inputs and outputs
|
||||||
x = np.array([[1, 0]])
|
x = tensor(np.array([[1, 0]]))
|
||||||
y = np.array([[1]])
|
y = tensor(np.array([[1]]))
|
||||||
|
|
||||||
# we're doing xavier initialisation - see <http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf>
|
# we're doing xavier initialisation - see <http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf>
|
||||||
w1 = np.random.randn(2, 3) / np.sqrt(2)
|
w1 = tensor(np.random.randn(2, 3) / np.sqrt(2))
|
||||||
w2 = np.random.randn(3, 1) / np.sqrt(3)
|
w2 = tensor(np.random.randn(3, 1) / np.sqrt(3))
|
||||||
|
|
||||||
def single_pass():
|
def single_pass():
|
||||||
|
global w1, w2
|
||||||
|
|
||||||
# forward pass
|
# forward pass
|
||||||
h = np.matmul(x, w1)
|
h = x.mul(w1)
|
||||||
h_hat = np.tanh(h)
|
h_hat = h.tanh()
|
||||||
j = np.matmul(h_hat, w2)
|
j = h_hat.mul(w2)
|
||||||
print("prediction {}".format(j))
|
print(f"prediction {j}")
|
||||||
|
|
||||||
# loss calculation
|
# loss calculation
|
||||||
loss = cross_entropy_loss(j, y)
|
loss = mean_squared_error(j, y)
|
||||||
print("loss {}".format(loss))
|
print(f"loss {loss}")
|
||||||
|
|
||||||
# TODO Backward pass.
|
loss.backward()
|
||||||
return
|
print(w1.grad, w2.grad)
|
||||||
|
|
||||||
|
w1.value -= 0.1 * w1.grad
|
||||||
|
w2.value -= 0.1 * w2.grad
|
||||||
|
|
||||||
# initialise layers
|
# initialise layers
|
||||||
# self.lin1 = nn.Linear(2, 3)
|
# self.lin1 = nn.Linear(2, 3)
|
||||||
|
@ -48,7 +53,7 @@ def single_pass():
|
||||||
# Small test to see if autograd works.
|
# Small test to see if autograd works.
|
||||||
def test():
|
def test():
|
||||||
# Input tensors.
|
# Input tensors.
|
||||||
x, y, z = tensor.Tensor(np.array([[1, 2, 3]])), tensor.Tensor(np.array([[2, 3, 4]])), tensor.Tensor(np.array([[1], [2], [3]]))
|
x, y, z = Tensor(np.array([[1, 2, 3]])), Tensor(np.array([[2, 3, 4]])), Tensor(np.array([[1], [2], [3]]))
|
||||||
|
|
||||||
# Forward pass.
|
# Forward pass.
|
||||||
q = x.add(y)
|
q = x.add(y)
|
||||||
|
|
|
@ -54,7 +54,7 @@ class Tensor:
|
||||||
|
|
||||||
def back(upstream):
|
def back(upstream):
|
||||||
a, b = tensor._parents
|
a, b = tensor._parents
|
||||||
return np.dot(b.value, upstream), np.dot(a.value.T, upstream)
|
return np.dot(upstream, b.value.T), np.dot(a.value.T, upstream)
|
||||||
|
|
||||||
tensor._back = back
|
tensor._back = back
|
||||||
return tensor
|
return tensor
|
||||||
|
@ -131,7 +131,7 @@ class Tensor:
|
||||||
def back(upstream):
|
def back(upstream):
|
||||||
# dtanh(x)/dx = 1 - tanh2(x)
|
# dtanh(x)/dx = 1 - tanh2(x)
|
||||||
a, = tensor._parents
|
a, = tensor._parents
|
||||||
return [1 - np.dot(np.tanh(a.value) ** 2, upstream)]
|
return [np.ones_like(self.value) - np.dot(upstream, (np.tanh(a.value) ** 2).T)]
|
||||||
|
|
||||||
tensor._back = back
|
tensor._back = back
|
||||||
return tensor
|
return tensor
|
||||||
|
|
Loading…
Reference in a new issue