Advertisement
mirosh111000

Використання нейронної мережi Хемiнга з шаром MAXNET для фiльтрацiї шумових сигналiв(pr9)

Nov 18th, 2024
45
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.03 KB | None | 0 0
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import os
  4. from PIL import Image
  5. from scipy.ndimage import center_of_mass
  6. from scipy.ndimage import shift
  7. import datetime as dt
  8. import os
  9. import pandas as pd
  10. from IPython.display import clear_output
  11. from sklearn.metrics import accuracy_score, classification_report
  12. import re
  13. from matplotlib.colors import Normalize
  14. from matplotlib.cm import ScalarMappable
  15.  
  16. def plot_classification_report(report, type='', prob=''):
  17.  
  18.     pattern = r'\s*(\d+)\s+(\d+\.\d{2})\s+(\d+\.\d{2})\s+(\d+\.\d{2})\s+(\d+)\n?'
  19.     matches = re.findall(pattern, report)
  20.     matches = pd.DataFrame(matches, columns=['Class', 'Precision', 'Recall', 'F1-score', 'Support'])
  21.    
  22.     for col in matches.columns: matches[col] = matches[col].astype(float)
  23.    
  24.     for col in ['Precision', 'Recall', 'F1-score']:
  25.         plt.figure(figsize=(10, 4))
  26.        
  27.         cmap = plt.get_cmap('coolwarm')
  28.         norm = Normalize(0, 1)
  29.    
  30.         for index, value in enumerate(matches[col]):
  31.             gradient = np.linspace(0, value, 100)
  32.             gradient = gradient.reshape(1, -1)
  33.            
  34.             plt.imshow(gradient, aspect='auto', cmap=cmap, norm=norm, extent=[0, value, index - 0.4, index + 0.4])
  35.             if value > 0:
  36.                 plt.text(value - 0.05, index, f'{value:.2f}', va='center')
  37.        
  38.         plt.grid(True, axis='x')
  39.         plt.title(f'{col} кожного з класів (Рівень {type} {prob}%)')
  40.         plt.ylabel('Клас')
  41.         plt.xlabel(col)
  42.         plt.yticks(ticks=np.arange(len(matches)), labels=matches['Class'].astype(int))
  43.         plt.xlim(0, 1)
  44.         plt.ylim(-0.5, len(matches) - 0.5)
  45.         plt.show()
  46.  
  47. def visualize_symbols(symbols):
  48.  
  49.     fig, axes = plt.subplots(1, len(symbols), figsize=(7, 5))
  50.     for ax, (symbol, pattern) in zip(axes, symbols.items()):
  51.         ax.imshow(pattern.reshape(height, width), cmap="gray")
  52.         ax.set_title(symbol)
  53.         ax.axis("off")
  54.     plt.show()
  55.  
  56. def center_image_before_resize(img):
  57.     cy, cx = center_of_mass(img)
  58.    
  59.     shift_y = img.shape[0] // 2 - cy
  60.     shift_x = img.shape[1] // 2 - cx
  61.  
  62.     centered_img = shift(img, shift=[shift_y, shift_x], mode='constant', cval=0)
  63.    
  64.     return centered_img
  65.  
  66. def blackout_noise(image, blackout_prob=0.2):
  67.     noisy_image = np.copy(image)
  68.     black_pixels = np.where(image == 0)
  69.     num_black_pixels = len(black_pixels[0])
  70.    
  71.     for i in range(num_black_pixels):
  72.         random_num = np.random.random()
  73.         if random_num <= blackout_prob:
  74.             noisy_image[black_pixels[0][i]] = 1
  75.            
  76.     return noisy_image
  77.  
  78. def add_random_noise(image, noise_prob=0.1):
  79.  
  80.     black_pixels = np.where(image == 0)
  81.     num_black_pixels = len(black_pixels[0])
  82.    
  83.     noisy_image = blackout_noise(image, blackout_prob=noise_prob)
  84.  
  85.     for i in range(num_black_pixels):
  86.         random_num = np.random.random()
  87.         if random_num <= noise_prob:
  88.             random_idx = np.random.randint(0, len(noisy_image))
  89.             noisy_image[random_idx] = 0
  90.     return noisy_image
  91.  
  92. def generate_noisy_symbols(method='blackout', blackout_prob=0.2, noise_prob=0.2):
  93.     noisy_symbols = {}
  94.     for i in range(N):
  95.         if method == 'blackout':
  96.             noisy_symbols[str(i)] = blackout_noise(symbols[str(i)], blackout_prob)
  97.         elif method == 'add_random':
  98.             noisy_symbols[str(i)] = add_random_noise(symbols[str(i)], noise_prob)
  99.     return noisy_symbols
  100.  
  101.  
  102. def one_hot_encode(label, num_classes=10):
  103.     y = np.zeros(num_classes)
  104.     y[label] = 1
  105.     return y
  106.  
  107. def activation_function(s, T):
  108.     activations = []
  109.     for i in s:
  110.         if i <= 0: activations.append(0)
  111.         elif i >= T: activations.append(T)
  112.         else: activations.append(i)
  113.     return np.array(activations)
  114.  
  115.  
  116. class HammingLayer:
  117.     def __init__(self, reference_images):
  118.         self.M = len(reference_images[0])
  119.         self.weights = np.copy(reference_images).T / 2
  120.         self.bias = np.array([self.M / 2 for _ in range(len(reference_images))])
  121.  
  122.     def activate(self, x):
  123.         activation = np.dot(x, self.weights) + self.bias
  124.         return activation_function(s=activation, T=self.M)
  125.  
  126. class MaxNetLayer:
  127.     def __init__(self, num_neurons, epsilon):
  128.         self.num_neurons = num_neurons
  129.         self.epsilon = epsilon
  130.         self.weights = np.full((num_neurons, num_neurons), -epsilon)
  131.         np.fill_diagonal(self.weights, 1)
  132.  
  133.     def activate(self, x, T):
  134.         y = x.copy()
  135.         _ = 0
  136.         while np.sum(y > 0) > 1:
  137.             y = activation_function(s=np.dot(y, self.weights), T=T)
  138.             _ += 1
  139.             if _ > 100000:
  140.                 # print('break')
  141.                 break
  142.         return y
  143.  
  144.  
  145. class HammingNetwork:
  146.     def __init__(self, reference_images, epsilon=0.1):
  147.         self.hamming_layer = HammingLayer(reference_images)
  148.         self.maxnet_layer = MaxNetLayer(len(reference_images), epsilon)
  149.  
  150.     def predict(self, x):
  151.         hamming_activations = self.hamming_layer.activate(x)
  152.         # print(f'hamming_activations = {hamming_activations}')
  153.         maxnet_output = self.maxnet_layer.activate(hamming_activations, T=self.hamming_layer.M)
  154.         # print(f'maxnet_output = {maxnet_output}')
  155.         return np.argmax(maxnet_output)
  156.  
  157. width = 28
  158. height = 28
  159. N = 10
  160. num = 10
  161. M = width * height
  162.  
  163. digit_images = []
  164. for i in range(N):
  165.    
  166.     img = np.array(Image.open(f'D:/SUMDU/4 курс/Моделювання нейронних мереж/pr9/{i}.png').convert('L'))
  167.     centered_img = center_image_before_resize(img)
  168.     centered_img = np.array(centered_img)[num:-num, num:-num]
  169.     centered_img = np.array(Image.fromarray(centered_img).resize((width, height)))
  170.     centered_img = np.where(centered_img > 255/2, 1, 0)
  171.    
  172.     digit_images.append(centered_img.reshape(M))
  173.    
  174.     # plt.imshow(centered_img, cmap='gray')
  175.     # plt.show()
  176.  
  177.  
  178. symbols = {str(i): digit for i, digit in enumerate(digit_images)}
  179. visualize_symbols(symbols)
  180.  
  181. noisy_symbols_blackout = generate_noisy_symbols(method='blackout', blackout_prob=0.2)
  182. noisy_symbols_random = generate_noisy_symbols(method='add_random', noise_prob=0.2)
  183.  
  184. visualize_symbols(noisy_symbols_blackout)
  185. visualize_symbols(noisy_symbols_random)
  186.  
  187. reference_images = np.copy([i for _, i in symbols.items()])
  188.  
  189. eps = 1 / N * 0.1
  190. model = HammingNetwork(reference_images, epsilon=eps)
  191. n = 10000
  192. df = pd.DataFrame(columns=['blackout_input', 'blackout_prob', 'noise_input', 'noise_prob', 'target', 'blackout_pred', 'blackout_error, %', 'noise_pred', 'noise_error, %'], index=[i for i in range(n)])
  193. symbol = 0
  194.  
  195. df_res = pd.DataFrame(columns=['blackout_error, %', 'noise_error, %', 'blackout_report', 'noise_report'])
  196. df_res.index.name = 'prob, %'
  197. num_prob = 100
  198. start_time = dt.datetime.now()
  199.  
  200. for _, prob in enumerate(np.linspace(0, 1, num_prob)):
  201.    
  202.     for i in range(n):
  203.    
  204.         df['target'].iloc[i] = symbol
  205.         df['blackout_prob'].iloc[i] = prob
  206.         df['noise_prob'].iloc[i] = prob
  207.    
  208.         df['blackout_input'].iloc[i] = blackout_noise(symbols[str(symbol)], blackout_prob=prob)
  209.         df['noise_input'].iloc[i] = add_random_noise(symbols[str(symbol)], noise_prob=prob)
  210.  
  211.         df['blackout_pred'].iloc[i] = model.predict(df['blackout_input'].iloc[i])
  212.         df['noise_pred'].iloc[i] = model.predict(df['noise_input'].iloc[i])
  213.    
  214.         if symbol == 9:
  215.             symbol = 0
  216.         else:
  217.             symbol += 1
  218.  
  219.     df['target'] = df['target'].astype(int)
  220.     df['blackout_pred'] = df['blackout_pred'].astype(int)
  221.     df['noise_pred'] = df['noise_pred'].astype(int)
  222.    
  223.  
  224.     df_res.loc[prob*100] = [(1 - accuracy_score(y_true=df['target'], y_pred=df['blackout_pred'])) * 100,
  225.                             (1 - accuracy_score(y_true=df['target'], y_pred=df['noise_pred'])) * 100,
  226.                             classification_report(y_true=df['target'], y_pred=df['blackout_pred']),
  227.                             classification_report(y_true=df['target'], y_pred=df['noise_pred']),
  228.                            
  229.                            ]
  230.  
  231.     prcnt = (_+1)/num_prob * 100
  232.     print(f'№{_+1}/{num_prob} - {round(prcnt, 2)}% | total time: {dt.datetime.now() - start_time} | time remaining: {(dt.datetime.now() - start_time) / prcnt * (100 - prcnt)} | end time: {dt.datetime.now() + (dt.datetime.now() - start_time) / prcnt * (100 - prcnt)}', end='\r')
  233.     os.system('cls' if os.name == 'nt' else 'clear')
  234.  
  235. plt.figure(figsize=(10, 4))
  236. plt.plot(df_res.index, df_res.iloc[:, 0], c='blue', label='Затирання')
  237. plt.plot(df_res.index, df_res.iloc[:, 1], c='red', label='Шум')
  238. plt.legend()
  239. plt.title('Відсоток неправильно класифікованих цифр')
  240. plt.xlabel('Noise level [%]')
  241. plt.ylabel('Percentage of error, [%]')
  242. plt.grid()
  243. plt.show()
  244.  
  245.  
  246. for i in range(len(df_res)):
  247.     plot_classification_report(df_res.blackout_report.iloc[i], type='Затирання', prob=round(df_res.index[i], 2))
  248.     plot_classification_report(df_res.noise_report.iloc[i], type='Шум', prob=round(df_res.index[i], 2))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement