Exemple #1
0
    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))
Exemple #6
0
    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)
Exemple #11
0
    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)
Exemple #14
0
    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()
Exemple #19
0
    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)