def test_genome(self): genome_empty = Genome(20) self.assertEqual(20, genome_empty.seed) self.assertEqual([], genome_empty.nodes) node_list = [ Node(2, NodeType.INPUT, bias=0.5, activation_function=lambda x: x + 1, x_position=0), Node("node_number", NodeType.OUTPUT, bias=0.4, activation_function=lambda x: x + 1, x_position=1) ] connection_list = [ Connection(1, 2, 3, 0.5, True), Connection("connection_number", 2, 3, 0.7, False) ] genome = Genome(40, node_list, connection_list) self.assertEqual(40, genome.seed) self.assertEqual(node_list, genome.nodes) self.assertEqual(connection_list, genome.connections)
def test_cross_over(self): node1_1 = Node(1, NodeType.INPUT, 1.1, step_activation, 0) node1_2 = Node(2, NodeType.INPUT, 1.2, step_activation, 0) node1_5 = Node(5, NodeType.OUTPUT, 1.5, step_activation, 1) node1_7 = Node(7, NodeType.HIDDEN, 1.7, step_activation, 0.5) nodes1 = [node1_1, node1_2, node1_5, node1_7] node2_1 = Node(1, NodeType.INPUT, 2.1, modified_sigmoid_activation, 0) node2_2 = Node(2, NodeType.INPUT, 2.2, modified_sigmoid_activation, 0) node2_4 = Node(4, NodeType.OUTPUT, 2.4, modified_sigmoid_activation, 1) node2_7 = Node(7, NodeType.HIDDEN, 2.7, modified_sigmoid_activation, 0.5) node2_8 = Node(8, NodeType.HIDDEN, 2.8, modified_sigmoid_activation, 0.5) nodes2 = [node2_1, node2_2, node2_4, node2_7, node2_8] connection1_1 = Connection(innovation_number=1, input_node=1, output_node=2, weight=1.2, enabled=False) connection1_2 = Connection(innovation_number=2, input_node=1, output_node=2, weight=1.2, enabled=True) connection1_4 = Connection(innovation_number=4, input_node=1, output_node=2, weight=1.2, enabled=True) connection1_7 = Connection(innovation_number=7, input_node=1, output_node=2, weight=1.2, enabled=False) connections1 = [connection1_1, connection1_2, connection1_4, connection1_7] connection2_1 = Connection(innovation_number=1, input_node=1, output_node=2, weight=1.2, enabled=False) connection2_2 = Connection(innovation_number=2, input_node=1, output_node=2, weight=1.2, enabled=True) connection2_3 = Connection(innovation_number=3, input_node=1, output_node=2, weight=1.2, enabled=True) connection2_5 = Connection(innovation_number=5, input_node=1, output_node=2, weight=1.2, enabled=True) connection2_7 = Connection(innovation_number=7, input_node=1, output_node=2, weight=1.2, enabled=False) connections2 = [connection2_1, connection2_2, connection2_3, connection2_5, connection2_7] more_fit_parent = Genome(1, nodes1, connections1) less_fit_parent = Genome(2, nodes2, connections2) config = NeatConfig(probability_enable_gene=0.31) # Random values: # 1 rnd.uniform(0, 1) = 0.417022004702574 -> First node (node1_1) # 1 rnd.uniform(0, 1) = 0.7203244934421581 -> Second node(node2_2) # 1 rnd.uniform(0, 1) = 0.00011437481734488664 -> First node (node7_1) # 1 rnd.uniform(0, 1) = 0.30233257263183977 -> Select first connection (connection1_1) # 1 rnd.uniform(0, 1) = 0.14675589081711304 -> Re-enable connection (connection1_1) # 1 rnd.uniform(0, 1) = 0.0923385947687978 -> Select first connection (connection1_2) # 1 rnd.uniform(0, 1) = 0.1862602113776709 -> Select first connection (connection1_7) # 1 rnd.uniform(0, 1) = 0.34556072704304774 -> Re-enable connection False (connection1_7) child_nodes, child_connections = cross_over(more_fit_parent, less_fit_parent, self.rnd, config) # Check nodes self.assertEqual(4, len(child_nodes)) self.compare_nodes(node1_1, child_nodes[0]) self.compare_nodes(node2_2, child_nodes[1]) self.compare_nodes(node1_5, child_nodes[2]) self.compare_nodes(node1_7, child_nodes[3]) # Check connections self.assertEqual(4, len(child_connections)) connection1_1.enabled = True self.compare_connections(connection1_1, child_connections[0]) self.compare_connections(connection1_2, child_connections[1]) self.compare_connections(connection1_4, child_connections[2]) self.compare_connections(connection1_7, child_connections[3])
def setUp(self) -> None: self.inn_generator = InnovationNumberGeneratorSingleCore() self.rnd = np.random.RandomState(1) self.node_input1 = Node(self.inn_generator.get_node_innovation_number(), NodeType.INPUT, 0, step_activation, 0) self.node_input2 = Node(self.inn_generator.get_node_innovation_number(), NodeType.INPUT, 0, step_activation, 0) self.node_output1 = Node(self.inn_generator.get_node_innovation_number(), NodeType.OUTPUT, 1.2, step_activation, 1) self.node_hidden1 = Node(self.inn_generator.get_node_innovation_number(), NodeType.HIDDEN, 1.3, step_activation, 0.5) self.nodes = [self.node_input1, self.node_input2, self.node_output1, self.node_hidden1] self.connection1 = Connection(self.inn_generator.get_connection_innovation_number(), input_node=self.node_input1.innovation_number, output_node=self.node_output1.innovation_number, weight=-2.1, enabled=True) self.connection2 = Connection(self.inn_generator.get_connection_innovation_number(), input_node=self.node_input2.innovation_number, output_node=self.node_output1.innovation_number, weight=-1.2, enabled=True) self.connection3 = Connection(self.inn_generator.get_connection_innovation_number(), input_node=self.node_input1.innovation_number, output_node=self.node_hidden1.innovation_number, weight=0.6, enabled=True) self.connection4 = Connection(self.inn_generator.get_connection_innovation_number(), input_node=self.node_hidden1.innovation_number, output_node=self.node_output1.innovation_number, weight=0, enabled=False) self.connections = [self.connection1, self.connection2, self.connection3, self.connection4] self.genome = Genome(1, self.nodes, connections=self.connections)
def test_mutate_add_connection(self): config = NeatConfig(connection_initial_min_weight=-3, connection_initial_max_weight=3, allow_recurrent_connections=True, probability_mutate_add_connection=0.4, mutate_connection_tries=2) self.genome.connections = [] # Random values for with seed 1 # rnd.uniform(0, 1) = 0.417022004702574 -> No mutation _, conn = mutate_add_connection(self.genome, self.rnd, self.inn_generator, config) self.assertEqual(0, len(self.genome.connections)) self.assertIsNone(conn) # Set higher config value, reset random config.probability_mutate_add_connection = 1 self.rnd = np.random.RandomState(1) # Random values for with seed 1 # rnd.uniform(0, 1) = 0.417022004702574 -> Mutate # rnd.randint(low=0,high=4) = 0 # rnd.randint(low=0,high=2) = 0 # rnd.uniform(low=-3, high=3) = -2.9993137510959307 _, new_con1 = mutate_add_connection(self.genome, self.rnd, self.inn_generator, config) self.assertEqual(1, len(self.genome.connections)) self.assertEqual(4, new_con1.innovation_number) self.assertEqual(self.node_input1.innovation_number, new_con1.input_node) self.assertEqual(self.node_hidden1.innovation_number, new_con1.output_node) self.assertAlmostEqual(-2.9993137510959307, new_con1.weight, delta=0.0000000001) # Random values # rnd.uniform(0, 1) = 0.00011437481734488664 -> Mutate # rnd.randint(low=0,high=4) = 3 # rnd.randint(low=0,high=2) = 0 # rnd.uniform(low=-3, high=3) = -2.445968431387213 _, new_con2 = mutate_add_connection(self.genome, self.rnd, self.inn_generator, config) self.assertEqual(2, len(self.genome.connections)) self.assertEqual(5, new_con2.innovation_number) self.assertEqual(self.node_output1.innovation_number, new_con2.input_node) self.assertEqual(self.node_hidden1.innovation_number, new_con2.output_node) self.assertAlmostEqual(-2.445968431387213, new_con2.weight, delta=0.0000000001) # Brute force - check if all nodes are connected after 1000 tries for _ in range(1000): _, _ = mutate_add_connection(self.genome, self.rnd, self.inn_generator, config) # Maximum connections with recurrent self.assertEqual(8, len(self.genome.connections)) # Set recurrent to false config.allow_recurrent = False genome_feed_forward = Genome(1, self.nodes, connections=[]) for _ in range(1000): genome_feed_forward, _ = mutate_add_connection(genome_feed_forward, self.rnd, self.inn_generator, config) # Maximum connections with recurrent=false self.assertEqual(5, len(genome_feed_forward.connections))
def test_evaluate_genome_structure(self): genome = Genome(0, [ Node(0, NodeType.INPUT, 0, modified_sigmoid_activation, 0), Node(1, NodeType.INPUT, 0, modified_sigmoid_activation, 0), Node(2, NodeType.OUTPUT, 0, modified_sigmoid_activation, 1), Node(3, NodeType.HIDDEN, 0, modified_sigmoid_activation, 0.5), Node(4, NodeType.HIDDEN, 0, modified_sigmoid_activation, 0.5) ], [ Connection(1, 0, 3, 0.1, True), Connection(2, 1, 3, 0.1, True), Connection(3, 0, 4, 0.1, True), Connection(4, 1, 4, 0.1, True), Connection(5, 3, 2, 0.1, True), Connection(6, 4, 2, 0.1, True) ]) self.optimizer_single.evaluate_genome_structure( genome, self.challenge, self.config, 1) expected_generation_number = 10 # Test callback functions self.assertEqual(1, self.challenge.initialization_count) # Reproduction functions self.assertEqual(expected_generation_number, self.callback.on_reproduction_start_count) self.assertEqual(expected_generation_number, self.callback.on_compose_offsprings_start_count) self.assertEqual(expected_generation_number, self.callback.on_compose_offsprings_end_count) self.assertEqual(expected_generation_number, self.callback.on_reproduction_start_count) # Evaluation loop self.assertEqual(expected_generation_number + 1, self.callback.on_generation_evaluation_start_count) self.assertEqual( (1 + expected_generation_number) * self.config.population_size, self.callback.on_agent_evaluation_start_count) self.assertEqual( (1 + expected_generation_number) * self.config.population_size, self.callback.on_agent_evaluation_end_count) self.assertEqual(expected_generation_number + 1, self.callback.on_generation_evaluation_end_count) self.assertEqual(expected_generation_number, self.callback.finish_evaluation_count) # Finish evaluation self.assertEqual(1, self.callback.on_finish_count) self.assertEqual(1, self.callback.on_cleanup_count) # Check generated networks self.assertEqual(self.config.population_size, len(self.callback.finish_generation.agents))
def setUp(self) -> None: self.agent1 = Agent(1, Genome(1, [], [])) self.agent2 = Agent(2, Genome(1, [], [])) self.agent3 = Agent(3, Genome(1, [], [])) self.agent4 = Agent(4, Genome(1, [], [])) self.agent5 = Agent(5, Genome(1, [], [])) self.agent6 = Agent(6, Genome(1, [], [])) self.agent7 = Agent(7, Genome(1, [], [])) self.species_reporter = sp.SpeciesReporter()
def deep_copy_genome(genome: Genome) -> Genome: """ Make a deep copy of the given genome and return the new instance :param genome: the genome to be copied :return: the newly created instance """ nodes = [deep_copy_node(original_node) for original_node in genome.nodes] connections = [ deep_copy_connection(connection) for connection in genome.connections ] return Genome(genome.seed, nodes, connections)
def test_set_new_genome_weights(self): original_genome = Genome(123, [Node(1, NodeType.INPUT, 1.1, step_activation, 0)], [Connection(124, 10, 20, 1.2, True), Connection("124124", 12, 22, 0.8, False)]) config = NeatConfig(connection_initial_min_weight=-10, connection_initial_max_weight=10) new_genome = set_new_genome_weights(original_genome, np.random.RandomState(2), config=config) # First 3 random values # 1. -1.2801019571599248 # 2. -9.481475363442174 # 3. -1.293552147634463 self.assertAlmostEqual(-1.2801019571599248, new_genome.connections[0].weight, delta=0.00000001) self.assertAlmostEqual(-9.481475363442174, new_genome.connections[1].weight, delta=0.00000001)
def test_create_initial_generation_genome(self): genome = Genome(20, [ Node("abc", NodeType.INPUT, 0.3, step_activation, 0), Node("def", NodeType.OUTPUT, 0.4, step_activation, 1) ], [ Connection("x", "abc", "def", 1.0, True), Connection("y", "def", "abc", -5, True) ]) generation = gs.create_initial_generation_genome( genome, InnovationNumberGeneratorSingleCore(), SpeciesIDGeneratorSingleCore(), AgentIDGeneratorSingleCore(), NeatConfig(population_size=3), seed=1) self.assertEqual(3, len(generation.agents)) self.assertEqual(0, generation.number) self.assertEqual(1, len(generation.species_list)) self.assertEqual(3, len(generation.species_list[0].members)) self.assertEqual(1, generation.seed) # First three random numbers # 1 - 12710949 # 2 - 4686059 # 3 - 6762380 self.assertEqual(12710949, generation.agents[0].genome.seed) self.assertEqual(4686059, generation.agents[1].genome.seed) self.assertEqual(6762380, generation.agents[2].genome.seed) for node1, node2, node3, i in zip(generation.agents[0].genome.nodes, generation.agents[1].genome.nodes, generation.agents[2].genome.nodes, range(3)): self.assertEqual(node1.innovation_number, node2.innovation_number) self.assertEqual(node2.innovation_number, node3.innovation_number) self.assertEqual(node3.innovation_number, i) for connection1, connection2, connection3, i in zip( generation.agents[0].genome.connections, generation.agents[1].genome.connections, generation.agents[2].genome.connections, range(3)): self.assertEqual(connection1.innovation_number, connection2.innovation_number) self.assertEqual(connection2.innovation_number, connection3.innovation_number) self.assertEqual(connection3.innovation_number, i)
def create_genome_structure( amount_input_nodes: int, amount_output_nodes: int, activation_function, config: NeatConfig, generator: InnovationNumberGeneratorInterface) -> Genome: """ Create an initial genome struture with the given amount of input and output nodes. The nodes will be fully connected, that means, that every input node will be connected to every output node. The bias of the nodes, as well as the connections will have the value 0! They must be set before usage :param amount_input_nodes: the amount of input nodes, that will be placed in the genome :param amount_output_nodes: the amount of output nodes, that will be placed in the genome :param activation_function: the activation function for the nodes :param config: the config :param generator: for the innovation numbers for nodes and connections :return: the generated genome """ input_nodes = [ Node(generator.get_node_innovation_number(), NodeType.INPUT, bias=0, activation_function=activation_function, x_position=0.0) for _ in range(amount_input_nodes) ] output_nodes = [ Node(generator.get_node_innovation_number(), NodeType.OUTPUT, bias=0, activation_function=activation_function, x_position=1.0) for _ in range(amount_output_nodes) ] connections = [] for input_node in input_nodes: for output_node in output_nodes: connections.append( Connection(innovation_number=generator. get_connection_innovation_number(), input_node=input_node.innovation_number, output_node=output_node.innovation_number, weight=0, enabled=True)) return Genome(seed=None, nodes=input_nodes + output_nodes, connections=connections)
def setUp(self) -> None: seed = np.random.RandomState().randint(2**24) rnd = np.random.RandomState(seed) self.genome = Genome(seed, [ Node(1, NodeType.INPUT, rnd.uniform(-5, 5), step_activation, 0.5), Node(2, NodeType.OUTPUT, rnd.uniform(-5, 5), modified_sigmoid_activation, 0.5), Node(3, NodeType.HIDDEN, rnd.uniform(-5, 5), step_activation, 0.5), Node(4, NodeType.HIDDEN, rnd.uniform(-5, 5), step_activation, 0.5), ], [ Connection(1, 1, 2, rnd.uniform(-5, 5), True), Connection(2, 1, 4, rnd.uniform(-5, 5), True), Connection(3, 1, 3, rnd.uniform(-5, 5), True), Connection(4, 3, 2, rnd.uniform(-5, 5), True), Connection(5, 4, 2, rnd.uniform(-5, 5), True), Connection(6, 2, 2, rnd.uniform(-5, 5), False), ])
def test_deep_copy_genome(self): original_genome = Genome(123, [Node(1, NodeType.INPUT, 1.1, step_activation, 0), Node("asfaf", NodeType.OUTPUT, 1.2, step_activation, 1)], [Connection(124, 10, 20, 1.2, True), Connection("124124", 12, 22, 0.8, False)]) copied_genome = deep_copy_genome(original_genome) # Check if genomes dont have the same id self.assertIsNotNone(original_genome) self.assertIsNotNone(copied_genome) self.assertNotEqual(id(original_genome), id(copied_genome)) # Compare values self.assertEqual(original_genome.seed, copied_genome.seed) for original_node, copied_node in zip(original_genome.nodes, copied_genome.nodes): self.compare_nodes(original_node, copied_node) for original_connection, copied_connection in zip(original_genome.connections, copied_genome.connections): self.compare_connections(original_connection, copied_connection)
def test_build_generation_from_genome(self): initial_genome = Genome(20, [ Node(1, NodeType.INPUT, 0, step_activation, 0), Node(2, NodeType.OUTPUT, 0.4, step_activation, 1) ], [Connection(1, 1, 2, 1.0, True), Connection(2, 1, 2, -5, True)]) rnd = np.random.RandomState(1) generation = gs._build_generation_from_genome( initial_genome, SpeciesIDGeneratorSingleCore(), AgentIDGeneratorSingleCore(), 19, rnd, NeatConfig(population_size=3)) self.assertEqual(3, len(generation.agents)) self.assertEqual(0, generation.number) self.assertEqual(1, len(generation.species_list)) self.assertEqual(3, len(generation.species_list[0].members)) self.assertEqual(19, generation.seed) # First three random numbers # 1 - 12710949 # 2 - 4686059 # 3 - 6762380 self.assertEqual(12710949, generation.agents[0].genome.seed) self.assertEqual(4686059, generation.agents[1].genome.seed) self.assertEqual(6762380, generation.agents[2].genome.seed) # Check if every weight and bias is not equal to 0 for agent, i in zip(generation.agents, range(len(generation.agents))): genome = agent.genome self.assertEqual(i, agent.id) for node in genome.nodes: # Input nodes can have bias 0 if node.node_type == NodeType.INPUT: continue self.assertNotAlmostEqual(0, node.bias, delta=0.00000000001) for conn in genome.connections: self.assertNotAlmostEqual(0, conn.weight, delta=0.00000000001)
def evaluate_fix_structure(self, optimizer: NeatOptimizer, seed: int = None): optimizer.register_callback(self) config = NeatConfig(allow_recurrent_connections=False, population_size=150, compatibility_threshold=3, connection_min_weight=-5, connection_max_weight=5, bias_min=-5, bias_max=5, probability_mutate_add_node=0, probability_mutate_add_connection=0) # Create random seed, if none is specified if seed is None: seed = np.random.RandomState().randint(2**24) logger.info("Used Seed: {}".format(seed)) genome = Genome(0, [ Node(0, NodeType.INPUT, 0, modified_sigmoid_activation, 0), Node(1, NodeType.INPUT, 0, modified_sigmoid_activation, 0), Node(2, NodeType.OUTPUT, 0, modified_sigmoid_activation, 1), Node(3, NodeType.HIDDEN, 0, modified_sigmoid_activation, 0.5), Node(4, NodeType.HIDDEN, 0, modified_sigmoid_activation, 0.5) ], [ Connection(1, 0, 3, 0.1, True), Connection(2, 1, 3, 0.1, True), Connection(3, 0, 4, 0.1, True), Connection(4, 1, 4, 0.1, True), Connection(5, 3, 2, 0.1, True), Connection(6, 4, 2, 0.1, True) ]) optimizer.evaluate_genome_structure(genome_structure=genome, challenge=ChallengeXOR(), config=config, seed=seed)
def test_randomize_weight_bias(self): genome = Genome(20, [ Node(1, NodeType.INPUT, 0.0, step_activation, 0), Node(2, NodeType.OUTPUT, 0.0, step_activation, 1) ], [Connection(3, 1, 2, 0, True), Connection(4, 2, 1, 0, True)]) config = NeatConfig(bias_initial_min=1, bias_initial_max=2, connection_initial_min_weight=3, connection_initial_max_weight=4) randomized_genome = gs._randomize_weight_bias(genome, np.random.RandomState(1), config) for node in randomized_genome.nodes: if node.node_type == NodeType.INPUT: self.assertEqual(0, node.bias) else: self.assertTrue(1 <= node.bias <= 2) for conn in randomized_genome.connections: self.assertTrue(3 <= conn.weight <= 4)
def _build_new_generation(self, generation: Generation, innovation_number_generator: InnovationNumberGeneratorInterface, species_id_generator: SpeciesIDGeneratorSingleCore, agent_id_generator: AgentIDGeneratorSingleCore, config: NeatConfig) -> Generation: # Notify callback self._notify_reporters_callback(lambda r: r.on_reproduction_start(generation)) # Get the random generator for the new generation new_generation_seed = np.random.RandomState(generation.seed).randint(2 ** 24) rnd = np.random.RandomState(new_generation_seed) # Get the best agents, which will be copied later best_agents_genomes = gs.get_best_genomes_from_species(generation.species_list, config.species_size_copy_best_genome) # Get allowed species for reproduction generation = ss.update_fitness_species(generation) species_list = ss.get_allowed_species_for_reproduction(generation, config.species_stagnant_after_generations) # TODO handle error no species if len(species_list) <= 5: species_list = generation.species_list # assert len(species_list) >= 1 # Calculate the adjusted fitness values min_fitness = min([a.fitness for a in generation.agents]) max_fitness = max([a.fitness for a in generation.agents]) species_list = ss.calculate_adjusted_fitness(species_list, min_fitness, max_fitness) # Remove the low performing genomes species_list = ss.remove_low_genomes(species_list, config.percentage_remove_low_genomes) # Calculate offspring for species off_spring_list = ss.calculate_amount_offspring(species_list, config.population_size - len(best_agents_genomes)) # Calculate off spring combinations off_spring_pairs = [] for species, amount_offspring in zip(species_list, off_spring_list): off_spring_pairs += ss.create_offspring_pairs(species, amount_offspring, agent_id_generator, generation, rnd, config) # Notify innovation number generator, that a new generation is created innovation_number_generator.next_generation(generation.number) # Create a dictionary for easy access agent_dict = {agent.id: agent for agent in generation.agents} # Create new agents - fill initially with best agents new_agents = [Agent(agent_id_generator.get_agent_id(), genome) for genome in best_agents_genomes] # Create agents with crossover self._notify_reporters_callback(lambda r: r.on_compose_offsprings_start()) for parent1_id, parent2_id, child_id in off_spring_pairs: parent1 = agent_dict[parent1_id] parent2 = agent_dict[parent2_id] child_seed = (parent1.genome.seed + parent2.genome.seed) % 2 ** 24 rnd_child = np.random.RandomState(child_seed) # Perform crossover for to get the nodes and connections for the child if parent1.fitness > parent2.fitness: child_nodes, child_connections = rp.cross_over(parent1.genome, parent2.genome, rnd_child, config) else: child_nodes, child_connections = rp.cross_over(parent2.genome, parent1.genome, rnd_child, config) # Create child genome child_genome = Genome(child_seed, child_nodes, child_connections) # Mutate genome child_genome = rp.mutate_weights(child_genome, rnd_child, config) child_genome, _, _, _ = rp.mutate_add_node(child_genome, rnd_child, innovation_number_generator, config) child_genome, _ = rp.mutate_add_connection(child_genome, rnd_child, innovation_number_generator, config) child_agent = Agent(child_id, child_genome) new_agents.append(child_agent) # Notify callback end self._notify_reporters_callback(lambda r: r.on_compose_offsprings_end()) # TODO convert back # Select new representative existing_species = [ss.select_new_representative(species, rnd) for species in generation.species_list] # Reset members and fitness existing_species = [ss.reset_species(species) for species in existing_species] # existing_species = [ss.reset_species(species) for species in generation.species_list] # Sort members into species new_species_list = ss.sort_agents_into_species(existing_species, new_agents, species_id_generator, config) logger.info("Species IDs: {}".format([s.id_ for s in new_species_list])) logger.info("Species Mem: {}".format([len(s.members) for s in new_species_list])) # Filter out empty species new_species_list = ss.get_species_with_members(new_species_list) # Create new generation, notify callback and return new generation new_generation = Generation(generation.number + 1, new_generation_seed, new_agents, new_species_list) self._notify_reporters_callback(lambda r: r.on_reproduction_end(new_generation)) return new_generation
def setUp(self) -> None: self.config = NeatConfig(compatibility_factor_matching_genes=1, compatibility_factor_disjoint_genes=2, compatibility_threshold=2.5, compatibility_genome_size_threshold=0, population_size=8) self.g1_nodes = [ Node(1, NodeType.INPUT, 0, step_activation, 0), Node(2, NodeType.INPUT, 0, step_activation, 0), Node(3, NodeType.OUTPUT, 1.2, step_activation, 1), Node(4, NodeType.HIDDEN, 1.5, step_activation, 0.5), Node(6, NodeType.HIDDEN, 0.5, step_activation, 0.5), Node(7, NodeType.HIDDEN, 0.2, step_activation, 0.25) ] self.g1_connections = [ Connection(1, 1, 3, 1.2, True), Connection(2, 2, 3, 0.5, False), Connection(3, 1, 4, -1.2, True), Connection(4, 4, 3, 0.2, True), Connection(5, 2, 6, 2.0, True), Connection(6, 6, 3, -1.1, False) ] self.g1 = Genome(1, self.g1_nodes, self.g1_connections) self.g2_nodes = [ Node(1, NodeType.INPUT, 0, step_activation, 0), Node(2, NodeType.INPUT, 0, step_activation, 0), Node(3, NodeType.OUTPUT, 0.2, step_activation, 1), Node(4, NodeType.HIDDEN, 1.2, step_activation, 0.5), Node(5, NodeType.HIDDEN, 2.8, step_activation, 0.5) ] self.g2_connections = [ Connection(1, 1, 3, 0.8, True), Connection(2, 2, 3, 1.5, True), Connection(3, 1, 4, 1.2, True), Connection(4, 4, 3, 3.2, True), Connection(6, 6, 3, -1.1, False), Connection(7, 6, 3, -0.1, False), Connection(8, 1, 4, -1.1, False) ] self.g2 = Genome(2, self.g2_nodes, self.g2_connections) self.agent1 = Agent(1, self.g1) self.agent1.fitness = 1 self.agent2 = Agent(2, self.g2) self.agent2.fitness = 2 # Add some more agents, and complete species self.inno_num_generator = InnovationNumberGeneratorSingleCore() self.species_id_generator = SpeciesIDGeneratorSingleCore() self.genome3 = gs.create_genome_structure(2, 1, step_activation, self.config, self.inno_num_generator) self.genome4 = gs.create_genome_structure(2, 1, step_activation, self.config, self.inno_num_generator) self.genome5 = gs.create_genome_structure(2, 1, step_activation, self.config, self.inno_num_generator) self.genome6 = gs.create_genome_structure(2, 1, step_activation, self.config, self.inno_num_generator) self.genome7 = gs.create_genome_structure(2, 1, step_activation, self.config, self.inno_num_generator) self.genome8 = gs.create_genome_structure(2, 1, step_activation, self.config, self.inno_num_generator) self.agent3 = Agent(3, self.genome3) self.agent3.fitness = 3 self.agent4 = Agent(4, self.genome4) self.agent4.fitness = 4 self.agent5 = Agent(5, self.genome5) self.agent5.fitness = 5 self.agent6 = Agent(6, self.genome6) self.agent6.fitness = 6 self.agent7 = Agent(7, self.genome7) self.agent7.fitness = 7 self.agent8 = Agent(8, self.genome8) self.agent8.fitness = 8 self.species1 = Species(self.species_id_generator.get_species_id(), self.agent1.genome, [self.agent1, self.agent2, self.agent3], max_species_fitness=1.5, generation_max_species_fitness=10) self.species2 = Species(self.species_id_generator.get_species_id(), self.agent4.genome, [self.agent4, self.agent5, self.agent6], max_species_fitness=7, generation_max_species_fitness=5) self.species3 = Species(self.species_id_generator.get_species_id(), self.agent6.genome, [self.agent7, self.agent8], max_species_fitness=0, generation_max_species_fitness=6) self.generation = Generation( 21, 2, agents=[ self.agent1, self.agent2, self.agent3, self.agent4, self.agent5, self.agent6, self.agent7, self.agent8 ], species_list=[self.species1, self.species2, self.species3])
def setUp(self) -> None: self.feed_forward_hidden_bias = -0.5 self.feed_forward_output_bias = -0.6 self.nodes_feed_forward = [ Node(1, NodeType.INPUT, 0, step_activation, x_position=0), Node(2, NodeType.INPUT, 0, step_activation, x_position=0), Node(3, NodeType.INPUT, 0, step_activation, x_position=0), Node(4, NodeType.OUTPUT, self.feed_forward_output_bias, step_activation, x_position=1), Node(15, NodeType.HIDDEN, self.feed_forward_hidden_bias, step_activation, x_position=0.5), ] self.connections_feed_forward = [ Connection(innovation_number=5, input_node=1, output_node=4, weight=0.5, enabled=True), Connection(innovation_number=16, input_node=1, output_node=15, weight=-0.4, enabled=True), Connection(innovation_number=17, input_node=15, output_node=4, weight=2.0, enabled=True), Connection(innovation_number=18, input_node=2, output_node=15, weight=-1.0, enabled=True), Connection(innovation_number=6, input_node=2, output_node=4, weight=-15.0, enabled=False), Connection(innovation_number=19, input_node=3, output_node=15, weight=2.0, enabled=True), Connection(innovation_number=19, input_node=3, output_node=4, weight=15.0, enabled=False) ] self.genome_feed_forward = Genome(10, self.nodes_feed_forward, self.connections_feed_forward) # Truth table for the neural network above # X Y Z # Input 0 0 0: Result: 0.0 # Input 0 0 1: Result: 1.0 # Input 0 1 0: Result: 0.0 # Input 0 1 1: Result: 1.0 # Input 1 0 0: Result: 0.0 # Input 1 0 1: Result: 1.0 # Input 1 1 0: Result: 0.0 # Input 1 1 1: Result: 1.0 self.net_feed_forward = BasicNeuralNetwork() self.nodes_recurrent = [ Node(1, NodeType.INPUT, 0, modified_sigmoid_activation, x_position=0), Node(2, NodeType.INPUT, 0, modified_sigmoid_activation, x_position=0), Node(3, NodeType.INPUT, 0, modified_sigmoid_activation, x_position=0), Node(4, NodeType.OUTPUT, -1.0, modified_sigmoid_activation, x_position=1), Node(10, NodeType.HIDDEN, -0.6, modified_sigmoid_activation, x_position=0.5), Node(15, NodeType.HIDDEN, -1.2, modified_sigmoid_activation, x_position=0.5), ] self.connections_recurrent = [ Connection(innovation_number=11, input_node=1, output_node=10, weight=0.5, enabled=True), Connection(innovation_number=12, input_node=2, output_node=10, weight=-0.3, enabled=True), Connection(innovation_number=22, input_node=10, output_node=10, weight=1.5, enabled=True), Connection(innovation_number=21, input_node=15, output_node=10, weight=-0.1, enabled=True), Connection(innovation_number=16, input_node=2, output_node=15, weight=2.0, enabled=True), Connection(innovation_number=17, input_node=3, output_node=15, weight=-1.6, enabled=True), Connection(innovation_number=20, input_node=10, output_node=15, weight=-0.3, enabled=True), Connection(innovation_number=18, input_node=4, output_node=15, weight=0.6, enabled=True), Connection(innovation_number=13, input_node=10, output_node=4, weight=1.6, enabled=True), Connection(innovation_number=19, input_node=15, output_node=4, weight=-0.6, enabled=True), Connection(innovation_number=14, input_node=3, output_node=4, weight=-0.3, enabled=True), ] self.genome_recurrent = Genome(20, self.nodes_recurrent, self.connections_recurrent) self.net_recurrent = BasicNeuralNetwork()
def setUp(self) -> None: self.nodes_recurrent = [ Node(1, NodeType.INPUT, 1.0, lambda x: x, x_position=0), Node(2, NodeType.INPUT, 1.2, lambda x: x, x_position=0), Node(3, NodeType.INPUT, 1.3, lambda x: x, x_position=0), Node(4, NodeType.OUTPUT, 1.4, lambda x: x, x_position=1), Node(10, NodeType.HIDDEN, 1.5, lambda x: x, x_position=0.5), Node(15, NodeType.HIDDEN, 1.6, lambda x: x, x_position=0.5), ] self.connections_recurrent = [ Connection(innovation_number=11, input_node=1, output_node=10, weight=0.5, enabled=True), Connection(innovation_number=12, input_node=2, output_node=10, weight=-0.3, enabled=False), Connection(innovation_number=22, input_node=10, output_node=10, weight=1.5, enabled=True), Connection(innovation_number=21, input_node=15, output_node=10, weight=-0.1, enabled=False), Connection(innovation_number=16, input_node=2, output_node=15, weight=2.0, enabled=True), Connection(innovation_number=17, input_node=3, output_node=15, weight=-1.6, enabled=True), Connection(innovation_number=20, input_node=10, output_node=15, weight=-0.3, enabled=True), Connection(innovation_number=18, input_node=4, output_node=15, weight=0.6, enabled=True), Connection(innovation_number=13, input_node=10, output_node=4, weight=1.6, enabled=True), Connection(innovation_number=19, input_node=15, output_node=4, weight=-0.6, enabled=True), Connection(innovation_number=14, input_node=3, output_node=4, weight=-0.3, enabled=True), ] self.genome_recurrent = Genome(20, self.nodes_recurrent, self.connections_recurrent)