Example #1
0
	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)
Example #2
0
    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)
Example #3
0
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)
Example #4
0
            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
Example #6
0
    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()