def test_minimal(): # sample fitness function def eval_fitness(population): for individual in population: individual.fitness = 1.0 # creates the population local_dir = os.path.dirname(__file__) config = Config(os.path.join(local_dir, 'test_configuration')) pop = Population(config) # run the simulation for up to 20 generations pop.run(eval_fitness, 20) # get statistics avg_fitness = pop.statistics.get_average_fitness() assert len(avg_fitness) == 1 assert all(f == 1 for f in avg_fitness) # Change fitness threshold and do another run. config.max_fitness_threshold = 1.1 pop = Population(config) # runs the simulation for 20 generations pop.run(eval_fitness, 20) # get statistics avg_fitness = pop.statistics.get_average_fitness() assert len(avg_fitness) == 20 assert all(f == 1 for f in avg_fitness)
def main(): try: pop = Population.load_from_file(constants.res_loc("networks") + pop_name + ".pop") except: seed = random.randint(0, 1000) pop = Population(seed, 100) pool = Pool(number_of_processes) while True: worlds = [] for net in pop.current_generation: nWorld = NeuronalWorld(pop.seed, net) worlds.append(nWorld) nWorld.generatePlatform() # evaluate all neuronal worlds fitnesses = pool.map(evaluate, worlds) # set the fitness (because multiprocessing) for world, fit in zip(worlds, fitnesses): world.nn.fitness = fit path = constants.res_loc("networks") + pop.name + ".pop" pop.save_to_file(path) best_fitness = max(nn.fitness for nn in pop.current_generation) print("best fitness:", best_fitness) pop.create_next_generation() pop.generation_count += 1
def evolve(config, evalfun, seed, task_name, ngen, checkpoint): ''' NEAT evolution with parallel evaluator ''' # Set random seed (including None) random.seed(seed) # Make directories for saving results os.makedirs('models', exist_ok=True) os.makedirs('visuals', exist_ok=True) # Create an ordinary population or a population for NoveltySearch pop = _NoveltyPopulation(config) if config.is_novelty() else Population( config) # Add a stdout reporter to show progress in the terminal. pop.add_reporter(_StdOutReporter(show_species_detail=False)) stats = neat.StatisticsReporter() pop.add_reporter(stats) # Add a reporter (which can also checkpoint the best) pop.add_reporter(_SaveReporter(task_name, checkpoint)) # Create a parallel fitness evaluator pe = neat.ParallelEvaluator(mp.cpu_count(), evalfun) # Run for number of generations specified in config file winner = pop.run(pe.evaluate) if ngen is None else pop.run( pe.evaluate, ngen) # Save winner config.save_genome(winner)
def __init__(self, seed, setContextFunc, population=None, train=True): BaseContext.__init__(self, setContextFunc) self.seed = seed self.pop = Population(seed, 100) if population is None else population if train: self.worlds = [] for net in sorted(self.pop.current_generation, key=lambda x: x.fitness, reverse=True): nWorld = NeuronalWorld(self.pop.seed, net) nWorld.renderer = RenderNeuronalWorld(nWorld) self.worlds.append(nWorld) nWorld.generatePlatform() else: best_nn = max((n for n in self.pop.current_generation), key=lambda x: x.fitness) nWorld = NeuronalWorld(self.pop.seed, best_nn) nWorld.renderer = RenderNeuronalWorld(nWorld) self.worlds = [nWorld] self.drawmode = 0 self._train = train # the gui overlays self._overlays = texhandler.adjustedSurface(texhandler.Textures.overlays, height=48) fontObj = SysFont("Monospace", 30, bold=True) # mode switch buttons self.addElements({ "bNext": GuiButton(constants.screenWidth - 100, constants.screenHeight - 70, fontObj, "->", width=70).connect(self.buttonModeSwitch, 1), "bPrevious": GuiButton(30, constants.screenHeight - 70, fontObj, "<-", width=70).connect( self.buttonModeSwitch, -1) })
def __init__(self, organism_type, config={}, assessor_function=None, verbose=True): self.organism_type = organism_type self.check_organism_type() self.verbose = verbose self.assessor_function = assessor_function self.config = dict(self.default_config(), **config) self.population = Population(organism_type, self.config)
def restore_checkpoint(filename): """Resumes the simulation from a previous saved point.""" with gzip.open(filename) as f: generation, config, population, species_set, rndstate = pickle.load( f) random.setstate(rndstate) return Population(config, (population, species_set, generation))
def restore_checkpoint(filename): """Resumes the simulation from a previous saved point.""" with open(filename, 'rb') as f: generation, config, population, species_set, best_genome, rndstate = dill.load( f) random.setstate(rndstate) return Population(config, (population, species_set, generation))
def test_minimal(): local_dir = os.path.dirname(__file__) config_path = os.path.join(local_dir, 'test_configuration') pop = Population(config_path) pe = parallel.ParallelEvaluator(4, eval_fitness) pop.run(pe.evaluate, 400)
def _epoch(self): if self.current_generation == 0: self.population = Population(self.configuration) else: # Create the next generation from the current generation. self.population.population = self.population.reproduction.reproduce(self.population.config, self.population.species, self.population.config.pop_size, self.population.generation) # Check for complete extinction. if not self.population.species.species: self.population.reporters.complete_extinction() # If requested by the user, create a completely new population, # otherwise raise an exception. if self.population.config.reset_on_extinction: self.population.population = self.population.reproduction.create_new(self.population.config.genome_type, self.population.config.genome_config, self.population.config.pop_size) else: raise CompleteExtinctionException() # Evaluate all genomes using the user-provided function. self._eval_genomes(list(iteritems(self.population.population)), self.population.config) # Gather and report statistics. best = None for g in itervalues(self.population.population): if best is None or g.fitness > best.fitness: best = g # Track the best genome ever seen. if self.population.best_genome is None or best.fitness > self.population.best_genome.fitness: self.population.best_genome = best self.champion = self.population.best_genome # Divide the new population into species. self.population.species.speciate(self.population.config, self.population.population, self.population.generation) return self.stopping_criterion.evaluate(self)
def test_checkpoint(): # sample fitness function def eval_fitness(population): for individual in population: individual.fitness = 0.99 # creates the population local_dir = os.path.dirname(__file__) config = Config(os.path.join(local_dir, 'test_configuration')) pop = Population(config) pop.run(eval_fitness, 20) t = tempfile.NamedTemporaryFile(delete=False) t.close() pop.save_checkpoint(t.name) pop2 = Population(config) pop2.load_checkpoint(t.name)
def __init__(self, config: Config): self.config = config self.population = Population(self.config) self.observers = [] # type: List[AbstractObserver] self.best_genotype = None self.best_genotype_score = None self.best_genotypes = [] self.min_score_history = [] self.avg_score_history = [] self.max_score_history = [] self.max_score_history_gens = []
def restore_checkpoint(filename): """Resumes the simulation from a previous saved point.""" with gzip.open(filename) as f: generation, config, population, species_set, rndstate = pickle.load( f) random.setstate(rndstate) # print('generation: ', generation) # print('config: ', config) pop = list(population.keys()) pop.sort() # print('population: ', population) # print('-'*20) # print('species_set: ', species_set) # print('rndstate: ', rndstate) return Population(config, (population, species_set, generation))
def test_config_options(): # sample fitness function def eval_fitness(population): for individual in population: individual.fitness = 1.0 local_dir = os.path.dirname(__file__) config = Config(os.path.join(local_dir, 'test_configuration')) for hn in (0, 1, 2): config.hidden_nodes = hn for fc in (0, 1): config.fully_connected = fc for act in activation_functions.functions.keys(): config.allowed_activation = [act] for ff in (0, 1): config.feedforward = ff pop = Population(config) pop.run(eval_fitness, 250)
def restore_checkpoint(filename): """Resumes the simulation from a previous saved point.""" with gzip.open(filename) as f: generation, config, population, species_set, rndstate = pickle.load( f) # Truncates the fitplot data file to the current generation: rebuilt = [] with open('fitness_population', 'r') as f: lines = f.readlines() for line in lines: if line.startswith(str(generation)): break else: rebuilt.append(line) if rebuilt: with open('fitness_population', 'w') as f: f.writelines(rebuilt) random.setstate(rndstate) return Population(config, (population, species_set, generation))
def __init__(self, env, n_pops=150, offline=False): self.env = env self.n_trials = env.spec.trials self.reward_threshold = env.spec.reward_threshold genesis = Creature(env.observation_space.shape[0], env.action_space.n) self.population = Population(genesis, n_pops) self.fitness_history = [] self.snapshot_i = 0 run_id_hash = hashlib.sha1() run_id_hash.update(str(time()).encode('utf-8')) self.run_id = run_id_hash.hexdigest()[:16] self.offline = offline if not self.offline: r = requests.request('POST', NeatAlgorithm.api_url + '/runs', json=dict(id=self.run_id)) if r.status_code != 201: print('WARNING: Could not add run data to database.') print(r.json())
if self.isRendered: screen.fill(colors.black) ship.draw(screen) for bullet in bullets: bullet.draw(screen) for asteroid in asteroids: asteroid.draw(screen) pygame.display.flip() clock.tick(60) fitness = self.score if self.shoots > 0: fitness += self.score / self.shoots * 68 fitness += self.time / 4000 * 68 return [fitness, self.score] p = Population(300) for i in range(100): for genome in p.genomes: for j in range(5): result = Game.forAI(genome, False).run() genome.fitness += result[0] / 5 if result[1] > genome.score: genome.score = result[1] print "=======================================================" print "best fitness: %s" % max([g.fitness for g in p.genomes]) p.naturalSelection() while True: raw_input("Press Enter") Game.forAI(p.champion).run()
def main(): """ The program's starting point and main logic """ # Initialize pygame, the screen and the framerate clock pygame.init() screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) frame_clock = pygame.time.Clock() # Lists to keep track of fitness and best network for every generation fitness_history = [] network_history = [] # Parse the map description and generate walls and checkpoints accordingly start_pos, walls, checkpoints = game_map.gen_map('assets/track.png') # Instantiate a new game simulation game = Game(CARS_PER_GENERATION, start_pos, walls, checkpoints) # Generate an initial population (with networks which have 4 inputs and 4 outputs) population = Population(CARS_PER_GENERATION, 4, 4) cur_generation = 0 # Compute the usable neural network for each genome in the initial population networks = [ organism.genome.as_neural_network() for organism in population.organisms ] # The car sensor data that the neural networks use is the values sensed last frame, so we need # to save them last_car_sensors = None # We track the total runtime of the generation simulation so we can stop if the cars get stuck # but don't die running_time = 0 # We also track the fitness from the last simulation update so we can detect if there was a # positivedelta in fitness, i.e. the cars made progress last_fitness = None while True: # Handle pygame events for event in pygame.event.get(): if event.type == pygame.QUIT: # Exit if the close button was pressed sys.exit() elif event.type == pygame.KEYDOWN: # Keyboard shortcuts if event.key == pygame.K_f: # If the letter `f` was pressed, print the fitness of all simulated cars print(game.get_cars_fitness()) elif event.key == pygame.K_s: # If the letter `s` was pressed, dump the history print('fitness_history =', fitness_history) print('network_history =', network_history) fitness = game.get_cars_fitness() if last_fitness is not None: # We go through each car and check if its fitness improved by some epsilon, to detect if # any of the cars made progress had_progress = False for last, cur in zip(last_fitness, fitness): if cur > last + 0.05: had_progress = True break # If some car did make progress, we don't want to end the simulation early, so we push # back the runtime by 100ms if had_progress: running_time = max(0, running_time - 100) last_fitness = fitness # If all the cars have died by colliding with a wall, or the cars did not make sufficient # progress in over 1 second (1000ms), we end the simulation if all(game.dead) or running_time > 1000: print(f'Finished generation {cur_generation}') print( f'Average: {sum(fitness)/len(fitness):5.2f} Max: {max(fitness):5.2f}' ) # Record the fitness scores of each car in the generation fitness_history.append(fitness) # Find and record the genome of the most fit organism fo this generation best_idx = 0 for i in range(1, CARS_PER_GENERATION): if fitness[i] > fitness[best_idx]: best_idx = i network_history.append( population.organisms[best_idx].genome.connections) # Update NEAT's view of the fitness scores of the organisms so the genetic algorithm # can proceed. A tiny epsilon is added because a fitness score of zero does not work # well when the relative fitness is calculated for i in range(CARS_PER_GENERATION): population.organisms[i].fitness = 0.00001 + fitness[i] # Go through all of the genetic algorithm steps, creating the next generation population.epoch() # Keep track of the current generation cur_generation += 1 # Reset the running time running_time = 0 # Recompute the usable neural networks for the new organisms networks = [ organism.genome.as_neural_network() for organism in population.organisms ] # Reset the game simulation game = Game(CARS_PER_GENERATION, start_pos, walls, checkpoints) # Reset the last frame data last_car_sensors = None last_fitness = None # Background color screen.fill((57, 57, 57)) # We need to choose which car the game camera tracks: We pick the most fit car which is not # dead best_car = None for i in range(0, CARS_PER_GENERATION): if game.dead[i]: continue if best_car is None or fitness[i] > fitness[best_car]: best_car = i # If all cars are dead we just default to the first one if best_car is None: best_car = 0 game.track_car(best_car) # If this is the first frame, we don't yet have sensor data to base our decision on, so we # just don't move if last_car_sensors is None: controls = [{ 'forward': False, 'left': False, 'backward': False, 'right': False }] * CARS_PER_GENERATION else: # We compute the controls for each car controls = [] for i in range(CARS_PER_GENERATION): # We run the sensor data from last frame through the car's network network_output = networks[i].evaluate_input( last_car_sensors[i]) # We then decide whether to enable that control based on a simple threshold control = { 'forward': network_output[0] >= 0, 'left': network_output[1] >= 0, 'backward': network_output[2] >= 0, 'right': network_output[3] >= 0 } controls.append(control) # We make a simulation update step last_car_sensors = game.update(frame_clock.get_time() / 1000, controls) # We ask the game to draw the current state to the screen game.draw_scene(screen) # We draw the speedometer on top of the game, showing the speed of the tracked car ui.draw_speedometer(screen, game.cars[best_car].get_normalized_speed()) # We display the drawn frame pygame.display.flip() running_time += frame_clock.tick(30) # Limit framerate to 30 FPS
def execute(config): population = Population(config) population.evaluate(eval_xor, 600)
time_out = config.fitness_threshold proper_game = play(game=proper_tetris, brain=brain, time_out=time_out) return proper_game.score evaluator = ParallelEvaluator( num_workers=CPU_COUNT, eval_function=fitness_f, ) if __name__ == '__main__': print('CPU_COUNT:', CPU_COUNT) p = Population(MAIN_CONFIG) p.add_reporter(StdOutReporter(True)) stats = StatisticsReporter() p.add_reporter(stats) p.add_reporter(Checkpointer(50)) try: winner = p.run(evaluator.evaluate, 1000) except KeyboardInterrupt: pass stats.save() print(stats.best_genome())
def population(): pop_config = PopulationConfiguration(pop_size, inputs, outputs) population = Population(pop_config, Innovations(), MutationRates()) return population