def test_evaluate_species(self): neat = NEAT() neat.species.append(Species(TestGenome1(), unimproved_life_time = 1)) neat.species.append(Species(TestGenome1(), unimproved_life_time = 2)) neat.species.append(Species(TestGenome1(), unimproved_life_time = 3)) self.assertEqual(len(neat.species), 3) neat.evaluate_species() self.assertEqual(len(neat.species), 2)
def __init__(self, eval_env, population_configuration: PopulationConfiguration, mutation_rates: MutationRates = MutationRates()): # CPPNs take 4 inputs, gotta move this somewhere else nrOfLayers: int = 3 self.layers = np.linspace(-1.0, 1.0, num=nrOfLayers) cppnInputs: int = 2 # cppnOutputs: int = nrOfLayers - 1 cppnOutputs = 1 self.n_inputs = population_configuration.n_inputs self.n_outputs = population_configuration.n_outputs # Substrate hiddenLayersWidth: int = self.n_inputs self.substrateNeurons: List[NeuronGene] = [] for y in self.layers: if y == -1.0: for x in np.linspace(-1.0, 1.0, num=self.n_inputs): self.substrateNeurons.append( NeuronGene(NeuronType.INPUT, len(self.substrateNeurons), y, x)) elif y == 1.0: for x in np.linspace(-1.0, 1.0, num=self.n_outputs): self.substrateNeurons.append( NeuronGene(NeuronType.OUTPUT, len(self.substrateNeurons), y, x)) else: for x in np.linspace(-1.0, 1.0, num=hiddenLayersWidth): self.substrateNeurons.append( NeuronGene(NeuronType.HIDDEN, len(self.substrateNeurons), y, x)) print("Nodes in substrate: {}".format(len(self.substrateNeurons))) population_configuration._data["n_inputs"] = cppnInputs population_configuration._data["n_outputs"] = cppnOutputs self.neat = NEAT(eval_env, population_configuration, mutation_rates)
class HyperNEAT(NEAT): def __init__(self, eval_env, population_configuration: PopulationConfiguration, mutation_rates: MutationRates = MutationRates()): # CPPNs take 4 inputs, gotta move this somewhere else nrOfLayers: int = 3 self.layers = np.linspace(-1.0, 1.0, num=nrOfLayers) cppnInputs: int = 2 # cppnOutputs: int = nrOfLayers - 1 cppnOutputs = 1 self.n_inputs = population_configuration.n_inputs self.n_outputs = population_configuration.n_outputs # Substrate hiddenLayersWidth: int = self.n_inputs self.substrateNeurons: List[NeuronGene] = [] for y in self.layers: if y == -1.0: for x in np.linspace(-1.0, 1.0, num=self.n_inputs): self.substrateNeurons.append( NeuronGene(NeuronType.INPUT, len(self.substrateNeurons), y, x)) elif y == 1.0: for x in np.linspace(-1.0, 1.0, num=self.n_outputs): self.substrateNeurons.append( NeuronGene(NeuronType.OUTPUT, len(self.substrateNeurons), y, x)) else: for x in np.linspace(-1.0, 1.0, num=hiddenLayersWidth): self.substrateNeurons.append( NeuronGene(NeuronType.HIDDEN, len(self.substrateNeurons), y, x)) print("Nodes in substrate: {}".format(len(self.substrateNeurons))) population_configuration._data["n_inputs"] = cppnInputs population_configuration._data["n_outputs"] = cppnOutputs self.neat = NEAT(eval_env, population_configuration, mutation_rates) def epoch(self, update_data: PopulationUpdate) -> List[Phenotype]: self.neat.population.updatePopulation(update_data) print("Reproducing") cppns = self.neat.population.reproduce() substrates = [] for i, c in enumerate(cppns): # print("epoch:", i) substrates.append(self.createSubstrate(c)) print("\rCreated substrates: %d/%d" % (i, len(cppns)), end='') print("") return substrates def create_phenotypes(self): return [self.createSubstrate(g) for g in self.neat.population.genomes] def epoch(self): for _ in self.neat.epoch(): cppns = self.neat.population.genomes substrates = [] for i, c in enumerate(cppns): # print("epoch:", i) substrates.append(self.createSubstrate(c)) print("\rCreated substrates: %d/%d" % (i, len(cppns)), end='') yield def createSubstrate(self, cppn: Genome) -> Phenotype: cppnPheno = cppn.createPhenotype() # Visualize().update(cppnPheno) graph = nx.DiGraph() # graph.add_nodes_from([(n.ID, {"activation": n.activation, "type": n.neuronType}) for n in self.substrateNeurons if n.neuronType != NeuronType.HIDDEN]) graph.add_nodes_from([(n.ID, { "activation": n.activation, "type": n.neuronType, "pos": (n.x, n.y) }) for n in self.substrateNeurons]) paths = [ list( nx.all_simple_paths(cppnPheno.graph, source=n[0], target=[o[0] for o in cppnPheno.out_nodes])) for n in cppnPheno.in_nodes ] num_of_paths = len([p for p in paths if len(p) > 0]) # print("Nr. of paths in cppn: {}".format(num_of_paths)) if num_of_paths == 0: return Phenotype(graph, cppn.ID) # nrOfInputs = self.n_inputs # nrOfOutputs = self.n_outputs layers = [ list(g) for k, g in groupby(self.substrateNeurons, lambda n: n.y) ] coordinates = [] for l in layers: singleLayer = np.array([n for n in l]) coordinates.append(singleLayer) coordinates = np.array(coordinates) for i in range(coordinates.shape[0] - 1): leftNeuronLayer = coordinates[i] X = np.array([(n.x, n.y) for n in leftNeuronLayer]) X_IDs = np.array([n.ID for n in leftNeuronLayer]) X_data = {"data": X, "IDs": X_IDs} for j in range(i + 1, coordinates.shape[0]): rightNeuronLayer = coordinates[j] Y = np.array([(n.x, n.y) for n in rightNeuronLayer]) Y_IDs = np.array([n.ID for n in rightNeuronLayer]) Y_data = {"data": Y, "IDs": Y_IDs} substrateCUDA = SubstrateCUDA(cppnPheno) outputs = substrateCUDA.update(X_data, Y_data) graph.add_weighted_edges_from(outputs) # isolated_hidden = [n for n in nx.isolates(graph) if graph.nodes[n]['type'] == NeuronType.HIDDEN] # graph.remove_nodes_from(isolated_hidden) return Phenotype(graph, cppn.ID)
fitnesses_t = fitnesses.T for i in range(fitnesses_t.shape[0]): fitness = fitnesses_t[i] mean = np.sum(fitness)/num_of_runs final_fitnesses.append(mean) return (np.array(final_fitnesses[:len(phenotypes)]), np.zeros((len(phenotypes), 0))) env = gym.make(env_name) pop_size = 100 envs_size = 100 inputs = 4 outputs = 2 pop_config = SpeciesConfiguration(pop_size, inputs, outputs) neat = NEAT(TestOrganism(), pop_config) highest_fitness = -1000.0 for _ in neat.epoch(): print("Epoch {}/{}".format(neat.epochs, 150)) most_fit = max([{"fitness": g.fitness, "genome": g} for g in neat.population.genomes], key=lambda e: e["fitness"]) if most_fit["fitness"] > highest_fitness: print("New highescore: {:1.2f}".format(most_fit["fitness"])) run_env_once(most_fit["genome"].createPhenotype(), env) highest_fitness = most_fit["fitness"] for s in neat.population.species: i = np.argmax([m.fitness for m in s.members]) print("{}: {}".format(s.ID, s.members[i]))
def run(): print("Creating neat object") pop_config = WeightAgnosticConfiguration(pop_size, inputs, outputs) neat = NEAT(TestOrganism(), pop_config) highest_fitness = -1000.0 last_best = neat.population.genomes[0] start = time.time() for _ in neat.epoch(): # if neat.epochs == 150: # break # print("Epoch Time: {}".format(time.time() - start)) # random_phenotype = random.choice(neat.phenotypes) most_fit = max([(g.fitness, g) for g in neat.population.genomes], key=lambda e: e[0]) # most_novel = max([(g.novelty, g) for g in neat.population.genomes], key=lambda e: e[0]) # best_phenotype = max(neat.phenotypes, key=lambda e: e.fitness) # if max_fitness[0] >= highest_fitness: # run_env_once(max_fitness[1].createPhenotype(), env) # highest_fitness = max_fitness[0] # run_env_once(most_novel[1].createPhenotype(), env) # run_env_once(most_fit[1].createPhenotype(), env) # run_env_once(random_phenotype, env) if most_fit[0] > highest_fitness: print("New highescore: {:1.2f}".format(most_fit[0])) # run_env_once(most_fit[1].createPhenotype(), env) highest_fitness = most_fit[0] # print("Highest fitness all-time: {}".format(highest_fitness)) print("Epoch {}/{}".format(neat.epochs, 150)) print("Time: {}".format(time.time() - start)) print("Highest fitness ({}): {:1.2f}/{:1.2f}".format(most_fit[1].ID, most_fit[0], highest_fitness)) # run_env_once(most_fit[1].createPhenotype(), env) found_last = next((m for m in neat.population.genomes if m.ID == last_best.ID), None) if found_last is not None: print("Last best ({}): {:1.2f}/{:1.2f}".format(last_best.ID, found_last.fitness, highest_fitness)) # run_env_once(last_best.createPhenotype(), env) else: print("Last best genome is no longer in population.") table = PrettyTable(["ID", "age", "members", "max fitness", "avg. distance", "stag", "neurons", "links", "avg. weight", "max. compat.", "to spawn"]) for s in neat.population.species: table.add_row([ # Species ID s.ID, # Age s.age, # Nr. of members len(s.members), # Max fitness "{:1.4f}".format(max([m.fitness for m in s.members])), # Average distance "{:1.4f}".format(max([m.distance for m in s.members])), # Stagnation s.generationsWithoutImprovement, # Neurons # "{:1.2f}".format(np.mean([len([n for n in p.graph.nodes.data() if n[1]['type'] == NeuronType.HIDDEN]) for p in neat.phenotypes])), "{:1.2f}".format(np.mean( [len([n for n in m.createPhenotype().graph.nodes.data() if n[1]['type'] == NeuronType.HIDDEN]) for m in s.members])), # Links # "{:1.2f}".format(np.mean([len(p.graph.edges) for p in neat.phenotypes])), "{:1.2f}".format(np.mean([len(m.createPhenotype().graph.edges) for m in s.members])), # Avg. weight "{:1.2f}".format(np.mean([l.weight for m in s.members for l in m.links])), # Max. compatiblity "{:1.2}".format(np.max([m.calculateCompatibilityDistance(s.leader) for m in s.members])), # Nr. of members to spawn s.numToSpawn]) print(table) start = time.time() # print("########## Epoch {} ##########".format(neat.epochs)) last_best = most_fit[1] return highest_fitness
env = gym.make('BipedalWalker-v2') inputs = env.observation_space.shape[0] outputs = env.action_space.shape[0] neat = None novelty_map = None if (args.load): print("Loading NEAT object from file") with open("saves/" + args.load, "rb") as load: neat, innovations, novelty_map = pickle.load(load) neat.populationSize = 150 # neat.milestone = 157.0 else: print("Creating NEAT object") neat = NEAT(500, inputs, outputs, fullyConnected=False) novelty_map = np.empty((0, 14), float) # neat = None # print("Loading NEAT object from file") # with open("saves/lotsofspecies.ne", "rb") as load: # with open("saves/bipedal/bipedal.178", "rb") as load: # neat, innovations, novelty_map = pickle.load(load) # General settings IDToRender = None highestReward = [-1000.0, 0] # milestone: float = 1.0 # nrOfSteps: int = 600 # vis = Visualize()