



'''simple docstring'''

import pickle

import numpy as np
from matplotlib import pyplot as plt

class      __magic_name__						:







							def __init__(							self :	List[Any]     ,_UpperCAmelCase :	Dict     ,_UpperCAmelCase :	Tuple     ,_UpperCAmelCase :	str     ,_UpperCAmelCase :	Optional[Any]     ,_UpperCAmelCase :	Optional[Any]     ,_UpperCAmelCase :	int=0.2     ,_UpperCAmelCase :	int=0.2		):
									_a					:				List[Any]				=							bp_numa
									_a					:				str				=							bp_numa
									_a					:				int				=							bp_numa
									_a					:				int				=							conva_get[:2]
									_a					:				Tuple				=							conva_get[2]
									_a					:				Optional[int]				=							size_pa
									_a					:				List[Any]				=							rate_w
									_a					:				Tuple				=							rate_t
									_a					:				Tuple				=							[
									    np.mat(-1 * np.random.rand(self.conva[0]     ,self.conva[0]		) + 0.5		)
									    for i in range(self.conva[1]		)
									]
									_a					:				int				=							np.mat(-1 * np.random.rand(self.num_bpa     ,self.num_bpa		) + 0.5		)
									_a					:				int				=							np.mat(-1 * np.random.rand(self.num_bpa     ,self.num_bpa		) + 0.5		)
									_a					:				List[Any]				=							-2 * np.random.rand(self.conva[1]		) + 1
									_a					:				Dict				=							-2 * np.random.rand(self.num_bpa		) + 1
									_a					:				str				=							-2 * np.random.rand(self.num_bpa		) + 1







							def 							__lowercase      (							self :	str     ,_UpperCAmelCase :	str		):
									# save model dict with pickle
									_a					:				int				=							{
									    'num_bp1': self.num_bpa,
									    'num_bp2': self.num_bpa,
									    'num_bp3': self.num_bpa,
									    'conv1': self.conva,
									    'step_conv1': self.step_conva,
									    'size_pooling1': self.size_poolinga,
									    'rate_weight': self.rate_weight,
									    'rate_thre': self.rate_thre,
									    'w_conv1': self.w_conva,
									    'wkj': self.wkj,
									    'vji': self.vji,
									    'thre_conv1': self.thre_conva,
									    'thre_bp2': self.thre_bpa,
									    'thre_bp3': self.thre_bpa,
									}
									with open(_UpperCAmelCase     ,'wb'		) as f:
											pickle.dump(_UpperCAmelCase     ,_UpperCAmelCase		)

									print(F"""Model saved： {save_path}"""		)







							@classmethod
							def 							__lowercase      (							cls :	Optional[Any]     ,_UpperCAmelCase :	Any		):
									# read saved model
									with open(_UpperCAmelCase     ,'rb'		) as f:
											_a					:				str				=							pickle.load(_UpperCAmelCase		)  # noqa: S301

									_a					:				Tuple				=							model_dic.get('conv1'		)
									conv_get.append(model_dic.get('step_conv1'		)		)
									_a					:				str				=							model_dic.get('size_pooling1'		)
									_a					:				Union[str, Any]				=							model_dic.get('num_bp1'		)
									_a					:				List[Any]				=							model_dic.get('num_bp2'		)
									_a					:				Union[str, Any]				=							model_dic.get('num_bp3'		)
									_a					:				int				=							model_dic.get('rate_weight'		)
									_a					:				List[Any]				=							model_dic.get('rate_thre'		)
									# create model instance
									_a					:				Dict				=							CNN(_UpperCAmelCase     ,_UpperCAmelCase     ,_UpperCAmelCase     ,_UpperCAmelCase     ,_UpperCAmelCase     ,_UpperCAmelCase     ,_UpperCAmelCase		)
									# modify model parameter
									_a					:				Optional[int]				=							model_dic.get('w_conv1'		)
									_a					:				Union[str, Any]				=							model_dic.get('wkj'		)
									_a					:				List[Any]				=							model_dic.get('vji'		)
									_a					:				List[str]				=							model_dic.get('thre_conv1'		)
									_a					:				Dict				=							model_dic.get('thre_bp2'		)
									_a					:				int				=							model_dic.get('thre_bp3'		)
									return conv_ins







							def 							__lowercase      (							self :	List[Any]     ,_UpperCAmelCase :	str		):
									return 1 / (1 + np.exp(-1 * x		))







							def 							__lowercase      (							self :	Optional[Any]     ,_UpperCAmelCase :	Any		):
									return round(_UpperCAmelCase     ,3		)







							def 							__lowercase      (							self :	Optional[Any]     ,_UpperCAmelCase :	List[str]     ,_UpperCAmelCase :	str     ,_UpperCAmelCase :	Dict     ,_UpperCAmelCase :	Any     ,_UpperCAmelCase :	Tuple		):
									# convolution process
									_a					:				Any				=							convs[0]
									_a					:				Tuple				=							convs[1]
									_a					:				Dict				=							np.shape(_UpperCAmelCase		)[0]
									# get the data slice of original image data, data_focus
									_a					:				List[str]				=							[]
									for i_focus in range(0     ,size_data - size_conv + 1     ,_UpperCAmelCase		):
											for j_focus in range(0     ,size_data - size_conv + 1     ,_UpperCAmelCase		):
													_a					:				str				=							data[
													    i_focus : i_focus + size_conv, j_focus : j_focus + size_conv
													]
													data_focus.append(_UpperCAmelCase		)
        # calculate the feature map of every single kernel, and saved as list of matrix
									_a					:				int				=							[]
									_a					:				Any				=							int((size_data - size_conv) / conv_step + 1		)
									for i_map in range(_UpperCAmelCase		):
											_a					:				Union[str, Any]				=							[]
											for i_focus in range(len(_UpperCAmelCase		)		):
													_a					:				Union[str, Any]				=							(
													    np.sum(np.multiply(data_focus[i_focus]     ,w_convs[i_map]		)		)
													    - thre_convs[i_map]
													)
													featuremap.append(self.sig(_UpperCAmelCase		)		)
											_a					:				int				=							np.asmatrix(_UpperCAmelCase		).reshape(
											    _UpperCAmelCase     ,_UpperCAmelCase		)
											data_featuremap.append(_UpperCAmelCase		)

									# expanding the data slice to One dimenssion
									_a					:				Tuple				=							[]
									for each_focus in data_focus:
											focusa_list.extend(self.Expand_Mat(_UpperCAmelCase		)		)
									_a					:				Tuple				=							np.asarray(_UpperCAmelCase		)
									return focus_list, data_featuremap







							def 							__lowercase      (							self :	List[Any]     ,_UpperCAmelCase :	Dict     ,_UpperCAmelCase :	Union[str, Any]     ,_UpperCAmelCase :	Dict="average_pool"		):
									# pooling process
									_a					:				int				=							len(featuremaps[0]		)
									_a					:				Tuple				=							int(size_map / size_pooling		)
									_a					:				int				=							[]
									for i_map in range(len(_UpperCAmelCase		)		):
											_a					:				Union[str, Any]				=							featuremaps[i_map]
											_a					:				int				=							[]
											for i_focus in range(0     ,_UpperCAmelCase     ,_UpperCAmelCase		):
													for j_focus in range(0     ,_UpperCAmelCase     ,_UpperCAmelCase		):
															_a					:				List[str]				=							feature_map[
															    i_focus : i_focus + size_pooling,
															    j_focus : j_focus + size_pooling,
															]
															if pooling_type == "average_pool":
																	# average pooling
																	map_pooled.append(np.average(_UpperCAmelCase		)		)
															elif pooling_type == "max_pooling":
																	# max pooling
																	map_pooled.append(np.max(_UpperCAmelCase		)		)
											_a					:				Any				=							np.asmatrix(_UpperCAmelCase		).reshape(_UpperCAmelCase     ,_UpperCAmelCase		)
											featuremap_pooled.append(_UpperCAmelCase		)
									return featuremap_pooled







							def 							__lowercase      (							self :	Dict     ,_UpperCAmelCase :	Any		):
									# expanding three dimension data to one dimension list
									_a					:				Optional[int]				=							[]
									for i in range(len(_UpperCAmelCase		)		):
											_a					:				List[str]				=							np.shape(data[i]		)
											_a					:				List[Any]				=							data[i].reshape(1     ,shapes[0] * shapes[1]		)
											_a					:				List[str]				=							data_listed.getA().tolist()[0]
											data_expanded.extend(_UpperCAmelCase		)
									_a					:				List[str]				=							np.asarray(_UpperCAmelCase		)
									return data_expanded







							def 							__lowercase      (							self :	List[Any]     ,_UpperCAmelCase :	Optional[int]		):
									# expanding matrix to one dimension list
									_a					:				List[str]				=							np.asarray(_UpperCAmelCase		)
									_a					:				str				=							np.shape(_UpperCAmelCase		)
									_a					:				List[str]				=							data_mat.reshape(1     ,shapes[0] * shapes[1]		)
									return data_expanded







							def 							__lowercase      (							self :	Dict     ,_UpperCAmelCase :	List[str]     ,_UpperCAmelCase :	Optional[int]     ,_UpperCAmelCase :	Optional[int]     ,_UpperCAmelCase :	str     ,_UpperCAmelCase :	Tuple		):
									_a					:				List[str]				=							[]
									_a					:				Any				=							0
									for i_map in range(_UpperCAmelCase		):
											_a					:				Union[str, Any]				=							np.ones((size_map, size_map)		)
											for i in range(0     ,_UpperCAmelCase     ,_UpperCAmelCase		):
													for j in range(0     ,_UpperCAmelCase     ,_UpperCAmelCase		):
															_a					:				Tuple				=							pd_pool[
															    i_pool
															]
															_a					:				Dict				=							i_pool + 1
											_a					:				Any				=							np.multiply(
											    _UpperCAmelCase     ,np.multiply(out_map[i_map]     ,(1 - out_map[i_map])		)		)
											pd_all.append(_UpperCAmelCase		)
									return pd_all







							def 							__lowercase      (							self :	Union[str, Any]     ,_UpperCAmelCase :	Tuple     ,_UpperCAmelCase :	int     ,_UpperCAmelCase :	List[Any]     ,_UpperCAmelCase :	Tuple     ,_UpperCAmelCase :	List[str]     ,_UpperCAmelCase :	str=bool		):
									# model traning
									print('----------------------Start Training-------------------------'		)
									print((' - - Shape: Train_Data  ', np.shape(_UpperCAmelCase		))		)
									print((' - - Shape: Teach_Data  ', np.shape(_UpperCAmelCase		))		)
									_a					:				int				=							0
									_a					:				List[Any]				=							[]
									_a					:				Tuple				=							10000
									while rp < n_repeat and mse >= error_accuracy:
											_a					:				Dict				=							0
											print(F"""-------------Learning Time {rp}--------------"""		)
											for p in range(len(_UpperCAmelCase		)		):
													# print('------------Learning Image: %d--------------'%p)
													_a					:				Union[str, Any]				=							np.asmatrix(datas_train[p]		)
													_a					:				List[str]				=							np.asarray(datas_teach[p]		)
													_a	, _a					:				str				=							self.convolute(
													    _UpperCAmelCase     ,self.conva     ,self.w_conva     ,self.thre_conva     ,conv_step=self.step_conva     ,)
													_a					:				int				=							self.pooling(_UpperCAmelCase     ,self.size_poolinga		)
													_a					:				str				=							np.shape(_UpperCAmelCase		)
													_a					:				Optional[Any]				=							self._expand(_UpperCAmelCase		)
													_a					:				List[str]				=							data_bp_input

													_a					:				Optional[Any]				=							np.dot(_UpperCAmelCase     ,self.vji.T		) - self.thre_bpa
													_a					:				Union[str, Any]				=							self.sig(_UpperCAmelCase		)
													_a					:				Optional[int]				=							np.dot(_UpperCAmelCase     ,self.wkj.T		) - self.thre_bpa
													_a					:				Dict				=							self.sig(_UpperCAmelCase		)

													# --------------Model Leaning ------------------------
													# calculate error and gradient---------------
													_a					:				Union[str, Any]				=							np.multiply(
													    (data_teach - bp_outa)     ,np.multiply(_UpperCAmelCase     ,(1 - bp_outa)		)		)
													_a					:				Any				=							np.multiply(
													    np.dot(_UpperCAmelCase     ,self.wkj		)     ,np.multiply(_UpperCAmelCase     ,(1 - bp_outa)		)		)
													_a					:				Optional[int]				=							np.dot(_UpperCAmelCase     ,self.vji		)

													_a					:				str				=							pd_i_all / (self.size_poolinga * self.size_poolinga)
													_a					:				Dict				=							pd_conva_pooled.T.getA().tolist()
													_a					:				Dict				=							self._calculate_gradient_from_pool(
													    _UpperCAmelCase     ,_UpperCAmelCase     ,shape_featuremapa[0]     ,shape_featuremapa[1]     ,self.size_poolinga     ,)
													# weight and threshold learning process---------
													# convolution layer
													for k_conv in range(self.conva[1]		):
															_a					:				Optional[Any]				=							self._expand_mat(pd_conva_all[k_conv]		)
															_a					:				Optional[Any]				=							self.rate_weight * np.dot(_UpperCAmelCase     ,_UpperCAmelCase		)

															_a					:				Any				=							self.w_conva[k_conv] + delta_w.reshape(
															    (self.conva[0], self.conva[0])		)

															_a					:				List[str]				=							(
															    self.thre_conva[k_conv]
															    - np.sum(pd_conva_all[k_conv]		) * self.rate_thre
															)
													# all connected layer
													_a					:				Optional[int]				=							self.wkj + pd_k_all.T * bp_outa * self.rate_weight
													_a					:				Tuple				=							self.vji + pd_j_all.T * bp_outa * self.rate_weight
													_a					:				List[str]				=							self.thre_bpa - pd_k_all * self.rate_thre
													_a					:				str				=							self.thre_bpa - pd_j_all * self.rate_thre
													# calculate the sum error of all single image
													_a					:				Dict				=							np.sum(abs(data_teach - bp_outa		)		)
													error_count += errors
													# print('   ----Teach      ',data_teach)
													# print('   ----BP_output  ',bp_out3)
											_a					:				Any				=							rp + 1
											_a					:				Optional[Any]				=							error_count / patterns
											all_mse.append(_UpperCAmelCase		)

									def draw_error():
											_a					:				int				=							[error_accuracy for i in range(int(n_repeat * 1.2		)		)]
											plt.plot(_UpperCAmelCase     ,'+-'		)
											plt.plot(_UpperCAmelCase     ,'r--'		)
											plt.xlabel('Learning Times'		)
											plt.ylabel('All_mse'		)
											plt.grid(_UpperCAmelCase     ,alpha=0.5		)
											plt.show()

									print('------------------Training Complished---------------------'		)
									print((' - - Training epoch: ', rp, F"""     - - Mse: {mse:.6f}""")		)
									if draw_e:
											draw_error()
									return mse







							def 							__lowercase      (							self :	Dict     ,_UpperCAmelCase :	Dict		):
									# model predict
									_a					:				str				=							[]
									print('-------------------Start Testing-------------------------'		)
									print((' - - Shape: Test_Data  ', np.shape(_UpperCAmelCase		))		)
									for p in range(len(_UpperCAmelCase		)		):
											_a					:				List[Any]				=							np.asmatrix(datas_test[p]		)
											_a	, _a					:				Any				=							self.convolute(
											    _UpperCAmelCase     ,self.conva     ,self.w_conva     ,self.thre_conva     ,conv_step=self.step_conva     ,)
											_a					:				Optional[Any]				=							self.pooling(_UpperCAmelCase     ,self.size_poolinga		)
											_a					:				Union[str, Any]				=							self._expand(_UpperCAmelCase		)

											_a					:				str				=							data_bp_input
											_a					:				int				=							bp_outa * self.vji.T - self.thre_bpa
											_a					:				Any				=							self.sig(_UpperCAmelCase		)
											_a					:				List[str]				=							bp_outa * self.wkj.T - self.thre_bpa
											_a					:				Optional[Any]				=							self.sig(_UpperCAmelCase		)
											produce_out.extend(bp_outa.getA().tolist()		)
									_a					:				List[Any]				=							[list(map(self.do_round     ,_UpperCAmelCase		)		) for each in produce_out]
									return np.asarray(_UpperCAmelCase		)







							def 							__lowercase      (							self :	List[str]     ,_UpperCAmelCase :	Any		):
									# return the data of image after convoluting process so we can check it out
									_a					:				Dict				=							np.asmatrix(_UpperCAmelCase		)
									_a	, _a					:				List[str]				=							self.convolute(
									    _UpperCAmelCase     ,self.conva     ,self.w_conva     ,self.thre_conva     ,conv_step=self.step_conva     ,)
									_a					:				Dict				=							self.pooling(_UpperCAmelCase     ,self.size_poolinga		)

									return data_conveda, data_pooleda


if __name__ == "__main__":
							pass









'''simple docstring'''

# Function to print upper half of diamond (pyramid)



def 					__lowerCamelCase					(				lowerCAmelCase_  )      ->				int:
		for i in range(0						,      lowerCAmelCase_  ):
				for _ in range(0						,      n - i - 1  ):  # printing spaces
						print(' '						,      end=''  )
				for _ in range(0						,      i + 1  ):  # printing stars
						print('* '						,      end=''  )
				print()



def 					__lowerCamelCase					(				lowerCAmelCase_  )      ->				Union[str, Any]:
		for i in range(lowerCAmelCase_						,      0						,      -1  ):
				for _ in range(lowerCAmelCase_						,      0						,      -1  ):  # printing stars
						print('* '						,      end=''  )
				print()
				for _ in range(n - i + 1						,      0						,      -1  ):  # printing spaces
						print(' '						,      end=''  )



def 					__lowerCamelCase					(				lowerCAmelCase_  )      ->				Tuple:
		if n <= 0:
				print('       ...       ....        nothing printing :('  )
				return
		floyd(lowerCAmelCase_  )  # upper half
		reverse_floyd(lowerCAmelCase_  )  # lower half


if __name__ == "__main__":
							print(r'''| /\ | |- |  |-  |--| |\  /| |-''')
							print(r'''|/  \| |- |_ |_  |__| | \/ | |_''')
							__lowerCAmelCase						      =       1
							while K:
														__lowerCAmelCase						      =       int(input('''enter the number and , and see the magic : '''))
														print()
														pretty_print(user_number)
														__lowerCAmelCase						      =       int(input('''press 0 to exit... and 1 to continue...'''))

							print('''Good Bye...''')




