8000 Little improvement in speed by reshaping before training. · Capsar/python-neural-network@0c5f4b1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0c5f4b1

Browse files
committed
Little improvement in speed by reshaping before training.
1 parent 1e203d6 commit 0c5f4b1

File tree

2 files changed

+42
-51
lines changed

2 files changed

+42
-51
lines changed

main.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import numpy as np
22
import z_helper as h
3+
import time
4+
35

46
class NeuralNetwork:
57

@@ -8,49 +10,44 @@ def __init__(self, layer_sizes, layer_activations, learning_rate=0.1, low=-2, hi
810
assert len(layer_sizes)-1 == len(layer_activations)
911

1012
# Initialize weights between every neuron in all adjacent layers.
11-
self.weights = [h.random_np(low, high, (layer_sizes[i-1], layer_sizes[i])) for i in range(1, len(layer_sizes))]
13+
self.weights = [np.random.uniform(low, high, (layer_sizes[i-1], layer_sizes[i])) for i in range(1, len(layer_sizes))]
1214
# Initialize biases for every neuron in all layers
13-
self.biases = np.array([h.random_np(low, high, layer_sizes[i]).reshape(-1, 1) for i in range(1, len(layer_sizes))])
15+
self.biases = np.array([np.random.uniform(low, high, (layer_sizes[i], 1)) for i in range(1, len(layer_sizes))])
1416
# Initialize empty list of output of every neuron in all layers.
15-
self.layer_outputs = [np.zeros(layer_sizes[i]).reshape(-1, 1) for i in range(len(layer_sizes))]
17+
self.layer_outputs = [np.zeros((layer_sizes[i], 1)) for i in range(len(layer_sizes))]
1618

1719
self.layer_activations = layer_activations
1820
self.layer_sizes = layer_sizes
1921
self.learning_rate = learning_rate
2022

2123
def calculate_output(self, input_data):
22-
input_data = np.array(input_data).reshape(-1, 1)
2324
assert len(input_data) == self.layer_sizes[0]
2425
num_calculations = len(self.weights)
2526

2627
y = input_data
2728
self.layer_outputs[0] = y
2829

2930
for i in range(num_calculations):
30-
y = h.activation(self.layer_activations[i])(np.dot(self.weights[i].T, y) + self.biases[i])
31+
y = self.layer_activations[i](np.dot(self.weights[i].T, y) + self.biases[i], False)
3132
self.layer_outputs[i+1] = y
3233

3334
return y
3435

3536
def train(self, input_data, desired_output_data):
36-
input_data = np.array(input_data).reshape(-1, 1)
37-
desired_output_data = np.array(desired_output_data).reshape(-1, 1)
3837
assert len(input_data) == self.layer_sizes[0]
3938
assert len(desired_output_data) == self.layer_sizes[-1]
4039
self.calculate_output(input_data)
4140

42-
error = (desired_output_data - self.layer_outputs[-1]) * h.derivative(self.layer_activations[-1])(self.layer_outputs[-1])
41+
error = (desired_output_data - self.layer_outputs[-1]) * self.layer_activations[-1](self.layer_outputs[-1], True)
4342
self.weights[-1] += (self.learning_rate * self.layer_outputs[-2] * error.T)
4443
self.biases[-1] += self.learning_rate * error
4544

4645
for i in reversed(range(len(self.weights)-1)):
47-
error = np.dot(self.weights[i+1], error) * h.derivative(self.layer_activations[i])(self.layer_outputs[i+1])
46+
error = np.dot(self.weights[i+1], error) * self.layer_activations[i](self.layer_outputs[i+1], True)
4847
self.weights[i] += (self.learning_rate * self.layer_outputs[i] * error.T)
4948
self.biases[i] += self.learning_rate * error
50-
49+
5150
def calculate_SSE(self, input_data, desired_output_data):
52-
input_data = np.array(input_data).reshape(-1, 1)
53-
desired_output_data = np.array(desired_output_data).reshape(-1, 1)
5451
assert len(input_data) == self.layer_sizes[0]
5552
assert len(desired_output_data) == self.layer_sizes[-1]
5653
return np.sum(np.power(desired_output_data - self.calculate_output(input_data), 2))
@@ -61,32 +58,35 @@ def print_weights_and_biases(self):
6158

6259

6360
np.set_printoptions(linewidth=200)
64-
for i in range(5):
61+
62+
data_input = h.import_from_csv("data/features.txt", float)
63+
data_output = h.import_from_csv("data/targets.txt", int)
64+
data_output = np.array([h.class_to_array(np.amax(data_output), x) for x in data_output])
65+
66+
data_input = data_input.reshape((len(data_input), -1, 1))
67+
data_output = data_output.reshape((len(data_input), -1, 1))
68+
69+
for i in range(4):
6570
random_seed = np.random.randint(10, 1010)
6671
np.random.seed(random_seed)
6772

68-
data_input = h.import_from_csv("data/features.txt", float)
69-
data_output = h.import_from_csv("data/targets.txt", int)
70-
data_output = np.array([h.class_to_array(np.amax(data_output), x) for x in data_output])
71-
7273
train_input, validate_input, test_input = h.kfold(4, data_input, random_seed)
7374
train_output, validate_output, test_output = h.kfold(4, data_output, random_seed)
7475

75-
nn = NeuralNetwork(layer_sizes=[10, 15, 7], layer_activations=["sigmoid", "sigmoid"])
76+
nn = NeuralNetwork(layer_sizes=[10, 15, 7], layer_activations=[h.sigmoid, h.sigmoid])
7677

7778
previous_mse = 1
7879
current_mse = 0
7980
epochs = 0
81+
begin_time = time.time_ns()
8082
while(current_mse < previous_mse):
83+
epochs += 1
8184
previous_mse = h.calculate_MSE(nn, validate_input, validate_output)
8285
for i in range(len(train_input)):
8386
nn.train(train_input[i], train_output[i])
8487
current_mse = h.calculate_MSE(nn, validate_input, validate_output)
85-
86-
epochs += 1
87-
# if epochs % 10 == 0: print("Epoch: " + str(epochs) + " MSE: " + str(current_mse))
88-
88+
end_time = time.time_ns()
8989

9090
train_mse = h.calculate_MSE(nn, train_input, train_output)
9191
test_mse = h.calculate_MSE(nn, test_input, test_output)
92-
print("Random_Seed: " + str(random_seed) + " Epochs: " + str(epochs) + " Tr: " + str(train_mse) + " V: " + str(current_mse) + " T: " + str(test_mse))
92+
print("Seed:", random_seed, "Epochs:", epochs, "Time:", (end_time-begin_time)/1e9, "Tr:", train_mse, "V:", current_mse, "T:", test_mse)

z_helper.py

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,51 @@
11
import numpy as np
22

3+
34
def import_from_csv(path, data_type):
4-
return np.genfromtxt(path, dtype=data_type, delimiter=',')
5+
return np.genfromtxt(path, dtype=data_type, delimiter=',')
6+
57

68
def class_to_array(maximum_class, x):
79
data = np.zeros(maximum_class)
810
data[x-1] = 1
9-
return data
11+
return data
12+
1013

1114
def kfold(k, data, seed=99):
1215
np.random.seed(seed)
13-
np.random.shuffle(data)
16+
data = np.random.permutation(data)
1417
fold_size = int(len(data) / k)
1518
return data[:fold_size], data[fold_size:fold_size*2], data[fold_size*2:]
1619

20+
1721
def calculate_MSE(nn, input_data, output_data):
1822
size = len(input_data)
1923
sum_error = 0
2024
for i in range(size):
2125
sum_error += nn.calculate_SSE(input_data[i], output_data[i])
2226
return sum_error / size
2327

28+
2429
def random_np(low, high, size):
2530
assert low <= high
2631
return np.random.random(size)*(high-low) + low
2732

28-
def activation(s):
29-
if s == "relu":
30-
return relu
31-
if s == "sigmoid":
32-
return sigmoid
33-
else:
34-
return "Error"
3533

36-
def derivative(s):
37-
if s == "relu":
38-
return relu_derivative
39-
if s == "sigmoid":
40-
return sigmoid_derivative
34+
def sigmoid(x, derivative):
35+
if derivative:
36+
return x * (1.0 - x)
4137
else:
42-
return "Error"
43-
38+
return 1.0 / (1.0 + np.exp(-x))
4439

45-
def sigmoid(x):
46-
return 1.0 / (1.0 + np.exp(-x))
4740

48-
def sigmoid_derivative(x):
49-
return x * (1.0 - x)
50-
51-
def relu(x):
52-
return np.maximum(0, x)
41+
def relu(x, derivative):
42+
if derivative:
43+
x[x <= 0] = 0
44+
x[x > 0] = 1
45+
return x
46+
else:
47+
return np.maximum(0, x)
5348

54-
def relu_derivative(x):
55-
x[x<=0] = 0
56-
x[x>0] = 1
57-
return x
5849

5950
def softmax(x):
6051
return np.exp(x) / np.sum(np.exp(x))

0 commit comments

Comments
 (0)
0