def test_next_generation(self): node1 = Node(1, NodeType.INPUT, 1.0, step_activation, 0) node2 = Node("abc", NodeType.HIDDEN, 1.1, step_activation, 0.5) node3 = Node(3, NodeType.OUTPUT, 1.2, step_activation, 1) generator = InnovationNumberGeneratorSingleCore() # Nodes self.assertEqual(0, generator.get_node_innovation_number()) self.assertEqual(1, generator.get_node_innovation_number(node1, node2)) self.assertEqual(1, generator.get_node_innovation_number(node1, node2)) # Connections self.assertEqual(0, generator.get_connection_innovation_number()) self.assertEqual( 1, generator.get_connection_innovation_number(node1, node3)) self.assertEqual( 1, generator.get_connection_innovation_number(node1, node3)) generator.next_generation(5) # Nodes self.assertEqual(2, generator.get_node_innovation_number(node1, node2)) self.assertEqual(2, generator.get_node_innovation_number(node1, node2)) # Connections self.assertEqual(2, generator.get_connection_innovation_number()) self.assertEqual( 1, generator.get_connection_innovation_number(node1, node3)) self.assertEqual( 3, generator.get_connection_innovation_number(node2, node3)) self.assertEqual( 3, generator.get_connection_innovation_number(node2, node3))
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 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_deep_copy_node(self): original_node = Node(1, NodeType.INPUT, 1.1, step_activation, 0) original_node_str = Node("asfaf", NodeType.OUTPUT, 1.2, step_activation, 1) copied_node = deep_copy_node(original_node) copied_node_str = deep_copy_node(original_node_str) self.compare_nodes(original_node, copied_node) self.compare_nodes(original_node_str, copied_node_str)
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 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 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 deep_copy_node(node: Node) -> Node: """ Make a deep copy of the given node and return the new instance :param node: the node to be copied :return: the newly created node """ return Node(node.innovation_number, node.node_type, node.bias, node.activation_function, node.x_position)
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 mutate_add_node( genome: Genome, rnd: np.random.RandomState, generator: InnovationNumberGeneratorInterface, config: NeatConfig) -> (Genome, Node, Connection, Connection): """ Add with a given probability from the config a new node to the genome. A random connections is selected, which will be disabled. A new node will be placed between the in and out node of the connection. Then two new connections will be created, one which leads into the new node (weight=1) and one out (weight = weight of the disabled connection). :param genome: the genome that should be modified :param rnd: a random generator to determine if, the genome is mutated, and how :param generator: a generator for innovation number for nodes and connections :param config: a config that specifies the mutation params :return: the modified genome, as well as the generated node and the two connections (if they were mutated) """ # Check if node should mutate if rnd.uniform(0, 1) > config.probability_mutate_add_node: return genome, None, None, None selected_connection = genome.connections[rnd.randint( 0, len(genome.connections))] selected_connection.enabled = False in_node = next(x for x in genome.nodes if x.innovation_number == selected_connection.input_node) out_node = next(x for x in genome.nodes if x.innovation_number == selected_connection.output_node) # Select activation function either from one of the nodes new_node_activation = in_node.activation_function if rnd.uniform( 0, 1) <= 0.5 else out_node.activation_function new_node_x_position = (in_node.x_position + out_node.x_position) / 2 new_node = Node( generator.get_node_innovation_number(in_node, out_node), NodeType.HIDDEN, rnd.uniform(low=config.bias_initial_min, high=config.bias_initial_max), new_node_activation, new_node_x_position) new_connection_in = Connection(generator.get_connection_innovation_number( in_node, new_node), in_node.innovation_number, new_node.innovation_number, weight=1, enabled=True) new_connection_out = Connection(generator.get_connection_innovation_number( new_node, out_node), new_node.innovation_number, out_node.innovation_number, weight=selected_connection.weight, enabled=True) genome.nodes.append(new_node) genome.connections.append(new_connection_in) genome.connections.append(new_connection_out) return genome, new_node, new_connection_in, new_connection_out
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 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 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_node(self): input_node = Node(1, NodeType.INPUT, 0.3, modified_sigmoid_activation, 0) output_node = Node(2, NodeType.OUTPUT, 0.4, modified_sigmoid_activation, 1) hidden_node = Node("hidden_node", NodeType.HIDDEN, 0.6, modified_sigmoid_activation, 0.5) self.assertEqual(1, input_node.innovation_number) self.assertEqual(NodeType.INPUT, input_node.node_type) self.assertEqual(0.3, input_node.bias) self.assertEqual(0.5, input_node.activation_function(0)) self.assertEqual(0, input_node.x_position) self.assertEqual(2, output_node.innovation_number) self.assertEqual(NodeType.OUTPUT, output_node.node_type) self.assertEqual(0.4, output_node.bias) self.assertEqual(1, output_node.x_position) self.assertEqual("hidden_node", hidden_node.innovation_number) self.assertEqual(NodeType.HIDDEN, hidden_node.node_type) self.assertEqual(0.6, hidden_node.bias) self.assertEqual(0.5, hidden_node.x_position)
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 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 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)
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()