Skip to content

Commit ebcc391

Browse files
committed
Finish network in python
1 parent da7c553 commit ebcc391

File tree

9 files changed

+174
-6
lines changed

9 files changed

+174
-6
lines changed

__pycache__/loader.cpython-37.pyc

3.86 KB
Binary file not shown.

__pycache__/neuralnet.cpython-37.pyc

3.96 KB
Binary file not shown.

imgPr2.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import cv2 as cv
2+
import numpy as np
3+
img_i = cv.imread("sud.jpg")
4+
img = cv.resize(img_i, (400, 400), interpolation=cv.INTER_AREA)
5+
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
6+
7+
8+
initial = np.float32([[31,10],[373,15],[14,377],[394,381]])
9+
final = np.float32([[0,0],[1000,0],[0,1000],[1000,1000]])
10+
11+
M = cv.getPerspectiveTransform(initial, final)
12+
13+
img_f = cv.warpPerspective(img, M, (1000, 1000))
14+
15+
cv.namedWindow('image', cv.WINDOW_NORMAL)
16+
cv.resizeWindow('image', 1000, 1000)
17+
cv.imshow('image', img_f)
18+
cv.waitKey(0)
19+
cv.destroyAllWindows()

loader.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"""
2+
mnist_loader
3+
~~~~~~~~~~~~
4+
5+
A library to load the MNIST image data. For details of the data
6+
structures that are returned, see the doc strings for ``load_data``
7+
and ``load_data_wrapper``. In practice, ``load_data_wrapper`` is the
8+
function usually called by our neural network code.
9+
"""
10+
11+
#### Libraries
12+
# Standard library
13+
import cPickle
14+
import gzip
15+
16+
# Third-party libraries
17+
import numpy as np
18+
19+
def load_data():
20+
"""Return the MNIST data as a tuple containing the training data,
21+
the validation data, and the test data.
22+
23+
The ``training_data`` is returned as a tuple with two entries.
24+
The first entry contains the actual training images. This is a
25+
numpy ndarray with 50,000 entries. Each entry is, in turn, a
26+
numpy ndarray with 784 values, representing the 28 * 28 = 784
27+
pixels in a single MNIST image.
28+
29+
The second entry in the ``training_data`` tuple is a numpy ndarray
30+
containing 50,000 entries. Those entries are just the digit
31+
values (0...9) for the corresponding images contained in the first
32+
entry of the tuple.
33+
34+
The ``validation_data`` and ``test_data`` are similar, except
35+
each contains only 10,000 images.
36+
37+
This is a nice data format, but for use in neural networks it's
38+
helpful to modify the format of the ``training_data`` a little.
39+
That's done in the wrapper function ``load_data_wrapper()``, see
40+
below.
41+
"""
42+
f = gzip.open('mnist.pkl.gz', 'rb')
43+
training_data, validation_data, test_data = cPickle.load(f)
44+
f.close()
45+
return (training_data, validation_data, test_data)
46+
47+
def load_data_wrapper():
48+
"""Return a tuple containing ``(training_data, validation_data,
49+
test_data)``. Based on ``load_data``, but the format is more
50+
convenient for use in our implementation of neural networks.
51+
52+
In particular, ``training_data`` is a list containing 50,000
53+
2-tuples ``(x, y)``. ``x`` is a 784-dimensional numpy.ndarray
54+
containing the input image. ``y`` is a 10-dimensional
55+
numpy.ndarray representing the unit vector corresponding to the
56+
correct digit for ``x``.
57+
58+
``validation_data`` and ``test_data`` are lists containing 10,000
59+
2-tuples ``(x, y)``. In each case, ``x`` is a 784-dimensional
60+
numpy.ndarry containing the input image, and ``y`` is the
61+
corresponding classification, i.e., the digit values (integers)
62+
corresponding to ``x``.
63+
64+
Obviously, this means we're using slightly different formats for
65+
the training data and the validation / test data. These formats
66+
turn out to be the most convenient for use in our neural network
67+
code."""
68+
tr_d, va_d, te_d = load_data()
69+
training_inputs = [np.reshape(x, (784, 1)) for x in tr_d[0]]
70+
training_results = [vectorized_result(y) for y in tr_d[1]]
71+
training_data = zip(training_inputs, training_results)
72+
validation_inputs = [np.reshape(x, (784, 1)) for x in va_d[0]]
73+
validation_data = zip(validation_inputs, va_d[1])
74+
test_inputs = [np.reshape(x, (784, 1)) for x in te_d[0]]
75+
test_data = zip(test_inputs, te_d[1])
76+
return (training_data, validation_data, test_data)
77+
78+
def vectorized_result(j):
79+
"""Return a 10-dimensional unit vector with a 1.0 in the jth
80+
position and zeroes elsewhere. This is used to convert a digit
81+
(0...9) into a corresponding desired output from the neural
82+
network."""
83+
e = np.zeros((10, 1))
84+
e[j] = 1.0
85+
return e

loader.pyc

3.67 KB
Binary file not shown.

mnist.pkl.gz

16.3 MB
Binary file not shown.

neuralnet.py

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class Network:
66
def __init__(self, params):
77
# params is a list containing sizes layer wises
88
self.layers = len(params)
9-
self.biases = [np.random.randn(siz) for siz in params[1:]] # first layer won't have bias
9+
self.biases = [np.random.randn(siz, 1) for siz in params[1:]] # first layer won't have bias
1010
#to do check if the param should have a 1 (bias should be a row vector)
1111
self.weights = [np.random.randn(siz, prev) for siz, prev in zip(params[1:], params[:-1])]
1212

@@ -17,18 +17,58 @@ def gradient_descent(self, training_data, cycles, eta, batch_size, num_batches):
1717
# to get better averaging we do this grouping cycles number of times
1818
n = len(training_data)
1919
for iter in range(cycles):
20-
random.shuffle(training_data)
2120
mini_batches = [training_data[s:s+batch_size] for s in range(0, n, batch_size)]
2221

22+
count = 0
2323
for batch in mini_batches:
24+
base_w = [np.zeros(w.shape) for w in self.weights]
25+
# random.shuffle(training_data)
26+
base_b = [np.zeros(b.shape) for b in self.biases]
2427
for dataset in batch:
28+
2529
# do back propagation for this dataset
2630
# average out this to obtain the gradient
2731
change_w, change_b = self.back_prop(dataset)
32+
base_w = [w + ch for w, ch in zip(base_w, change_w)]
33+
base_b = [b + ch for b, ch in zip(base_b, change_b)]
34+
35+
# we have the average gradient
36+
self.weights = [w-(eta*ch/len(batch)) for w, ch in zip(self.weights, base_w)]
37+
self.biases = [b-(eta*ch/len(batch)) for b, ch in zip(self.biases, base_b)]
38+
count += 1
39+
print ("Finished batch {0}".format(count))
40+
41+
def test(self, training_data, l, r):
42+
i = l
43+
success = 0
44+
total = 0
45+
while i<=r:
46+
result = self.forward(training_data[i][0])
47+
best_val = 0
48+
best = -1
49+
j = 0
50+
actual = -1
51+
while j<=9:
52+
if result[j] > best_val:
53+
best_val = result[i]
54+
best = j
55+
if training_data[i][1][j] > 0.5:
56+
actual = j
57+
j+=1
58+
59+
for term, actual in zip(result, training_data[i][1]):
60+
net_cost += (term-actual)*(term-actual)
61+
net_cost /= len(result)
62+
63+
if actual == best:
64+
success+=1
65+
total += 1
66+
67+
print ("Success: {0}/{1}".format(success, total))
2868

2969
def sigmoid(self, vector):
3070
#returns sigmoid of a vector
31-
return 1.0/1.0 + np.exp(-vector)
71+
return 1.0/(1.0 + np.exp(-vector))
3272

3373
def sigmoid_prime(self, vector):
3474
return self.sigmoid(vector)*(1-self.sigmoid(vector))
@@ -44,14 +84,32 @@ def back_prop(self, dataset):
4484
zs = []
4585
a = dataset[0]
4686
for weight, bias in zip(self.weights, self.biases):
87+
# print(bias.shape)
4788
zs.append(np.dot(weight, a) + bias)
4889
a = self.sigmoid(np.dot(weight, a) + bias)
4990
activations.append(a)
5091

92+
layers = len(self.weights) + 1
5193
delta = 2*(activations[-1]-dataset[1])*self.sigmoid_prime(zs[-1])
52-
53-
54-
94+
change_bias = self.biases
95+
change_weight = self.weights
5596

97+
change_bias[layers-2] = delta
98+
# currently operating on weights at layers-2-iter
99+
for j in range(len(change_weight[layers-2])):
100+
for k in range(len(change_weight[layers-2][j])):
101+
change_weight[layers-2][j][k] = activations[layers-2][k]*delta[j]
56102

103+
# want to return gradients layer wise
104+
for iter in range(layers-3):
105+
delta = np.dot(self.weights[layers-2-iter].transpose(), delta)*self.sigmoid_prime(zs[layers-3-iter])
106+
change_bias[layers-3-iter] = delta
107+
# currently operating on weights at layers-2-iter
108+
for j in range(len(change_weight[layers-3-iter])):
109+
for k in range(len(change_weight[layers-3-iter][j])):
110+
change_weight[layers-3-iter][j][k] = activations[layers-3-iter][k]*delta[j]
111+
# back propagate delta
57112

113+
114+
return change_weight, change_bias
115+

neuralnet.pyc

4.01 KB
Binary file not shown.

test.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from neuralnet import *
2+
from loader import *
3+
4+
net = Network([784, 40, 10])
5+
train, valid, dest = load_data_wrapper()
6+
net.gradient_descent(train, 10, 0.1, 100, 500)

0 commit comments

Comments
 (0)