Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import numpy as np
- import matplotlib.pyplot as plt
- import datetime as dt
- import os
- from IPython.display import clear_output
- import pandas as pd
- def generate_symbol(symbol, height, width):
- pattern = np.ones((height, width)) * -1
- if symbol == 'П':
- pattern[:, 1] = 1
- pattern[:, -2] = 1
- pattern[0, 1:-2] = 1
- elif symbol == 'Т':
- pattern[:, int(height/2)] = 1
- pattern[0, :] = 1
- elif symbol == 'К':
- pattern[:, 0] = 1
- pattern[int(height/2), :int(width/2)] = 1
- for _, k in enumerate(range(int(width/2), width-1)):
- num = _ + 1
- for i in [-num, num]:
- if k > int(height/2)+1:
- pattern[int(height/2)+i, k+1] = 1
- elif k == int(height/2)+1:
- pattern[int(height/2)+i, k:k+2] = 1
- else:
- pattern[int(height/2)+i, k] = 1
- else:
- return None
- return pattern.reshape(M)
- def visualize_comparison(original, noisy, recalled, title=''):
- fig, axes = plt.subplots(1, 3, figsize=(9, 3))
- for ax, img, title in zip(axes, [original, noisy, recalled], ["Оригінал", title, "Відновлений"]):
- ax.imshow(img.reshape(height, width), cmap="gray_r")
- ax.set_title(title)
- ax.axis("off")
- plt.show()
- def visualize_symbols(symbols):
- fig, axes = plt.subplots(1, len(symbols), figsize=(7, 5))
- for ax, (symbol, pattern) in zip(axes, symbols.items()):
- ax.imshow(pattern.reshape(height, width), cmap="gray_r")
- ax.set_title(symbol)
- ax.axis("off")
- plt.show()
- class Hopfield():
- def __init__(self, M, max_iter=100):
- self.M = M
- self.max_iter = max_iter
- self.weights = None
- def fit(self, symbols):
- W = np.zeros((self.M, self.M))
- for symbol_vector in symbols.values():
- W += np.outer(symbol_vector, symbol_vector)
- np.fill_diagonal(W, 0)
- self.weights = W / self.M
- def hard_threshold_activation(self, x):
- return np.where(x > 0, 1, -1)
- def predict(self, input_vector):
- y = np.copy(input_vector)
- for _ in range(self.max_iter):
- y_new = self.hard_threshold_activation(self.weights @ y)
- if np.array_equal(y, y_new):
- break
- y = y_new
- return y
- def blackout_noise(image, blackout_prob=0.2):
- noisy_image = np.copy(image)
- black_pixels = np.where(image == 1)
- num_black_pixels = len(black_pixels[0])
- for i in range(num_black_pixels):
- random_num = np.random.random()
- if random_num <= blackout_prob:
- noisy_image[black_pixels[0][i]] = -1
- return noisy_image
- def add_random_noise(image, noise_prob=0.1):
- black_pixels = np.where(image == 1)
- num_black_pixels = len(black_pixels[0])
- noisy_image = blackout_noise(image, blackout_prob=noise_prob)
- for i in range(num_black_pixels):
- random_num = np.random.random()
- if random_num <= noise_prob:
- random_idx = np.random.randint(0, len(noisy_image))
- noisy_image[random_idx] = 1
- return noisy_image
- def generate_noisy_symbols(method='blackout', blackout_prob=0.2, noise_prob=0.2):
- noisy_symbols = {}
- for i in ['П', 'Т', 'К']:
- if method == 'blackout':
- noisy_symbols[str(i)] = blackout_noise(symbols[str(i)], blackout_prob)
- elif method == 'add_random':
- noisy_symbols[str(i)] = add_random_noise(symbols[str(i)], noise_prob)
- return noisy_symbols
- width = 9
- height = 9
- M = width * height
- symbols = {str(i): generate_symbol(i, height, width) for i in ['П', 'Т', 'К']}
- visualize_symbols(symbols)
- noisy_symbols_blackout = generate_noisy_symbols(method='blackout', blackout_prob=0.2)
- noisy_symbols_random = generate_noisy_symbols(method='add_random', noise_prob=0.2)
- visualize_symbols(noisy_symbols_blackout)
- visualize_symbols(noisy_symbols_random)
- model = Hopfield(M=M, max_iter=100)
- model.fit(symbols)
- for s in ['П', 'Т', 'К']:
- test_symbol = symbols[s]
- noisy_test_symbol = add_random_noise(test_symbol, noise_prob=0.2)
- blackout_test_symbol = blackout_noise(test_symbol, blackout_prob=0.2)
- recalled_symbol_blackout = model.predict(noisy_test_symbol)
- recalled_symbol_noise = model.predict(blackout_test_symbol)
- visualize_comparison(test_symbol, blackout_test_symbol, recalled_symbol_blackout, 'Затирання')
- visualize_comparison(test_symbol, noisy_test_symbol, recalled_symbol_noise, 'Шум')
- n = 9999
- df = pd.DataFrame(columns=['blackout_input', 'blackout_prob', 'noise_input', 'noise_prob', 'target', 'symbol', 'blackout_pred', 'blackout_error, %', 'blackout_class_error', 'noise_pred', 'noise_error, %', 'noise_class_error'], index=[i for i in range(n)])
- symbol = 'П'
- df_res = pd.DataFrame(columns=['blackout_error, %', 'noise_error, %', 'blackout_class_error, %', 'noise_class_error, %'])
- df_res.index.name = 'prob, %'
- num_prob = 250
- start_time = dt.datetime.now()
- for _, prob in enumerate(np.linspace(0, 1, num_prob)):
- for i in range(n):
- df['symbol'].iloc[i] = symbol
- df['target'].iloc[i] = symbols[symbol]
- df['blackout_prob'].iloc[i] = prob
- df['noise_prob'].iloc[i] = prob
- df['blackout_input'].iloc[i] = blackout_noise(symbols[symbol], blackout_prob=prob)
- df['noise_input'].iloc[i] = add_random_noise(symbols[symbol], noise_prob=prob)
- df['blackout_pred'].iloc[i] = model.predict(df['blackout_input'].iloc[i])
- df['noise_pred'].iloc[i] = model.predict(df['noise_input'].iloc[i])
- df['blackout_error, %'].iloc[i] = np.sum(np.abs(df['target'].iloc[i] - df['blackout_pred'].iloc[i])) / len(df['target'].iloc[i]) * 100
- df['noise_error, %'].iloc[i] = np.sum(np.abs(df['target'].iloc[i] - df['noise_pred'].iloc[i])) / len(df['target'].iloc[i]) * 100
- df['blackout_error, %'].iloc[i] = np.sum(np.abs(df['target'].iloc[i] - df['blackout_pred'].iloc[i])) / len(df['target'].iloc[i]) * 100
- df['noise_error, %'].iloc[i] = np.sum(np.abs(df['target'].iloc[i] - df['noise_pred'].iloc[i])) / len(df['target'].iloc[i]) * 100
- df['blackout_class_error'].iloc[i] = np.array_equal(df['target'].iloc[i], df['blackout_pred'].iloc[i])
- df['noise_class_error'].iloc[i] = np.array_equal(df['target'].iloc[i], df['noise_pred'].iloc[i])
- if symbol == 'П': symbol = 'Т'
- elif symbol == 'Т': symbol = 'К'
- elif symbol == 'К': symbol = 'П'
- df_res.loc[prob*100] = [df['blackout_error, %'].mean(), df['noise_error, %'].mean(),
- (1 - np.sum(df['blackout_class_error']) / len(df['blackout_class_error'])) * 100,
- (1 - np.sum(df['noise_class_error']) / len(df['noise_class_error'])) * 100]
- prcnt = (_+1)/num_prob * 100
- 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='\r')
- os.system('cls' if os.name == 'nt' else 'clear')
- # clear_output()
- plt.figure(figsize=(10, 4))
- plt.plot(df_res.index, df_res.iloc[:, 0], c='blue', label='Затирання')
- plt.plot(df_res.index, df_res.iloc[:, 1], c='red', label='Шум')
- plt.legend()
- plt.title('Відсоток неправильно відновлених клітинок')
- plt.xlabel('Noise level [%]')
- plt.ylabel('Percentage of error, [%]')
- plt.grid()
- plt.show()
- plt.figure(figsize=(10, 4))
- plt.plot(df_res.index, df_res.iloc[:, 2], c='blue', label='Затирання')
- plt.plot(df_res.index, df_res.iloc[:, 3], c='red', label='Шум')
- plt.legend()
- plt.title('Відсоток неправильно відновлених символів')
- plt.xlabel('Noise level [%]')
- plt.ylabel('Percentage of error, [%]')
- plt.grid()
- plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement