Exemplo n.º 1
0
    def test_from_genes_constructor(self):
        g = minimal(input_size=2, output_size=3, depth=5)
        n2 = g.add_node(4)
        g.add_edge(g.layers[0][0], n2)
        g.add_edge(n2, g.outputs[0])
        n2 = g.add_node(3)
        g.add_edge(g.layers[0][1], n2)
        g.add_edge(n2, g.outputs[2])
        n2 = g.add_node(3)
        g.add_edge(g.layers[0][0], n2)
        g.add_edge(n2, g.outputs[2])

        edges = [e.to_reduced_repr for e in g.edges]
        nodes = [n.to_reduced_repr for n in g.nodes]
        g_2 = from_genes(
            nodes,
            edges,
            input_size=2,
            output_size=3,
            depth=5)

        self.assertEqual(
            [[n.to_reduced_repr for n in layer] for layer in g_2.layers],
            [[n.to_reduced_repr for n in layer] for layer in g.layers]
        )

        self.assertEqual(
            [edge.to_reduced_repr for edge in g_2.edges],
            [edge.to_reduced_repr for edge in g.edges]
        )
Exemplo n.º 2
0
def simple_adres_example():
    genome = minimal(
        input_size=1,
        output_size=1
    )

    weights_len = len(genome.edges) + len(genome.nodes)
    init_mu = np.random.uniform(-3, 3, weights_len)

    mutator = ADRESMutator(
        initial_mu=init_mu,
        std_dev=0.1
    )

    seeder = curry_genome_seeder(
        mutator=mutator,
        seed_genomes=[genome]
    )

    population = RESPopulation(
        population_size=1000,
        genome_seeder=seeder
    )

    target_mu = np.random.uniform(-3, 3, len(init_mu))
    assign_population_fitness = build_simple_env(target_mu)

    for i in range(100):
        assign_population_fitness(population)
        mutator(population)
        loss = np.linalg.norm(mutator.mu - target_mu)
        print(f'generation: {i}, loss: {loss}')
Exemplo n.º 3
0
def neat_bipedal_walker():
    pop_size = 400
    mutator = NEATMutator(new_edge_probability=0.1, new_node_probability=0.05)
    genome = minimal(input_size=24, output_size=4, depth=5)
    seeder = curry_genome_seeder(mutator=mutator, seed_genomes=[genome])
    metric = generate_neat_metric(c_1=1, c_2=1, c_3=3)
    population = NEATPopulation(population_size=pop_size,
                                delta=4,
                                genome_seeder=seeder,
                                metric=metric)

    ds = DataStore(name='bip_walker_NEAT_data')

    assign_population_fitness = build_env(env_name='BipedalWalker-v3',
                                          num_steps=200,
                                          repetition=1)
    counter_fn = make_counter_fn()

    for i in range(500):
        success = assign_population_fitness(population)
        if success and counter_fn():
            break
        population.speciate()
        data = population.to_dict()
        mutator(population)
        ds.save(data)
        print_progress(data)
    return True
Exemplo n.º 4
0
def curry_genome_seeder(mutator, seed_genomes=None):
    """Construct genome generator.

    Given a mutator and a collection of initial genomes builds a
    function that can then return as many as needed. Used for
    populating Population Objects.

    :param mutator: defined Mutator object that acts on genomes.
    :param seed_genomes: list of genomes that will be copied and mutated.
    :return: Generator function that takes a value n and returns n genomes
      generated by sampling the seed_genome list, copying and mutating.
    :raises ValueError: mutator param must be of type Mutator.
    """
    if not seed_genomes:
        seed_genomes = [minimal()]

    if not issubclass(type(mutator), Mutator):
        raise ValueError('Mutator param must be of type Mutator')

    def genome_seeder(n):
        count = 0
        while count < n:
            for seed_genome in seed_genomes:
                genome = copy(seed_genome)
                mutator(genome)
                yield genome
                count += 1

    return genome_seeder
Exemplo n.º 5
0
def neat_cart_pole():
    pop_size = 1000
    mutator = NEATMutator(new_edge_probability=0.1, new_node_probability=0.05)
    seed_genome = minimal(input_size=4, output_size=1, depth=5)
    seeder = curry_genome_seeder(mutator=mutator, seed_genomes=[seed_genome])
    metric = generate_neat_metric(c_1=1, c_2=1, c_3=3)
    population = NEATPopulation(population_size=pop_size,
                                genome_seeder=seeder,
                                delta=4,
                                metric=metric)

    assign_population_fitness = build_env()
    counter_fn = make_counter_fn()

    for i in range(5):
        success = assign_population_fitness(population)
        if success and counter_fn():
            break
        population.speciate()
        data = population.to_dict()
        print_progress(data)
        mutator(population)

    score = run_env(data['best_genome'], env_name='CartPole-v0', render=True)
    print(f'best_fitness: {score}')
    return True
Exemplo n.º 6
0
def simple_simple_example():
    genome = minimal(
        input_size=1,
        output_size=1
    )

    weights_len = len(genome.edges) + len(genome.nodes)
    init_mu = np.random.uniform(-3, 3, weights_len)

    mutator = SIMPLEMutator(
        std_dev=0.01,
        survival_rate=0.01
    )

    seeder = curry_genome_seeder(
        mutator=mutator,
        seed_genomes=[genome]
    )

    population = SIMPLEPopulation(
        population_size=1000,
        genome_seeder=seeder
    )

    target_mu = np.random.uniform(-3, 3, len(init_mu))
    assign_population_fitness = build_simple_env(target_mu)

    for i in range(100):
        assign_population_fitness(population)
        mutator(population)
        weights = np.array([genome.weights for genome in population.genomes])
        mu = weights.mean(axis=0)
        loss = np.linalg.norm(mu - target_mu)
        print(f'generation: {i}, loss: {loss}')
Exemplo n.º 7
0
def genome_factory(weight_gen=default_gen(), bias_gen=default_gen()):
    Node.innov_iter = itertools.count()
    Edge.innov_iter = itertools.count()

    np.random.seed(1)

    g1 = minimal(input_size=2, output_size=3, depth=5)
    n1 = g1.add_node(4)
    g1.add_edge(g1.layers[0][0], n1)
    g1.add_edge(n1, g1.outputs[0])

    n2 = g1.add_node(3)
    g1.add_edge(g1.layers[0][1], n2)
    g1.add_edge(n2, g1.outputs[2])
    n5 = g1.add_node(4)
    g1.add_edge(g1.layers[3][0], n5)
    g1.add_edge(n5, g1.outputs[0])

    n3 = g1.add_node(3)
    e1 = g1.add_edge(g1.layers[0][0], n3)
    e2 = g1.add_edge(n3, g1.outputs[2])
    n6 = g1.add_node(3)
    g1.add_edge(g1.layers[0][0], n6)
    g1.add_edge(n6, g1.outputs[1])

    for w, edge in zip(weight_gen, g1.edges):
        edge.weight = w

    for w, node in zip(bias_gen, g1.nodes):
        node.weight = w

    return g1
Exemplo n.º 8
0
    def test_edge_copy(self):
        g1 = minimal(input_size=1, output_size=1, depth=1)
        g2 = minimal(input_size=1, output_size=1, depth=1)

        n = g1.add_node(1)
        g2.add_node(1)

        e1 = g1.add_edge(g1.layers[0][0], n)
        g1.add_edge(n, g1.layers[2][0])

        mutation_rate = 0.1
        ne = Edge.copy(e1, g2)

        self.assertNotEqual(ne, e1)
        self.assertEqual(ne.innov, e1.innov)
        self.assertLess(abs(ne.weight - e1.weight), mutation_rate)
Exemplo n.º 9
0
    def test_edge_copy_err(self):
        # Test copy edge throws correct error if node doesn't exist on
        # new_genome.

        g1 = minimal(input_size=1, output_size=1, depth=1)
        g2 = minimal(input_size=1, output_size=1, depth=1)

        n = g1.add_node(1)

        e1 = g1.add_edge(g1.layers[0][0], n)
        g1.add_edge(n, g1.layers[2][0])

        with self.assertRaises(Exception) as context:
            Edge.copy(e1, g2)

        err_msg = 'to_node does not exist on new_genome.'
        self.assertTrue(err_msg == str(context.exception))
Exemplo n.º 10
0
 def test_update_weights(self):
     g = minimal(input_size=2, output_size=3, depth=5)
     update_vector = [random() for _ in range(len(g.edges) + len(g.nodes))]
     g.weights = update_vector
     updated_weights = [
         target.weight for target in itertools.chain(g.nodes, g.edges)
     ]
     self.assertEqual(update_vector, updated_weights)
Exemplo n.º 11
0
 def test_add_edge_mutation(self):
     g = minimal(input_size=2, output_size=3, depth=5)
     num_of_nodes = len(g.nodes)
     num_of_edges = len(g.edges)
     greatest_edge_innov = sorted(g.edges, key=lambda n: n.innov)[-1].innov
     add_edge(g)
     self.assertEqual(len(g.nodes), num_of_nodes)
     self.assertEqual(len(g.edges), num_of_edges + 1)
     new_edge = sorted(g.edges, key=lambda n: n.innov)[-1]
     self.assertEqual(new_edge.innov, greatest_edge_innov + 1)
     self.assertGreater(new_edge.to_node.layer_num,
                        new_edge.from_node.layer_num)
Exemplo n.º 12
0
 def test_add_node_mutation(self):
     g = minimal(input_size=2, output_size=3, depth=5)
     num_of_nodes = len(g.nodes)
     num_of_edges = len(g.edges)
     add_node(g)
     self.assertEqual(len(g.nodes), num_of_nodes + 1)
     self.assertEqual(len(g.edges), num_of_edges + 2)
     old_edge = [e for e in g.edges if not e.active][0]
     new_node = sorted(g.nodes, key=lambda n: n.innov)[-1]
     self.assertEqual(new_node.edges_in[0].from_node.layer_num,
                      old_edge.from_node.layer_num)
     self.assertEqual(new_node.edges_out[0].to_node.layer_num,
                      old_edge.to_node.layer_num)
Exemplo n.º 13
0
def setup_simple_res_env(mutator_type=None):
    genome = minimal(input_size=1, output_size=1)

    weights_len = len(genome.edges) + len(genome.nodes)
    init_mu = np.random.uniform(-3, 3, weights_len)

    if mutator_type == RESMutator:
        mutator = mutator_type(initial_mu=init_mu, std_dev=0.1, alpha=1)
    elif mutator_type == ADRESMutator:
        mutator = mutator_type(initial_mu=init_mu, std_dev=0.1)
    else:
        mutator = SIMPLEMutator(std_dev=0.01, survival_rate=0.1)

    seeder = curry_genome_seeder(mutator=mutator, seed_genomes=[genome])

    population = RESPopulation(population_size=1000, genome_seeder=seeder)
    return population, mutator, init_mu
Exemplo n.º 14
0
    def test_get_addmissable_edges(self):
        g = minimal(input_size=2, output_size=3, depth=5)
        n2 = g.add_node(3)
        g.add_edge(g.layers[0][0], n2)
        g.add_edge(n2, g.outputs[0])

        self.assertEqual(len(g.layer_edges_in(3)), 1)
        self.assertEqual(len(g.layer_edges_out(3)), 1)

        for layer_num in [2, 4, 5]:
            self.assertEqual(len(g.layer_edges_in(layer_num)), 0)
            self.assertEqual(len(g.layer_edges_out(layer_num)), 0)

        self.assertEqual(len(g.get_admissible_edges()), 5)
        addmissable = lambda e: e.to_node.layer_num - e.from_node.layer_num > 1
        for e in g.get_admissible_edges():
            self.assertEqual(addmissable(e), True)
Exemplo n.º 15
0
    def test_genome_weight_mutation(self):
        new_uniform_weight = 0.5
        with patch('numpy.random.uniform',
                   side_effect=[
                       0.1, *[0.95, 0.4, 0.95, *[random() for _ in range(10)]],
                       new_uniform_weight, *[random() for _ in range(10)]
                   ]):
            with patch('numpy.random.normal',
                       side_effect=[[0.1], [0.4],
                                    [random() for _ in range(10)]]):
                g = minimal(input_size=2, output_size=3, depth=5)
                m_g = copy(g)
                mutate_weights = curry_weight_mutator(
                    weight_mutation_likelihood=0.8,
                    weight_mutation_rate_random=0.1,
                    weight_mutation_rate_uniform=0.9,
                    weight_mutation_variance=0.1)
                mutate_weights(m_g)

        self.assertEqual(m_g.edges[0].weight, new_uniform_weight)
        self.assertEqual(g.edges[1].weight + 0.1, m_g.edges[1].weight)
Exemplo n.º 16
0
    def test_copy_factory(self):
        g = minimal()
        n2 = g.add_node(3)
        g.add_edge(g.layers[0][0], n2)
        g.add_edge(n2, g.outputs[0])
        g_copy = copy(g)
        self.assertNotEqual(g_copy, g)
        for node_copy, node in zip(g_copy.nodes, g.nodes):
            self.assertEqual(node_copy.innov, node.innov)

        for layer_copy, layer in zip(g_copy.layers, g.layers):
            self.assertEqual(len(layer_copy), len(layer))
            for node_copy, node in zip(layer_copy, layer):
                self.assertNotEqual(node_copy, node)
                self.assertEqual(node_copy.innov, node.innov)
                self.assertEqual(len(node_copy.edges_in), len(node.edges_in))
                self.assertEqual(len(node_copy.edges_out), len(node.edges_out))

        for edge_copy, edge in zip(g_copy.edges, g.edges):
            self.assertNotEqual(edge_copy, edge)
            self.assertEqual(edge_copy.innov, edge.innov)
Exemplo n.º 17
0
    def test_minimal_factory(self):
        g = minimal(input_size=2, output_size=3, depth=5)

        # Check correct nodes
        self.assertEqual(len(g.inputs), 2)
        self.assertEqual(len(g.nodes), 1)
        self.assertEqual(len(g.outputs), 3)
        for node in g.inputs:
            self.assertEqual(node.layer_num, 0)
        for node in g.outputs:
            self.assertEqual(node.layer_num, len(g.layers) - 1)
        self.assertEqual(len(g.layers), 7)

        # check central connecting node edges
        self.assertEqual(
            g.layer_edges_in(layer_num=6),
            g.layer_edges_out(layer_num=1)
        )
        self.assertEqual(
            g.layer_edges_in(layer_num=1),
            g.layer_edges_out(layer_num=0)
        )
Exemplo n.º 18
0
def neat_xor_example():
    pop_size = 150
    mutator = NEATMutator(
        new_edge_probability=0.1,
        new_node_probability=0.05
    )
    seed_genome = minimal(
        input_size=2,
        output_size=1,
        depth=3
    )
    seeder = curry_genome_seeder(
        mutator=mutator,
        seed_genomes=[seed_genome]
    )
    metric = generate_neat_metric()
    population = NEATPopulation(
        population_size=pop_size,
        delta=3,
        genome_seeder=seeder,
        metric=metric
    )

    def xor(a, b):
        return bool(a) != bool(b)

    def generate_data(n):
        data = [
            [[True, True], xor(True, True)],
            [[True, False], xor(True, False)],
            [[False, True], xor(False, True)],
            [[False, False], xor(False, False)]
        ]
        for i in range(n):
            yield data[i % 4]

    sln_count = 0
    best_fitness = None
    for _ in tqdm(range(1000)):
        for genome in population.genomes:
            fitness = 0
            best_fitness = 0
            model = Model(genome.to_reduced_repr)
            for inputs, output in generate_data(4):
                pred = model(inputs)[0]
                pred = pred > 0
                fitness += pred == output
                if fitness > best_fitness:
                    best_fitness = fitness
            genome.fitness = fitness/4
        if best_fitness == 4:
            sln_count += 1

        if sln_count == 10:
            break

        population.speciate()
        mutator(population)

    fitness_scores = []
    best_genome = None
    best_fitness = 0
    for genome in population.genomes:
        fitness = 0
        model = Model(genome.to_reduced_repr)
        for inputs, output in generate_data(4):
            pred = model(inputs)[0]
            pred = pred > 0
            fitness += pred == output
        fitness = fitness / 4
        if fitness > best_fitness:
            best_fitness = fitness
            best_genome = genome
        fitness_scores.append(fitness)
    print()
    print('best_fitness:', best_fitness)
    print_population(population)
    print_genome(best_genome)
    return True
Exemplo n.º 19
0
 def test_update_weights_error(self):
     g = minimal(input_size=2, output_size=3, depth=5)
     with self.assertRaises(DimensionMismatchError):
         g.weights = [0 for _ in range(len(g.edges) + len(g.nodes) - 1)]