2021-06-25 10:25:25 +02:00

282 lines
10 KiB
Python

from pathlib import Path
from typing import List, Dict, Union
from tqdm import tqdm
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import numpy as np
from sklearn.decomposition import PCA
import random
import string
from matplotlib import rcParams
rcParams['axes.labelpad'] = 20
def plot_output(output):
""" Plotting the values of the final output """
plt.figure()
plt.imshow(output)
plt.colorbar()
plt.show()
def plot_loss(loss_array, directory: Union[str, Path], batch_size=1):
""" Plotting the evolution of the loss function."""
fig = plt.figure()
fig.set_figheight(10)
fig.set_figwidth(12)
for i in range(len(loss_array)):
plt.plot(loss_array[i], label=f"Last loss value: {str(loss_array[i][len(loss_array[i])-1])}")
plt.legend()
plt.xlabel("Epochs")
plt.ylabel("Loss")
directory = Path(directory)
filename = "nets_loss_function.png"
file_path = directory / filename
plt.savefig(str(file_path))
plt.clf()
def bar_chart_fixpoints(fixpoint_counter: Dict, population_size: int, directory: Union[str, Path], learning_rate: float,
exp_details: str, source_check=None):
""" Plotting the number of fixpoints in a barchart. """
fig = plt.figure()
fig.set_figheight(10)
fig.set_figwidth(12)
legend_population_size = mpatches.Patch(color="white", label=f"No. of nets: {str(population_size)}")
learning_rate = mpatches.Patch(color="white", label=f"Learning rate: {str(learning_rate)}")
epochs = mpatches.Patch(color="white", label=f"{str(exp_details)}")
if source_check == "summary":
plt.legend(handles=[legend_population_size, learning_rate, epochs])
plt.ylabel("No. of nets/run")
plt.title("Summary: avg. amount of fixpoints/run")
else:
plt.legend(handles=[legend_population_size, learning_rate, epochs])
plt.ylabel("Number of networks")
plt.title("Fixpoint count")
plt.bar(range(len(fixpoint_counter)), list(fixpoint_counter.values()), align='center')
plt.xticks(range(len(fixpoint_counter)), list(fixpoint_counter.keys()))
directory = Path(directory)
directory.mkdir(parents=True, exist_ok=True)
filename = f"{str(population_size)}_nets_fixpoints_barchart.png"
filepath = directory / filename
plt.savefig(str(filepath))
plt.clf()
def plot_3d(matrices_weights_history, directory: Union[str, Path], population_size, z_axis_legend,
exp_name="experiment", is_trained="", batch_size=1, plot_pca_together=False, nets_array=None):
""" Plotting the the weights of the nets in a 3d form using principal component analysis (PCA) """
fig = plt.figure()
fig.set_figheight(10)
fig.set_figwidth(12)
pca = PCA(n_components=2, whiten=True)
ax = plt.axes(projection='3d')
if plot_pca_together:
weight_histories = []
start_times = []
for wh, st in matrices_weights_history:
start_times.append(st)
wm = np.array(wh)
n, x, y = wm.shape
wm = wm.reshape(n, x * y)
weight_histories.append(wm)
weight_data = np.array(weight_histories)
n, x, y = weight_data.shape
weight_data = weight_data.reshape(n*x, y)
pca.fit(weight_data)
weight_data_pca = pca.transform(weight_data)
for transformed_trajectory, start_time in zip(np.split(weight_data_pca, n), start_times):
start_log_time = int(start_time / batch_size)
xdata = transformed_trajectory[start_log_time:, 0]
ydata = transformed_trajectory[start_log_time:, 1]
zdata = np.arange(start_time, len(ydata)*batch_size+start_time, batch_size).tolist()
ax.plot3D(xdata, ydata, zdata, label=f"net")
ax.scatter(xdata, ydata, zdata, s=7)
else:
loop_matrices_weights_history = tqdm(range(len(matrices_weights_history)))
for i in loop_matrices_weights_history:
loop_matrices_weights_history.set_description("Plotting weights 3D PCA %s" % i)
weight_matrix, start_time = matrices_weights_history[i]
weight_matrix = np.array(weight_matrix)
n, x, y = weight_matrix.shape
weight_matrix = weight_matrix.reshape(n, x * y)
pca.fit(weight_matrix)
weight_matrix_pca = pca.transform(weight_matrix)
xdata, ydata = [], []
start_log_time = int(start_time / 10)
for j in range(start_log_time, len(weight_matrix_pca)):
xdata.append(weight_matrix_pca[j][0])
ydata.append(weight_matrix_pca[j][1])
zdata = np.arange(start_time, len(ydata)*batch_size+start_time, batch_size)
ax.plot3D(xdata, ydata, zdata, label=f"net {i}", c="b")
if "parent" in nets_array[i].name:
ax.scatter(np.asarray(xdata), np.asarray(ydata), zdata, s=3, c="b")
else:
ax.scatter(np.asarray(xdata), np.asarray(ydata), zdata, s=3)
#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")
if False:
if z_axis_legend == "Self-application":
if is_trained == '_trained':
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:
ax.legend(handles=[population_size])
ax.set_title(f"PCA Transformed Weight Trajectories")
# ax.set_xlabel("PCA Transformed X-Axis")
# ax.set_ylabel("PCA Transformed Y-Axis")
ax.set_zlabel(f"Self Training Steps")
# FIXME: Replace this kind of operation with pathlib.Path() object interactions
directory = Path(directory)
directory.mkdir(parents=True, exist_ok=True)
filename = f"{exp_name}{is_trained}.png"
filepath = directory / filename
if filepath.exists():
letters = string.ascii_lowercase
random_letters = ''.join(random.choice(letters) for _ in range(5))
plt.savefig(f"{filepath.stem}_{random_letters}.png")
else:
plt.savefig(str(filepath))
plt.show()
def plot_3d_self_train(nets_array: List, exp_name: str, directory: Union[str, Path], batch_size: int, plot_pca_together: bool):
""" Plotting the evolution of the weights in a 3D space when doing self training. """
matrices_weights_history = []
loop_nets_array = tqdm(range(len(nets_array)))
for i in loop_nets_array:
loop_nets_array.set_description("Creating ST weights history %s" % i)
matrices_weights_history.append((nets_array[i].s_train_weights_history, nets_array[i].start_time))
z_axis_legend = "epochs"
return plot_3d(matrices_weights_history, directory, len(nets_array), z_axis_legend, exp_name, "", batch_size,
plot_pca_together=plot_pca_together, nets_array=nets_array)
def plot_3d_self_application(nets_array: List, exp_name: str, directory_name: Union[str, Path], batch_size: int) -> None:
""" Plotting the evolution of the weights in a 3D space when doing self application. """
matrices_weights_history = []
loop_nets_array = tqdm(range(len(nets_array)))
for i in loop_nets_array:
loop_nets_array.set_description("Creating SA weights history %s" % i)
matrices_weights_history.append( (nets_array[i].s_application_weights_history, nets_array[i].start_time) )
if nets_array[i].trained:
is_trained = "_trained"
else:
is_trained = "_not_trained"
# Fixme: Are the both following lines on the correct intendation? -> Value of "is_trained" changes multiple times!
z_axis_legend = "epochs"
plot_3d(matrices_weights_history, directory_name, len(nets_array), z_axis_legend, exp_name, is_trained, batch_size)
def plot_3d_soup(nets_list, exp_name, directory: Union[str, Path]):
""" Plotting the evolution of the weights in a 3D space for the soup environment. """
# This batch size is not relevant for soups. To not affect the number of epochs shown in the 3D plot,
# will send forward the number "1" for batch size with the variable <irrelevant_batch_size>.
irrelevant_batch_size = 1
# plot_3d_self_train(nets_list, exp_name, directory, irrelevant_batch_size, False)
plot_3d_self_train(nets_list, exp_name, directory, 10, True)
def line_chart_fixpoints(fixpoint_counters_history: list, epochs: int, ST_steps_between_SA: int,
SA_steps, directory: Union[str, Path], population_size: int):
""" Plotting the percentage of fixpoints after each iteration of SA & ST steps. """
fig = plt.figure()
fig.set_figheight(10)
fig.set_figwidth(12)
ST_steps_per_SA = np.arange(0, ST_steps_between_SA * epochs, ST_steps_between_SA).tolist()
legend_population_size = mpatches.Patch(color="white", label=f"No. of nets: {str(population_size)}")
legend_SA_steps = mpatches.Patch(color="white", label=f"SA_steps: {str(SA_steps)}")
legend_SA_and_ST_runs = mpatches.Patch(color="white", label=f"SA_and_ST_runs: {str(epochs)}")
legend_ST_steps_between_SA = mpatches.Patch(color="white", label=f"ST_steps_between_SA: {str(ST_steps_between_SA)}")
plt.legend(handles=[legend_population_size, legend_SA_and_ST_runs, legend_SA_steps, legend_ST_steps_between_SA])
plt.xlabel("Epochs")
plt.ylabel("Percentage")
plt.title("Percentage of fixpoints")
plt.plot(ST_steps_per_SA, fixpoint_counters_history, color="green", marker="o")
directory = Path(directory)
filename = f"{str(population_size)}_nets_fixpoints_linechart.png"
filepath = directory / filename
plt.savefig(str(filepath))
plt.clf()
def box_plot(data, directory: Union[str, Path], population_size):
fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(10, 7))
# ax = fig.add_axes([0, 0, 1, 1])
plt.title("Fixpoint variation")
plt.xlabel("Amount of noise")
plt.ylabel("Steps")
# data = numpy.array(data)
# ax.boxplot(data)
axs[1].boxplot(data)
axs[1].set_title('Box plot')
directory = Path(directory)
filename = f"{str(population_size)}_nets_fixpoints_barchart.png"
filepath = directory / filename
plt.savefig(str(filepath))
plt.clf()
def write_file(text, directory: Union[str, Path]):
directory = Path(directory)
filepath = directory / 'experiment.txt'
with filepath.open('w+') as f:
f.write(text)
f.close()