



import numpy



class     _UpperCAmelCase			:




     def __init__(				self ,						a__ ,						a__):
         A__		 =					input_array

         # Random initial weights are assigned where first argument is the
         # number of nodes in previous layer and second argument is the
         # number of nodes in the next layer.

         # Random initial weights are assigned.
         # self.input_array.shape[1] is used to represent number of nodes in input layer.
         # First hidden layer consists of 4 nodes.
         A__		 =					numpy.random.rand(
             self.input_array.shape[1] ,						4)

         # Random initial values for the first hidden layer.
         # First hidden layer has 4 nodes.
         # Second hidden layer has 3 nodes.
         A__		 =					numpy.random.rand(
             4 ,						3)

         # Random initial values for the second hidden layer.
         # Second hidden layer has 3 nodes.
         # Output layer has 1 node.
         A__		 =					numpy.random.rand(3 ,						1)

         # Real output values provided.
         A__		 =					output_array

         # Predicted output values by the neural network.
         # Predicted_output array initially consists of zeroes.
         A__		 =					numpy.zeros(output_array.shape)




     def 		snake_case_		(				self):
         A__		 =					sigmoid(
             numpy.dot(self.input_array ,						self.input_layer_and_first_hidden_layer_weights))

         # layer_between_first_hidden_layer_and_second_hidden_layer is the layer
         # connecting the first hidden set of nodes with the second hidden set of nodes.
         A__		 =					sigmoid(
             numpy.dot(
                 self.layer_between_input_and_first_hidden_layer ,						self.first_hidden_layer_and_second_hidden_layer_weights ,						))

         # layer_between_second_hidden_layer_and_output is the layer connecting
         # second hidden layer with the output node.
         A__		 =					sigmoid(
             numpy.dot(
                 self.layer_between_first_hidden_layer_and_second_hidden_layer ,						self.second_hidden_layer_and_output_layer_weights ,						))

         return self.layer_between_second_hidden_layer_and_output




     def 		snake_case_		(				self):
         A__		 =					numpy.dot(
             self.layer_between_first_hidden_layer_and_second_hidden_layer.T ,						2
             * (self.output_array - self.predicted_output)
             * sigmoid_derivative(self.predicted_output) ,						)
         A__		 =					numpy.dot(
             self.layer_between_input_and_first_hidden_layer.T ,						numpy.dot(
                 2
                 * (self.output_array - self.predicted_output)
                 * sigmoid_derivative(self.predicted_output) ,						self.second_hidden_layer_and_output_layer_weights.T ,						)
             * sigmoid_derivative(
                 self.layer_between_first_hidden_layer_and_second_hidden_layer) ,						)
         A__		 =					numpy.dot(
             self.input_array.T ,						numpy.dot(
                 numpy.dot(
                     2
                     * (self.output_array - self.predicted_output)
                     * sigmoid_derivative(self.predicted_output) ,						self.second_hidden_layer_and_output_layer_weights.T ,						)
                 * sigmoid_derivative(
                     self.layer_between_first_hidden_layer_and_second_hidden_layer) ,						self.first_hidden_layer_and_second_hidden_layer_weights.T ,						)
             * sigmoid_derivative(self.layer_between_input_and_first_hidden_layer) ,						)

         self.input_layer_and_first_hidden_layer_weights += (
             updated_input_layer_and_first_hidden_layer_weights
         )
         self.first_hidden_layer_and_second_hidden_layer_weights += (
             updated_first_hidden_layer_and_second_hidden_layer_weights
         )
         self.second_hidden_layer_and_output_layer_weights += (
             updated_second_hidden_layer_and_output_layer_weights
         )




     def 		snake_case_		(				self ,						a__ ,						a__ ,						a__):
         for iteration in range(1 ,						iterations + 1):
             A__		 =					self.feedforward()
             self.back_propagation()
             if give_loss:
                 A__		 =					numpy.mean(numpy.square(output - self.feedforward()))
                 print(F"Iteration {iteration} Loss: {loss}")




     def 		snake_case_		(				self ,						a__):
         A__		 =					input_arr

         A__		 =					sigmoid(
             numpy.dot(self.array ,						self.input_layer_and_first_hidden_layer_weights))

         A__		 =					sigmoid(
             numpy.dot(
                 self.layer_between_input_and_first_hidden_layer ,						self.first_hidden_layer_and_second_hidden_layer_weights ,						))

         A__		 =					sigmoid(
             numpy.dot(
                 self.layer_between_first_hidden_layer_and_second_hidden_layer ,						self.second_hidden_layer_and_output_layer_weights ,						))

         return int(self.layer_between_second_hidden_layer_and_output > 0.6)







def 		lowerCAmelCase__    (					UpperCamelCase_				:       numpy.ndarray	)->  numpy.ndarray:
    return 1 / (1 + numpy.exp(-value	))



def 		lowerCAmelCase__    (					UpperCamelCase_				:       numpy.ndarray	)->  numpy.ndarray:
    return (value) * (1 - (value))



def 		lowerCAmelCase__    (					)->  int:
    A__		 =					numpy.array(
        (
            [0, 0, 0],
            [0, 0, 1],
            [0, 1, 0],
            [0, 1, 1],
            [1, 0, 0],
            [1, 0, 1],
            [1, 1, 0],
            [1, 1, 1],
        ) ,       dtype=numpy.floataa ,       )

    # True output values for the given input values.
    A__		 =					numpy.array(([0], [1], [1], [0], [1], [0], [0], [1]) ,       dtype=numpy.floataa	)

    # Calling neural network class.
    A__		 =					TwoHiddenLayerNeuralNetwork(
        input_array=UpperCamelCase_ ,       output_array=UpperCamelCase_	)

    # Calling training function.
    # Set give_loss to True if you want to see loss in every iteration.
    neural_network.train(output=UpperCamelCase_ ,       iterations=1_0 ,       give_loss=UpperCamelCase_	)

    return neural_network.predict(numpy.array(([1, 1, 1]) ,       dtype=numpy.floataa	)	)


if __name__ == "__main__":
   example()





def 		lowerCAmelCase__    (					UpperCamelCase_				:       float ,       UpperCamelCase_				:       int	)->  float:
    if digit_amount > 0:
        return round(number - int(UpperCamelCase_	) ,       UpperCamelCase_	)
    return number - int(UpperCamelCase_	)


if __name__ == "__main__":
   print(decimal_isolate(1.53, 0))
   print(decimal_isolate(35.345, 1))
   print(decimal_isolate(35.345, 2))
   print(decimal_isolate(35.345, 3))
   print(decimal_isolate(-14.789, 3))
   print(decimal_isolate(0, 2))
   print(decimal_isolate(-14.123, 1))
   print(decimal_isolate(-14.123, 2))
   print(decimal_isolate(-14.123, 3))
