def test_v003(): folder_path = './data/tmp1' utils.make_dir_if_not_exists(folder_path) evo = Evolution( random_seed=utils.random_int(), population_size=4, genotype_size=2, evaluation_function=lambda pop, seeds: np.sum( pop, axis=1), #np.arange(1,0,-1/len(pop)), performance_objective=0.5, #MAX MIN ZERO ABS_MAX fitness_normalization_mode='NONE', selection_mode='UNIFORM', # UNIFORM, SUS, RWS reproduce_from_elite=True, reproduction_mode= 'GENETIC_ALGORITHM', # 'GENETIC_ALGORITHM' 'HILL_CLIMBING' mutation_variance=0.1, elitist_fraction=0.5, mating_fraction=0.5, crossover_probability=0.5, crossover_mode='UNIFORM', max_generation=100, termination_function=None, checkpoint_interval=1, folder_path=folder_path, timeit=True) evo.run() evo.timing.report()
def test_random_genotypes(): # gen_size = 20 # pop_size = 96 a = Evolution.get_random_genotype(RandomState(None), 20) b = Evolution.get_random_genotype(RandomState(None), 20) a = linmap(a, (-1, 1), (0, 1)) b = linmap(b, (-1, 1), (0, 1)) dist = np.linalg.norm(a - b) similarity = 1 - dist print(a) print(b) print(a - b) print(dist) print(similarity)
def test_crossover(): evo = Evolution( population_size=0, genotype_size=10, evaluation_function=lambda _: 0, # crossover_mode = "UNIFORM" crossover_mode="1-POINT", crossover_points=[2, 5, 8]) genotype1 = [0] * evo.genotype_size genotype2 = [1] * evo.genotype_size a, b = evo.crossover(genotype1, genotype2) print(''.join(str(int(x)) for x in a)) print(''.join(str(int(x)) for x in b))
def test_random_genotype(): from dol import gen_structure from pyevolver.evolution import Evolution from numpy.random import RandomState num_dim = 1 num_neurons = 2 default_gen_structure = gen_structure.DEFAULT_GEN_STRUCTURE( num_dim, num_neurons) gen_size = gen_structure.get_genotype_size(default_gen_structure) num_brain_neurons = gen_structure.get_num_brain_neurons( default_gen_structure) print('Gen size of agent: {}'.format(gen_size)) print('Num brain neurons: {}'.format(num_brain_neurons)) random_genotype = Evolution.get_random_genotype(RandomState(None), gen_size) agent = Agent( num_dim, num_brain_neurons, brain_step_size=0.1, genotype_structure=default_gen_structure, ) agent.init_params() agent.genotype_to_phenotype(random_genotype) for i in range(10): agent.brain.euler_step() print(i) print(' brain output: {}'.format(agent.brain.output)) agent.compute_motor_outputs() print(' motor output: {}'.format(agent.motors))
def run_random_agents(): genotype_structure=gen_structure.DEFAULT_GEN_STRUCTURE(2) gen_size = gen_structure.get_genotype_size(genotype_structure) random_genotype = Evolution.get_random_genotype(RandomState(None), gen_size*2) # pairs of agents in a single genotype sim = Simulation( genotype_structure=genotype_structure, agent_body_radius=4, agents_pair_initial_distance=20, agent_sensors_divergence_angle=np.radians(45), # angle between sensors and axes of symmetry brain_step_size=0.1, trial_duration=200, # the brain would iterate trial_duration/brain_step_size number of time num_cores=1 ) trial_index = 0 data_record_list = [] random_seed = utils.random_int() perf = sim.run_simulation([random_genotype],0, random_seed, data_record_list=data_record_list) print("random perf: {}".format(perf)) data_record = data_record_list[0] vis = Visualization(sim) vis.start_simulation_from_data(trial_index, data_record)
def random_pairs(): dir = "data/2n_rp-3_shannon-dd_neural_social_coll-edge/seed_001" evo_file = os.path.join(dir, "evo_2000.json") sim_file = os.path.join(dir, "simulation.json") output_file = os.path.join(dir, "perf_dist.json") evo = Evolution.load_from_file(evo_file, folder_path=dir) sim = Simulation.load_from_file(sim_file) sim.num_random_pairings = 0 # we build the pairs dynamically pop_size = len(evo.population) best_agent = evo.population[0] if os.path.exists(output_file): perfomances, distances = read_data_from_file(output_file) else: new_population_pairs = [] perfomances = [] distances = [] for j in range(1, pop_size): b = evo.population[j] pair = np.concatenate([best_agent, b]) new_population_pairs.append(pair) distances.append(euclidean_distance(best_agent, b)) for i in tqdm(range(pop_size - 1)): perf = sim.run_simulation(new_population_pairs, i) perfomances.append(perf) write_data_to_file(perfomances, distances, output_file) plt.scatter(distances, perfomances) plt.show()
def test_mutate(): np.random.seed(11) evo = Evolution( population_size=2, genotype_size=10, search_constraint=np.array([True] * 10), # search_constraint = np.array([False] * 10), evaluation_function=lambda _: [1], max_generation=0, ) genotype = np.array([-1] * 10) mutant = evo.mutate(genotype) print(mutant) print('SUCCESS!')
def test_select_mating_pool_RWS(): from collections import Counter performances = np.array([1000, 1000, 300, 200, 200, 100, 50, 50, 50, 50]) np.random.seed(11) evo = Evolution( population_size=10, population=np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), genotype_size=1, fitness_normalization_mode='RANK', selection_mode='RWS', evaluation_function=lambda _: performances, max_generation=0, elitist_fraction=0.2, mating_fraction=0.8, # in beer this is 1 - elitist_fraction ) evo.run() print("Fitnesses: {}".format(evo.fitnesses)) # assert evo.n_elite == 2 # only in genetic algorithm # assert evo.n_fillup == 0 # only in genetic algorithm assert evo.n_mating == evo.population_size mating_counter = Counter() repetitions = 10000 for _ in range(repetitions): mating_pool = evo.select_mating_pool() for e in mating_pool: mating_counter[e] += 1 # we check if the number of time each genome is selected is proportionate to the its performance (and fitness) # not guaranteed to work for fitness_normalization_mode == 'FPS' because of the linear scaling # not easy to test this further (not implemented in beer) for i in range(2, 9): assert mating_counter[i] > mating_counter[i + 1] print(sorted(mating_counter.items(), key=lambda kv: kv[0])) print('SUCCESS!')
def single_paired_agents(input_dir='data'): """ Test whether individually evolved agents can perform the task together and calculate their combined neural complexity. """ from dol.simulation import Simulation import json seed_dir = f'{input_dir}/2n_exc-0.1_zfill/seed_001' generation = 5000 population_idx = 0 rs = RandomState(1) sim_json_filepath = os.path.join(seed_dir, 'simulation.json') evo_json_filepath = os.path.join(seed_dir, 'evo_{}.json'.format(generation)) sim = Simulation.load_from_file( sim_json_filepath, switch_agents_motor_control=True, # forcing switch num_random_pairings=1 # forcing to play with one another ) evo = Evolution.load_from_file(evo_json_filepath, folder_path=None) original_populations = evo.population_unsorted best_two_agent_pop = np.array([ [ original_populations[0][x] for x in evo.population_sorted_indexes[population_idx][:2] ] ]) data_record_list = [] performance, sim_perfs, _ = sim.run_simulation( best_two_agent_pop, 0, 0, 0, None, data_record_list ) nc = get_sim_agent_complexity( sim_perfs, sim, data_record_list, agent_index=None, sim_idx=None, analyze_sensors=True, analyze_brain=True, analyze_motors=False, combined_complexity=False, only_part_n1n2=False, rs=rs ) print('performance', performance) print("Sim agents similarity: ", sim.agents_genotype_distance[0]) print('nc', nc)
def time_evolution(): evo = Evolution( random_seed=123, population_size=5000, genotype_size=100, evaluation_function=lambda pop, seeds: [1] * len(pop), fitness_normalization_mode='RANK', selection_mode='RWS', # SUS, RWS reproduction_mode= 'GENETIC_ALGORITHM', # 'GENETIC_ALGORITHM' 'HILL_CLIMBING' mutation_variance=0.1, elitist_fraction=0.1, mating_fraction=0.9, crossover_probability=0.5, crossover_mode='1-POINT', max_generation=100, termination_function=None, checkpoint_interval=1, timeit=True) evo.run() evo.timing.report()
def test_fitness_RANK(): performances = np.array([1, 50, 15, 21, 100, 23, 88, 45, 44, 76]) evo = Evolution(population_size=10, genotype_size=0, fitness_normalization_mode='RANK', evaluation_function=lambda _: performances, max_generation=0) evo.run() correct_fitness_rank = sorted([ 0.11000000000000001, 0.10777777777777779, 0.10555555555555556, 0.10333333333333335, 0.10111111111111111, 0.09888888888888889, 0.09666666666666666, 0.09444444444444444, 0.09222222222222222, 0.09 ], reverse=True) assert list(evo.fitnesses) == correct_fitness_rank # print('fitnesses_rank: {}'.format(fitnesses_rank)) print('SUCCESS!')
def test_select_mating_pool_SUS(): np.random.seed(11) evo = Evolution( population_size=10, population=np.array(list(range(1, 11))), genotype_size=1, fitness_normalization_mode='FPS', selection_mode='SUS', reproduction_mode='GENETIC_ALGORITHM', evaluation_function=lambda _: [0.3, 0.2, 0.1, 0.1, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05], max_generation=0, elitist_fraction=0.2, mating_fraction=0.8, # in beer this is 1 - elitist_fraction ) evo.run() evo.fitnesses = np.array( [0.3, 0.2, 0.1, 0.1, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05]) # print("Fitnesses: {}".format(evo.fitnesses)) assert evo.n_mating == 8 assert evo.n_elite == 2 assert evo.n_fillup == 0 mating_pool = evo.select_mating_pool() print(mating_pool) assert mating_pool == [1, 1, 1, 2, 3, 4, 6, 8] print('SUCCESS!')
def test_fitness_FPS(): performances = np.array([1, 50, 15, 21, 100, 23, 88, 45, 44, 76]) evo = Evolution(population_size=10, genotype_size=0, fitness_normalization_mode='FPS', evaluation_function=lambda _: performances, max_generation=0) evo.run() correct_fitness_fps = sorted([ 0.09156424581005587, 0.10068901303538176, 0.09417132216014897, 0.09528864059590317, 0.11000000000000001, 0.0956610800744879, 0.10776536312849162, 0.09975791433891994, 0.09957169459962756, 0.10553072625698326 ], reverse=True) assert list(evo.fitnesses) == correct_fitness_fps # print('fitnesses_fps: {}'.format(fitnesses_fps)) print('SUCCESS!')
def main_scatter_plot(input_dir='data'): """ From a given seed, look at the last generation, and compute the neural complexity for all agents. Plot correlation between fitness and complexity. """ seed_dir = f'{input_dir}/2n_exc-0.1_zfill/seed_001' generation = 5000 pop_index = 0 analyze_sensors = True analyze_brain = True analyze_motors = False combined_complexity = False only_part_n1n2 = True rs = RandomState(1) evo_file = sorted([f for f in os.listdir(seed_dir) if 'evo_' in f])[0] evo_json_filepath = os.path.join(seed_dir, evo_file) evo = Evolution.load_from_file(evo_json_filepath, folder_path=None) pop_size = len(evo.population[0]) print('pop_size', pop_size) perf_data = np.zeros(pop_size) nc_data = np.zeros(pop_size) for genotype_idx in tqdm(range(pop_size)): perf, sim_perfs, evo, sim, data_record_list, sim_idx = run_simulation_from_dir( seed_dir, generation, genotype_idx, population_idx=pop_index, quiet=True) agent_index = None # agent_index must be None (to get best agents of the two) sim_idx = None # sim_idx must be None (to get best sim among randomom pairs) nc_avg = get_sim_agent_complexity( sim_perfs, sim, data_record_list, agent_index, sim_idx, analyze_sensors, analyze_brain, analyze_motors, combined_complexity, only_part_n1n2, rs ) perf_data[genotype_idx] = perf nc_data[genotype_idx] = nc_avg fig = plt.figure(figsize=(10, 6)) ax = fig.add_subplot(1, 1, 1) ax.scatter(perf_data, nc_data) plt.xlabel('performance') plt.ylabel('nc') plt.show()
def test_continuation(): eval_func = lambda pop, rand_seed: RandomState(rand_seed).random(len(pop)) print('Loading evolution from json file') folder_path = './tmp_cont1' utils.make_dir_if_not_exists(folder_path) evo1 = Evolution( random_seed=123, population_size=1000, genotype_size=2, evaluation_function=eval_func, fitness_normalization_mode='RANK', selection_mode='RWS', reproduction_mode= 'GENETIC_ALGORITHM', #'HILL_CLIMBING', 'GENETIC_ALGORITHM' mutation_variance=0.1, elitist_fraction=0.1, mating_fraction=0.9, crossover_probability=0.5, crossover_mode='1-POINT', max_generation=100, folder_path=folder_path, termination_function=None, checkpoint_interval=50) evo1.run() print() new_folder_path = './tmp_cont2' utils.make_dir_if_not_exists(new_folder_path) evo2 = Evolution.load_from_file(os.path.join(folder_path, 'evo_00050.json'), evaluation_function=eval_func, folder_path=new_folder_path, max_generation=110) evo2.run()
def test_random_genotype(): from dyadic_interaction import gen_structure from pyevolver.evolution import Evolution from numpy.random import RandomState default_gen_structure = gen_structure.DEFAULT_GEN_STRUCTURE(2) gen_size = gen_structure.get_genotype_size(default_gen_structure) num_brain_neurons = gen_structure.get_num_brain_neurons(default_gen_structure) print('Gen size of agent: {}'.format(gen_size)) print('Num brain neurons: {}'.format(num_brain_neurons)) random_genotype = Evolution.get_random_genotype(RandomState(None), gen_size) agent_net = AgentNetwork( num_brain_neurons, brain_step_size=0.1, genotype_structure=default_gen_structure, genotype = random_genotype ) agent_net.brain.states = np.array([0., 0.]) agent_net.brain.compute_output() print('brain output: {}'.format(agent_net.brain.output)) motor_outputs = agent_net.compute_motor_outputs() print('motor output: {}'.format(motor_outputs))
def same_pairs(): dir = "data/2n_shannon-dd_neural_social_coll-edge/seed_001" evo_file = os.path.join(dir, "evo_2000.json") sim_file = os.path.join(dir, "simulation.json") output_file = os.path.join(dir, "perf_dist.json") if os.path.exists(output_file): perfomances, distances = read_data_from_file(output_file) else: evo = Evolution.load_from_file(evo_file, folder_path=dir) sim = Simulation.load_from_file(sim_file) assert sim.num_random_pairings == 0 pop_size = len(evo.population) perfomances = [] distances = [] for i in tqdm(range(pop_size)): perf = sim.run_simulation(evo.population, i) a, b = np.array_split(evo.population[i], 2) perfomances.append(perf) distances.append(euclidean_distance(a, b)) write_data_to_file(perfomances, distances, output_file) plt.scatter(distances, perfomances) plt.show()
def run_simulation_from_dir(dir, generation=None, genotype_idx=0, **kwargs): ''' utitity function to get data from a simulation ''' random_pos_angle = kwargs.get('random_pos_angle', None) entropy_type = kwargs.get('entropy_type', None) entropy_target_value = kwargs.get('entropy_target_value', None) concatenate = kwargs.get('concatenate', None) collision_type = kwargs.get('collision_type', None) ghost_index = kwargs.get('ghost_index', None) initial_distance = kwargs.get('initial_distance', None) isolation = kwargs.get('isolation', None) write_data = kwargs.get('write_data', None) func_arguments = locals() from pyevolver.evolution import Evolution evo_files = [f for f in os.listdir(dir) if f.startswith('evo_')] assert len(evo_files) > 0, "Can't find evo files in dir {}".format(dir) file_num_zfill = len(evo_files[0].split('_')[1].split('.')[0]) if generation is None: # assumes last generation evo_files = sorted([f for f in os.listdir(dir) if f.startswith('evo')]) evo_json_filepath = os.path.join(dir, evo_files[-1]) else: generation = str(generation).zfill(file_num_zfill) evo_json_filepath = os.path.join(dir, 'evo_{}.json'.format(generation)) sim_json_filepath = os.path.join(dir, 'simulation.json') sim = Simulation.load_from_file(sim_json_filepath) evo = Evolution.load_from_file(evo_json_filepath, folder_path=dir) if initial_distance is not None: print("Forcing initial distance to: {}".format(initial_distance)) sim.agents_pair_initial_distance = initial_distance sim.set_initial_positions_angles() if random_pos_angle: print("Randomizing positions and angles") random_state = RandomState() sim.set_initial_positions_angles(random_state) if entropy_type is not None: sim.entropy_type = entropy_type print("Forcing entropy type: {}".format(sim.entropy_type)) if entropy_target_value is not None: sim.entropy_target_value = entropy_target_value print("Forcing entropy target value: {}".format( sim.entropy_target_value)) if concatenate is not None: sim.concatenate = concatenate == 'on' print("Forcing concatenation: {}".format(sim.concatenate)) if collision_type is not None: sim.collision_type = collision_type sim.init_agents_pair() print("Forcing collision_type: {}".format(sim.collision_type)) if isolation is not None: sim.isolation = isolation print("Forcing isolation to: {}".format(isolation)) data_record_list = [] genotype_idx_unsorted = evo.population_sorted_indexes[genotype_idx] random_seed = evo.pop_eval_random_seeds[genotype_idx_unsorted] if ghost_index is not None: assert ghost_index in [0, 1], 'ghost_index must be 0 or 1' # get original results without ghost condition and no random func_arguments['ghost_index'] = None func_arguments['random_pos_angle'] = False func_arguments['initial_distance'] = None func_arguments['write_data'] = None _, _, original_data_record_list = run_simulation_from_dir( **func_arguments) perf = sim.run_simulation( evo.population_unsorted, genotype_idx_unsorted, random_seed, data_record_list, ghost_index=ghost_index, original_data_record_list=original_data_record_list) print( "Overall Performance recomputed (non-ghost agent only): {}".format( perf)) else: perf = sim.run_simulation(evo.population_unsorted, genotype_idx_unsorted, random_seed, data_record_list) if genotype_idx == 0: original_perfomance = evo.best_performances[-1] print("Original Performance: {}".format(original_perfomance)) print("Overall Performance recomputed: {}".format(perf)) if write_data: for s, data_record in enumerate(data_record_list, 1): if len(data_record_list) > 1: outdir = os.path.join(dir, 'data', 'sim_{}'.format(s)) else: outdir = os.path.join(dir, 'data') utils.make_dir_if_not_exists(outdir) for t in range(sim.num_trials): for k, v in data_record.items(): if v is dict: # summary if t == 0: # only once outfile = os.path.join(outdir, '{}.json'.format(k)) utils.save_json_numpy_data(v, outfile) elif len(v) != sim.num_trials: # genotype/phenotype outfile = os.path.join(outdir, '{}.json'.format(k)) utils.save_json_numpy_data(v, outfile) elif len(v[0]) == 2: # data for each agent for a in range(2): outfile = os.path.join( outdir, '{}_{}_{}.json'.format(k, t + 1, a + 1)) utils.save_json_numpy_data(v[t][a], outfile) else: # single data for both agent (e.g., distance) outfile = os.path.join(outdir, '{}_{}.json'.format(k, t + 1)) utils.save_json_numpy_data(v[t], outfile) return evo, sim, data_record_list
def compute_std_from_random_runs(num_cores, num_good_runs, entropy_target_value): from dyadic_interaction.simulation import Simulation assert entropy_target_value in ['neural', 'distance', 'angle'] genotype_structure = gen_structure.DEFAULT_GEN_STRUCTURE(num_neurons) gen_size = gen_structure.get_genotype_size(genotype_structure) num_data_points_per_agent_pair = sim_duration * num_trials num_data_points = num_data_points_per_agent_pair * num_good_runs # 8 million! if entropy_target_value == 'distance': num_all_runs = num_good_runs * MULTIPLY_FACTOR else: num_all_runs = num_good_runs all_distances = np.zeros(num_data_points) rs = RandomState(seed) sim_array = [ Simulation( entropy_type='shannon-dd', genotype_structure=genotype_structure, ) for _ in range(num_cores) ] random_genotypes = [ Evolution.get_random_genotype(rs, gen_size * 2) for _ in range(num_all_runs) ] def run_one_core(r): data_record_list = [] sim_array[r % num_cores].run_simulation( random_genotypes, r, data_record_list=data_record_list) data_record = data_record_list[0] if entropy_target_value == 'neural': concat_outputs = np.concatenate([ data_record['brain_output'][t][a] for t in range(4) for a in range(2) ]) concat_outputs = np.concatenate( [concat_outputs[:, c] for c in range(num_neurons)]) return concat_outputs elif entropy_target_value == 'distance': concat_distances = np.concatenate(data_record['distance']) if any(concat_distances > MAX_DISTANCE): return None return concat_distances else: assert entropy_target_value == 'angle' concat_angles = np.concatenate([ data_record['angle'][t][a] for t in range(4) for a in range(2) ]) return concat_angles run_distances = Parallel( n_jobs=num_cores)( # prefer="threads" does not work delayed(run_one_core)(r) for r in tqdm(range(num_all_runs))) good_run_distances = [run for run in run_distances if run is not None] print("Number of good runs: {}".format(len(good_run_distances))) assert len(good_run_distances) >= num_good_runs all_distances = np.concatenate(good_run_distances[:num_good_runs] ) # take only the first 1000 good runs # json.dump( # all_distances, # open('data/tmp_distances.json', 'w'), # indent=3, # cls=NumpyListJsonEncoder # ) std = all_distances.std() print(std)
if args.num_random_pairings == 0: genotype_size *= 2 # two agents per genotype evo = Evolution( random_seed=args.seed, population_size=args.popsize, genotype_size=genotype_size, evaluation_function=sim.evaluate, performance_objective=args.perf_obj, fitness_normalization_mode= 'NONE', # 'NONE', FPS', 'RANK', 'SIGMA' -> NO NORMALIZATION selection_mode='UNIFORM', # 'UNIFORM', 'RWS', 'SUS' reproduce_from_elite=True, reproduction_mode= 'GENETIC_ALGORITHM', # 'HILL_CLIMBING', 'GENETIC_ALGORITHM' mutation_variance=0.1, # mutation noice with variance 0.1 elitist_fraction=0.04, # elite fraction of the top 4% solutions mating_fraction=0.96, # the remaining mating fraction crossover_probability=0.1, crossover_mode='UNIFORM', crossover_points=None, #genotype_structure['crossover_points'], folder_path=outdir, max_generation=args.num_gen, termination_function=None, checkpoint_interval=np.ceil(args.num_gen / 100), ) evo.run() if args.entropy_type == 'transfer': # shutdown JVM
def get_simulation_data_from_random_agent(gen_struct, rs, num_dim=1): from pyevolver.evolution import Evolution gen_size = gen_structure.get_genotype_size(gen_struct) random_genotype = Evolution.get_random_genotype(rs, gen_size) return get_simulation_data_from_agent(gen_struct, random_genotype, rs, num_dim)
args = parser.parse_args() dir = args.dir evo_files = sorted([f for f in os.listdir(dir) if f.startswith('evo_')]) assert len(evo_files) > 0, "Can't find evo files in dir {}".format(dir) last_generation = evo_files[-1].split('_')[1].split('.')[0] file_num_zfill = len(last_generation) sim_json_filepath = os.path.join(dir, 'simulation.json') evo_json_filepath = os.path.join(dir, 'evo_{}.json'.format(last_generation)) assert args.max_gen > int(last_generation), \ "max_gen is <= of the last available generation ({})".format(last_generation) sim = Simulation.load_from_file(sim_json_filepath) if args.cores > 0: sim.cores = args.cores evo = Evolution.load_from_file(evo_json_filepath, evaluation_function=sim.evaluate, max_generation=args.max_gen) t = TicToc() t.tic() evo.run() print('Ellapsed time: {}'.format(t.tocvalue()))
def main(raw_args=None): parser = argparse.ArgumentParser( description='Run the Division of Labor Simulation' ) # evolution arguments parser.add_argument('--seed', type=int, default=0, help='Random seed') parser.add_argument('--dir', type=str, default=None, help='Output directory') parser.add_argument('--perf_obj', default='MAX', help='Performance objective') # 'MAX', 'MIN', 'ZERO', 'ABS_MAX' or float value parser.add_argument('--gen_zfill', type=bool, default=False, help='whether to fill geotipes with zeros (True) or random (false - default)') parser.add_argument('--popsize', type=int, default=96, help='Population size') parser.add_argument('--max_gen', type=int, default=10, help='Number of generations') # simulation arguments parser.add_argument('--num_neurons', type=int, default=2, help='Number of neurons in agent') parser.add_argument('--num_dim', type=int, choices=[1, 2], default=1, help='Number of dimensions of the simulation') parser.add_argument('--num_trials', type=int, default=4, help='Number of trials') parser.add_argument('--trial_duration', type=int, default=50, help='Trial duration') parser.add_argument('--num_random_pairings', type=int, default=None, help='None -> agents are alone in the simulation (default). ' '0 -> agents are evolved in pairs: a genotype contains a pair of agents. ' 'n>0 -> each agent will go though a simulation with N other agents (randomly chosen).') parser.add_argument('--switch_agents_motor_control', type=bool, default=False, help= 'when num_agents is 2 this decides whether the two agents switch control of L/R motors ' 'in different trials (switch=True) or not (switch=False) in which case the first agent ' 'always control the left motor and the second the right') parser.add_argument('--exclusive_motors_threshold', type=float, default=None, help='prevent motors to run at the same time') parser.add_argument('--dual_population', type=bool, default=False, help='If to evolve two separate populations, one always controlling the left ' 'motor and the other the right') parser.add_argument('--cores', type=int, default=1, help='Number of cores') # Gather the provided arguements as an array. args = parser.parse_args(raw_args) t = TicToc() t.tic() genotype_structure = gen_structure.DEFAULT_GEN_STRUCTURE(args.num_dim, args.num_neurons) genotype_size = gen_structure.get_genotype_size(genotype_structure) if args.dir is not None: # create default path if it specified dir already exists if os.path.isdir(args.dir): subdir = '{}d_{}n'.format(args.num_dim, args.num_neurons) if args.exclusive_motors_threshold is not None: subdir += '_exc-{}'.format(args.exclusive_motors_threshold) if args.gen_zfill: subdir += '_zfill' if args.num_random_pairings is not None: subdir += '_rp-{}'.format(args.num_random_pairings) if args.switch_agents_motor_control: subdir += '_switch' if args.dual_population: subdir += '_dual' seed_dir = 'seed_{}'.format(str(args.seed).zfill(3)) outdir = os.path.join(args.dir, subdir, seed_dir) else: # use the specified dir if it doesn't exist outdir = args.dir utils.make_dir_if_not_exists_or_replace(outdir) else: outdir = None checkpoint_interval = int(np.ceil(args.max_gen / 10)) sim = Simulation( genotype_structure=genotype_structure, num_dim=args.num_dim, num_trials=args.num_trials, trial_duration=args.trial_duration, # the brain would iterate trial_duration/brain_step_size number of time num_random_pairings=args.num_random_pairings, switch_agents_motor_control=args.switch_agents_motor_control, exclusive_motors_threshold=args.exclusive_motors_threshold, dual_population=args.dual_population, num_cores=args.cores ) if outdir is not None: sim_config_json = os.path.join(outdir, 'simulation.json') sim.save_to_file(sim_config_json) if args.num_random_pairings == 0: genotype_size *= 2 # two agents per genotype num_populations = 2 if args.dual_population else 1 population = None # by default randomly initialized in evolution if args.gen_zfill: # all genotypes initialized with zeros population = np.zeros( (num_populations, args.popsize, genotype_size) ) evo = Evolution( random_seed=args.seed, population=population, num_populations=num_populations, population_size=args.popsize, genotype_size=genotype_size, evaluation_function=sim.evaluate, performance_objective=args.perf_obj, fitness_normalization_mode='FPS', # 'NONE', 'FPS', 'RANK', 'SIGMA' -> NO NORMALIZATION selection_mode='RWS', # 'UNIFORM', 'RWS', 'SUS' reproduce_from_elite=False, reproduction_mode='GENETIC_ALGORITHM', # 'HILL_CLIMBING', 'GENETIC_ALGORITHM' mutation_variance=0.05, # mutation noice with variance 0.1 elitist_fraction=0.05, # elite fraction of the top 4% solutions mating_fraction=0.95, # the remaining mating fraction (consider leaving something for random fill) crossover_probability=0.1, crossover_mode='UNIFORM', crossover_points=None, # genotype_structure['crossover_points'], folder_path=outdir, max_generation=args.max_gen, termination_function=None, checkpoint_interval=checkpoint_interval ) print('Output path: ', outdir) print('n_elite, n_mating, n_filling: ', evo.n_elite, evo.n_mating, evo.n_fillup) evo.run() print('Ellapsed time: {}'.format(t.tocvalue())) return sim, evo
def run_simulation_from_dir(dir, generation=None, genotype_idx=0, population_idx=0, random_target_seed=None, random_pairing_seed=None, isolation_idx=None, write_data=False, **kwargs): """ Utitity function to get data from a simulation """ evo_files = sorted([f for f in os.listdir(dir) if f.startswith('evo_')]) assert len(evo_files) > 0, "Can't find evo files in dir {}".format(dir) file_num_zfill = len(evo_files[0].split('_')[1].split('.')[0]) if generation is None: evo_json_filepath = os.path.join(dir, evo_files[-1]) generation = int(evo_files[-1].split('_')[1].split('.')[0]) else: generation_str = str(generation).zfill(file_num_zfill) evo_json_filepath = os.path.join(dir, 'evo_{}.json'.format(generation_str)) sim_json_filepath = os.path.join(dir, 'simulation.json') sim = Simulation.load_from_file(sim_json_filepath) evo = Evolution.load_from_file(evo_json_filepath, folder_path=dir) data_record_list = [] random_seed = evo.pop_eval_random_seed expect_same_results = isolation_idx is None # overwriting simulaiton if random_target_seed is not None: print("Using random target") # standard target was initialized in sim.__post_init__ # so this is going to overwrite it sim.init_target(RandomState(random_target_seed)) expect_same_results = False if random_pairing_seed is not None: print("Setting random pairing with seed ", random_pairing_seed) random_seed = random_pairing_seed expect_same_results = False original_populations = evo.population_unsorted # get the indexes of the populations as they were before being sorted by performance # we only need to do this for the first population (index 0) original_genotype_idx = evo.population_sorted_indexes[population_idx][genotype_idx] performance, sim_perfs, _ = sim.run_simulation( original_populations, original_genotype_idx, random_seed, population_idx, isolation_idx, data_record_list ) performance = sim.normalize_performance(performance) verbose = not kwargs.get('quiet', False) if verbose: if genotype_idx == 0: perf_orig = evo.best_performances[generation][population_idx] perf_orig = sim.normalize_performance(perf_orig) print("Performace original: {}".format(perf_orig)) print("Performace recomputed: {}".format(performance)) if expect_same_results: diff_perfomance = abs(perf_orig - performance) if diff_perfomance > 1e-5: print(f'Warning: diff_perfomance: {diff_perfomance}') # assert diff_perfomance < 1e-5, f'diff_perfomance: {diff_perfomance}' # if performance == perf_orig: # print("Exact!!") if write_data: for s, data_record in enumerate(data_record_list, 1): if len(data_record_list) > 1: outdir = os.path.join(dir, 'data', 'sim_{}'.format(s)) else: outdir = os.path.join(dir, 'data') utils.make_dir_if_not_exists_or_replace(outdir) for k, v in data_record.items(): if type(v) is dict: # summary outfile = os.path.join(outdir, '{}.json'.format(k)) utils.save_json_numpy_data(v, outfile) else: outfile = os.path.join(outdir, '{}.json'.format(k)) utils.save_json_numpy_data(v, outfile) if kwargs.get('select_sim', None) is None: # select best one sim_idx = np.argmax(sim_perfs) # if sim.num_random_pairings != None and sim.num_random_pairings > 0: if verbose: print("Best sim (random pairings)", sim_idx+1) else: sim_idx = kwargs['select_sim'] - 1 # zero based if verbose: print("Selecting simulation", sim_idx+1) if verbose: sim_perf = sim.normalize_performance(sim_perfs[sim_idx]) print("Performance recomputed (sim): ", sim_idx+1, sim_perf) if sim.num_agents == 2: print("Sim agents genotype distance: ", sim.agents_genotype_distance[sim_idx]) # print agents signatures agents_sign = [get_numpy_signature(gt) for gt in data_record_list[sim_idx]['genotypes']] print('Agent(s) signature(s):', agents_sign) if kwargs.get('compute_complexity', False): from dol.analyze_complexity import get_sim_agent_complexity for a in range(sim.num_agents): nc = get_sim_agent_complexity( sim_perfs, sim, data_record_list, agent_index=a, sim_idx=sim_idx, analyze_sensors=True, analyze_brain=True, analyze_motors=False, combined_complexity=False, only_part_n1n2=True, rs=RandomState(1) ) print('TSE', a+1, nc) return performance, sim_perfs, evo, sim, data_record_list, sim_idx
def test_split_genotypes(): dir = "data/2n_shannon-dd_neural_social_coll-edge/seed_001" evo_file = os.path.join(dir, "evo_2000.json") evo = Evolution.load_from_file(evo_file, folder_path=dir) get_similarity_matrix(evo.population) get_similarity_split(evo.population)