def test_regression_case(self): config = create_configuration(filename='/regression-siso.json') config.parallel_evaluation = False genome = Genome(key=1) genome.create_random_genome() dataset = get_dataset(config.dataset, train_percentage=config.train_percentage, testing=True) n_samples = 3 network = ComplexStochasticNetwork(genome=genome) x, y_true, output_distribution = calculate_prediction_distribution( network, dataset=dataset, problem_type=config.problem_type, is_testing=True, n_samples=n_samples, use_sigmoid=False) expected_output_distribution_shape = [ len(y_true), n_samples, config.n_output ] self.assertEqual(list(output_distribution.shape), expected_output_distribution_shape)
def _calculate_possible_inputs_when_adding_connection( genome: Genome, out_node_key: int, config: BaseConfiguration): # all nodes possible_input_keys_set = set(genome.node_genes.keys()).union( set(genome.get_input_nodes_keys())) # no connection between two output nodes possible_input_keys_set -= set(genome.get_output_nodes_keys()) if config.feed_forward: # avoid self-recurrency possible_input_keys_set -= {out_node_key} # pass # REMOVE POSSIBLE CONNECTIONS possible_connection_set = set( itertools.product(list(possible_input_keys_set), [out_node_key])) # remove already existing connections: don't duplicate connections possible_connection_set -= set(genome.connection_genes.keys()) # remove possible connections that introduce cycles possible_connection_set = \ ArchitectureMutation._remove_connection_that_introduces_cycles(genome=genome, possible_connection_set=possible_connection_set) # # remove possible connections that introduce multihop jumps # possible_connection_set = \ # Mutation._remove_connection_that_introduces_multihop_jumps(genome=genome, # possible_connection_set=possible_connection_set) if len(possible_connection_set) == 0: return [] possible_input_keys_set = list(zip(*list(possible_connection_set)))[0] return possible_input_keys_set
def generate_genome_with_hidden_units(n_input, n_output, n_hidden=3): # nodes node_genes = {} for i in range(n_output + n_hidden): node_genes = add_node(node_genes, key=i) # connections # input to hidden connection_genes = {} input_hidden_tuples = list( product(list(range(-1, -n_input - 1, -1)), list(range(n_output, n_output + n_hidden)))) for tuple_ in input_hidden_tuples: connection_genes = add_connection(connection_genes, key=tuple_) # hidden to output hidden_output_tuples = list( product(list(range(n_output, n_output + n_hidden)), list(range(0, n_output)))) for tuple_ in hidden_output_tuples: connection_genes = add_connection(connection_genes, key=tuple_) # initialize genome genome = Genome(key=1) genome.node_genes = node_genes genome.connection_genes = connection_genes return genome
def plot_genome_network(genome: Genome, filename='./network.png', view=True): return plot_network(nodes=list(genome.node_genes.keys()), edges=list(genome.connection_genes.keys()), input_nodes=genome.get_input_nodes_keys(), output_nodes=genome.get_output_nodes_keys(), filename=filename, view=view)
def initialze_network(self, **kwargs): number_hidden_nodes = kwargs['number_hidden_nodes'] number_genes = kwargs['number_genes'] new_weight_range = kwargs['new_weight_range'] genome = Genome() genes = [] genome.allocate_hidden_nodes(number_hidden_nodes) self.input_node1 = genome.add_input_node() self.input_node2 = genome.add_input_node() self.output_node = genome.add_output_node() genes.append( Gene(0, self.output_node, new_weight_range - 2 * new_weight_range * random.random())) genes.append( Gene(self.input_node1, self.output_node, new_weight_range - 2 * new_weight_range * random.random())) genes.append( Gene(self.input_node2, self.output_node, new_weight_range - 2 * new_weight_range * random.random())) genome.set_genes(genes) genome.allocate_genes(number_genes) return Network(genome)
def test_mate(self): Genome.reset() for pair in Genome.GENE_INNOVATION_PAIRS: print(pair[0]) print(pair[1]) genome_parent_1 = TestGenome() genome_parent_2 = TestGenome() genome_child = TestGenome() network_parent_1 = Network(genome_parent_1) network_parent_2 = Network(genome_parent_2) network_child = Network(genome_child) genome_parent_1.add_new_node(0) genome_parent_2.add_new_node(1) genome_child.add_new_node(2) Genome.mate(genome_parent_1, genome_parent_2, genome_child) network_child.set_up(genome_child) for i in range(-1, -4, -1): self.assertTrue(network_child.genome.genes[i].enabled) self.assertTrue(network_child.genome.genes[i].used) self.assertEqual(network_child.genome.genes[3].innovation, 1) self.assertEqual(network_child.genome.genes[4].innovation, 2) self.assertEqual(network_child.genome.genes[5].innovation, 3)
def test_execute(self): Genome.reset() network = XORNetwork() value_11 = 1 value_12 = 0 value_21 = 0 value_22 = 1 value_31 = 0 value_32 = 0 value_41 = 1 value_42 = 1 input_values_node_ids1 = [(value_11, network.input_node_id_1), (value_12, network.input_node_id_2)] input_values_node_ids2 = [(value_21, network.input_node_id_1), (value_22, network.input_node_id_2)] input_values_node_ids3 = [(value_31, network.input_node_id_1), (value_32, network.input_node_id_2)] input_values_node_ids4 = [(value_41, network.input_node_id_1), (value_42, network.input_node_id_2)] results1 = network.execute(input_values_node_ids1) results2 = network.execute(input_values_node_ids2) results3 = network.execute(input_values_node_ids3) results4 = network.execute(input_values_node_ids4) self.assertEqual(int(value_11 != value_12), round(results1[5])) self.assertEqual(int(value_21 != value_22), round(results2[5])) self.assertEqual(int(value_31 != value_32), round(results3[5])) self.assertEqual(int(value_41 != value_42), round(results4[5]))
def test_add_node(self): Genome.reset() genome = Genome() genome.allocate_hidden_nodes(3) input_node_id_1 = genome.add_input_node() input_node_id_2 = genome.add_input_node() hidden_node_id_1 = genome.add_hidden_node() hidden_node_id_2 = genome.add_hidden_node() hidden_node_id_3 = genome.add_hidden_node() output_node_id_1 = genome.add_output_node() output_node_id_2 = genome.add_output_node() #Inserted check self.assertTrue(input_node_id_1 in range(len(genome.nodes))) self.assertTrue(input_node_id_2 in range(len(genome.nodes))) self.assertTrue(hidden_node_id_1 in range(len(genome.nodes))) self.assertTrue(hidden_node_id_2 in range(len(genome.nodes))) self.assertTrue(hidden_node_id_3 in range(len(genome.nodes))) self.assertTrue(output_node_id_1 in range(len(genome.nodes))) self.assertTrue(output_node_id_2 in range(len(genome.nodes))) #Added to output ndoes check self.assertFalse(input_node_id_1 in genome.output_nodes_ids) self.assertFalse(input_node_id_2 in genome.output_nodes_ids) self.assertFalse(hidden_node_id_1 in genome.output_nodes_ids) self.assertFalse(hidden_node_id_2 in genome.output_nodes_ids) self.assertFalse(hidden_node_id_3 in genome.output_nodes_ids) self.assertTrue(output_node_id_1 in genome.output_nodes_ids) self.assertTrue(output_node_id_2 in genome.output_nodes_ids) #Type set check self.assertEqual(genome.nodes[input_node_id_1].type, Type.INPUT) self.assertEqual(genome.nodes[input_node_id_2].type, Type.INPUT) self.assertEqual(genome.nodes[hidden_node_id_1].type, Type.HIDDEN) self.assertEqual(genome.nodes[hidden_node_id_2].type, Type.HIDDEN) self.assertEqual(genome.nodes[hidden_node_id_3].type, Type.HIDDEN) self.assertEqual(genome.nodes[output_node_id_1].type, Type.OUTPUT) self.assertEqual(genome.nodes[output_node_id_2].type, Type.OUTPUT) #ID set check self.assertEqual(genome.nodes[input_node_id_1].id, input_node_id_1) self.assertEqual(genome.nodes[input_node_id_2].id, input_node_id_2) self.assertEqual(genome.nodes[hidden_node_id_1].id, hidden_node_id_1) self.assertEqual(genome.nodes[hidden_node_id_2].id, hidden_node_id_2) self.assertEqual(genome.nodes[hidden_node_id_3].id, hidden_node_id_3) self.assertEqual(genome.nodes[output_node_id_1].id, output_node_id_1) self.assertEqual(genome.nodes[output_node_id_2].id, output_node_id_2)
def generate_genome_given_graph(graph, connection_weights): genome = Genome(key='foo') unique_node_keys = [] input_nodes = [] for connection in graph: for node_key in connection: if node_key not in unique_node_keys: unique_node_keys.append(node_key) if node_key < 0: input_nodes.append(node_key) input_nodes = set(input_nodes) unique_node_keys = list( set(unique_node_keys + genome.get_output_nodes_keys()) - input_nodes) nodes = {} for node_key in unique_node_keys: node = NodeGene(key=node_key).random_initialization() node.set_mean(0) node.set_std(STD) nodes[node_key] = node connections = {} for connection_key, weight in zip(graph, connection_weights): connection = ConnectionGene(key=connection_key) connection.set_mean(weight) connection.set_std(STD) connections[connection_key] = connection genome.connection_genes = connections genome.node_genes = nodes return genome
def create(self): genomes = [] for i in range(self.genome_params.population_size): g = Genome(self.genome_params) g.connect() genomes.append(g) return genomes
def breed(self): c1 = self.clients.select_random() c2 = self.clients.select_random() if c1.score > c2.score: return Genome.crossover(c1.genome, c2.genome) elif c1.score < c2.score: return Genome.crossover(c2.genome, c1.genome) else: return Genome.crossover(c1.genome, c2.genome, equal=True)
def setUp(self): self.config = Config('../tests/conf_tester.conf') NodeGene.counter = 1 LinkGene.innovation_counter = 0 self.test_node_genes = [NodeGene(node_type='INPUT',), NodeGene(node_type='INPUT'), NodeGene(node_type='OUTPUT'), NodeGene(node_type='OUTPUT')] self.test_link_genes = [LinkGene(2, 3, weight=1), LinkGene(1, 3, weight=1)] self.genome = Genome(self.config, node_genes=self.test_node_genes, link_genes=self.test_link_genes)
def generate_genome_without_hidden_units(): # output nodes node_genes = {} node_genes = add_node(node_genes, key=0) connection_genes = {} connection_genes = add_connection(connection_genes, key=(-1, 0)) connection_genes = add_connection(connection_genes, key=(-2, 0)) genome = Genome(key=1) genome.node_genes = node_genes genome.connection_genes = connection_genes return genome
def initialize_population(self): population = {} for i in range(self.pop_size): key = next(self.genome_indexer) if self.config.initial_genome_filename is None: genome = Genome(key=key) genome.create_random_genome() else: filename = self.config.initial_genome_filename genome = Genome.create_from_file(filename=filename, key=key) population[key] = genome self.ancestors[key] = tuple() return population
def test_classification_case(self): config = create_configuration(filename='/classification-miso.json') genome = Genome(key=1) genome.create_random_genome() n_samples = 5 estimator = PredictionDistributionEstimatorGenome(genome=genome, config=config, testing=True, n_samples=n_samples)\ .estimate() \ .enrich_with_dispersion_quantile() \ .calculate_metrics_by_dispersion_quantile() results = estimator.results self.assertTrue(isinstance(results, pd.DataFrame))
def _remove_connection_that_introduces_multihop_jumps( genome: Genome, possible_connection_set: set) -> set: output_node_keys = genome.get_output_nodes_keys() input_node_keys = genome.get_input_nodes_keys() connections_to_remove = [] for connection in possible_connection_set: connections = list(genome.connection_genes.keys()) + [connection] if adds_multihop_jump(connections=connections, output_node_keys=output_node_keys, input_node_keys=input_node_keys): connections_to_remove.append(connection) possible_connection_set -= set(connections_to_remove) return possible_connection_set
def test_distance(self): Genome.reset() genome1 = TestGenome3() genome2 = TestGenome2() species = Species(genome1) genome2.add_new_node(0) distance1 = species.compare(genome1) distance2 = species.compare(genome2) self.assertEqual(distance1, 0.0) self.assertEqual(distance2, 2.0/3.0)
def test_genome_doesnt_create_inputs_as_sinks(self): link_tester = [LinkGene(0, 1), LinkGene(3, 2), LinkGene(2, 4)] try: genome = Genome(self.config, node_genes=self.test_node_genes, link_genes=link_tester) self.fail("Genome should raise exception if input is sink") except ValueError: pass
def test_genome_doesnt_create_duplicate_links(self): link_tester = [LinkGene(0, 3), LinkGene(1, 3), LinkGene(2, 4)] try: genome = Genome(self.config, node_genes=self.test_node_genes, link_genes=link_tester) self.fail("Genome should raise exception if duplicate links exist") except AssertionError: pass
def test_genome_only_links_to_valid_nodes(self): link_tester = [LinkGene(0, 3), LinkGene(1, 3), LinkGene(2, 4), LinkGene(0, 5)] try: genome = Genome(self.config, node_genes=self.test_node_genes, link_genes=link_tester) self.fail("Genome should raise exception if link connects to non-existing node") except ValueError: pass
def convert_stochastic_network_to_genome(network: ComplexStochasticNetwork, original_genome: Genome = None, fitness=None, fix_std=True) -> Genome: if original_genome is None: raise ValueError('Not implemented') genome = original_genome.copy() for layer_index in range(network.n_layers): stochastic_linear_layer = getattr(network, f'layer_{layer_index}') layer = network.layers[layer_index] for bias_index, node_key in enumerate(layer.output_keys): # if node_key in genome.node_genes.keys(): genome.node_genes[node_key].set_mean(stochastic_linear_layer.qb_mean[bias_index]) if fix_std: bias_logvar = DEFAULT_LOGVAR else: bias_logvar = stochastic_linear_layer.qb_logvar[bias_index] genome.node_genes[node_key].set_log_var(bias_logvar) for connection_input_index, input_node_key in enumerate(layer.input_keys): for connection_output_index, output_node_key in enumerate(layer.output_keys): connection_key = (input_node_key, output_node_key) mean = stochastic_linear_layer.qw_mean[connection_output_index, connection_input_index] if fix_std: weight_logvar = DEFAULT_LOGVAR else: weight_logvar = stochastic_linear_layer.qw_logvar[connection_output_index, connection_input_index] if connection_key in genome.connection_genes.keys(): genome.connection_genes[connection_key].set_mean(mean) genome.connection_genes[connection_key].set_log_var(weight_logvar) genome.fitness = fitness return genome
def test_genome_needs_right_number_output_genes(self): try: self.config.num_outputs = 3 genome = Genome(self.config, node_genes=self.test_node_genes) self.config.num_outputs = 2 self.fail("Should raise exception if n_outputs does not match number of output genes") except AssertionError: pass
def test_draw_random_phenome(self): self.config.num_inputs = 3 self.config.num_outputs = 3 gen = Genome(self.config) phenome = FeedForwardPhenome(genome=gen, config=self.config) self.config.num_inputs = 2 self.config.num_outputs = 2 phenome.draw(testing=True)
def _get_execution_configuration(self, report): genome_dict = report.data['best_individual'] best_individual_fitness = report.data['best_individual_fitness'] print(f'Fitness of best individual: {best_individual_fitness}') genome = Genome.from_dict(genome_dict) config = genome.genome_config return config
def test_genome_does_not_allow_duplicate_node_indices(self): print(len(self.test_node_genes)) self.test_node_genes[0].idx = 1 self.test_node_genes[1].idx = 1 try: genome = Genome(self.config, node_genes=self.test_node_genes) except AssertionError: pass
def test_mutate_delete_connection(self): genome = Genome(key='foo').create_random_genome() possible_connections_to_delete = \ set(ArchitectureMutation._calculate_possible_connections_to_delete(genome=genome)) expected_possible_connections_to_delete = {(-1, 0), (-2, 0)} self.assertSetEqual(expected_possible_connections_to_delete, possible_connections_to_delete)
def _read_population(self, generation): file_dir = self._get_configuration_directory() filename = f'{file_dir}/generation_{generation}_population.json' _wait_for_file_to_be_available(filename=filename, timeout=60) genomes = read_json_file_to_dict(filename=filename) population = {} for genome_dict in genomes: genome = Genome.create_from_julia_dict(genome_dict) population[genome.key] = genome return population
def test_randomly_created_genome(self): config = self.config config.num_outputs = 3 config.num_inputs = 3 genome = Genome(config) self.config = Config('../tests/conf_tester.conf') assert len(genome.output_genes) == 3, \ "Genome should have 3 outputs, has %i" % len(genome.output_genes) assert len(genome.input_genes) == 3, \ "Genome should have 3 inputs, has %i" % len(genome.input_genes)
def test_mutate_delete_connection_when_two_input_one_hidden(self): self.config.n_initial_hidden_neurons = 1 genome = Genome(key='foo').create_random_genome() possible_connections_to_delete = set( ArchitectureMutation._calculate_possible_connections_to_delete( genome=genome)) expected_possible_connections_to_delete = {(-1, 1), (-2, 1), (1, 0)} self.assertSetEqual(expected_possible_connections_to_delete, possible_connections_to_delete)
def test_genome_json(self): """Test whether genome objects can be saved to and loaded from JSON.""" genome = GenomeUnitTest.generate_genome() dump = json.dumps(genome.to_json()) genome_load = Genome.from_json(json.loads(dump)) self.assertEqual(len(genome), len(genome_load)) self.assertEqual( genome.connection_genes.union(genome_load.connection_genes), genome.connection_genes)