1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
import numpy as np
import math
from scipy.special import expit
from dataset import Dataset
CYRILLIC_ALPHABET = ['I', 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ë', 'Ж', 'З',
'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С',
'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы',
'Ь', 'Э', 'Ю', 'Я']
"""The neural network class."""
class NeuralNetwork:
def __init__(self, learning_rate: float, input_resolution: int) -> None:
self.learning_rate = learning_rate
self.input_layer_size = input_resolution
self.hidden_layer_size = len(CYRILLIC_ALPHABET)
self._hidden_weights = self._random_array(self.hidden_layer_size,
input_resolution)
self._output_weights = self._random_array(input_resolution, 1)
"""
Train the neural network. It loads the dataset contained in ./data,
converts each image into a numpy array and uses that data for training.
Algorithm:
1-. Feedforward the input matrix.
2-. Calculate the output layer error.
3-. Adjust the weights of the output layer via gradient descent.
3-. Calculate the hidden layer error by backpropagating the output layer
error.
4-. Adjust the weights of the hidden layer via gradient descent.
"""
def train(self):
pass
"""
Guess the letter contained in the image file pointed by
input_image (a path).
"""
def guess(self, input_image: np.array) -> str:
output_layer = self._feedforward(input_image)
return self.guessed_char(output_layer)
"""
Save the weights to a csv file.
"""
def save(self, weights_filename):
pass
"""
Load the weights from a csv file.
"""
def load(self, weights_file: str):
pass
"""
Get the result from a sigmoid matrix (the index with the highest chance
of being the correct answer).
"""
def _guessed_char(self, output_layer: np.array) -> str:
return CYRILLIC_ALPHABET[np.argmax(np.transpose(output_layer))]
"""
Feedforwarding.
"""
def _feedforward(self, input_layer: np.array):
hidden_layer_inputs = np.dot(self._hidden_weights, input_layer)
hidden_layer_outputs = self._get_layer_output(hidden_layer_inputs)
output_layer_inputs = np.dot(hidden_layer_outputs,
self._output_weights)
# The output layer outputs. (Final output of the neural network).
return self._get_layer_output(output_layer_inputs)
"""
Apply the sigmoid function to a given layer
"""
def _get_layer_output(self, layer: np.array):
return expit(layer)
"""
Generate a random array via an uniform distribution.
"""
def _random_array(self, rows: int, columns: int) -> np.array:
low = -1 / math.sqrt(rows)
high = 1 / math.sqrt(columns)
return np.random.uniform(low, high, (rows, columns))
|