Skip to content

Commit 5c8d172

Browse files
authored
Add files via upload
1 parent 4cb3374 commit 5c8d172

File tree

3 files changed

+180
-0
lines changed

3 files changed

+180
-0
lines changed

network.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import numpy as np
2+
import random
3+
4+
class NeuralNetwork():
5+
6+
def __init__(self, sizes):
7+
# sizes is an array with the number of units in each layer
8+
# [2,3,1] means w neurons of input, 3 in the hidden layer and 1 as output
9+
self.num_layers = len(sizes)
10+
self.sizes = sizes
11+
# the syntax [1:] gets all elements of sizes array beginning at index 1 (second position)
12+
# np,random.randn(rows, cols) retuns a matrix of random elements
13+
# np.random.randn(2,1) =>
14+
# array([[ 0.68265325],
15+
# [-0.52939261]])
16+
# biases will have one vector per layer
17+
self.biases = [np.random.randn(y,1) for y in sizes[1:]]
18+
#zip returns a tuple in which x is the element of the first array and y the element of the second
19+
#sizes[:-1] returns all the elements till the second to last
20+
#sizes[1:] returns all the elements from the second and on]
21+
# [2,3,1] means:
22+
# * matrix of 3 rows and 2 columns -- will be multiplied by the inputs
23+
# * matrix of 1 row and 3 columns -- will multiply the hidden layer and produce the output
24+
self.weights = [np.random.randn(y,x) for x,y in zip(sizes[:-1],sizes[1:])]
25+
26+
def feedforward(self, a):
27+
for b,w in zip(self.biases, self.weights):
28+
a = sigmoid(np.dot(w, a) + b)
29+
return a
30+
31+
def separate_batches(self, training_data, batch_size):
32+
random.shuffle(training_data)
33+
n = len(training_data)
34+
# extracts chunks of data from the training set
35+
# the xrange function will return indices starting with 0 untill n, with a step size o batch_size
36+
# batches, then, will have several chunks of the main set, each defined by the batch_size_variable
37+
return [training_data[i:i + batch_size] for i in range(0, n, batch_size)]
38+
39+
def update_batches(self, batches, alpha):
40+
for batch in batches:
41+
nabla_b = [np.zeros(b.shape) for b in self.biases]
42+
nabla_w = [np.zeros(w.shape) for w in self.weights]
43+
44+
m = len(batch)
45+
46+
# x is a array of length 901
47+
# y is a single value indicating the digit represented by the 901 elements
48+
for x, y in batch:
49+
delta_b, delta_w = self.backpropagation(x, y)
50+
nabla_b = [nb + dnb for nb, dnb in zip(nabla_b, delta_b)]
51+
nabla_w = [nw + dnw for nw, dnw in zip(nabla_w, delta_w)]
52+
53+
self.weights = [w - (alpha / m) * nw for w, nw in zip(self.weights, nabla_w)]
54+
self.biases = [b - (alpha / m) * nb for b, nb in zip(self.biases, nabla_b)]
55+
56+
def backpropagation(self, x, y):
57+
nabla_b = [np.zeros(b.shape) for b in self.biases]
58+
nabla_w = [np.zeros(w.shape) for w in self.weights]
59+
60+
activation = x
61+
activations = [x]
62+
zs = []
63+
for b, w in zip(self.biases, self.weights):
64+
# layer-bound b and w
65+
z = np.dot(w, activation)+b
66+
zs.append(z)
67+
activation = sigmoid(z)
68+
activations.append(activation)
69+
# backward pass
70+
delta = self.cost_derivative(activations[-1], y) * \
71+
sigmoid_prime(zs[-1])
72+
nabla_b[-1] = delta
73+
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
74+
75+
for l in range(2, self.num_layers):
76+
z = zs[-l]
77+
sp = sigmoid_prime(z)
78+
delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
79+
nabla_b[-l] = delta
80+
nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
81+
return (nabla_b, nabla_w)
82+
83+
def sgd(self, training_data, epochs, batch_size, alpha, test_data):
84+
n_test = len(test_data)
85+
86+
for epoch in range(epochs):
87+
batches = self.separate_batches(training_data, batch_size)
88+
self.update_batches(batches, alpha)
89+
90+
print("Epoch {0}: {1} / {2}".format(epoch, self.evaluate(test_data), n_test))
91+
92+
def evaluate(self, test_data):
93+
#r = [self.feedforward(x) for (x, y) in test_data]
94+
#for a in r:
95+
# print("{0}, {1}".format(format(a[0][0], 'f'), format(a[1][0], 'f'))) ;
96+
test_results = [(np.argmax(self.feedforward(x)), y)
97+
for (x, y) in test_data]
98+
return sum(int(x == y) for (x, y) in test_results)
99+
100+
def cost_derivative(self, output_activations, y):
101+
return output_activations - y
102+
103+
104+
def sigmoid(z):
105+
return 1.0 / (1.0 + np.exp(-z))
106+
107+
108+
109+
def sigmoid_prime(z):
110+
return sigmoid(z) * (1-sigmoid(z))

preprocessor.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import cv2
2+
import numpy as np
3+
4+
5+
def prepare(input):
6+
# preprocessing the image input
7+
clean = cv2.fastNlMeansDenoising(input)
8+
ret, tresh = cv2.threshold(clean, 127, 1, cv2.THRESH_BINARY_INV)
9+
img = crop(tresh)
10+
11+
# 40x10 image as a flatten array
12+
flatten_img = cv2.resize(img, (40, 10), interpolation=cv2.INTER_AREA).flatten()
13+
14+
# resize to 400x100
15+
resized = cv2.resize(img, (400, 100), interpolation=cv2.INTER_AREA)
16+
columns = np.sum(resized, axis=0) # sum of all columns
17+
lines = np.sum(resized, axis=1) # sum of all lines
18+
19+
h, w = img.shape
20+
aspect = w / h
21+
22+
return [*flatten_img, *columns, *lines, aspect]
23+
24+
25+
def crop(img):
26+
points = cv2.findNonZero(img)
27+
x, y, w, h = cv2.boundingRect(points)
28+
return img[y: y+h, x: x+w]

sigrecog.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import cv2
2+
import os
3+
import numpy as np
4+
import network
5+
import preprocessor
6+
7+
8+
def main():
9+
print('OpenCV version {} '.format(cv2.__version__))
10+
11+
current_dir = os.path.dirname(__file__)
12+
13+
author = '024'
14+
training_folder = os.path.join(current_dir, 'data/training/', author)
15+
test_folder = os.path.join(current_dir, 'data/test/', author)
16+
17+
training_data = []
18+
for filename in os.listdir(training_folder):
19+
img = cv2.imread(os.path.join(training_folder, filename), 0)
20+
if img is not None:
21+
data = np.array(preprocessor.prepare(img))
22+
data = np.reshape(data, (901, 1))
23+
result = [[0], [1]] if "genuine" in filename else [[1], [0]]
24+
result = np.array(result)
25+
result = np.reshape(result, (2, 1))
26+
training_data.append((data, result))
27+
28+
test_data = []
29+
for filename in os.listdir(test_folder):
30+
img = cv2.imread(os.path.join(test_folder, filename), 0)
31+
if img is not None:
32+
data = np.array(preprocessor.prepare(img))
33+
data = np.reshape(data, (901, 1))
34+
result = 1 if "genuine" in filename else 0
35+
test_data.append((data, result))
36+
37+
net = network.NeuralNetwork([901, 500, 500, 2])
38+
net.sgd(training_data, 10, 50, 0.01, test_data)
39+
40+
41+
if __name__ == '__main__':
42+
main()

0 commit comments

Comments
 (0)