Exemple #1
0
    def test_generation(self):
        genome1 = create_genome_structure(
            5, 2, modified_sigmoid_activation, NeatConfig(),
            InnovationNumberGeneratorSingleCore())

        genome2 = create_genome_structure(
            5, 2, modified_sigmoid_activation, NeatConfig(),
            InnovationNumberGeneratorSingleCore())

        agent1 = Agent(1, genome1)
        agent2 = Agent(2, genome2)
        members = [agent1, agent2]

        species = [
            Species(1,
                    genome2, [agent1, agent2],
                    max_species_fitness=10,
                    generation_max_species_fitness=3,
                    adjust_fitness=8)
        ]

        seed = 10
        generation = Generation(2, seed, members, species)

        self.assertEqual(2, generation.number)
        self.assertEqual(species, generation.species_list)
        self.assertEqual(members, generation.agents)
        self.assertEqual(seed, generation.seed)
Exemple #2
0
    def test_agent(self):
        genome = create_genome_structure(5, 2, modified_sigmoid_activation,
                                         NeatConfig(),
                                         InnovationNumberGeneratorSingleCore())
        agent = Agent(1, genome)

        self.assertEqual(1, agent.id)
        self.assertEqual(genome, agent.genome)
        self.assertIsNone(agent.neural_network)
        self.assertEqual(0, agent.fitness)
        self.assertEqual(0, agent.adjusted_fitness)
Exemple #3
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 setUp(self) -> None:
        self.config = NeatConfig(population_size=7)
        self.inno_num_generator = InnovationNumberGeneratorSingleCore()
        self.species_id_generator = SpeciesIDGeneratorSingleCore()
        self.agent_id_generator = AgentIDGeneratorSingleCore()

        self.genome1 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        self.genome2 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        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.agent1 = Agent(1, self.genome1)
        self.agent1.fitness = 1
        self.agent2 = Agent(2, self.genome2)
        self.agent2.fitness = 2
        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.species1 = Species(
            self.species_id_generator.get_species_id(), self.agent1.genome,
            [self.agent1, self.agent1, self.agent2, self.agent3])
        self.species2 = Species(self.species_id_generator.get_species_id(),
                                self.agent4.genome, [self.agent4, self.agent5])
        self.species3 = Species(self.species_id_generator.get_species_id(),
                                self.agent6.genome, [self.agent6, self.agent7])
Exemple #5
0
    def test_species(self):
        genome1 = create_genome_structure(5, 2, modified_sigmoid_activation, NeatConfig(),
                                          InnovationNumberGeneratorSingleCore())

        genome2 = create_genome_structure(5, 2, modified_sigmoid_activation, NeatConfig(),
                                          InnovationNumberGeneratorSingleCore())
        members = [Agent(1, genome1)]

        species = Species(1, genome2, members, max_species_fitness=10, generation_max_species_fitness=3,
                          adjust_fitness=8)

        self.assertEqual(genome2, species.representative)
        self.assertEqual(8, species.adjusted_fitness)
        self.assertEqual(10, species.max_species_fitness)
        self.assertEqual(3, species.generation_max_species_fitness)
        self.assertEqual(members, species.members)
        self.assertEqual(1, species.id_)
    def test_sort_agents_into_species(self):
        species_id_generator = SpeciesIDGeneratorSingleCore()
        species_list_new = ss.sort_agents_into_species(
            [], [self.agent1, self.agent2], species_id_generator, self.config)
        self.assertEqual(2, len(species_list_new))

        # Test first species
        self.assertEqual(self.g1, species_list_new[0].representative)
        self.assertEqual(1, len(species_list_new[0].members))
        self.assertEqual(self.agent1, species_list_new[0].members[0])
        self.assertEqual(0, species_list_new[0].id_)

        # Test second species
        self.assertEqual(self.g2, species_list_new[1].representative)
        self.assertEqual(1, len(species_list_new[1].members))
        self.assertEqual(self.agent2, species_list_new[1].members[0])
        self.assertEqual(1, species_list_new[1].id_)

        # Insert one more matching genome
        genome_new = rs.deep_copy_genome(self.g1)
        agent_new = Agent(1, genome_new)

        species_list_new = ss.sort_agents_into_species(species_list_new,
                                                       [agent_new],
                                                       species_id_generator,
                                                       self.config)
        self.assertEqual(2, len(species_list_new))
        # Test first species
        self.assertEqual(self.g1, species_list_new[0].representative)
        self.assertEqual(2, len(species_list_new[0].members))
        self.assertEqual(self.agent1, species_list_new[0].members[0])
        self.assertEqual(agent_new, species_list_new[0].members[1])
        self.assertEqual(0, species_list_new[0].id_)

        # Test second species
        self.assertEqual(self.g2, species_list_new[1].representative)
        self.assertEqual(1, len(species_list_new[1].members))
        self.assertEqual(self.agent2, species_list_new[1].members[0])
        self.assertEqual(1, species_list_new[1].id_)
def _build_generation_from_genome(
        initial_genome: Genome,
        species_id_generator: SpeciesIDGeneratorInterface,
        agent_id_generator: AgentIDGeneratorInterface, generation_seed: int,
        rnd: np.random.RandomState, config: NeatConfig) -> Generation:
    """
    Build a generation from the given genome. The genome will be copied and the weight and biases will be randomized
    :param initial_genome: the genome as initial structure
    :param species_id_generator a generator to get species ids
    :param a generator to get agent ids
    :param generation_seed the seed for the generation
    :param rnd: a random generator to generate the seeds
    :param config: the neat config to specify the weights bounds
    :return: a new initialized generation with number 0, the created agents, and one species
    """
    # Deep copy genome and set new weights
    genomes = []
    for _ in range(config.population_size):
        seed = rnd.randint(2**24)
        rnd_generator_genome = np.random.RandomState(seed)

        # Copy genome, set new values and save seed
        copied_genome = rp.deep_copy_genome(initial_genome)
        copied_genome = _randomize_weight_bias(copied_genome,
                                               rnd_generator_genome, config)
        copied_genome.seed = seed
        genomes.append(copied_genome)

    agents = [
        Agent(agent_id_generator.get_agent_id(), genome) for genome in genomes
    ]
    species = Species(id_=species_id_generator.get_species_id(),
                      representative=genomes[0],
                      members=agents)

    return Generation(0, generation_seed, agents, [species])
    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])