def __init__(self, population_size=150, delta=3.0, genome_seeder=curry_genome_seeder(NEATMutator()), metric=generate_neat_metric(1, 1, 3)): """Speciated Population of genomes used within the NEAT algorithm. Extends Population class. Notes: - The distance metric allows us to speciate using a compatibility threshold delta. An ordered list of species is maintained. In each generation, genomes are sequentially placed into species. :param genome_seeder: An iterable of genomes that will be used to generate the initial population. :param population_size: An integer number giving the size of the total Population. :param delta: A float number that defines the minimum distance two genomes require to be apart before there sorted into different species. Set to None if single species is desired (no speciation). :param metric: Function that takes two genomes and returns the distance between them. The metric is used to partition the genomes into species. If None then no speciation will take place. """ super().__init__(population_size=population_size, delta=delta, genome_seeder=genome_seeder, metric=metric)
def neat_bipedal_walker(): pop_size = 400 mutator = NEATMutator(new_edge_probability=0.1, new_node_probability=0.05) genome = minimal(input_size=24, output_size=4, depth=5) seeder = curry_genome_seeder(mutator=mutator, seed_genomes=[genome]) metric = generate_neat_metric(c_1=1, c_2=1, c_3=3) population = NEATPopulation(population_size=pop_size, delta=4, genome_seeder=seeder, metric=metric) ds = DataStore(name='bip_walker_NEAT_data') assign_population_fitness = build_env(env_name='BipedalWalker-v3', num_steps=200, repetition=1) counter_fn = make_counter_fn() for i in range(500): success = assign_population_fitness(population) if success and counter_fn(): break population.speciate() data = population.to_dict() mutator(population) ds.save(data) print_progress(data) return True
def cart_pole_res_example(): genome = dense(input_size=4, output_size=1, layer_dims=[2, 2, 2]) weights_len = len(genome.edges) + len(genome.nodes) init_mu = np.random.uniform(-1, 1, weights_len) mutator = ADRESMutator(initial_mu=init_mu, std_dev=0.1) seeder = curry_genome_seeder(mutator=mutator, seed_genomes=[genome]) population = RESPopulation(population_size=50, genome_seeder=seeder) assign_population_fitness = build_env() counter_fn = make_counter_fn() for i in range(100): success = assign_population_fitness(population) if success and counter_fn(): break data = population.to_dict() mutator(population) print( f'generation: {i}, mean score: {data["mean_fitness"]}, best score: {data["best_fitness"]}' ) data = population.to_dict() run_env(data['best_genome'], render=True, env_name='CartPole-v0')
def simple_simple_example(): genome = minimal( input_size=1, output_size=1 ) weights_len = len(genome.edges) + len(genome.nodes) init_mu = np.random.uniform(-3, 3, weights_len) mutator = SIMPLEMutator( std_dev=0.01, survival_rate=0.01 ) seeder = curry_genome_seeder( mutator=mutator, seed_genomes=[genome] ) population = SIMPLEPopulation( population_size=1000, genome_seeder=seeder ) target_mu = np.random.uniform(-3, 3, len(init_mu)) assign_population_fitness = build_simple_env(target_mu) for i in range(100): assign_population_fitness(population) mutator(population) weights = np.array([genome.weights for genome in population.genomes]) mu = weights.mean(axis=0) loss = np.linalg.norm(mu - target_mu) print(f'generation: {i}, loss: {loss}')
def simple_adres_example(): genome = minimal( input_size=1, output_size=1 ) weights_len = len(genome.edges) + len(genome.nodes) init_mu = np.random.uniform(-3, 3, weights_len) mutator = ADRESMutator( initial_mu=init_mu, std_dev=0.1 ) seeder = curry_genome_seeder( mutator=mutator, seed_genomes=[genome] ) population = RESPopulation( population_size=1000, genome_seeder=seeder ) target_mu = np.random.uniform(-3, 3, len(init_mu)) assign_population_fitness = build_simple_env(target_mu) for i in range(100): assign_population_fitness(population) mutator(population) loss = np.linalg.norm(mutator.mu - target_mu) print(f'generation: {i}, loss: {loss}')
def neat_cart_pole(): pop_size = 1000 mutator = NEATMutator(new_edge_probability=0.1, new_node_probability=0.05) seed_genome = minimal(input_size=4, output_size=1, depth=5) seeder = curry_genome_seeder(mutator=mutator, seed_genomes=[seed_genome]) metric = generate_neat_metric(c_1=1, c_2=1, c_3=3) population = NEATPopulation(population_size=pop_size, genome_seeder=seeder, delta=4, metric=metric) assign_population_fitness = build_env() counter_fn = make_counter_fn() for i in range(5): success = assign_population_fitness(population) if success and counter_fn(): break population.speciate() data = population.to_dict() print_progress(data) mutator(population) score = run_env(data['best_genome'], env_name='CartPole-v0', render=True) print(f'best_fitness: {score}') return True
def test_dense_factory(self): from gerel.algorithms.RES.population import RESPopulation from gerel.algorithms.RES.mutator import RESMutator from gerel.populations.genome_seeders import curry_genome_seeder genome = dense( input_size=1, output_size=1, layer_dims=[4] ) weights_len = len(genome.edges) + len(genome.nodes) init_mu = np.random.uniform(-1, 1, weights_len) mutator = RESMutator( initial_mu=init_mu, std_dev=0.1, alpha=0.1 ) seeder = curry_genome_seeder( mutator=mutator, seed_genomes=[genome] ) RESPopulation( population_size=1, genome_seeder=seeder )
def setup_simple_res_env(mutator_type=None): genome = minimal(input_size=1, output_size=1) weights_len = len(genome.edges) + len(genome.nodes) init_mu = np.random.uniform(-3, 3, weights_len) if mutator_type == RESMutator: mutator = mutator_type(initial_mu=init_mu, std_dev=0.1, alpha=1) elif mutator_type == ADRESMutator: mutator = mutator_type(initial_mu=init_mu, std_dev=0.1) else: mutator = SIMPLEMutator(std_dev=0.01, survival_rate=0.1) seeder = curry_genome_seeder(mutator=mutator, seed_genomes=[genome]) population = RESPopulation(population_size=1000, genome_seeder=seeder) return population, mutator, init_mu
def bipedal_walker_RES(): genome = dense( input_size=24, output_size=4, layer_dims=[20] ) weights_len = len(genome.edges) + len(genome.nodes) init_mu = np.random.uniform(-1, 1, weights_len) mutator = RESMutator( initial_mu=init_mu, std_dev=0.5, alpha=1 ) seeder = curry_genome_seeder( mutator=mutator, seed_genomes=[genome] ) population = RESPopulation( population_size=400, genome_seeder=seeder ) ds = DataStore(name='bip_walker_RES_data') assign_population_fitness = build_env( env_name='BipedalWalker-v3', num_steps=200, repetition=1) counter_fn = make_counter_fn() for i in range(500): success = assign_population_fitness(population) if success and counter_fn(): break data = population.to_dict() mutator(population) print_progress(data) ds.save(data) return True
def cart_pole_simple_example(): genome = dense(input_size=4, output_size=1, layer_dims=[2, 2, 2]) mutator = SIMPLEMutator(std_dev=0.1, survival_rate=0.1) seeder = curry_genome_seeder(mutator=mutator, seed_genomes=[genome]) population = SIMPLEPopulation(population_size=50, genome_seeder=seeder) assign_population_fitness = build_env() counter_fn = make_counter_fn() for i in range(100): success = assign_population_fitness(population) if success and counter_fn(): break data = population.to_dict() mutator(population) print( f'generation: {i}, mean score: {data["mean_fitness"]}, best score: {data["best_fitness"]}' ) run_env(data['best_genome'])
def neat_xor_example(): pop_size = 150 mutator = NEATMutator( new_edge_probability=0.1, new_node_probability=0.05 ) seed_genome = minimal( input_size=2, output_size=1, depth=3 ) seeder = curry_genome_seeder( mutator=mutator, seed_genomes=[seed_genome] ) metric = generate_neat_metric() population = NEATPopulation( population_size=pop_size, delta=3, genome_seeder=seeder, metric=metric ) def xor(a, b): return bool(a) != bool(b) def generate_data(n): data = [ [[True, True], xor(True, True)], [[True, False], xor(True, False)], [[False, True], xor(False, True)], [[False, False], xor(False, False)] ] for i in range(n): yield data[i % 4] sln_count = 0 best_fitness = None for _ in tqdm(range(1000)): for genome in population.genomes: fitness = 0 best_fitness = 0 model = Model(genome.to_reduced_repr) for inputs, output in generate_data(4): pred = model(inputs)[0] pred = pred > 0 fitness += pred == output if fitness > best_fitness: best_fitness = fitness genome.fitness = fitness/4 if best_fitness == 4: sln_count += 1 if sln_count == 10: break population.speciate() mutator(population) fitness_scores = [] best_genome = None best_fitness = 0 for genome in population.genomes: fitness = 0 model = Model(genome.to_reduced_repr) for inputs, output in generate_data(4): pred = model(inputs)[0] pred = pred > 0 fitness += pred == output fitness = fitness / 4 if fitness > best_fitness: best_fitness = fitness best_genome = genome fitness_scores.append(fitness) print() print('best_fitness:', best_fitness) print_population(population) print_genome(best_genome) return True