def predict(self, input_array):

        inputs = Matrix.from_array(input_array)

        hidden = Matrix.multiply_matrix(self.weights_ih, inputs)
        hidden = Matrix.add_matrix(hidden, self.bias_h)
        hidden.map(NeuralNetwork.sigmoid)

        output = Matrix.multiply_matrix(self.weights_ho, hidden)
        output = Matrix.add_matrix(output, self.bias_o)
        output.map(NeuralNetwork.sigmoid)

        return Matrix.to_array(output)
    def train(self, input_array, targets_array):

        inputs = Matrix.from_array(input_array)

        hidden = Matrix.multiply_matrix(self.weights_ih, inputs)
        hidden = Matrix.add_matrix(hidden, self.bias_h)

        hidden.map(NeuralNetwork.sigmoid)

        outputs = Matrix.multiply_matrix(self.weights_ho, hidden)
        outputs = Matrix.add_matrix(outputs, self.bias_o)
        outputs.map(NeuralNetwork.sigmoid)

        targets = Matrix.from_array(targets_array)

        outputs_errors = Matrix.subtract_matrix(targets, outputs)

        gradients = Matrix.map_matrix(outputs, self.dsigmoid)
        gradients = Matrix.multiply_matrix(gradients, outputs_errors)
        gradients.multiply(self.lr)

        self.bias_o = Matrix.add_matrix(self.bias_o, gradients)

        hidden_t = Matrix.transpose_matrix(hidden)
        weight_ho_deltas = Matrix.multiply_matrix(gradients, hidden_t)

        self.weights_ho = Matrix.add_matrix(self.weights_ho, weight_ho_deltas)

        weights_t = Matrix.transpose_matrix(self.weights_ho)
        hidden_errors = Matrix.multiply_matrix(weights_t, outputs_errors)

        hidden_gradient = Matrix.map_matrix(hidden, self.dsigmoid)
        hidden_gradient = Matrix.multiply_matrix(hidden_gradient,
                                                 hidden_errors)
        hidden_gradient.multiply(self.lr)

        self.bias_h = Matrix.add_matrix(self.bias_h, hidden_gradient)

        inputs_t = Matrix.transpose_matrix(inputs)
        weight_ih_deltas = Matrix.multiply_matrix(hidden_gradient, inputs_t)

        self.weights_ih = Matrix.add_matrix(self.weights_ih, weight_ih_deltas)
 def test_add_matrix(self):
     first_matrix = Matrix([[1, 2], [3, 4]])
     second_matrix = Matrix([[5, 6], [7, 8]])
     self.assertEqual(first_matrix.add_matrix(second_matrix),
                      [[6, 8], [10, 12]])
 def test_add_matrix(self):
     a = Matrix([[1, 2], [3, 4]])
     b = Matrix([[5, 6], [7, 8]])
     self.assertEqual(a.add_matrix(b), [[6, 8], [10, 12]])