Spaces:
Sleeping
Sleeping
Commit
·
4e6140d
1
Parent(s):
0f9e8ef
got it working! now I want to make it so that we can have more than just one node in the middle
Browse files- main.py +10 -12
- neural_network/backprop.py +13 -9
- neural_network/main.py +16 -3
- neural_network/model.py +20 -0
- requirements.txt +1 -0
main.py
CHANGED
@@ -1,18 +1,16 @@
|
|
1 |
-
import numpy as np
|
2 |
from opts import options
|
|
|
|
|
3 |
|
4 |
|
5 |
-
def random_dataset():
|
6 |
"""
|
7 |
-
|
8 |
-
a testing dataset in the form
|
9 |
-
of numpy arrays
|
10 |
"""
|
11 |
-
np.random.
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
)
|
16 |
|
17 |
|
18 |
def main():
|
@@ -22,8 +20,8 @@ def main():
|
|
22 |
except KeyError:
|
23 |
raise f"Invalid method \"{method}\". Try one of these\n{list(options.keys())}"
|
24 |
|
25 |
-
X, y = random_dataset()
|
26 |
-
|
27 |
|
28 |
|
29 |
if __name__ == "__main__":
|
|
|
|
|
1 |
from opts import options
|
2 |
+
import numpy as np
|
3 |
+
from pprint import pprint
|
4 |
|
5 |
|
6 |
+
def random_dataset(rows: int, features: int):
|
7 |
"""
|
8 |
+
Initializes a training and a testing dataset in the form of numpy arrays
|
|
|
|
|
9 |
"""
|
10 |
+
rng = np.random.default_rng()
|
11 |
+
X = rng.normal(size=(rows, features))
|
12 |
+
y = rng.integers(5, size=(rows, 1))
|
13 |
+
return X, y
|
|
|
14 |
|
15 |
|
16 |
def main():
|
|
|
20 |
except KeyError:
|
21 |
raise f"Invalid method \"{method}\". Try one of these\n{list(options.keys())}"
|
22 |
|
23 |
+
X, y = random_dataset(rows=10, features=2)
|
24 |
+
func(X, y)
|
25 |
|
26 |
|
27 |
if __name__ == "__main__":
|
neural_network/backprop.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import numpy as np
|
|
|
2 |
|
3 |
from neural_network.opts import activation
|
4 |
|
@@ -12,21 +13,21 @@ def bp(X_train: np.array, y_train: np.array, wb: dict, args: dict):
|
|
12 |
lr = args["learning_rate"]
|
13 |
|
14 |
r = {}
|
15 |
-
for e in range(epochs):
|
16 |
# forward prop
|
17 |
-
node1 = compute_node(X_train, w1, b1, func)
|
18 |
-
y_hat = compute_node(node1, w2, b2, func)
|
19 |
error = y_hat - y_train
|
20 |
|
21 |
# backprop
|
22 |
-
dw2 = np.dot(
|
23 |
-
node1.T,
|
24 |
-
error * func_prime(y_hat),
|
25 |
-
)
|
26 |
dw1 = np.dot(
|
27 |
X_train.T,
|
28 |
np.dot(error * func_prime(y_hat), w2.T) * func_prime(node1),
|
29 |
)
|
|
|
|
|
|
|
|
|
30 |
db2 = np.sum(error * func_prime(y_hat), axis=0)
|
31 |
db1 = np.sum(np.dot(error * func_prime(y_hat), w2.T) * func_prime(node1), axis=0)
|
32 |
|
@@ -51,5 +52,8 @@ def bp(X_train: np.array, y_train: np.array, wb: dict, args: dict):
|
|
51 |
return r
|
52 |
|
53 |
|
54 |
-
def compute_node(
|
55 |
-
|
|
|
|
|
|
|
|
1 |
import numpy as np
|
2 |
+
from tqdm import tqdm
|
3 |
|
4 |
from neural_network.opts import activation
|
5 |
|
|
|
13 |
lr = args["learning_rate"]
|
14 |
|
15 |
r = {}
|
16 |
+
for e in tqdm(range(epochs)):
|
17 |
# forward prop
|
18 |
+
node1 = compute_node(arr=X_train, w=w1, b=b1, func=func)
|
19 |
+
y_hat = compute_node(arr=node1, w=w2, b=b2, func=func)
|
20 |
error = y_hat - y_train
|
21 |
|
22 |
# backprop
|
|
|
|
|
|
|
|
|
23 |
dw1 = np.dot(
|
24 |
X_train.T,
|
25 |
np.dot(error * func_prime(y_hat), w2.T) * func_prime(node1),
|
26 |
)
|
27 |
+
dw2 = np.dot(
|
28 |
+
node1.T,
|
29 |
+
error * func_prime(y_hat),
|
30 |
+
)
|
31 |
db2 = np.sum(error * func_prime(y_hat), axis=0)
|
32 |
db1 = np.sum(np.dot(error * func_prime(y_hat), w2.T) * func_prime(node1), axis=0)
|
33 |
|
|
|
52 |
return r
|
53 |
|
54 |
|
55 |
+
def compute_node(arr, w, b, func):
|
56 |
+
"""
|
57 |
+
Computes nodes during forward prop
|
58 |
+
"""
|
59 |
+
return func(np.dot(arr, w) + b)
|
neural_network/main.py
CHANGED
@@ -1,7 +1,10 @@
|
|
1 |
from sklearn.model_selection import train_test_split
|
2 |
-
from neural_network.backprop import bp
|
3 |
import numpy as np
|
4 |
|
|
|
|
|
|
|
|
|
5 |
|
6 |
def get_args() -> dict:
|
7 |
"""
|
@@ -17,7 +20,7 @@ def get_args() -> dict:
|
|
17 |
}
|
18 |
|
19 |
|
20 |
-
def init(X: np.array,
|
21 |
"""
|
22 |
returns a dictionary containing randomly initialized
|
23 |
weights and biases to start off the neural_network
|
@@ -35,7 +38,7 @@ def main(
|
|
35 |
y: np.array,
|
36 |
) -> None:
|
37 |
args = get_args()
|
38 |
-
wb = init(X,
|
39 |
X_train, X_test, y_train, y_test = train_test_split(
|
40 |
X,
|
41 |
y,
|
@@ -43,4 +46,14 @@ def main(
|
|
43 |
random_state=8675309
|
44 |
)
|
45 |
|
|
|
|
|
46 |
results = bp(X_train, y_train, wb, args)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
from sklearn.model_selection import train_test_split
|
|
|
2 |
import numpy as np
|
3 |
|
4 |
+
from neural_network.opts import activation
|
5 |
+
from neural_network.backprop import bp
|
6 |
+
from neural_network.model import Model
|
7 |
+
|
8 |
|
9 |
def get_args() -> dict:
|
10 |
"""
|
|
|
20 |
}
|
21 |
|
22 |
|
23 |
+
def init(X: np.array, hidden_size: int) -> dict:
|
24 |
"""
|
25 |
returns a dictionary containing randomly initialized
|
26 |
weights and biases to start off the neural_network
|
|
|
38 |
y: np.array,
|
39 |
) -> None:
|
40 |
args = get_args()
|
41 |
+
wb = init(X, args["hidden_size"])
|
42 |
X_train, X_test, y_train, y_test = train_test_split(
|
43 |
X,
|
44 |
y,
|
|
|
46 |
random_state=8675309
|
47 |
)
|
48 |
|
49 |
+
# once we have these results we should test it against
|
50 |
+
# the y_test data
|
51 |
results = bp(X_train, y_train, wb, args)
|
52 |
+
final = results[args["epochs"]-1]
|
53 |
+
func = activation[args["activation_func"]]["main"]
|
54 |
+
fm = Model(final_wb=final, activation_func=func)
|
55 |
+
|
56 |
+
# predict the x test data and compare it to y test data
|
57 |
+
pred = fm.predict(X_test)
|
58 |
+
mse = np.mean((pred - y_test) ** 2)
|
59 |
+
print(f"mean squared error: {mse}")
|
neural_network/model.py
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
from typing import Callable
|
3 |
+
|
4 |
+
|
5 |
+
class Model:
|
6 |
+
def __init__(self, final_wb: dict[str, np.array], activation_func: Callable):
|
7 |
+
self.func = activation_func
|
8 |
+
self.final_wb = final_wb
|
9 |
+
self.w1 = final_wb["W1"]
|
10 |
+
self.w2 = final_wb["W2"]
|
11 |
+
self.b1 = final_wb["b1"]
|
12 |
+
self.b2 = final_wb["b2"]
|
13 |
+
|
14 |
+
def predict(self, x: np.array) -> np.array:
|
15 |
+
n1 = self.compute_node(x, self.w1, self.b1, self.func)
|
16 |
+
return self.compute_node(n1, self.w2, self.b2, self.func)
|
17 |
+
|
18 |
+
@staticmethod
|
19 |
+
def compute_node(arr, w, b, func):
|
20 |
+
return func(np.dot(arr, w) + b)
|
requirements.txt
CHANGED
@@ -1,2 +1,3 @@
|
|
1 |
numpy==1.24.2
|
2 |
scikit_learn==1.2.2
|
|
|
|
1 |
numpy==1.24.2
|
2 |
scikit_learn==1.2.2
|
3 |
+
tqdm==4.65.0
|