journal linspace basins
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | /output/ | ||||||
| @@ -8,15 +8,12 @@ import numpy as np | |||||||
| import torch | import torch | ||||||
|  |  | ||||||
| from functionalities_test import is_identity_function, test_status | from functionalities_test import is_identity_function, test_status | ||||||
| from journal_basins import SpawnExperiment, prng, mean_invariate_manhattan_distance | from journal_basins import SpawnExperiment, mean_invariate_manhattan_distance | ||||||
| from network import Net | from network import Net | ||||||
|  |  | ||||||
| from sklearn.metrics import mean_absolute_error as MAE | from sklearn.metrics import mean_absolute_error as MAE | ||||||
| from sklearn.metrics import mean_squared_error as MSE | from sklearn.metrics import mean_squared_error as MSE | ||||||
|  |  | ||||||
| import seaborn as sns |  | ||||||
| from matplotlib import pyplot as plt |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class SpawnLinspaceExperiment(SpawnExperiment): | class SpawnLinspaceExperiment(SpawnExperiment): | ||||||
|  |  | ||||||
| @@ -28,6 +25,12 @@ class SpawnLinspaceExperiment(SpawnExperiment): | |||||||
|                      'status_post']) |                      'status_post']) | ||||||
|  |  | ||||||
|         # For every initial net {i} after populating (that is fixpoint after first epoch); |         # For every initial net {i} after populating (that is fixpoint after first epoch); | ||||||
|  |         # parent = self.parents[0] | ||||||
|  |         # parent_clone = clone = Net(parent.input_size, parent.hidden_size, parent.out_size, | ||||||
|  |         #                         name=f"{parent.name}_clone_{0}", start_time=self.ST_steps) | ||||||
|  |         # parent_clone.apply_weights(torch.as_tensor(parent.create_target_weights(parent.input_weight_matrix()))) | ||||||
|  |         # parent_clone = parent_clone.apply_noise(self.noise) | ||||||
|  |         # self.parents.append(parent_clone) | ||||||
|         pairwise_net_list = itertools.combinations(self.parents, 2) |         pairwise_net_list = itertools.combinations(self.parents, 2) | ||||||
|         for net1, net2 in pairwise_net_list: |         for net1, net2 in pairwise_net_list: | ||||||
|             # We set parent start_time to just before this epoch ended, so plotting is zoomed in. Comment out to |             # We set parent start_time to just before this epoch ended, so plotting is zoomed in. Comment out to | ||||||
| @@ -42,11 +45,12 @@ class SpawnLinspaceExperiment(SpawnExperiment): | |||||||
|             net2_target_data = net2.create_target_weights(net2_input_data) |             net2_target_data = net2.create_target_weights(net2_input_data) | ||||||
|  |  | ||||||
|             if is_identity_function(net1) and is_identity_function(net2): |             if is_identity_function(net1) and is_identity_function(net2): | ||||||
|  |             # if True: | ||||||
|                 # Clone the fixpoint x times and add (+-)self.noise to weight-sets randomly; |                 # Clone the fixpoint x times and add (+-)self.noise to weight-sets randomly; | ||||||
|                 # To plot clones starting after first epoch (z=ST_steps), set that as start_time! |                 # To plot clones starting after first epoch (z=ST_steps), set that as start_time! | ||||||
|                 # To make sure PCA will plot the same trajectory up until this point, we clone the |                 # To make sure PCA will plot the same trajectory up until this point, we clone the | ||||||
|                 # parent-net's weight history as well. |                 # parent-net's weight history as well. | ||||||
|                 in_between_weights = np.linspace(net1_target_data, net2_target_data, number_clones,endpoint=False) |                 in_between_weights = np.linspace(net1_target_data, net2_target_data, number_clones, endpoint=False) | ||||||
|  |  | ||||||
|                 for j, in_between_weight in enumerate(in_between_weights): |                 for j, in_between_weight in enumerate(in_between_weights): | ||||||
|                     clone = Net(net1.input_size, net1.hidden_size, net1.out_size, |                     clone = Net(net1.input_size, net1.hidden_size, net1.out_size, | ||||||
| @@ -89,7 +93,6 @@ class SpawnLinspaceExperiment(SpawnExperiment): | |||||||
|             for _ in range(self.epochs - 1): |             for _ in range(self.epochs - 1): | ||||||
|                 for _ in range(self.ST_steps): |                 for _ in range(self.ST_steps): | ||||||
|                     parent.self_train(1, self.log_step_size, self.net_learning_rate) |                     parent.self_train(1, self.log_step_size, self.net_learning_rate) | ||||||
|              |  | ||||||
|  |  | ||||||
|         self.df = df |         self.df = df | ||||||
|  |  | ||||||
| @@ -106,7 +109,7 @@ if __name__ == '__main__': | |||||||
|     ST_log_step_size = 10 |     ST_log_step_size = 10 | ||||||
|  |  | ||||||
|     # Define number of networks & their architecture |     # Define number of networks & their architecture | ||||||
|     nr_clones = 3 |     nr_clones = 20 | ||||||
|     ST_population_size = 3 |     ST_population_size = 3 | ||||||
|     ST_net_hidden_size = 2 |     ST_net_hidden_size = 2 | ||||||
|     ST_net_learning_rate = 0.04 |     ST_net_learning_rate = 0.04 | ||||||
| @@ -123,7 +126,7 @@ if __name__ == '__main__': | |||||||
|         epochs=ST_epochs, |         epochs=ST_epochs, | ||||||
|         st_steps=ST_steps, |         st_steps=ST_steps, | ||||||
|         nr_clones=nr_clones, |         nr_clones=nr_clones, | ||||||
|         noise=None, |         noise=1e-8, | ||||||
|         directory=Path('output') / 'spawn_basin' / f'{ST_name_hash}' / f'linage' |         directory=Path('output') / 'spawn_basin' / f'{ST_name_hash}' / f'linage' | ||||||
|     ) |     ) | ||||||
|     df = exp.df |     df = exp.df | ||||||
| @@ -133,10 +136,10 @@ if __name__ == '__main__': | |||||||
|     print(f"\nSaved experiment to {directory}.") |     print(f"\nSaved experiment to {directory}.") | ||||||
|  |  | ||||||
|     # Boxplot with counts of nr_fixpoints, nr_other, nr_etc. on y-axis |     # Boxplot with counts of nr_fixpoints, nr_other, nr_etc. on y-axis | ||||||
|     sns.countplot(data=df, x="noise", hue="status_post") |     # sns.countplot(data=df, x="noise", hue="status_post") | ||||||
|     plt.savefig(f"output/spawn_basin/{ST_name_hash}/fixpoint_status_countplot.png") |     # plt.savefig(f"output/spawn_basin/{ST_name_hash}/fixpoint_status_countplot.png") | ||||||
|  |  | ||||||
|     # Catplot (either kind="point" or "box") that shows before-after training distances to parent |     # Catplot (either kind="point" or "box") that shows before-after training distances to parent | ||||||
|     mlt = df[["MIM_pre", "MIM_post", "noise"]].melt("noise", var_name="time", value_name='Average Distance') |     # mlt = df[["MIM_pre", "MIM_post", "noise"]].melt("noise", var_name="time", value_name='Average Distance') | ||||||
|     sns.catplot(data=mlt, x="time", y="Average Distance", col="noise", kind="point", col_wrap=5, sharey=False) |     # sns.catplot(data=mlt, x="time", y="Average Distance", col="noise", kind="point", col_wrap=5, sharey=False) | ||||||
|     plt.savefig(f"output/spawn_basin/{ST_name_hash}/clone_distance_catplot.png") |     # plt.savefig(f"output/spawn_basin/{ST_name_hash}/clone_distance_catplot.png") | ||||||
|   | |||||||
| @@ -84,21 +84,6 @@ def distance_from_parent(nets, distance="MIM", print_it=True): | |||||||
|  |  | ||||||
| class SpawnExperiment: | class SpawnExperiment: | ||||||
|  |  | ||||||
|     @staticmethod |  | ||||||
|     def apply_noise(network, noise: int): |  | ||||||
|         """ Changing the weights of a network to values + noise """ |  | ||||||
|  |  | ||||||
|         for layer_id, layer_name in enumerate(network.state_dict()): |  | ||||||
|             for line_id, line_values in enumerate(network.state_dict()[layer_name]): |  | ||||||
|                 for weight_id, weight_value in enumerate(network.state_dict()[layer_name][line_id]): |  | ||||||
|                     # network.state_dict()[layer_name][line_id][weight_id] = weight_value + noise |  | ||||||
|                     if prng() < 0.5: |  | ||||||
|                         network.state_dict()[layer_name][line_id][weight_id] = weight_value + noise |  | ||||||
|                     else: |  | ||||||
|                         network.state_dict()[layer_name][line_id][weight_id] = weight_value - noise |  | ||||||
|  |  | ||||||
|         return network |  | ||||||
|  |  | ||||||
|     def __init__(self, population_size, log_step_size, net_input_size, net_hidden_size, net_out_size, net_learning_rate, |     def __init__(self, population_size, log_step_size, net_input_size, net_hidden_size, net_out_size, net_learning_rate, | ||||||
|                  epochs, st_steps, nr_clones, noise, directory) -> None: |                  epochs, st_steps, nr_clones, noise, directory) -> None: | ||||||
|         self.population_size = population_size |         self.population_size = population_size | ||||||
| @@ -171,7 +156,7 @@ class SpawnExperiment: | |||||||
|                                 f"ST_net_{str(i)}_clone_{str(j)}", start_time=self.ST_steps) |                                 f"ST_net_{str(i)}_clone_{str(j)}", start_time=self.ST_steps) | ||||||
|                     clone.load_state_dict(copy.deepcopy(net.state_dict()))  |                     clone.load_state_dict(copy.deepcopy(net.state_dict()))  | ||||||
|                     rand_noise = prng() * self.noise |                     rand_noise = prng() * self.noise | ||||||
|                     clone = self.apply_noise(clone, rand_noise) |                     clone = clone.apply_noise(rand_noise) | ||||||
|                     clone.s_train_weights_history = copy.deepcopy(net.s_train_weights_history) |                     clone.s_train_weights_history = copy.deepcopy(net.s_train_weights_history) | ||||||
|                     clone.number_trained = copy.deepcopy(net.number_trained) |                     clone.number_trained = copy.deepcopy(net.number_trained) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -91,7 +91,6 @@ class RobustnessComparisonExperiment: | |||||||
|         self.time_to_vergence, self.time_as_fixpoint = self.test_robustness( |         self.time_to_vergence, self.time_as_fixpoint = self.test_robustness( | ||||||
|             seeds=population_size if self.is_synthetic else 1) |             seeds=population_size if self.is_synthetic else 1) | ||||||
|  |  | ||||||
|  |  | ||||||
|     def populate_environment(self): |     def populate_environment(self): | ||||||
|         nets = [] |         nets = [] | ||||||
|         if self.is_synthetic: |         if self.is_synthetic: | ||||||
| @@ -125,8 +124,8 @@ class RobustnessComparisonExperiment: | |||||||
|         # This checks wether to use synthetic setting with multiple seeds |         # This checks wether to use synthetic setting with multiple seeds | ||||||
|         #   or multi network settings with a singlee seed |         #   or multi network settings with a singlee seed | ||||||
|  |  | ||||||
|         df = pd.DataFrame(columns=['setting', 'Noise Level', 'steps', 'absolute_loss', |         df = pd.DataFrame(columns=['setting', 'Noise Level', 'Self Train Steps', 'absolute_loss', | ||||||
|                                    'time_to_vergence', 'time_as_fixpoint']) |                                    'Time to vergence', 'Time as fixpoint']) | ||||||
|         with tqdm(total=max(len(self.id_functions), seeds)) as pbar: |         with tqdm(total=max(len(self.id_functions), seeds)) as pbar: | ||||||
|             for i, fixpoint in enumerate(self.id_functions):  # 1 / n |             for i, fixpoint in enumerate(self.id_functions):  # 1 / n | ||||||
|                 row_headers.append(fixpoint.name) |                 row_headers.append(fixpoint.name) | ||||||
| @@ -138,8 +137,7 @@ class RobustnessComparisonExperiment: | |||||||
|                         clone = Net(fixpoint.input_size, fixpoint.hidden_size, fixpoint.out_size, |                         clone = Net(fixpoint.input_size, fixpoint.hidden_size, fixpoint.out_size, | ||||||
|                                     f"{fixpoint.name}_clone_noise10e-{noise_level}") |                                     f"{fixpoint.name}_clone_noise10e-{noise_level}") | ||||||
|                         clone.load_state_dict(copy.deepcopy(fixpoint.state_dict())) |                         clone.load_state_dict(copy.deepcopy(fixpoint.state_dict())) | ||||||
|                         rand_noise = prng() * pow(10, -noise_level)  # n / 1 |                         clone = clone.apply_noise(pow(10, -noise_level)) | ||||||
|                         clone = self.apply_noise(clone, rand_noise) |  | ||||||
|  |  | ||||||
|                         while not is_zero_fixpoint(clone) and not is_divergent(clone): |                         while not is_zero_fixpoint(clone) and not is_divergent(clone): | ||||||
|                             # -> before |                             # -> before | ||||||
| @@ -154,7 +152,6 @@ class RobustnessComparisonExperiment: | |||||||
|  |  | ||||||
|                             absolute_loss = F.l1_loss(target_data_pre_application, target_data_post_application).item() |                             absolute_loss = F.l1_loss(target_data_pre_application, target_data_post_application).item() | ||||||
|  |  | ||||||
|  |  | ||||||
|                             if is_identity_function(clone): |                             if is_identity_function(clone): | ||||||
|                                 time_as_fixpoint[setting][noise_level] += 1 |                                 time_as_fixpoint[setting][noise_level] += 1 | ||||||
|                                 # When this raises a Type Error, we found a second order fixpoint! |                                 # When this raises a Type Error, we found a second order fixpoint! | ||||||
| @@ -166,26 +163,24 @@ class RobustnessComparisonExperiment: | |||||||
|                     pbar.update(1) |                     pbar.update(1) | ||||||
|  |  | ||||||
|         # Get the measuremts at the highest time_time_to_vergence |         # Get the measuremts at the highest time_time_to_vergence | ||||||
|         df_sorted = df.sort_values('Steps', ascending=False).drop_duplicates(['setting', 'Noise Level']) |         df_sorted = df.sort_values('Self Train Steps', ascending=False).drop_duplicates(['setting', 'Noise Level']) | ||||||
|         df_melted = df_sorted.reset_index().melt(id_vars=['setting', 'Noise Level', 'Steps'], |         df_melted = df_sorted.reset_index().melt(id_vars=['setting', 'Noise Level', 'Self Train Steps'], | ||||||
|                                                  value_vars=['Time to vergence', 'Time as fixpoint'], |                                                  value_vars=['Time to vergence', 'Time as fixpoint'], | ||||||
|                                                  var_name="Measurement", |                                                  var_name="Measurement", | ||||||
|                                                  value_name="Steps") |                                                  value_name="Steps").sort_values('Noise Level') | ||||||
|         # Plotting |         # Plotting | ||||||
|         sns.set(style='whitegrid', font_scale=2) |         sns.set(style='whitegrid', font_scale=2) | ||||||
|         bf = sns.boxplot(data=df_melted, y='Steps', x='Noise Level', hue='Measurement', palette=PALETTE) |         bf = sns.boxplot(data=df_melted, y='Steps', x='Noise Level', hue='Measurement', palette=PALETTE) | ||||||
|         synthetic = 'synthetic' if self.is_synthetic else 'natural' |         synthetic = 'synthetic' if self.is_synthetic else 'natural' | ||||||
|         bf.set_title(f'Robustness as self application steps per noise level for {synthetic} fixpoints.') |         # bf.set_title(f'Robustness as self application steps per noise level for {synthetic} fixpoints.') | ||||||
|         plt.tight_layout() |         plt.tight_layout() | ||||||
|  |  | ||||||
|         # sns.set(rc={'figure.figsize': (10, 50)}) |         # sns.set(rc={'figure.figsize': (10, 50)}) | ||||||
|         # bx = sns.catplot(data=df[df['absolute_loss'] < 1], y='absolute_loss', x='application_step', kind='box', |         # bx = sns.catplot(data=df[df['absolute_loss'] < 1], y='absolute_loss', x='application_step', kind='box', | ||||||
|         #                  col='noise_level', col_wrap=3, showfliers=False) |         #                  col='noise_level', col_wrap=3, showfliers=False) | ||||||
|         directory = Path('output') / 'robustness' |  | ||||||
|         directory.mkdir(parents=True, exist_ok=True) |  | ||||||
|         filename = f"absolute_loss_perapplication_boxplot_grid.png" |  | ||||||
|         filepath = directory / filename |  | ||||||
|  |  | ||||||
|  |         filename = f"absolute_loss_perapplication_boxplot_grid_{'synthetic' if self.is_synthetic else 'wild'}.png" | ||||||
|  |         filepath = self.directory / filename | ||||||
|         plt.savefig(str(filepath)) |         plt.savefig(str(filepath)) | ||||||
|  |  | ||||||
|         if print_it: |         if print_it: | ||||||
| @@ -219,11 +214,11 @@ if __name__ == "__main__": | |||||||
|     ST_steps = 1000 |     ST_steps = 1000 | ||||||
|     ST_epochs = 5 |     ST_epochs = 5 | ||||||
|     ST_log_step_size = 10 |     ST_log_step_size = 10 | ||||||
|     ST_population_size = 2 |     ST_population_size = 500 | ||||||
|     ST_net_hidden_size = 2 |     ST_net_hidden_size = 2 | ||||||
|     ST_net_learning_rate = 0.004 |     ST_net_learning_rate = 0.004 | ||||||
|     ST_name_hash = random.getrandbits(32) |     ST_name_hash = random.getrandbits(32) | ||||||
|     ST_synthetic = True |     ST_synthetic = False | ||||||
|  |  | ||||||
|     print(f"Running the robustness comparison experiment:") |     print(f"Running the robustness comparison experiment:") | ||||||
|     exp = RobustnessComparisonExperiment( |     exp = RobustnessComparisonExperiment( | ||||||
|   | |||||||
| @@ -1,14 +1,12 @@ | |||||||
| import os |  | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
| import pickle | import pickle | ||||||
| from torch import mean |  | ||||||
|  |  | ||||||
| from tqdm import tqdm | from tqdm import tqdm | ||||||
| import random | import random | ||||||
| import copy | import copy | ||||||
| from functionalities_test import is_identity_function, test_status, test_for_fixpoints, is_zero_fixpoint, is_divergent, is_secondary_fixpoint | from functionalities_test import is_identity_function, test_status, is_zero_fixpoint, is_divergent, is_secondary_fixpoint | ||||||
| from network import Net | from network import Net | ||||||
| from visualization import plot_3d_self_train, plot_loss, plot_3d_soup | from visualization import plot_loss, plot_3d_soup | ||||||
| import numpy as np | import numpy as np | ||||||
| from tabulate import tabulate | from tabulate import tabulate | ||||||
| from sklearn.metrics import mean_absolute_error as MAE | from sklearn.metrics import mean_absolute_error as MAE | ||||||
| @@ -18,10 +16,6 @@ import seaborn as sns | |||||||
| from matplotlib import pyplot as plt | from matplotlib import pyplot as plt | ||||||
|  |  | ||||||
|  |  | ||||||
| def prng(): |  | ||||||
|     return random.random() |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def l1(tup): | def l1(tup): | ||||||
|     a, b = tup |     a, b = tup | ||||||
|     return abs(a - b) |     return abs(a - b) | ||||||
| @@ -88,20 +82,6 @@ def distance_from_parent(nets, distance="MIM", print_it=True): | |||||||
|  |  | ||||||
| class SoupSpawnExperiment: | class SoupSpawnExperiment: | ||||||
|  |  | ||||||
|     @staticmethod |  | ||||||
|     def apply_noise(network, noise: int): |  | ||||||
|         """ Changing the weights of a network to values + noise """ |  | ||||||
|  |  | ||||||
|         for layer_id, layer_name in enumerate(network.state_dict()): |  | ||||||
|             for line_id, line_values in enumerate(network.state_dict()[layer_name]): |  | ||||||
|                 for weight_id, weight_value in enumerate(network.state_dict()[layer_name][line_id]): |  | ||||||
|                     # network.state_dict()[layer_name][line_id][weight_id] = weight_value + noise |  | ||||||
|                     if prng() < 0.5: |  | ||||||
|                         network.state_dict()[layer_name][line_id][weight_id] = weight_value + noise |  | ||||||
|                     else: |  | ||||||
|                         network.state_dict()[layer_name][line_id][weight_id] = weight_value - noise |  | ||||||
|  |  | ||||||
|         return network |  | ||||||
|  |  | ||||||
|     def __init__(self, population_size, log_step_size, net_input_size, net_hidden_size, net_out_size, net_learning_rate, |     def __init__(self, population_size, log_step_size, net_input_size, net_hidden_size, net_out_size, net_learning_rate, | ||||||
|                  epochs, st_steps, attack_chance, nr_clones, noise, directory) -> None: |                  epochs, st_steps, attack_chance, nr_clones, noise, directory) -> None: | ||||||
| @@ -220,8 +200,7 @@ class SoupSpawnExperiment: | |||||||
|                 clone = Net(net.input_size, net.hidden_size, net.out_size, |                 clone = Net(net.input_size, net.hidden_size, net.out_size, | ||||||
|                             f"net_{str(i)}_clone_{str(j)}", start_time=self.ST_steps) |                             f"net_{str(i)}_clone_{str(j)}", start_time=self.ST_steps) | ||||||
|                 clone.load_state_dict(copy.deepcopy(net.state_dict())) |                 clone.load_state_dict(copy.deepcopy(net.state_dict())) | ||||||
|                 rand_noise = prng() * self.noise |                 clone = clone.apply_noise(self.noise) | ||||||
|                 clone = self.apply_noise(clone, rand_noise) |  | ||||||
|                 clone.s_train_weights_history = copy.deepcopy(net.s_train_weights_history) |                 clone.s_train_weights_history = copy.deepcopy(net.s_train_weights_history) | ||||||
|                 clone.number_trained = copy.deepcopy(net.number_trained) |                 clone.number_trained = copy.deepcopy(net.number_trained) | ||||||
|  |  | ||||||
| @@ -262,9 +241,9 @@ class SoupSpawnExperiment: | |||||||
|                           f"\nMSE({i},{j}): {MSE_post}" |                           f"\nMSE({i},{j}): {MSE_post}" | ||||||
|                           f"\nMAE({i},{j}): {MAE_post}" |                           f"\nMAE({i},{j}): {MAE_post}" | ||||||
|                           f"\nMIM({i},{j}): {MIM_post}\n") |                           f"\nMIM({i},{j}): {MIM_post}\n") | ||||||
|                     self.parents_clones_id_functions.append(clone): |                     self.parents_clones_id_functions.append(clone) | ||||||
|  |  | ||||||
|                 df.loc[df.name==clone.name, ["MAE_post", "MSE_post", "MIM_post", "status_post"]] = [MAE_post, MSE_post, MIM_post, clone.is_fixpoint] |                 df.loc[df.name == clone.name, ["MAE_post", "MSE_post", "MIM_post", "status_post"]] = [MAE_post, MSE_post, MIM_post, clone.is_fixpoint] | ||||||
|  |  | ||||||
|             # Finally take parent net {i} and finish it's training for comparison to clone development. |             # Finally take parent net {i} and finish it's training for comparison to clone development. | ||||||
|             for _ in range(self.epochs - 1): |             for _ in range(self.epochs - 1): | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| import copy | import copy | ||||||
| import random | import random | ||||||
| import os.path |  | ||||||
| import pickle |  | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
| from typing import Union | from typing import Union | ||||||
|  |  | ||||||
| @@ -13,7 +12,6 @@ from matplotlib import pyplot as plt | |||||||
| from torch.nn import functional as F | from torch.nn import functional as F | ||||||
| from tabulate import tabulate | from tabulate import tabulate | ||||||
|  |  | ||||||
| from experiments.helpers import check_folder, summary_fixpoint_percentage, summary_fixpoint_experiment |  | ||||||
| from functionalities_test import test_for_fixpoints, is_zero_fixpoint, is_divergent, is_identity_function | from functionalities_test import test_for_fixpoints, is_zero_fixpoint, is_divergent, is_identity_function | ||||||
| from network import Net | from network import Net | ||||||
| from visualization import plot_loss, bar_chart_fixpoints, plot_3d_soup, line_chart_fixpoints | from visualization import plot_loss, bar_chart_fixpoints, plot_3d_soup, line_chart_fixpoints | ||||||
| @@ -25,20 +23,6 @@ def prng(): | |||||||
|  |  | ||||||
| class SoupRobustnessExperiment: | class SoupRobustnessExperiment: | ||||||
|  |  | ||||||
|     @staticmethod |  | ||||||
|     def apply_noise(network, noise: int): |  | ||||||
|         """ Changing the weights of a network to values + noise """ |  | ||||||
|         for layer_id, layer_name in enumerate(network.state_dict()): |  | ||||||
|             for line_id, line_values in enumerate(network.state_dict()[layer_name]): |  | ||||||
|                 for weight_id, weight_value in enumerate(network.state_dict()[layer_name][line_id]): |  | ||||||
|                     # network.state_dict()[layer_name][line_id][weight_id] = weight_value + noise |  | ||||||
|                     if prng() < 0.5: |  | ||||||
|                         network.state_dict()[layer_name][line_id][weight_id] = weight_value + noise |  | ||||||
|                     else: |  | ||||||
|                         network.state_dict()[layer_name][line_id][weight_id] = weight_value - noise |  | ||||||
|  |  | ||||||
|         return network |  | ||||||
|  |  | ||||||
|     def __init__(self, population_size, net_i_size, net_h_size, net_o_size, learning_rate, attack_chance, |     def __init__(self, population_size, net_i_size, net_h_size, net_o_size, learning_rate, attack_chance, | ||||||
|                  train_nets, ST_steps, epochs, log_step_size, directory: Union[str, Path]): |                  train_nets, ST_steps, epochs, log_step_size, directory: Union[str, Path]): | ||||||
|         super().__init__() |         super().__init__() | ||||||
| @@ -146,8 +130,7 @@ class SoupRobustnessExperiment: | |||||||
|                     clone = Net(fixpoint.input_size, fixpoint.hidden_size, fixpoint.out_size, |                     clone = Net(fixpoint.input_size, fixpoint.hidden_size, fixpoint.out_size, | ||||||
|                                 f"{fixpoint.name}_clone_noise10e-{noise_level}") |                                 f"{fixpoint.name}_clone_noise10e-{noise_level}") | ||||||
|                     clone.load_state_dict(copy.deepcopy(fixpoint.state_dict())) |                     clone.load_state_dict(copy.deepcopy(fixpoint.state_dict())) | ||||||
|                     rand_noise = prng() * pow(10, -noise_level)  # n / 1 |                     clone = clone.apply_noise(pow(10, -noise_level)) | ||||||
|                     clone = self.apply_noise(clone, rand_noise) |  | ||||||
|  |  | ||||||
|                     while not is_zero_fixpoint(clone) and not is_divergent(clone): |                     while not is_zero_fixpoint(clone) and not is_divergent(clone): | ||||||
|                         if is_identity_function(clone): |                         if is_identity_function(clone): | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								network.py
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								network.py
									
									
									
									
									
								
							| @@ -1,5 +1,6 @@ | |||||||
| # from __future__ import annotations | # from __future__ import annotations | ||||||
| import copy | import copy | ||||||
|  | import random | ||||||
| from typing import Union | from typing import Union | ||||||
|  |  | ||||||
| import torch | import torch | ||||||
| @@ -9,7 +10,12 @@ import numpy as np | |||||||
| from torch import optim, Tensor | from torch import optim, Tensor | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def prng(): | ||||||
|  |     return random.random() | ||||||
|  |  | ||||||
|  |  | ||||||
| class Net(nn.Module): | class Net(nn.Module): | ||||||
|  |  | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def create_target_weights(input_weight_matrix: Tensor) -> Tensor: |     def create_target_weights(input_weight_matrix: Tensor) -> Tensor: | ||||||
|         """ Outputting a tensor with the target weights. """ |         """ Outputting a tensor with the target weights. """ | ||||||
| @@ -171,3 +177,16 @@ class Net(nn.Module): | |||||||
|         SA_steps = 1 |         SA_steps = 1 | ||||||
|  |  | ||||||
|         return other_net.apply_weights(my_evaluation) |         return other_net.apply_weights(my_evaluation) | ||||||
|  |  | ||||||
|  |     def apply_noise(self, noise_size: float): | ||||||
|  |         """ Changing the weights of a network to values + noise """ | ||||||
|  |         for layer_id, layer_name in enumerate(self.state_dict()): | ||||||
|  |             for line_id, line_values in enumerate(self.state_dict()[layer_name]): | ||||||
|  |                 for weight_id, weight_value in enumerate(self.state_dict()[layer_name][line_id]): | ||||||
|  |                     # network.state_dict()[layer_name][line_id][weight_id] = weight_value + noise | ||||||
|  |                     if prng() < 0.5: | ||||||
|  |                         self.state_dict()[layer_name][line_id][weight_id] = weight_value + noise_size * prng() | ||||||
|  |                     else: | ||||||
|  |                         self.state_dict()[layer_name][line_id][weight_id] = weight_value - noise_size * prng() | ||||||
|  |  | ||||||
|  |         return self | ||||||
|   | |||||||
| @@ -9,6 +9,9 @@ from sklearn.decomposition import PCA | |||||||
| import random | import random | ||||||
| import string | import string | ||||||
|  |  | ||||||
|  | from matplotlib import rcParams | ||||||
|  | rcParams['axes.labelpad'] = 20 | ||||||
|  |  | ||||||
|  |  | ||||||
| def plot_output(output): | def plot_output(output): | ||||||
|     """ Plotting the values of the final output """ |     """ Plotting the values of the final output """ | ||||||
| @@ -65,6 +68,7 @@ def bar_chart_fixpoints(fixpoint_counter: Dict, population_size: int, directory: | |||||||
|     plt.xticks(range(len(fixpoint_counter)), list(fixpoint_counter.keys())) |     plt.xticks(range(len(fixpoint_counter)), list(fixpoint_counter.keys())) | ||||||
|  |  | ||||||
|     directory = Path(directory) |     directory = Path(directory) | ||||||
|  |     directory.mkdir(parents=True, exist_ok=True) | ||||||
|     filename = f"{str(population_size)}_nets_fixpoints_barchart.png" |     filename = f"{str(population_size)}_nets_fixpoints_barchart.png" | ||||||
|     filepath = directory / filename |     filepath = directory / filename | ||||||
|     plt.savefig(str(filepath)) |     plt.savefig(str(filepath)) | ||||||
| @@ -139,19 +143,19 @@ def plot_3d(matrices_weights_history, directory: Union[str, Path], population_si | |||||||
|  |  | ||||||
|     #steps = mpatches.Patch(color="white", label=f"{z_axis_legend}: {len(matrices_weights_history)} steps") |     #steps = mpatches.Patch(color="white", label=f"{z_axis_legend}: {len(matrices_weights_history)} steps") | ||||||
|     population_size = mpatches.Patch(color="white", label=f"Population: {population_size} networks") |     population_size = mpatches.Patch(color="white", label=f"Population: {population_size} networks") | ||||||
|  |     if False: | ||||||
|     if z_axis_legend == "Self-application": |         if z_axis_legend == "Self-application": | ||||||
|         if is_trained == '_trained': |             if is_trained == '_trained': | ||||||
|             trained = mpatches.Patch(color="white", label=f"Trained: true") |                 trained = mpatches.Patch(color="white", label=f"Trained: true") | ||||||
|  |             else: | ||||||
|  |                 trained = mpatches.Patch(color="white", label=f"Trained: false") | ||||||
|  |             ax.legend(handles=[population_size, trained]) | ||||||
|         else: |         else: | ||||||
|             trained = mpatches.Patch(color="white", label=f"Trained: false") |             ax.legend(handles=[population_size]) | ||||||
|         ax.legend(handles=[population_size, trained]) |  | ||||||
|     else: |  | ||||||
|         ax.legend(handles=[population_size]) |  | ||||||
|  |  | ||||||
|     ax.set_title(f"PCA Transformed Weight Trajectories") |     ax.set_title(f"PCA Transformed Weight Trajectories") | ||||||
|     ax.set_xlabel("PCA Transformed X-Axis") |     # ax.set_xlabel("PCA Transformed X-Axis") | ||||||
|     ax.set_ylabel("PCA Transformed Y-Axis") |     # ax.set_ylabel("PCA Transformed Y-Axis") | ||||||
|     ax.set_zlabel(f"Self Training Steps") |     ax.set_zlabel(f"Self Training Steps") | ||||||
|  |  | ||||||
|     # FIXME: Replace this kind of operation with pathlib.Path() object interactions |     # FIXME: Replace this kind of operation with pathlib.Path() object interactions | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 steffen-illium
					steffen-illium