diff --git a/code/experiment.py b/code/experiment.py index 6ef0506..9a96688 100644 --- a/code/experiment.py +++ b/code/experiment.py @@ -4,16 +4,22 @@ import dill from tqdm import tqdm import copy +from tensorflow.python.keras import backend as K + from abc import ABC, abstractmethod -class _BaseExperiment(ABC): +class Experiment(ABC): @staticmethod def from_dill(path): with open(path, "rb") as dill_file: return dill.load(dill_file) + @staticmethod + def reset_model(): + K.clear_session() + def __init__(self, name=None, ident=None): self.experiment_id = f'{ident or ""}_{time.time()}' self.experiment_name = name or 'unnamed_experiment' @@ -59,22 +65,27 @@ class _BaseExperiment(ABC): dill.dump(value, dill_file) @abstractmethod - def run_net(self, network, iterations, run_id=0): + def run_net(self, net, trains_per_application=100, step_limit=100, run_id=0, **kwargs): raise NotImplementedError pass + def run_exp(self, network_generator, exp_iterations, prints=False, **kwargs): + # INFO Run_ID needs to be more than 0, so that exp stores the trajectories! + for run_id in range(exp_iterations): + network = network_generator() + self.run_net(network, 100, run_id=run_id + 1, **kwargs) + self.historical_particles[run_id] = network + if prints: + print("Fixpoint? " + str(network.is_fixpoint())) + self.reset_model() -class Experiment(_BaseExperiment): - - def __init__(self, **kwargs): - super(Experiment, self).__init__(**kwargs) - pass - - def run_net(self, network, iterations, run_id=0): - pass + def reset_all(self): + self.reset_model() class FixpointExperiment(Experiment): + if kwargs.get('logging', False): + self.log(self.counters) def __init__(self, **kwargs): kwargs['name'] = self.__class__.__name__ if 'name' not in kwargs else kwargs['name'] @@ -82,7 +93,7 @@ class FixpointExperiment(Experiment): self.counters = dict(divergent=0, fix_zero=0, fix_other=0, fix_sec=0, other=0) self.interesting_fixpoints = [] - def run_net(self, net, step_limit=100, run_id=0): + def run_net(self, net, step_limit=100, run_id=0, **kwargs): i = 0 while i < step_limit and not net.is_diverged() and not net.is_fixpoint(): net.self_attack() @@ -105,31 +116,56 @@ class FixpointExperiment(Experiment): else: self.counters['other'] += 1 + def reset_counters(self): + for key in self.counters.keys(): + self.counters[key] = 0 + return True + + def reset_all(self): + super(FixpointExperiment, self).reset_all() + self.reset_counters() + class MixedFixpointExperiment(FixpointExperiment): - def run_net(self, net, trains_per_application=100, step_limit=100, run_id=0): - - i = 0 - while i < step_limit and not net.is_diverged() and not net.is_fixpoint(): + def run_net(self, net, trains_per_application=100, step_limit=100, run_id=0, **kwargs): + for i in range(step_limit): + if net.is_diverged() or net.is_fixpoint(): + break net.self_attack() with tqdm(postfix=["Loss", dict(value=0)]) as bar: for _ in range(trains_per_application): loss = net.compiled().train() bar.postfix[1]["value"] = loss bar.update() - i += 1 if run_id: net.save_state() self.count(net) class SoupExperiment(Experiment): - pass + + def __init__(self, **kwargs): + super(SoupExperiment, self).__init__(name=kwargs.get('name', self.__class__.__name__)) + + def run_exp(self, network_generator, exp_iterations, soup_generator=None, soup_iterations=0, prints=False): + for i in range(soup_iterations): + soup = soup_generator() + soup.seed() + for _ in tqdm(exp_iterations): + soup.evolve() + self.log(soup.count()) + self.save(soup=soup.without_particles()) + + def run_net(self, net, trains_per_application=100, step_limit=100, run_id=0, **kwargs): + raise NotImplementedError + pass class IdentLearningExperiment(Experiment): def __init__(self): super(IdentLearningExperiment, self).__init__(name=self.__class__.__name__) - pass + + def run_net(self, net, trains_per_application=100, step_limit=100, run_id=0, **kwargs): + pass diff --git a/code/network.py b/code/network.py index 4f1ba1a..66a986e 100644 --- a/code/network.py +++ b/code/network.py @@ -529,57 +529,46 @@ class TrainingNeuralNetworkDecorator: if __name__ == '__main__': - def run_exp(network, prints=False): - # INFO Run_ID needs to be more than 0, so that exp stores the trajectories! - exp.run_net(network, 100, run_id=run_id + 1) - exp.historical_particles[run_id] = network - if prints: - print("Fixpoint? " + str(network.is_fixpoint())) - print("Loss " + str(loss)) - if False: + if True: # WeightWise Neural Network + net_generator = ParticleDecorator(WeightwiseNeuralNetwork(width=2, depth=2).with_keras_params(activation='linear')) with FixpointExperiment() as exp: - for run_id in tqdm(range(10)): - net = ParticleDecorator( - WeightwiseNeuralNetwork(width=2, depth=2).with_keras_params(activation='linear')) - exp.run_exp(net) - K.clear_session() - exp.log(exp.counters) + exp.run_exp(net_generator, 10, logging=True) + exp.reset_all() if False: # Aggregating Neural Network + net_generator = ParticleDecorator(AggregatingNeuralNetwork(aggregates=4, width=2, depth=2).with_keras_params()) with FixpointExperiment() as exp: - for run_id in tqdm(range(10)): - net = ParticleDecorator( - AggregatingNeuralNetwork(aggregates=4, width=2, depth=2).with_keras_params()) - run_exp(net) - K.clear_session() - exp.log(exp.counters) + exp.run_exp(net_generator, 10, logging=True) + + exp.reset_all() if False: # FFT Aggregation + net_generator = lambda: ParticleDecorator( + AggregatingNeuralNetwork( + aggregates=4, width=2, depth=2, aggregator=AggregatingNeuralNetwork.aggregate_fft + ).with_keras_params(activation='linear')) with FixpointExperiment() as exp: for run_id in tqdm(range(10)): - net = ParticleDecorator( - AggregatingNeuralNetwork( - aggregates=4, width=2, depth=2, aggregator=AggregatingNeuralNetwork.aggregate_fft - ).with_keras_params(activation='linear')) - run_exp(net) - K.clear_session() - exp.log(exp.counters) + exp.run_exp(net_generator, 1) + exp.log(exp.counters) + exp.reset_model() + exp.reset_all() if True: # ok so this works quite realiably - with FixpointExperiment() as exp: - run_count = 1000 - net = TrainingNeuralNetworkDecorator(ParticleDecorator(WeightwiseNeuralNetwork(width=2, depth=2))) - net.with_params(epsilon=0.0001).with_keras_params(optimizer='sgd') + run_count = 10000 + net_generator = TrainingNeuralNetworkDecorator( + ParticleDecorator(WeightwiseNeuralNetwork(width=2, depth=2)) + ).with_params(epsilon=0.0001).with_keras_params(optimizer='sgd') + with MixedFixpointExperiment() as exp: for run_id in tqdm(range(run_count+1)): - net.compiled() - loss = net.train(epoch=run_id) + exp.run_exp(net_generator, 1) if run_id % 100 == 0: - run_exp(net) + exp.run_net(net_generator, 1) K.clear_session() if False: diff --git a/code/soup.py b/code/soup.py index bf11a9d..e38853b 100644 --- a/code/soup.py +++ b/code/soup.py @@ -109,39 +109,29 @@ class Soup(object): if __name__ == '__main__': - if False: - with SoupExperiment() as exp: - for run_id in range(1): - net_generator = lambda: WeightwiseNeuralNetwork(2, 2).with_keras_params(activation='linear').with_params() - # net_generator = lambda: FFTNeuralNetwork(2, 2).with_keras_params(activation='linear').with_params() - # net_generator = lambda: AggregatingNeuralNetwork(4, 2, 2).with_keras_params(activation='sigmoid')\ - # .with_params(shuffler=AggregatingNeuralNetwork.shuffle_random) - # net_generator = lambda: RecurrentNeuralNetwork(2, 2).with_keras_params(activation='linear').with_params() - soup = Soup(100, net_generator).with_params(remove_divergent=True, remove_zero=True) - soup.seed() - for _ in tqdm(range(1000)): - soup.evolve() - exp.log(soup.count()) - exp.save(soup=soup.without_particles()) + if True: + net_generator = lambda: WeightwiseNeuralNetwork(2, 2).with_keras_params(activation='linear').with_params() + soup_generator = Soup(100, net_generator).with_params(remove_divergent=True, remove_zero=True) + exp = SoupExperiment() + exp.run_exp(net_generator, 1000, soup_generator, 1, False) + + # net_generator = lambda: FFTNeuralNetwork(2, 2).with_keras_params(activation='linear').with_params() + # net_generator = lambda: AggregatingNeuralNetwork(4, 2, 2).with_keras_params(activation='sigmoid')\ + # .with_params(shuffler=AggregatingNeuralNetwork.shuffle_random) + # net_generator = lambda: RecurrentNeuralNetwork(2, 2).with_keras_params(activation='linear').with_params() if True: - with SoupExperiment("soup") as exp: - for run_id in range(1): - net_generator = lambda: TrainingNeuralNetworkDecorator(WeightwiseNeuralNetwork(2, 2))\ - .with_keras_params(activation='linear').with_params(epsilon=0.0001) - # net_generator = lambda: TrainingNeuralNetworkDecorator(AggregatingNeuralNetwork(4, 2, 2)) - # .with_keras_params(activation='linear')\ - # .with_params(shuffler=AggregatingNeuralNetwork.shuffle_random) - # net_generator = lambda: TrainingNeuralNetworkDecorator(FFTNeuralNetwork(4, 2, 2))\ - # .with_keras_params(activation='linear')\ - # .with_params(shuffler=AggregatingNeuralNetwork.shuffle_random) - # net_generator = lambda: RecurrentNeuralNetwork(2, 2).with_keras_params(activation='linear').with_params() - soup = Soup(100, net_generator).with_params(remove_divergent=True, remove_zero=True, train=20) - soup.seed() - for _ in tqdm(range(100)): - soup.evolve() - exp.log(soup.count()) - # you can access soup.historical_particles[particle_uid].states[time_step]['loss'] - # or soup.historical_particles[particle_uid].states[time_step]['weights'] - # from soup.dill - exp.save(soup=soup.without_particles()) + net_generator = lambda: TrainingNeuralNetworkDecorator(WeightwiseNeuralNetwork(2, 2)) \ + .with_keras_params(activation='linear').with_params(epsilon=0.0001) + soup_generator = lambda: Soup(100, net_generator).with_params(remove_divergent=True, remove_zero=True, train=20) + exp = SoupExperiment(name="soup") + + exp.run_exp(net_generator, 100, soup_generator, 1, False) + + # net_generator = lambda: TrainingNeuralNetworkDecorator(AggregatingNeuralNetwork(4, 2, 2)) + # .with_keras_params(activation='linear')\ + # .with_params(shuffler=AggregatingNeuralNetwork.shuffle_random) + # net_generator = lambda: TrainingNeuralNetworkDecorator(FFTNeuralNetwork(4, 2, 2))\ + # .with_keras_params(activation='linear')\ + # .with_params(shuffler=AggregatingNeuralNetwork.shuffle_random) + # net_generator = lambda: RecurrentNeuralNetwork(2, 2).with_keras_params(activation='linear').with_params()