51 lines
2.0 KiB
Python
51 lines
2.0 KiB
Python
import random
|
|
|
|
from tqdm import tqdm
|
|
|
|
from experiments.soup_exp import SoupExperiment
|
|
from functionalities_test import test_for_fixpoints
|
|
|
|
|
|
class MeltingSoupExperiment(SoupExperiment):
|
|
|
|
def __init__(self, melt_chance, *args, keep_population_size=True, **kwargs):
|
|
super(MeltingSoupExperiment, self).__init__(*args, **kwargs)
|
|
self.keep_population_size = keep_population_size
|
|
self.melt_chance = melt_chance
|
|
|
|
def population_melt(self):
|
|
# A network melting with another network by a given percentage
|
|
if random.randint(1, 100) <= self.melt_chance:
|
|
random_net1_idx, random_net2_idx, destroy_idx = random.sample(range(self.population_size), 3)
|
|
random_net1 = self.population[random_net1_idx]
|
|
random_net2 = self.population[random_net2_idx]
|
|
print(f"\n Melt: {random_net1.name} -> {random_net2.name}")
|
|
melted_network = random_net1.melt(random_net2)
|
|
if self.keep_population_size:
|
|
del self.population[destroy_idx]
|
|
self.population.append(melted_network)
|
|
|
|
def evolve(self):
|
|
""" Evolving consists of attacking, melting & self-training. """
|
|
|
|
loop_epochs = tqdm(range(self.epochs))
|
|
for i in loop_epochs:
|
|
loop_epochs.set_description("Evolving soup %s" % i)
|
|
|
|
self.population_attack()
|
|
|
|
self.population_melt()
|
|
|
|
self.population_self_train()
|
|
|
|
# Testing for fixpoints after each batch of ST steps to see relevant data
|
|
if i % self.ST_steps == 0:
|
|
test_for_fixpoints(self.fixpoint_counters, self.population)
|
|
fixpoints_percentage = round(self.fixpoint_counters["identity_func"] / self.population_size, 1)
|
|
self.fixpoint_counters_history.append(fixpoints_percentage)
|
|
|
|
# Resetting the fixpoint counter. Last iteration not to be reset -
|
|
# it is important for the bar_chart_fixpoints().
|
|
if i < self.epochs:
|
|
self.reset_fixpoint_counters()
|