def evolutionary_run(gens, pop_size, output_path, run_num, numofjoints): """ Conduct an evolutionary run using the snake and muscle model. """ params = NEAT.Parameters() params.CompatTreshold = 5.0 params.CompatTresholdModifier = 0.3 params.YoungAgeTreshold = 15 params.SpeciesMaxStagnation = 1000 params.OldAgeTreshold = 35 params.MinSpecies = 1 params.MaxSpecies = 25 params.RouletteWheelSelection = False params.RecurrentProb = 0.25 params.OverallMutationRate = 0.33 params.MutateWeightsProb = 0.90 params.WeightMutationMaxPower = 1.0 params.WeightReplacementMaxPower = 5.0 params.MutateWeightsSevereProb = 0.5 params.WeightMutationRate = 0.75 params.MaxWeight = 20 params.MutateAddNeuronProb = 0.4 params.MutateAddLinkProb = 0.4 params.MutateRemLinkProb = 0.05 params.CrossoverRate = 0.4 assert pop_size >= 0, "wrong population size argument! pop_size: %d" % pop_size params.PopulationSize = pop_size # worm has only one dof (turning around y-axis) per joint num_outputs = numofjoints # the inputs for the ANN are the 7 current joint positions and the amplitude of a sine wave as well as a bias num_inputs = numofjoints + 1 + 1 # Initialize the population # Genome(ID, NumInputs, NumHidden, NumOutputs, ActivationFunction?, Output activation function, Hidden layer acitvation function, seed, params) genome = NEAT.Genome(0, num_inputs, 0, num_outputs, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) # Population(Genome, params, randomizedweights?, randomrange) population = NEAT.Population(genome, params, True, 1.0) genome_list = NEAT.GetGenomeList(population) morph_pop = MorphGenomes(pop_size) for ind in genome_list: morph_pop.addIndividual(ind.GetID()) morph_genomes = morph_pop.getGenomes() # ANN genome and morphology genome are zipped together # Zip the two genome components together for use in the parallel call. zip_args = [(ind, morph_genomes[ind.GetID()]) for ind in genome_list] mnlog.write_population_statistics_headers(output_path + str(run_num) + "_fitnesses.dat") # Setup multiprocessing cores = mpc.cpu_count() #cores = 1 pool = mpc.Pool(initializer=initProcess, initargs=( GlobalVarWorkaround.args, GlobalVarWorkaround.man, GlobalVarWorkaround.worm, ), processes=cores) assert gens >= 0, "wrong number of generations as argument! gens: %d" % gens for gen in xrange(gens): print gen #fitnesses = map(evaluate_individual,zip_args) # serial execution fitnesses = pool.map(evaluate_individual, zip_args) replace_nanfitnesses(fitnesses) for g, f in zip(genome_list, fitnesses): g.SetFitness(f) print("Generation " + str(gen) + "\t: " + str(max(fitnesses))) # Write the best performing individual to a file. mnlog.write_best_individual( output_path + "best_individuals/Evo_NEAT_run_" + str(run_num) + "_best_gen_" + str(gen) + ".dat", genome_list[fitnesses.index(max(fitnesses))]) morph_pop.logGenome( genome_list[fitnesses.index(max(fitnesses))].GetID(), "Evo_NEAT_run_" + str(run_num) + "_best_gen_" + str(gen), output_path) # Write information about the best individual we wrote. with open( output_path + "/" + str(run_num) + "_best_individuals_logging.dat", "a") as f: f.write("Generation: "+str(gen)+" Individual is: "+str(genome_list[fitnesses.index(max(fitnesses))].GetID())+\ " Fitness is: "+str(max(fitnesses))+"\n") # Log the progress of the entire population. mnlog.write_population_statistics( output_path + str(run_num) + "_fitnesses.dat", genome_list, fitnesses, gen) # Log the final population for later evaluation. if gen == gens - 1: population.Save(output_path + "run_" + str(run_num) + "_population_generation_" + str(gen) + ".dat") # Create the next generation population.Epoch() genome_list = NEAT.GetGenomeList(population) morph_pop.NextGen() zip_args = [] for ind in genome_list: # PID .. parent ID pid1 = ind.GetPID1() # if pid2 is negative it means that no crossover happend! pid2 = ind.GetPID2() gid = ind.GetID() # Handle Crossover morph_pop.Crossover(gid, pid1, pid2) # Handle Mutation morph_pop.MutatePopulation() # Zip the arguments for calling the evolution function. morph_genomes = morph_pop.getGenomes() zip_args = [(ind, morph_genomes[ind.GetID()]) for ind in genome_list]
def evolutionary_run(**kwargs): """ Conduct an evolutionary run. Args: gens: generations of evolution pop_size: population size mut_prob: mutation probability """ global args, current_network, run_num, output_path, population_size, simulation params = NEAT.Parameters() params.CompatTreshold = 5.0 params.CompatTresholdModifier = 0.3 params.YoungAgeTreshold = 15 params.SpeciesMaxStagnation = 50 params.OldAgeTreshold = 35 params.MinSpecies = 1 params.MaxSpecies = 25 params.RouletteWheelSelection = False params.RecurrentProb = 0.25 params.OverallMutationRate = 0.33 params.MutateWeightsProb = 0.90 params.WeightMutationMaxPower = 1.0 params.WeightReplacementMaxPower = 5.0 params.MutateWeightsSevereProb = 0.5 params.WeightMutationRate = 0.75 params.MaxWeight = 20 params.MutateAddNeuronProb = 0.04 params.MutateAddLinkProb = 0.1 params.MutateRemSimpleNeuronProb = 0.04 params.MutateRemLinkProb = 0.1 # Phased Searching # params.PhasedSearching = True; # params.SimplifyingPhaseMPCTreshold = 20; # params.SimplifyingPhaseStagnationTreshold = 20; # params.ComplexityFloorGenerations = 20; params.PopulationSize = kwargs['pop_size'] params.Save(output_path + str(run_num) + "_NEAT_params.cfg") # Initialize the populations genome = NEAT.Genome(0, 22, 0, 16, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) # If not including a periodic input. if args.no_periodic: genome = NEAT.Genome(0, 21, 0, 16, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) population = NEAT.Population(genome, params, True, 1.0) genome_list = NEAT.GetGenomeList(population) mnlog.write_population_statistics_headers( output_path + str(run_num) + "_fitnesses.dat", optional_additions="Num_Neurons,Num_Connections") # Setup multiprocessing cores = mpc.cpu_count() pool = mpc.Pool(processes=cores - 2) for gen in xrange(kwargs['gens']): ind_descriptor = pool.map( evaluate_individual, genome_list) # 0 - fit, 1 - # neurons, 2 - # connections fitnesses = [] num_conns = [] num_neurons = [] for g, ind in zip(genome_list, ind_descriptor): g.SetFitness(ind[0]) fitnesses.append(ind[0]) num_neurons.append(ind[1]) num_conns.append(ind[2]) print("Generation " + str(gen) + "\t: " + str(max(fitnesses))) # Write the best performing individual to a file. mnlog.write_best_individual( output_path + "best_individuals/Evo_NEAT_Mus_run_" + str(run_num) + "_best_gen_" + str(gen) + ".dat", genome_list[fitnesses.index(max(fitnesses))]) # Log the progress of the entire population. mnlog.write_population_statistics( output_path + str(run_num) + "_fitnesses.dat", genome_list, fitnesses, gen, optional_additions=zip(num_neurons, num_conns)) # Log the final population for later evaluation. if gen == kwargs['gens'] - 1: population.Save(output_path + "run_" + str(run_num) + "_population_generation_" + str(gen) + ".dat") # Create the next generation population.Epoch() # Get the genomes genome_list = NEAT.GetGenomeList(population)
def evolutionary_run(**kwargs): """ Conduct an evolutionary run using the snake and muscle model. Args: gens: generations of evolution pop_size: population size mut_prob: mutation probability """ global args, current_network, run_num, output_path, population_size, simulation params = NEAT.Parameters() params.CompatTreshold = 5.0 params.CompatTresholdModifier = 0.3 params.YoungAgeTreshold = 15 params.SpeciesMaxStagnation = 50 params.OldAgeTreshold = 35 params.MinSpecies = 1 params.MaxSpecies = 25 params.RouletteWheelSelection = False params.RecurrentProb = 0.25 params.OverallMutationRate = 0.33 params.MutateWeightsProb = 0.90 params.WeightMutationMaxPower = 1.0 params.WeightReplacementMaxPower = 5.0 params.MutateWeightsSevereProb = 0.5 params.WeightMutationRate = 0.75 params.MaxWeight = 20 params.MutateAddNeuronProb = 0.04 params.MutateAddLinkProb = 0.1 params.MutateRemSimpleNeuronProb = 0.04 params.MutateRemLinkProb = 0.1 # Phased Searching # params.PhasedSearching = True; # params.SimplifyingPhaseMPCTreshold = 20; # params.SimplifyingPhaseStagnationTreshold = 20; # params.ComplexityFloorGenerations = 20; params.PopulationSize = kwargs['pop_size'] params.Save(output_path+str(run_num)+"_NEAT_params.cfg") # Initialize the populations genome = NEAT.Genome(0, 22, 0, 8, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) # If not including a periodic input. if args.no_periodic: genome = NEAT.Genome(0, 21, 0, 8, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) population = NEAT.Population(genome, params, True, 1.0) genome_list = NEAT.GetGenomeList(population) # Initialize the muscle groups either symmetrically or not symmetrically. if args.sym_mus_groups: mus_networks = {ind.GetID(): MuscleNetwork(gid=ind.GetID(),num_groups=4,num_nodes=[4,4,4,4]) for ind in genome_list} else: mus_networks = {ind.GetID(): MuscleNetwork(gid=ind.GetID(),num_groups=8,num_nodes=[4,4,4,4,4,4,4,4]) for ind in genome_list} mnlog.write_population_statistics_headers(output_path+str(run_num)+"_fitnesses.dat",optional_additions="Num_Neurons,Num_Connections") # Setup multiprocessing cores = mpc.cpu_count() pool = mpc.Pool(processes=cores-2) # Zip the arguments for the evaluate wrapper function. zip_args = [(ind,mus_networks[ind.GetID()]) for ind in genome_list] for gen in xrange(kwargs['gens']): ind_descriptor = pool.map(evaluate_individual,zip_args) # fitnesses = pool.map( # Simulation(log_frames=args.log_frames, run_num=args.run_num, eval_time=args.eval_time, dt=.02, n=4), # zip_args # ) fitnesses = [] num_conns = [] num_neurons = [] for g,ind in zip(genome_list,ind_descriptor): g.SetFitness(ind[0]) fitnesses.append(ind[0]) num_neurons.append(ind[1]) num_conns.append(ind[2]) print("Generation "+str(gen)+"\t: "+str(max(fitnesses))) # Write the best performing individual to a file. mnlog.write_best_individual(output_path+"best_individuals/Evo_NEAT_Mus_run_"+str(run_num)+"_best_gen_"+str(gen)+".dat", genome_list[fitnesses.index(max(fitnesses))]) muslog.write_network(output_path+"best_individuals/Evo_NEAT_Mus_run_"+str(run_num)+"_best_mn_gen_"+str(gen)+".dat", mus_networks[genome_list[fitnesses.index(max(fitnesses))].GetID()]) # Log the progress of the entire population. mnlog.write_population_statistics(output_path+str(run_num)+"_fitnesses.dat", genome_list, fitnesses, gen, optional_additions=zip(num_neurons,num_conns)) # Log the final population for later evaluation. if gen == kwargs['gens'] - 1: population.Save(output_path+"run_"+str(run_num)+"_population_generation_"+str(gen)+".dat") muslog.write_networks(output_path+"run_"+str(run_num)+"_population_generation_mus_nets_"+str(gen)+".dat", [mn for k, mn in mus_networks.iteritems()]) # Create the next generation population.Epoch() new_mus_nets = {} zip_args = [] # Perform evolutionary development of the Muscle Networks. genome_list = NEAT.GetGenomeList(population) for ind in genome_list: pid1 = ind.GetPID1() pid2 = ind.GetPID2() gid = ind.GetID() # Handle Crossover if pid2 >= 0: new_mus_nets[gid] = mus_networks[pid1].crossover(mus_networks[pid2]) else: new_mus_nets[gid] = mus_networks[pid1].copy() # Handle Mutation new_mus_nets[gid].mutate(kwargs['mut_prob']) # Set the Genome ID in the new muscle node. new_mus_nets[gid].gid = gid zip_args.append((ind,new_mus_nets[gid])) mus_networks = new_mus_nets
def evolutionary_run(**kwargs): """ Conduct an evolutionary run using the worm. Args: gens: generations of evolution pop_size: population size mut_prob: mutation probability """ global args, current_network, run_num, output_path, population_size, simulation params = NEAT.Parameters() params.CompatTreshold = 5.0 params.CompatTresholdModifier = 0.3 params.YoungAgeTreshold = 15 params.SpeciesMaxStagnation = 1000 params.OldAgeTreshold = 35 params.MinSpecies = 1 params.MaxSpecies = 25 params.RouletteWheelSelection = False params.RecurrentProb = 0.25 params.OverallMutationRate = 0.33 params.MutateWeightsProb = 0.90 params.WeightMutationMaxPower = 1.0 params.WeightReplacementMaxPower = 5.0 params.MutateWeightsSevereProb = 0.5 params.WeightMutationRate = 0.75 params.MaxWeight = 20 params.MutateAddNeuronProb = 0.4 params.MutateAddLinkProb = 0.4 params.MutateRemLinkProb = 0.05 params.PopulationSize = kwargs['pop_size'] # Calculate the number of inputs (without bias and periodic signal) and outputs based on the number of joints. num_outputs = kwargs['num_joints'] * 2 num_inputs = kwargs['num_joints'] * 2 + kwargs['num_joints'] + 1 # Initialize the populations genome = NEAT.Genome(0, num_inputs + 2, 0, num_outputs, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) # If not including a periodic input. if args.no_periodic: genome = NEAT.Genome(0, num_inputs + 1, 0, num_outputs, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) population = NEAT.Population(genome, params, True, 1.0) mnlog.write_population_statistics_headers(output_path + str(run_num) + "_fitnesses.dat") # Setup multiprocessing cores = mpc.cpu_count() pool = mpc.Pool(processes=cores - 2) for gen in xrange(kwargs['gens']): genome_list = NEAT.GetGenomeList(population) fitnesses = pool.map(evaluate_individual, genome_list) #fitnesses = [] #for g_l in genome_list: # fitnesses.append(evaluate_individual(g_l)) for g, f in zip(genome_list, fitnesses): g.SetFitness(f) print("Generation " + str(gen) + "\t: " + str(max(fitnesses))) # Write the best performing individual to a file. mnlog.write_best_individual( output_path + "best_individuals/Evo_NEAT_run_" + str(run_num) + "_best_gen_" + str(gen) + ".dat", genome_list[fitnesses.index(max(fitnesses))]) # Log the progress of the entire population. mnlog.write_population_statistics( output_path + str(run_num) + "_fitnesses.dat", genome_list, fitnesses, gen) # Log the final population for later evaluation. if gen == kwargs['gens'] - 1: population.Save(output_path + "run_" + str(run_num) + "_population_generation_" + str(gen) + ".dat") # Create the next generation population.Epoch()
def evolutionary_run(**kwargs): """ Conduct an evolutionary run using the snake and muscle model. Args: gens: generations of evolution pop_size: population size mut_prob: mutation probability """ global args, current_network, fitness_function, run_num, output_path, population_size, simulation params = NEAT.Parameters() params.CompatTreshold = 5.0 params.CompatTresholdModifier = 0.3 params.YoungAgeTreshold = 15 params.SpeciesMaxStagnation = 1000 params.OldAgeTreshold = 35 params.MinSpecies = 1 params.MaxSpecies = 25 params.RouletteWheelSelection = False params.RecurrentProb = 0.25 params.OverallMutationRate = 0.33 params.MutateWeightsProb = 0.90 params.WeightMutationMaxPower = 1.0 params.WeightReplacementMaxPower = 5.0 params.MutateWeightsSevereProb = 0.5 params.WeightMutationRate = 0.75 params.MaxWeight = 20 params.MutateAddNeuronProb = 0.4 params.MutateAddLinkProb = 0.4 params.MutateRemLinkProb = 0.05 params.PopulationSize = kwargs['pop_size'] # Initialize the population if args.fixed_strength: genome = NEAT.Genome(0, 22, 0, 16, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) # If not including a periodic input. if args.no_periodic: genome = NEAT.Genome(0, 21, 0, 16, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) else: genome = NEAT.Genome(0, 22, 0, 24, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) # If not including a periodic input. if args.no_periodic: genome = NEAT.Genome(0, 21, 0, 24, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) population = NEAT.Population(genome, params, True, 1.0) genome_list = NEAT.GetGenomeList(population) morph_pop = MorphGenomes(kwargs['pop_size']) for ind in genome_list: morph_pop.addIndividual(ind.GetID()) morph_genomes = morph_pop.getGenomes() # Zip the two genome components together for use in the parallel call. zip_args = [(ind, morph_genomes[ind.GetID()]) for ind in genome_list] mnlog.write_population_statistics_headers( output_path + str(run_num) + "_fitnesses.dat", optional_additions="Distance,Efficiency") # Setup multiprocessing cores = mpc.cpu_count() pool = mpc.Pool(processes=cores - 2) for gen in xrange(kwargs['gens']): #fitnesses = [] #for z in zip_args: # fitnesses.append(evaluate_individual(z)) fitnesses = pool.map(evaluate_individual, zip_args) # Validate the fitnesses. fitnesses = check_valid_fitnesses(fitnesses) # Set the fitnesses appropriately. genome_list, fitnesses, dist_fit = set_sliding_window_fitnesses( genome_list, fitnesses, args.window_size, fitness_function) print("Generation " + str(gen) + "\t: " + str(max(zip(*fitnesses)[1]))) # Write the best performing individual to a file. mnlog.write_best_individual( output_path + "best_individuals/Evo_NEAT_run_" + str(run_num) + "_best_gen_" + str(gen) + ".dat", genome_list[dist_fit.index(max(dist_fit))] ) #genome_list[fitnesses.index(max(zip(*fitnesses)[2]))] morph_pop.logGenome( genome_list[fitnesses.index(max(fitnesses))].GetID(), "Evo_NEAT_run_" + str(run_num) + "_best_gen_" + str(gen), output_path) # Write information about the best individual we wrote. with open( output_path + "/" + str(run_num) + "_best_individuals_logging.dat", "a") as f: f.write("Generation: "+str(gen)+" Individual is: "+str(genome_list[dist_fit.index(max(dist_fit))].GetID())+\ " Fitness is: "+str(max(dist_fit))+"\n") # Log the progress of the entire population. mnlog.write_population_statistics_multi_component( output_path + str(run_num) + "_fitnesses.dat", genome_list, fitnesses, gen) # Log the final population for later evaluation. if gen == kwargs['gens'] - 1: population.Save(output_path + "run_" + str(run_num) + "_population_generation_" + str(gen) + ".dat") # Create the next generation population.Epoch() morph_pop.NextGen() genome_list = NEAT.GetGenomeList(population) zip_args = [] for ind in genome_list: pid1 = ind.GetPID1() pid2 = ind.GetPID2() gid = ind.GetID() # Handle Crossover morph_pop.Crossover(gid, pid1, pid2) # Handle Mutation morph_pop.MutatePopulation() # Zip the arguments for calling the evolution function. morph_genomes = morph_pop.getGenomes() zip_args = [(ind, morph_genomes[ind.GetID()]) for ind in genome_list]
def evolutionary_run(**kwargs): """ Conduct an evolutionary run. Args: gens: generations of evolution pop_size: population size mut_prob: mutation probability """ global args, current_network, run_num, output_path, population_size, simulation params = NEAT.Parameters() params.CompatTreshold = 5.0 params.CompatTresholdModifier = 0.3 params.YoungAgeTreshold = 15 params.SpeciesMaxStagnation = 50 params.OldAgeTreshold = 35 params.MinSpecies = 1 params.MaxSpecies = 25 params.RouletteWheelSelection = False params.RecurrentProb = 0.25 params.OverallMutationRate = 0.33 params.MutateWeightsProb = 0.90 params.WeightMutationMaxPower = 1.0 params.WeightReplacementMaxPower = 5.0 params.MutateWeightsSevereProb = 0.5 params.WeightMutationRate = 0.75 params.MaxWeight = 20 params.MutateAddNeuronProb = 0.04 params.MutateAddLinkProb = 0.1 params.MutateRemSimpleNeuronProb = 0.04 params.MutateRemLinkProb = 0.1 # Phased Searching # params.PhasedSearching = True; # params.SimplifyingPhaseMPCTreshold = 20; # params.SimplifyingPhaseStagnationTreshold = 20; # params.ComplexityFloorGenerations = 20; params.PopulationSize = kwargs['pop_size'] params.Save(output_path+str(run_num)+"_NEAT_params.cfg") # Initialize the populations genome = NEAT.Genome(0, 22, 0, 16, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) # If not including a periodic input. if args.no_periodic: genome = NEAT.Genome(0, 21, 0, 16, False, NEAT.ActivationFunction.SIGNED_SIGMOID, NEAT.ActivationFunction.SIGNED_SIGMOID, 0, params) population = NEAT.Population(genome, params, True, 1.0) genome_list = NEAT.GetGenomeList(population) mnlog.write_population_statistics_headers(output_path+str(run_num)+"_fitnesses.dat",optional_additions="Num_Neurons,Num_Connections") # Setup multiprocessing cores = mpc.cpu_count() pool = mpc.Pool(processes=cores-2) for gen in xrange(kwargs['gens']): ind_descriptor = pool.map(evaluate_individual,genome_list) # 0 - fit, 1 - # neurons, 2 - # connections fitnesses = [] num_conns = [] num_neurons = [] for g,ind in zip(genome_list,ind_descriptor): g.SetFitness(ind[0]) fitnesses.append(ind[0]) num_neurons.append(ind[1]) num_conns.append(ind[2]) print("Generation "+str(gen)+"\t: "+str(max(fitnesses))) # Write the best performing individual to a file. mnlog.write_best_individual(output_path+"best_individuals/Evo_NEAT_Mus_run_"+str(run_num)+"_best_gen_"+str(gen)+".dat", genome_list[fitnesses.index(max(fitnesses))]) # Log the progress of the entire population. mnlog.write_population_statistics(output_path+str(run_num)+"_fitnesses.dat", genome_list, fitnesses, gen, optional_additions=zip(num_neurons,num_conns)) # Log the final population for later evaluation. if gen == kwargs['gens'] - 1: population.Save(output_path+"run_"+str(run_num)+"_population_generation_"+str(gen)+".dat") # Create the next generation population.Epoch() # Get the genomes genome_list = NEAT.GetGenomeList(population)