示例#1
0
def evolve(pop: Population, pop_name: str):
    """Evolve with the set constraints in mind."""
    # Create the next generation from the current generation
    pop.population = pop.reproduction.reproduce(
        config=pop.config,
        species=pop.species,
        generation=pop.generation,
        logger=pop.log,
    )

    # Constraint each of the population's new genomes to the given topology
    for g in pop.population.values():
        enforce_topology(pop_name, genome=g)

    # Check for complete extinction
    if not pop.species.species:
        pop.reporters.complete_extinction(logger=pop.log)

        # If requested by the user, create a completely new population, otherwise raise an exception
        pop.population = pop.reproduction.create_new(
            config=pop.config, num_genomes=pop.config.population.pop_size)

    # Divide the new population into species
    pop.species.speciate(config=pop.config,
                         population=pop.population,
                         generation=pop.generation,
                         logger=pop.log)

    # Add to each of the species its elites
    pop.update_species_fitness_hist()

    # Increment generation count
    pop.generation += 1
示例#2
0
def main(topology_id: int,
         iterations: int,
         eval_interval: int,
         experiment_id: int,
         hops: float = 0.1,
         weight_range: float = 1,
         mutate_combine: bool = False,
         mutate_bias: bool = True,
         mutate_reset: bool = True,
         mutate_update: bool = True,
         mutate_candidate: bool = True,
         init_population_size: int = 1000,
         unused_cpu: int = 2):
    """
    Run the fifth experiment.
    
    :param topology_id: Chosen topology to investigate
    :param iterations: Number of training iterations performed
    :param eval_interval: After how much training iterations evaluation is performed
    :param experiment_id: ID of the experiment used to train and evaluate the population on
    :param hops: Hops between variable-configurations
    :param weight_range: Range of deviation for one's weights
    :param mutate_combine: Combine the best results of each mutation type
    :param mutate_bias: Mutate the GRU's bias values
    :param mutate_reset: Mutate the reset-gate's weights
    :param mutate_update: Mutate the update-gate's weights
    :param mutate_candidate: Mutate the candidate-state's weights
    :param init_population_size: Initial size of the randomized population
    :param unused_cpu: Number of CPU-cores not used
    """
    # Get the population
    name = f"experiment{experiment_id}_topology{topology_id}_hops{hops}_range{weight_range}"
    pop = Population(
        name=name,
        folder_name='experiment5',
        use_backup=False,
    )

    # Define the games specific to the experiment
    _, game_ids_eval = get_game_ids(experiment_id=experiment_id)

    # Set the genomes if population is new
    if pop.generation == 0:
        # Get the requested topology-type
        if topology_id == 1:
            topology = get_topology1
        elif topology_id == 2:
            topology = get_topology2
        else:
            raise Exception(f"Topology {topology_id} not supported.")

        # Initialize the population with a randomized population
        pop.population = dict()
        for gid in range(init_population_size):
            new_genome = topology(pop.config, random_init=True)
            new_genome.key = gid
            pop.population[gid] = new_genome

        # Perform an initial training
        train_population(pop=pop, games=game_ids_eval, unused_cpu=unused_cpu)
        pop.generation = 0  # Don't count initial training as a generation

        # Get the fittest genome
        best = None
        for g in pop.population.values():
            if best is None or g.fitness > best.fitness: best = g
        pop.best_genome = best
        visualize_best_genome(pop=pop)

        # Test the initial population
        test_population(pop=pop, games=game_ids_eval)

        # Set the most fit genome as the starting-point
        set_population(pop=pop,
                       hops=hops,
                       weight_range=weight_range,
                       mutate_bias=mutate_bias,
                       mutate_reset=mutate_reset,
                       mutate_update=mutate_update,
                       mutate_candidate=mutate_candidate)

    # Evaluate the population
    for i in range(iterations):
        train_population(pop=pop, games=game_ids_eval, unused_cpu=unused_cpu)
        evaluate_fitness(pop=pop,
                         hops=hops,
                         weight_range=weight_range,
                         mutate_combine=mutate_combine,
                         mutate_bias=mutate_bias,
                         mutate_reset=mutate_reset,
                         mutate_update=mutate_update,
                         mutate_candidate=mutate_candidate)
        visualize_best_genome(pop=pop)
        if pop.generation % eval_interval == 0:
            test_population(pop=pop, games=game_ids_eval)
        set_population(pop=pop,
                       hops=hops,
                       weight_range=weight_range,
                       mutate_bias=mutate_bias,
                       mutate_reset=mutate_reset,
                       mutate_update=mutate_update,
                       mutate_candidate=mutate_candidate)
示例#3
0
def set_population(
    pop: Population,
    hops: float,
    weight_range: float,
    mutate_bias: bool = False,
    mutate_reset: bool = False,
    mutate_update: bool = False,
    mutate_candidate: bool = False,
):
    """Set the given population as mutations of the given genome."""
    assert weight_range > hops
    r = int(weight_range / hops)

    # Re-initialize the weight around the provided genome
    pop.population = dict()
    genome_key = 0

    # Create genome-mutations
    if mutate_bias:
        for i in range(3):
            for a in range(-r, r + 1):
                new_genome = copy.deepcopy(pop.best_genome)
                new_genome.nodes[2].bias_h[
                    i] = new_genome.nodes[2].bias_h[i] + a * hops
                new_genome.key = genome_key
                pop.population[genome_key] = new_genome
                genome_key += 1

    if mutate_reset:
        for a in range(-r, r + 1):
            for b in range(-r, r + 1):
                new_genome = copy.deepcopy(pop.best_genome)
                new_genome.nodes[2].weight_xh_full[
                    0, 0] = new_genome.nodes[2].weight_xh_full[0, 0] + a * hops
                new_genome.nodes[2].weight_hh[
                    0, 0] = new_genome.nodes[2].weight_hh[0, 0] + b * hops
                new_genome.key = genome_key
                pop.population[genome_key] = new_genome
                genome_key += 1

    if mutate_update:
        for a in range(-r, r + 1):
            for b in range(-r, r + 1):
                new_genome = copy.deepcopy(pop.best_genome)
                new_genome.nodes[2].weight_xh_full[
                    1, 0] = new_genome.nodes[2].weight_xh_full[1, 0] + a * hops
                new_genome.nodes[2].weight_hh[
                    1, 0] = new_genome.nodes[2].weight_hh[1, 0] + b * hops
                new_genome.key = genome_key
                pop.population[genome_key] = new_genome
                genome_key += 1

    if mutate_candidate:
        for a in range(-r, r + 1):
            for b in range(-r, r + 1):
                new_genome = copy.deepcopy(pop.best_genome)
                new_genome.nodes[2].weight_xh_full[
                    2, 0] = new_genome.nodes[2].weight_xh_full[2, 0] + a * hops
                new_genome.nodes[2].weight_hh[
                    2, 0] = new_genome.nodes[2].weight_hh[2, 0] + b * hops
                new_genome.key = genome_key
                pop.population[genome_key] = new_genome
                genome_key += 1

    # Save the updated population
    pop.save()