Skip to content

Commit 1c78cce

Browse files
committed
almost finish bp
1 parent 407dfae commit 1c78cce

File tree

1 file changed

+68
-10
lines changed

1 file changed

+68
-10
lines changed

bp.py

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from random import shuffle
2+
13
import numpy as np
24

35
from data import x_train, x_test, y_train, y_test
@@ -7,21 +9,70 @@ class NeuralNetwork():
79
"""
810
this is a basic class of neural network
911
"""
12+
eta = 5
1013

1114
def __init__(self, layers):
1215
# first we assume this network contains
1316
# only 3 layers: input, hidden, out
1417
self.n_input = layers[0]
15-
self.n_hidden = layers[0]
16-
self.n_out = layers[0]
18+
self.n_hidden = layers[1]
19+
self.n_out = layers[2]
20+
# initial random weight
21+
self.w_in2hidden = np.random.randn(self.n_hidden, self.n_input + 1)
22+
self.w_hidden2out = np.random.randn(10, self.n_hidden + 1)
1723

1824
def train(self, x_train, y_train):
1925
"""
2026
:param x_train: 2d array, features
2127
:param y_train: 1d array, labels of x_train
2228
:return: None
2329
"""
24-
pass
30+
n_samples, n_features = x_train.shape
31+
y_vec = np.zeros((n_samples, 10))
32+
y_vec[np.arange(n_samples), y_train] = 1
33+
34+
orders = list(range(n_samples))
35+
shuffle(orders)
36+
37+
N = 20
38+
n_batch = 0
39+
while (N * n_batch <= n_samples):
40+
n_batch += 1
41+
if n_batch % 50 == 0:
42+
print("processing:{0:.1f}%".format(100 * n_batch * N / n_samples), end="\r")
43+
batch = orders[N * n_batch: N * n_batch + N]
44+
errw_out2hidden = np.zeros((10, self.n_hidden + 1))
45+
errw_hidden2in = np.zeros((self.n_hidden, n_features + 1))
46+
for i in batch:
47+
y_sample = y_vec[orders[i]]
48+
sample = x_train[orders[i]]
49+
# forward
50+
# sample add 1 at the tail
51+
sample_add1 = np.hstack((sample, [1])).T
52+
u_hidden = np.dot(self.w_in2hidden, sample_add1)
53+
a_hidden = self.sigmoid(u_hidden)
54+
a_hidden_add1 = np.hstack((a_hidden, [1]))
55+
u_out = np.dot(self.w_hidden2out, a_hidden_add1)
56+
a_out = self.sigmoid(u_out)
57+
cost_dev = a_out - y_sample
58+
# back
59+
err_out = cost_dev * self.sigmoid_prime(u_out)
60+
errw_out2hidden += np.dot(err_out[:, np.newaxis], a_hidden_add1[np.newaxis, :])
61+
62+
err_hidden = np.dot(self.w_hidden2out.T, err_out)
63+
err_hidden = err_hidden[:-1]
64+
err_hidden *= self.sigmoid_prime(u_hidden)
65+
errw_hidden2in += np.dot(err_hidden[:, np.newaxis], sample_add1[np.newaxis, :])
66+
# update weight
67+
self.w_in2hidden -= self.eta * errw_hidden2in / N
68+
self.w_hidden2out -= self.eta * errw_out2hidden / N
69+
70+
71+
def sigmoid(self, x):
72+
return 1. / (1 + np.exp(-x))
73+
74+
def sigmoid_prime(self, x):
75+
return self.sigmoid(x) * (1 - self.sigmoid(x))
2576

2677
def predict(self, x_test):
2778
"""
@@ -31,15 +82,22 @@ def predict(self, x_test):
3182
"""
3283
y_test = []
3384
for sample in x_test:
34-
# todo
35-
# gen prediction of each sample
36-
# y_test.appen()
37-
pass
85+
sample_add1 = np.hstack((sample, [1]))
86+
u_hidden = np.dot(self.w_in2hidden, sample_add1)
87+
a_hidden = self.sigmoid(u_hidden)
88+
a_hidden_add1 = np.hstack((a_hidden, [1]))
89+
u_out = np.dot(self.w_hidden2out, a_hidden_add1)
90+
y_out = self.sigmoid(u_out)
91+
y_test.append(y_out)
3892
return y_test
3993

4094

4195
if __name__ == '__main__':
4296
nn = NeuralNetwork([784, 30, 10])
43-
nn.train(x_train, y_train)
44-
predicty = nn.predict(x_test)
45-
print(np.sum(predicty == y_test))
97+
98+
n_round = 30
99+
for r in range(n_round):
100+
print("round:", r)
101+
nn.train(x_train, y_train)
102+
predicty = nn.predict(x_test)
103+
print("result:", np.sum(np.argmax(predicty, axis=1) == y_test))

0 commit comments

Comments
 (0)