




'''simple docstring'''


import numpy
class   __A :



   """simple docstring"""







   def __init__(      self				, _lowerCamelCase				, _lowerCamelCase						)->       Tuple:
      lowercase__       							=							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.
      lowercase__       							=							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.
      lowercase__       							=							numpy.random.rand(
          4				, 3						)

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

      # Real output values provided.
      lowercase__       							=							output_array

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

   def snake_case_(      self						)->       List[Any]:
      lowercase__       							=							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.
      lowercase__       							=							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.
      lowercase__       							=							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						)->       Union[str, Any]:
      lowercase__       							=							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						)				, )
      lowercase__       							=							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						)				, )
      lowercase__       							=							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				, _lowerCamelCase				, _lowerCamelCase				, _lowerCamelCase						)->       Optional[Any]:




      for iteration in range(1				, iterations + 1						):
         lowercase__       							=							self.feedforward()
         self.back_propagation()
         if give_loss:
            lowercase__       							=							numpy.mean(numpy.square(output - self.feedforward()						)						)
            print(f'''Iteration {iteration} Loss: {loss}'''						)

   def snake_case_(      self				, _lowerCamelCase						)->       Dict:
      lowercase__       							=							input_arr

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

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

      lowercase__       							=							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							(   lowercase							: numpy.ndarray    )			->numpy.ndarray:
   """simple docstring"""




   return 1 / (1 + numpy.exp(-value    ))






def 		_lowerCAmelCase							(   lowercase							: numpy.ndarray    )			->numpy.ndarray:
   """simple docstring"""




   return (value) * (1 - (value))






def 		_lowerCAmelCase							(   )			->int:
   """simple docstring"""




   lowercase__       							=							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.
   lowercase__       							=							numpy.array(([0], [1], [1], [0], [1], [0], [0], [1])					,  dtype=numpy.floataa    )

   # Calling neural network class.
   lowercase__       							=							TwoHiddenLayerNeuralNetwork(
       input_array=snake_case_					,  output_array=snake_case_    )

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

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


if __name__ == "__main__":
  example()











"""simple docstring"""



from collections import namedtuple

a_					=     namedtuple("""from_to""", """from_ to""")

a_					=     {
    """cubicmeter""": from_to(1, 1),
    """litre""": from_to(0.001, 1000),
    """kilolitre""": from_to(1, 1),
    """gallon""": from_to(0.00454, 264.172),
    """cubicyard""": from_to(0.76455, 1.30795),
    """cubicfoot""": from_to(0.028, 35.3147),
    """cup""": from_to(0.000236588, 4226.75),
}







def 						__lowercase	(  snake_case_    :    float							,snake_case_    :    str							,snake_case_    :    str		)  ->float:



    '''simple docstring'''







    if from_type not in METRIC_CONVERSION:
        raise ValueError(
            F"""Invalid 'from_type' value: {from_type!r}  Supported values are:\n"""
            + ''', '''.join(snake_case_		)		)
    if to_type not in METRIC_CONVERSION:
        raise ValueError(
            F"""Invalid 'to_type' value: {to_type!r}.  Supported values are:\n"""
            + ''', '''.join(snake_case_		)		)
    return value * METRIC_CONVERSION[from_type].from_ * METRIC_CONVERSION[to_type].to


if __name__ == "__main__":
       import doctest

       doctest.testmod()




