mirosh111000

Numbers(pr7)

Oct 1st, 2024 (edited)
15
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.27 KB | None | 0 0
  1. import numpy as np
  2. import pandas as pd
  3. import tensorflow as tf
  4. import matplotlib.pyplot as plt
  5. from sklearn.metrics import log_loss, accuracy_score, classification_report, mean_squared_error
  6. from imblearn.over_sampling import SMOTE
  7. from mpl_toolkits.mplot3d import Axes3D
  8. from sklearn.preprocessing import StandardScaler
  9. from sklearn.decomposition import PCA
  10. import plotly.express as px
  11. import re
  12. from PIL import Image
  13. from scipy.ndimage import center_of_mass
  14. from scipy.ndimage import shift
  15. from matplotlib.colors import Normalize
  16. from matplotlib.cm import ScalarMappable
  17.  
  18. class Weights_pipeline:
  19.     def __init__(self, model):
  20.         self.model = model
  21.        
  22.     def save_to_file(self, fname):
  23.         try:
  24.             params = {}
  25.             for i, w in enumerate(self.model.weights):
  26.                 params[f'weight_{i}'] = w
  27.             for i, b in enumerate(self.model.biases):
  28.                 params[f'bias_{i}'] = b
  29.  
  30.             np.savez(fname, **params)
  31.             print(f"Weights and biases saved to {fname}")
  32.         except Exception as e:
  33.             print(f"Error saving weights: {e}")
  34.  
  35.     def load_from_file(self, fname):
  36.         try:
  37.  
  38.             loaded_params = np.load(fname)
  39.             weights = []
  40.             biases = []
  41.            
  42.             for key in loaded_params.files:
  43.                 if 'weight' in key:
  44.                     weights.append(loaded_params[key])
  45.                 elif 'bias' in key:
  46.                     biases.append(loaded_params[key])
  47.            
  48.             self.model.weights = weights
  49.             self.model.biases = biases
  50.             print(f"Weights and biases loaded from {fname}")
  51.             return self.model
  52.         except Exception as e:
  53.             print(f"Error loading weights: {e}")
  54.  
  55.  
  56. class MultiNeuralNetwork:
  57.     def __init__(self, type='reg', learning_rate=0.01, epochs=100000, hidden_layers=[10], C=1, early_stopping_rounds=np.inf):
  58.         self.type = type # 'reg', 'binary', 'multi'
  59.         self.learning_rate = learning_rate
  60.         self.epochs = epochs
  61.         self.hidden_layers = hidden_layers
  62.         self.C = C
  63.         self.early_stopping_rounds = early_stopping_rounds
  64.         self.weights = []
  65.         self.biases = []
  66.         self.loss_ = []
  67.         self.epochs_ = []
  68.  
  69.     def sigmoid(self, z):
  70.         return 1 / (1 + np.exp(-z))
  71.  
  72.     def sigmoid_derivative(self, z):
  73.         s = self.sigmoid(z)
  74.         return s * (1 - s)
  75.  
  76.     def linear(self, z, C=1):
  77.         return z * C
  78.  
  79.     def softmax(self, z):
  80.         exp_values = np.exp(z - np.max(z))
  81.         return exp_values / np.sum(exp_values, axis=0)
  82.  
  83.     def fit(self, x, y):
  84.         def initialize_parameters(input_size, output_size):
  85.             layers = [input_size] + self.hidden_layers + [output_size]
  86.             self.weights = [np.random.randn(layers[i], layers[i + 1]) * np.sqrt(1 / layers[i]) for i in range(len(layers) - 1)]
  87.             self.biases = [np.random.randn(layers[i + 1]) * 0.01 for i in range(len(layers) - 1)]
  88.  
  89.         best_err, count = np.inf, 0
  90.  
  91.         try:
  92.             input_size = x.shape[1]
  93.         except:
  94.             x = x.reshape(-1, 1)
  95.             input_size = x.shape[1]
  96.            
  97.         output_size = len(np.unique(y)) if self.type == 'multi' else 1
  98.         initialize_parameters(input_size=input_size, output_size=output_size)
  99.         for epoch in range(self.epochs):  
  100.             y_pred = []
  101.             for i, x_sample in enumerate(x):
  102.                 inputs, activations, outputs = [x_sample], [], []
  103.                 input = x_sample
  104.  
  105.                 len_ = len(self.weights)
  106.                 d_weights, d_biases = [None] * len_ , [None] * len_
  107.                
  108.                 for idx, _ in enumerate(zip(self.weights, self.biases)):
  109.                     w, b = _[0], _[1]
  110.                    
  111.                     activation = np.dot(input, w) + b
  112.                     activations.append(activation)
  113.                    
  114.                     if w.shape[1] == 1 and self.type == 'reg':
  115.                         output = self.linear(activation, C=self.C)
  116.                         outputs.append(output)
  117.                     elif w.shape[1] == 1 and self.type == 'binary':
  118.                         output = self.sigmoid(activation)
  119.                         outputs.append(output)
  120.                     elif idx == (len_-1) and self.type == 'multi':
  121.                         output = self.softmax(activation)
  122.                         outputs.append(output)
  123.                     else:
  124.                         input = self.sigmoid(activation)
  125.                         outputs.append(input)
  126.                         inputs.append(input)
  127.  
  128.                 y_pred.append(output)
  129.                
  130.                 if self.type == 'multi':
  131.                     delta = output - np.eye(output_size)[y[i]]
  132.                 else:
  133.                     delta = output - y[i]
  134.                    
  135.                 d_biases[len_-1] = delta * self.C
  136.                 d_weights[len_-1] = np.dot(inputs[len_-1].reshape(-1, 1), d_biases[len_-1].reshape(-1, 1).T)
  137.  
  138.                 for idx in reversed(range(len_ - 1)):
  139.                     d_biases[idx] = np.dot(d_biases[idx+1], self.weights[idx+1].T * self.sigmoid_derivative(activations[idx]))
  140.                     d_weights[idx] = np.dot(inputs[idx].reshape(-1, 1), d_biases[idx].reshape(-1, 1).T)
  141.  
  142.                 for idx in (range(len_)):
  143.                     self.weights[idx] -= self.learning_rate * d_weights[idx]
  144.                     self.biases[idx] -= self.learning_rate * d_biases[idx]
  145.        
  146.             if self.type == 'reg':
  147.                 err = mean_squared_error(y_true=y, y_pred=y_pred)
  148.                 print(f'Epoche={epoch}, MSE={err}')
  149.             elif self.type == 'binary' or self.type == 'multi':
  150.                 err = log_loss(y, y_pred)
  151.                 print(f'Epoche={epoch}, logloss={err}')
  152.             if err < best_err:
  153.                 count = 0
  154.                 best_err = err
  155.             else:
  156.                 count += 1
  157.             self.epochs_.append(epoch+1)
  158.             self.loss_.append(err)
  159.            
  160.             if count >= self.early_stopping_rounds:
  161.                 print(f"Навчання завершено на епохі {epoch} з помилкою {err}")
  162.                 break
  163.  
  164.     def predict(self, x):
  165.        
  166.         try:
  167.             _ = x.shape[1]
  168.         except:
  169.             x = x.reshape(-1, 1)
  170.        
  171.         y_pred = []
  172.         len_ = len(self.weights)
  173.         for x_sample in x:
  174.             input = x_sample
  175.             for idx, _ in enumerate(zip(self.weights, self.biases)):
  176.                 w, b = _[0], _[1]
  177.                 activation = np.dot(input, w) + b
  178.                
  179.                 if w.shape[1] == 1 and self.type == 'reg':
  180.                     output = self.linear(activation, C=self.C)
  181.                 elif w.shape[1] == 1 and self.type == 'binary':
  182.                     output = (self.sigmoid(activation) > 0.5).astype(int)
  183.                 elif idx == (len_-1) and self.type == 'multi':
  184.                     output = np.argmax(self.softmax(activation))
  185.                 else:
  186.                     input = self.sigmoid(activation)
  187.             y_pred.append(output)
  188.         return np.array(y_pred)
  189.  
  190. def plot_classification_report(report):
  191.  
  192.     pattern = r'\s*(\d+)\s+(\d+\.\d{2})\s+(\d+\.\d{2})\s+(\d+\.\d{2})\s+(\d+)\n?'
  193.     matches = re.findall(pattern, report)
  194.     matches = pd.DataFrame(matches, columns=['Class', 'Precision', 'Recall', 'F1-score', 'Support'])
  195.    
  196.     for col in matches.columns: matches[col] = matches[col].astype(float)
  197.    
  198.     for col in ['Precision', 'Recall', 'F1-score']:
  199.         plt.figure(figsize=(10, 4))
  200.        
  201.         cmap = plt.get_cmap('coolwarm')
  202.         norm = Normalize(0, 1)
  203.    
  204.         for index, value in enumerate(matches[col]):
  205.             gradient = np.linspace(0, value, 100)
  206.             gradient = gradient.reshape(1, -1)
  207.            
  208.             plt.imshow(gradient, aspect='auto', cmap=cmap, norm=norm, extent=[0, value, index - 0.4, index + 0.4])
  209.             plt.text(value - 0.05, index, f'{value:.2f}', va='center')
  210.        
  211.         plt.grid(True, axis='x')
  212.         plt.title(f'{col} кожного з класів')
  213.         plt.ylabel('Клас')
  214.         plt.xlabel(col)
  215.         plt.yticks(ticks=np.arange(len(matches)), labels=matches['Class'].astype(int))
  216.         plt.xlim(0, 1)
  217.         plt.ylim(-0.5, len(matches) - 0.5)
  218.        
  219.         plt.show()
  220.  
  221. def center_image_before_resize(img):
  222.     cy, cx = center_of_mass(img)
  223.    
  224.     shift_y = img.shape[0] // 2 - cy
  225.     shift_x = img.shape[1] // 2 - cx
  226.  
  227.     centered_img = shift(img, shift=[shift_y, shift_x], mode='constant', cval=0)
  228.    
  229.     return centered_img
  230.  
  231.  
  232. mnist = tf.keras.datasets.mnist
  233. (X_train, y_train), (X_test, y_test) = mnist.load_data()
  234.  
  235. x_train = X_train.reshape(X_train.shape[0], -1) / 255.0
  236. x_test = X_test.reshape(X_test.shape[0], -1) / 255.0
  237.  
  238. loaded_model = Weights_pipeline(model=MultiNeuralNetwork(type='multi')).load_from_file('model_wthout_res_params.npz')
  239. y_pred = loaded_model.predict(x_test)
  240.  
  241. text = classification_report(y_test, y_pred)
  242.  
  243. plot_classification_report(text)
  244. print(text)
  245.  
  246. arr = []
  247. y_true = []
  248. for i in range(10):
  249.     for k in range(1, 11):
  250.    
  251.         img = 255 - np.array(Image.open(f'D:/SUMDU/4 курс/Моделювання нейронних мереж/pr7(Numbers)/{i}_{k}.png').convert('L'))
  252.        
  253.         centered_img = center_image_before_resize(img)
  254.         centered_img = Image.fromarray(centered_img).resize((28, 28))
  255.         centered_img = np.array(centered_img)
  256.        
  257.         arr.append(centered_img)
  258.         y_true.append(i)
  259.  
  260. img_array, y_true = np.array(arr), np.array(y_true)
  261.  
  262. my_x_test = img_array.reshape(img_array.shape[0], -1) / 255.0
  263. y_pred = loaded_model.predict(my_x_test)
  264.  
  265. plt.figure(figsize=(10, 50))
  266. for i in range(100):
  267.     plt.subplot(20, 5, i + 1)
  268.     plt.imshow(img_array[i], cmap='gray_r')
  269.    
  270.     plt.title(f"Real: {y_true[i]} | Pred: ", color='black')
  271.    
  272.     color = 'green' if y_true[i] == y_pred[i] else 'red'
  273.    
  274.     plt.text(0.85, 1.045, f"{y_pred[i]}", color=color, fontsize=12, ha='center', transform=plt.gca().transAxes)
  275.  
  276.     plt.axis("off")
  277. plt.tight_layout()
  278. plt.show()
  279.  
  280. text = (classification_report(y_true, y_pred))
  281. plot_classification_report(text)
  282. print(text)
Add Comment
Please, Sign In to add comment