import numpy as np
from matplotlib import pyplot as plt






def    UpperCAmelCase__(						lowerCamelCase_  ):



   """simple docstring"""





   return 1 / (1 + np.exp(-1 * x  ))

class 	_SCREAMING_SNAKE_CASE							:






  """simple docstring"""







  def __init__(			self    :				List[Any]  ,					__SCREAMING_SNAKE_CASE    :				Union[str, Any]  ,					__SCREAMING_SNAKE_CASE    :				int=None  ,					__SCREAMING_SNAKE_CASE    :				Tuple=None  ,					__SCREAMING_SNAKE_CASE    :				Dict=False   ):






     """simple docstring"""
     _snake_case              =      units
     _snake_case              =      None
     _snake_case              =      None
     _snake_case              =      activation
     if learning_rate is None:
        _snake_case              =      0.3
     _snake_case              =      learning_rate
     _snake_case              =      is_input_layer



  def 				_a				(			self    :				str  ,					__SCREAMING_SNAKE_CASE    :				List[str]   ):






     """simple docstring"""
     _snake_case              =      np.asmatrix(np.random.normal(0  ,					0.5  ,					(self.units, back_units)   )   )
     _snake_case              =      np.asmatrix(np.random.normal(0  ,					0.5  ,					self.units   )   ).T
     if self.activation is None:
        _snake_case              =      sigmoid



  def 				_a				(			self    :				Optional[Any]   ):






     """simple docstring"""
     # activation function may be sigmoid or linear
     if self.activation == sigmoid:
        _snake_case              =      np.dot(self.output  ,					(1 - self.output).T   )
        _snake_case              =      np.diag(np.diag(__SCREAMING_SNAKE_CASE   )   )
     else:
        _snake_case              =      1
     return gradient_activation



  def 				_a				(			self    :				Any  ,					__SCREAMING_SNAKE_CASE    :				int   ):






     """simple docstring"""
     _snake_case              =      xdata
     if self.is_input_layer:
        # input layer
        _snake_case              =      xdata
        _snake_case              =      xdata
        return xdata
     else:
        _snake_case              =      np.dot(self.weight  ,					self.xdata   ) - self.bias
        _snake_case              =      self.activation(self.wx_plus_b   )
        return self.output







  def 				_a				(			self    :				Any  ,					__SCREAMING_SNAKE_CASE    :				Optional[Any]   ):






     """simple docstring"""
     _snake_case              =      self.cal_gradient()  # i * i 维
     _snake_case              =      np.asmatrix(np.dot(gradient.T  ,					__SCREAMING_SNAKE_CASE   )   )

     _snake_case              =      np.asmatrix(self.xdata   )
     _snake_case              =      -1
     _snake_case              =      self.weight

     _snake_case              =      np.dot(gradient.T  ,					self._gradient_weight.T   )
     _snake_case              =      gradient * self._gradient_bias
     _snake_case              =      np.dot(__SCREAMING_SNAKE_CASE  ,					self._gradient_x   ).T
     # upgrade: the Negative gradient direction
     _snake_case              =      self.weight - self.learn_rate * self.gradient_weight
     _snake_case              =      self.bias - self.learn_rate * self.gradient_bias.T
     # updates the weights and bias according to learning rate (0.3 if undefined)
     return self.gradient

class 	_SCREAMING_SNAKE_CASE							:






  """simple docstring"""







  def __init__(			self    :				Union[str, Any]   ):






     """simple docstring"""
     _snake_case              =      []
     _snake_case              =      []
     _snake_case              =      plt.figure()
     _snake_case              =      self.fig_loss.add_subplot(1  ,					1  ,					1   )



  def 				_a				(			self    :				Dict  ,					__SCREAMING_SNAKE_CASE    :				Dict   ):






     """simple docstring"""
     self.layers.append(__SCREAMING_SNAKE_CASE   )



  def 				_a				(			self    :				List[Any]   ):






     """simple docstring"""
     for i, layer in enumerate(self.layers[:]   ):
        if i < 1:
           _snake_case              =      True
        else:
           layer.initializer(self.layers[i - 1].units   )



  def 				_a				(			self    :				int   ):






     """simple docstring"""
     for i, layer in enumerate(self.layers[:]   ):
        print(F'------- layer {i} -------'   )
        print("weight.shape "  ,					np.shape(layer.weight   )   )
        print("bias.shape "  ,					np.shape(layer.bias   )   )



  def 				_a				(			self    :				Union[str, Any]  ,					__SCREAMING_SNAKE_CASE    :				str  ,					__SCREAMING_SNAKE_CASE    :				Optional[int]  ,					__SCREAMING_SNAKE_CASE    :				Dict  ,					__SCREAMING_SNAKE_CASE    :				Optional[int]   ):






     """simple docstring"""
     _snake_case              =      train_round
     _snake_case              =      accuracy

     self.ax_loss.hlines(self.accuracy  ,					0  ,					self.train_round * 1.1   )

     _snake_case              =      np.shape(__SCREAMING_SNAKE_CASE   )
     for _ in range(__SCREAMING_SNAKE_CASE   ):
        _snake_case              =      0
        for row in range(x_shape[0]   ):
           _snake_case              =      np.asmatrix(xdata[row, :]   ).T
           _snake_case              =      np.asmatrix(ydata[row, :]   ).T

           # forward propagation
           for layer in self.layers:
              _snake_case              =      layer.forward_propagation(_xdata   )

           _snake_case       , _snake_case              =      self.cal_loss(_ydata  ,					_xdata   )
           _snake_case              =      all_loss + loss

           # back propagation: the input_layer does not upgrade
           for layer in self.layers[:0:-1]:
              _snake_case              =      layer.back_propagation(__SCREAMING_SNAKE_CASE   )

        _snake_case              =      all_loss / x_shape[0]
        self.train_mse.append(__SCREAMING_SNAKE_CASE   )

        self.plot_loss()

        if mse < self.accuracy:
           print("----达到精度----"   )
           return mse
     return None



  def 				_a				(			self    :				int  ,					__SCREAMING_SNAKE_CASE    :				List[Any]  ,					__SCREAMING_SNAKE_CASE    :				str   ):






     """simple docstring"""
     _snake_case              =      np.sum(np.power((ydata - ydata_)  ,					2   )   )
     _snake_case              =      2 * (ydata_ - ydata)
     # vector (shape is the same as _ydata.shape)
     return self.loss, self.loss_gradient







  def 				_a				(			self    :				Dict   ):






     """simple docstring"""
     if self.ax_loss.lines:
        self.ax_loss.lines.remove(self.ax_loss.lines[0]   )
     self.ax_loss.plot(self.train_mse  ,					"r-"   )
     plt.ion()
     plt.xlabel("step"   )
     plt.ylabel("loss"   )
     plt.show()
     plt.pause(0.1   )






def    UpperCAmelCase__(						):



   """simple docstring"""





   _snake_case              =      np.random.randn(10							,	10  )
   _snake_case              =      np.asarray(
       [
           [0.8, 0.4],
           [0.4, 0.3],
           [0.3_4, 0.4_5],
           [0.6_7, 0.3_2],
           [0.8_8, 0.6_7],
           [0.7_8, 0.7_7],
           [0.5_5, 0.6_6],
           [0.5_5, 0.4_3],
           [0.5_4, 0.1],
           [0.1, 0.5],
       ]  )
   _snake_case              =      BPNN()
   for i in (10, 20, 30, 2):
      model.add_layer(DenseLayer(lowerCamelCase_  )  )
   model.build()
   model.summary()
   model.train(xdata=lowerCamelCase_							,	ydata=lowerCamelCase_							,	train_round=100							,	accuracy=0.0_1  )


if __name__ == "__main__":
   example()


from math import gcd






def    UpperCAmelCase__(						lowerCamelCase_ = 12000  ):



			"""simple docstring"""





			_snake_case              =      0
			for d in range(max_d + 1  ):
						for n in range(d // 3 + 1							,	(d + 1) // 2  ):
									if gcd(lowerCamelCase_							,	lowerCamelCase_  ) == 1:
												fractions_number += 1
			return fractions_number


if __name__ == "__main__":
			print(F"{solution() = }")

