code: 
  
  
  
  
  
  import numpy as np
  from matplotlib import pyplot as plt
  
  def     a						(      _lowercase   :     Dict       )     ->List[str]:
    return 1 / (1 + np.exp(-1 * x       ))
  
  
  
  
  class   _UpperCAmelCase	:
  
  
  
  
       def __init__(						self    ,      __lowerCAmelCase    ,      __lowerCAmelCase=None    ,      __lowerCAmelCase=None    ,      __lowerCAmelCase=False       )						->  List[str]:
         UpperCamelCase__         =	units
         UpperCamelCase__         =	None
         UpperCamelCase__         =	None
         UpperCamelCase__         =	activation
         if learning_rate is None:
           UpperCamelCase__         =	0.3
         UpperCamelCase__         =	learning_rate
         UpperCamelCase__         =	is_input_layer
  
  
  
  
       def 	snake_case_		(						self    ,      __lowerCAmelCase       )						->  Union[str, Any]:
         UpperCamelCase__         =	np.asmatrix(np.random.normal(0    ,      0.5    ,      (self.units, back_units)       )       )
         UpperCamelCase__         =	np.asmatrix(np.random.normal(0    ,      0.5    ,      self.units       )       ).T
         if self.activation is None:
           UpperCamelCase__         =	sigmoid
  
  
  
  
       def 	snake_case_		(						self       )						->  Any:
         # activation function may be sigmoid or linear
         if self.activation == sigmoid:
           UpperCamelCase__         =	np.dot(self.output    ,      (1 - self.output).T       )
           UpperCamelCase__         =	np.diag(np.diag(SCREAMING_SNAKE_CASE_       )       )
         else:
           UpperCamelCase__         =	1
         return gradient_activation
  
  
  
  
       def 	snake_case_		(						self    ,      __lowerCAmelCase       )						->  Optional[Any]:
         UpperCamelCase__         =	xdata
         if self.is_input_layer:
           # input layer
           UpperCamelCase__         =	xdata
           UpperCamelCase__         =	xdata
           return xdata
         else:
           UpperCamelCase__         =	np.dot(self.weight    ,      self.xdata       ) - self.bias
           UpperCamelCase__         =	self.activation(self.wx_plus_b       )
           return self.output
  
  
  
  
       def 	snake_case_		(						self    ,      __lowerCAmelCase       )						->  Dict:
         UpperCamelCase__         =	self.cal_gradient()  # i * i 维
         UpperCamelCase__         =	np.asmatrix(np.dot(gradient.T    ,      SCREAMING_SNAKE_CASE_       )       )
  
         UpperCamelCase__         =	np.asmatrix(self.xdata       )
         UpperCamelCase__         =	-1
         UpperCamelCase__         =	self.weight
  
         UpperCamelCase__         =	np.dot(gradient.T    ,      self._gradient_weight.T       )
         UpperCamelCase__         =	gradient * self._gradient_bias
         UpperCamelCase__         =	np.dot(SCREAMING_SNAKE_CASE_    ,      self._gradient_x       ).T
         # upgrade: the Negative gradient direction
         UpperCamelCase__         =	self.weight - self.learn_rate * self.gradient_weight
         UpperCamelCase__         =	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   _UpperCAmelCase	:
  
  
  
  
       def __init__(						self       )						->  List[Any]:
         UpperCamelCase__         =	[]
         UpperCamelCase__         =	[]
         UpperCamelCase__         =	plt.figure()
         UpperCamelCase__         =	self.fig_loss.add_subplot(1    ,      1    ,      1       )
  
  
  
  
       def 	snake_case_		(						self    ,      __lowerCAmelCase       )						->  Dict:
         self.layers.append(SCREAMING_SNAKE_CASE_       )
  
  
  
  
       def 	snake_case_		(						self       )						->  Union[str, Any]:
         for i, layer in enumerate(self.layers[:]       ):
           if i < 1:
             UpperCamelCase__         =	True
           else:
             layer.initializer(self.layers[i - 1].units       )
  
  
  
  
       def 	snake_case_		(						self       )						->  List[str]:
         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 	snake_case_		(						self    ,      __lowerCAmelCase    ,      __lowerCAmelCase    ,      __lowerCAmelCase    ,      __lowerCAmelCase       )						->  Union[str, Any]:
         UpperCamelCase__         =	train_round
         UpperCamelCase__         =	accuracy
  
         self.ax_loss.hlines(self.accuracy    ,      0    ,      self.train_round * 1.1       )
  
         UpperCamelCase__         =	np.shape(SCREAMING_SNAKE_CASE_       )
         for _ in range(SCREAMING_SNAKE_CASE_       ):
           UpperCamelCase__         =	0
           for row in range(x_shape[0]       ):
             UpperCamelCase__         =	np.asmatrix(xdata[row, :]       ).T
             UpperCamelCase__         =	np.asmatrix(ydata[row, :]       ).T
  
             # forward propagation
             for layer in self.layers:
               UpperCamelCase__         =	layer.forward_propagation(_xdata       )
  
             UpperCamelCase__  ,			UpperCamelCase__         =	self.cal_loss(_ydata    ,      _xdata       )
             UpperCamelCase__         =	all_loss + loss
  
             # back propagation: the input_layer does not upgrade
             for layer in self.layers[:0:-1]:
               UpperCamelCase__         =	layer.back_propagation(SCREAMING_SNAKE_CASE_       )
  
           UpperCamelCase__         =	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 	snake_case_		(						self    ,      __lowerCAmelCase    ,      __lowerCAmelCase       )						->  Optional[Any]:
         UpperCamelCase__         =	np.sum(np.power((ydata - ydata_)    ,      2       )       )
         UpperCamelCase__         =	2 * (ydata_ - ydata)
         # vector (shape is the same as _ydata.shape)
         return self.loss, self.loss_gradient
  
  
  
  
       def 	snake_case_		(						self       )						->  List[Any]:
         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     a						(      )     ->List[str]:
    UpperCamelCase__         =	np.random.randn(1_0 ,						1_0       )
    UpperCamelCase__         =	np.asarray(
        [
            [0.8, 0.4],
            [0.4, 0.3],
            [0.34, 0.45],
            [0.67, 0.32],
            [0.88, 0.67],
            [0.78, 0.77],
            [0.55, 0.66],
            [0.55, 0.43],
            [0.54, 0.1],
            [0.1, 0.5],
        ]       )
    UpperCamelCase__         =	BPNN()
    for i in (1_0, 2_0, 3_0, 2):
      model.add_layer(DenseLayer(_UpperCAmelCase       )       )
    model.build()
    model.summary()
    model.train(xdata=_UpperCAmelCase ,						ydata=_UpperCAmelCase ,						train_round=1_0_0 ,						accuracy=0.01       )
  
  
  if __name__ == "__main__":
      example()
  
  
  
  
  
  
style_context: 
  
  
  
  
  
  __lowerCAmelCase     =			{
      "0": 1,
      "1": 1,
      "2": 2,
      "3": 6,
      "4": 24,
      "5": 120,
      "6": 720,
      "7": 5_040,
      "8": 40_320,
      "9": 362_880,
  }
  
  __lowerCAmelCase     =			{145: 145}
  
  __lowerCAmelCase     =			{
      145: 0,
      169: 3,
      36_301: 3,
      1_454: 3,
      871: 2,
      45_361: 2,
      872: 2,
  }
  
  def     a						(      _lowercase   :     int       )     ->int:
  		if n in CACHE_SUM_DIGIT_FACTORIALS:
  				return CACHE_SUM_DIGIT_FACTORIALS[n]
  		UpperCamelCase__         =	sum(DIGIT_FACTORIALS[let] for let in str(_lowercase       )       )
  		UpperCamelCase__         =	ret
  		return ret
  
  def     a						(      _lowercase   :     int ,						_lowercase   :     set | None = None       )     ->int:
  		UpperCamelCase__         =	previous or set()
  		if n in CHAIN_LENGTH_CACHE:
  				return CHAIN_LENGTH_CACHE[n]
  		UpperCamelCase__         =	sum_digit_factorials(_lowercase       )
  		if next_number in previous:
  				UpperCamelCase__         =	0
  				return 0
  		else:
  				previous.add(_lowercase       )
  				UpperCamelCase__         =	1 + chain_length(_lowercase ,						_lowercase       )
  				UpperCamelCase__         =	ret
  				return ret
  
  def     a						(      _lowercase   :     int = 6_0 ,						_lowercase   :     int = 1_0_0_0_0_0_0       )     ->int:
  		return sum(1 for i in range(1 ,						_lowercase       ) if chain_length(_lowercase       ) == num_terms       )
  
  
  if __name__ == "__main__":
  				print(f"""{solution() = }""")
  
  
  
  
  
  