Ejemplo n.º 1
0
class NeuralNetwork:
    def __init__(self, neurons_input, neurons_hidden, neurons_output,
                 number_of_hidden_layers, learning_rate):
        self.neurons_input = neurons_input
        self.neurons_hidden = neurons_hidden
        self.neurons_output = neurons_output
        self.number_of_hidden_layers = number_of_hidden_layers
        self.learning_rate = learning_rate

        # create_layers
        self.input_layer = Layer(None, neurons_input)
        self.hidden_layers = []
        self.hidden_layers.append(Layer(self.input_layer, self.neurons_hidden))

        for i in range(number_of_hidden_layers - 1):
            self.hidden_layers.append(
                Layer(self.hidden_layers[i], self.neurons_hidden))

        self.output_layer = Layer(self.hidden_layers[-1], neurons_output)

    def feed_forward(self):
        for layer in self.hidden_layers:
            layer.calculate_output()
        self.output_layer.calculate_output()

    def back_propagate(self, last_layer):
        i = len(self.hidden_layers) - 1
        while i > 0:
            layer = self.hidden_layers[i]
            layer.error = calculate__error(last_layer)
            layer.weights += self.calculate_weight_change(
                layer, self.hidden_layers[i - 1])
            last_layer = self.hidden_layers[i]
            i -= 1
        if len(self.hidden_layers) > 1:
            self.hidden_layers[0].error = calculate__error(
                self.hidden_layers[1])
            self.hidden_layers[0].weights += self.calculate_weight_change(
                self.hidden_layers[0], self.input_layer)
        else:
            self.hidden_layers[0].error = calculate__error(last_layer)
            self.hidden_layers[0].weights += self.calculate_weight_change(
                self.hidden_layers[0], self.input_layer)

    def train(self, training_set, training_labels):
        right_answers = 0

        for i in range(len(training_set)):
            self.input_layer.output = np.reshape(np.array(training_set[i]),
                                                 (784, 1))
            self.feed_forward()

            print(
                f'{i} answer is {training_labels[i]} guess is {neural_answer(self.output_layer.data)}'
            )
            target = np.reshape(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
                                (10, 1))
            target[training_labels[i]] = 1

            if neural_answer(self.output_layer.data) == training_labels[i]:
                right_answers += 1
            # output error
            self.output_layer.error = np.subtract(target,
                                                  self.output_layer.output)
            self.output_layer.weights += self.calculate_weight_change(
                self.output_layer, self.hidden_layers[-1])

            self.back_propagate(self.output_layer)

        print(f'correctness = {right_answers / 60000}')

    def calculate_weight_change(self, layer, prev):
        return self.learning_rate * np.dot(
            (layer.error * layer.output *
             (1 - layer.output)), np.transpose(prev.output))

    def test(self, testing_set, testing_labels):
        right_answers = 0
        for i in range(len(testing_set)):
            self.input_layer.output = np.reshape(np.array(testing_set[i]),
                                                 (784, 1))
            self.feed_forward()

            print(
                f'{i} answer is {testing_labels[i]} guess is {neural_answer(self.output_layer.data)}'
            )
            if neural_answer(self.output_layer.data) == testing_labels[i]:
                right_answers += 1

        print(f'correctness = {right_answers / 10000}')