Advertisement
mirosh111000

Двошарова нейронна мережа прямого поширення(pr4)

Sep 11th, 2024 (edited)
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.79 KB | None | 0 0
  1. import numpy as np
  2. import pandas as pd
  3. import seaborn as sns
  4. import matplotlib.pyplot as plt
  5. from sklearn.metrics import log_loss, accuracy_score, classification_report, mean_squared_error
  6.  
  7. class MultiNeuralNetwork:
  8.     def __init__(self, type='reg', learning_rate=0.01, epochs=100000, hidden_layers=[10], C=1):
  9.         self.type = type # 'reg', 'binary', 'multi'
  10.         self.learning_rate = learning_rate
  11.         self.epochs = epochs
  12.         self.hidden_layers = hidden_layers
  13.         self.C = C
  14.         self.weights = []
  15.         self.biases = []
  16.         self.loss_ = []
  17.         self.epochs_ = []
  18.  
  19.     def sigmoid(self, z):
  20.         return 1 / (1 + np.exp(-z))
  21.  
  22.     def sigmoid_derivative(self, z):
  23.         s = self.sigmoid(z)
  24.         return s * (1 - s)
  25.  
  26.     def linear(self, z, C=1):
  27.         return z * C
  28.  
  29.     def softmax(self, z):
  30.         exp_values = np.exp(z - np.max(z))
  31.         return exp_values / np.sum(exp_values, axis=0)
  32.  
  33.     def fit(self, x, y):
  34.         def initialize_parameters(input_size, output_size):
  35.             layers = [input_size] + self.hidden_layers + [output_size]
  36.             self.weights = [np.random.randn(layers[i], layers[i + 1]) * np.sqrt(1 / layers[i]) for i in range(len(layers) - 1)]
  37.             self.biases = [np.random.randn(layers[i + 1]) * 0.01 for i in range(len(layers) - 1)]
  38.  
  39.         best_err, count = np.inf, 0
  40.  
  41.         try:
  42.             input_size = x.shape[1]
  43.         except:
  44.             x = x.reshape(-1, 1)
  45.             input_size = x.shape[1]
  46.            
  47.         output_size = len(np.unique(y)) if self.type == 'multi' else 1
  48.         initialize_parameters(input_size=input_size, output_size=output_size)
  49.         for epoch in range(self.epochs):  
  50.             y_pred = []
  51.             for i, x_sample in enumerate(x):
  52.                 inputs, activations, outputs = [x_sample], [], []
  53.                 input = x_sample
  54.  
  55.                 len_ = len(self.weights)
  56.                 d_weights, d_biases = [None] * len_ , [None] * len_
  57.                
  58.                 for idx, _ in enumerate(zip(self.weights, self.biases)):
  59.                     w, b = _[0], _[1]
  60.                    
  61.                     activation = np.dot(input, w) + b
  62.                     activations.append(activation)
  63.                    
  64.                     if w.shape[1] == 1 and self.type == 'reg':
  65.                         output = self.linear(activation, C=self.C)
  66.                         outputs.append(output)
  67.                     elif w.shape[1] == 1 and self.type == 'binary':
  68.                         output = self.sigmoid(activation)
  69.                         outputs.append(output)
  70.                     elif idx == (len_-1) and self.type == 'multi':
  71.                         output = self.softmax(activation)
  72.                         outputs.append(output)
  73.                     else:
  74.                         input = self.sigmoid(activation)
  75.                         outputs.append(input)
  76.                         inputs.append(input)
  77.  
  78.                 y_pred.append(output)
  79.                
  80.                 if self.type == 'multi':
  81.                     delta = output - np.eye(output_size)[y[i]]
  82.                 else:
  83.                     delta = output - y[i]
  84.                    
  85.                 d_biases[len_-1] = delta * self.C
  86.                 d_weights[len_-1] = np.dot(inputs[len_-1].reshape(-1, 1), d_biases[len_-1].reshape(-1, 1).T)
  87.  
  88.                 for idx in reversed(range(len_ - 1)):
  89.                     d_biases[idx] = np.dot(d_biases[idx+1], self.weights[idx+1].T * self.sigmoid_derivative(activations[idx]))
  90.                     d_weights[idx] = np.dot(inputs[idx].reshape(-1, 1), d_biases[idx].reshape(-1, 1).T)
  91.  
  92.                 for idx in (range(len_)):
  93.                     self.weights[idx] -= self.learning_rate * d_weights[idx]
  94.                     self.biases[idx] -= self.learning_rate * d_biases[idx]
  95.        
  96.             if self.type == 'reg':
  97.                 err = mean_squared_error(y_true=y, y_pred=y_pred)
  98.                 print(f'Epoche={epoch}, MSE={err}')
  99.             elif self.type == 'binary' or self.type == 'multi':
  100.                 err = log_loss(y, y_pred)
  101.                 print(f'Epoche={epoch}, logloss={err}')
  102.             if err < best_err:
  103.                 count = 0
  104.                 best_err = err
  105.             else:
  106.                 count += 1
  107.             self.epochs_.append(epoch+1)
  108.             self.loss_.append(err)
  109.            
  110.             if count >= 250:
  111.                 print(f"Навчання завершено на епохі {epoch} з помилкою {err}")
  112.                 break
  113.  
  114.     def predict(self, x):
  115.        
  116.         try:
  117.             _ = x.shape[1]
  118.         except:
  119.             x = x.reshape(-1, 1)
  120.        
  121.         y_pred = []
  122.         len_ = len(self.weights)
  123.         for x_sample in x:
  124.             input = x_sample
  125.             for idx, _ in enumerate(zip(self.weights, self.biases)):
  126.                 w, b = _[0], _[1]
  127.                 activation = np.dot(input, w) + b
  128.                
  129.                 if w.shape[1] == 1 and self.type == 'reg':
  130.                     output = self.linear(activation, C=self.C)
  131.                 elif w.shape[1] == 1 and self.type == 'binary':
  132.                     output = (self.sigmoid(activation) > 0.5).astype(int)
  133.                 elif idx == (len_-1) and self.type == 'multi':
  134.                     output = np.argmax(self.softmax(activation))
  135.                 else:
  136.                     input = self.sigmoid(activation)
  137.             y_pred.append(output)
  138.         return np.array(y_pred)
  139.  
  140.  
  141. def f(x):
  142.     return np.sin(x)
  143.  
  144. N = 100  
  145. a, b = 0, 10  
  146.  
  147. x = np.linspace(a, b, N)
  148. y = f(x)
  149.  
  150. x_test = x + 0.05
  151. y_test = f(x_test)
  152.  
  153. df = pd.DataFrame(x, columns=['X'])
  154.  
  155. df['target'] = y
  156. print(df)
  157.  
  158. sns.pairplot(df)
  159. plt.show()
  160.  
  161. model = MultiNeuralNetwork(type='reg', learning_rate=0.01, epochs=25000, hidden_layers=[10], C=1)
  162. model.fit(x, y)
  163.  
  164. plt.figure(figsize=(10, 5))
  165. plt.title('Залежність помилки від епохи навчання')
  166. plt.plot(model.epochs_, model.loss_, c='red', label=f'lr={model.learning_rate}')
  167. plt.ylabel('MSE')
  168. plt.xlabel('Epoche')
  169. plt.grid()
  170. plt.legend()
  171. plt.show()
  172.  
  173.  
  174. y_pred = model.predict(x)
  175.  
  176. plt.figure(figsize=(10, 5))
  177. plt.title('Тренувальні дані')
  178. plt.scatter(x, y, label='Реальні дані')
  179. plt.plot(x, y_pred, label=f'Передбачення {round(mean_squared_error(y_true=y, y_pred=y_pred), 6)}', color='red')
  180. plt.grid()
  181. plt.legend()
  182. plt.show()
  183.  
  184.  
  185. y_pred_test = model.predict(x_test)
  186.  
  187. plt.figure(figsize=(10, 5))
  188. plt.title('Тестові дані (x_test = x_train + 0.05)')
  189. plt.scatter(x_test, y_test, label='Тестові дані')
  190. plt.plot(x_test, y_pred_test, label=f'Передбачення (MSE={round(mean_squared_error(y_test, y_pred_test), 6)})', color='red')
  191. plt.grid()
  192. plt.legend()
  193. plt.show()
  194.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement