Пример #1
0
def test_ND():
    "test various tensor size random"

    TEST_INPUTS = [
        [SingleCrossover1D, (2, 4), 0.5],
        [SingleCrossover2D, (2, 4, 4), (0.5, 0.5)],
        [SingleCrossover3D, (2, 4, 4, 4), (0.5, 0.5, 0.5)],
    ]

    for inputs in TEST_INPUTS:
        OP = inputs[0]
        pop_shape = inputs[1]
        mutations_probability = inputs[2]
        population_fraction = 1
        population = B.randint(0, 1024, pop_shape)

        # eager
        RM = OP(population_fraction=population_fraction,
                mutations_probability=mutations_probability)

        population = RM(population)
        assert B.is_tensor(population)
        assert population.shape == pop_shape

        # graph
        RM = OP(population_fraction=population_fraction,
                mutations_probability=mutations_probability)

        population = RM._call_from_graph(population)
        assert B.is_tensor(population)
        assert population.shape == pop_shape
Пример #2
0
def test_crossover1D_output_shape():
    POPULATION_SHAPE = (8, 6)
    population = B.randint(0, 1024, POPULATION_SHAPE)
    population_fraction = 0.5
    mutations_probability = 0.2

    original_population = copy(population)
    population = DualCrossover1D(population_fraction,
                                 mutations_probability,
                                 debug=True)(population)

    cprint(population, 'cyan')
    cprint(original_population, 'yellow')

    assert population.shape == POPULATION_SHAPE
    # measuring mutation rate
    diff = B.clip(abs(population - original_population), 0, 1)

    # row test
    num_ones_in_row = 0
    for col in diff:
        num_ones_in_row = max(list(col).count(1), num_ones_in_row)

    max_one_in_row = int(POPULATION_SHAPE[1] * mutations_probability)
    assert num_ones_in_row == max_one_in_row
    assert num_ones_in_row
Пример #3
0
def test_binary_val_default_params():
    pop_shape = (6, 4)
    population = B.randint(0, 2, pop_shape)
    population = RandomMutations1D(max_gene_value=1, debug=1)(population)
    print(population)
    assert B.max(population) == 1
    assert not B.min(population)
Пример #4
0
def test_max_gene_val_2d():
    MAX_VAL = 10
    t = B.randint(0, MAX_VAL + 1, (10, 10, 10))
    max_sum_value = MAX_VAL * 10 * 10
    v = Sum(max_sum_value=max_sum_value).call(t)
    assert v.shape == (10, )
    for t in v:
        assert t < 1
Пример #5
0
def test_cosine_2d(backends):
    INSERTION_POINTS = [0, 10, 20]  # where we copy the ref chromosome

    ref_chromosome = B.randint(0, 2, (32, 32))
    ref_pop = B.randint(0, 2, (64, 32, 32))

    for idx in INSERTION_POINTS:
        ref_pop[idx] = ref_chromosome

    cs = InvertedCosineSimilarity(ref_chromosome)
    distances = cs(ref_pop)

    for idx, dst in enumerate(distances):
        if idx in INSERTION_POINTS:
            assert int(dst) == 1
        else:
            assert dst < 1
            assert dst > 0
Пример #6
0
    def call(self, populations):
        """ Create the mask use to generate mutations

        Args:
            population_shape (list): population tensor shape.
        Returns:
            tensor: mask

        Generation works by:
        1. creating a slice that contains the mutation
        2. Inserting it into the mask
        3. Shuffle the mask in every dimension to distribute them
        """
        results = []

        for population in populations:

            affected_population = int(population.shape[0] *
                                      self.population_fraction)

            # Build sub tensors & slices by iterating through tensor dimensions
            sub_tensor_shape = [affected_population]
            slices = [slice(0, affected_population)]
            for idx, pop_size in enumerate(population.shape[1:]):
                midx = idx - 1  # recall dim1 are genes.
                tsize = int(pop_size * self.mutations_probability[midx])
                sub_tensor_shape.append(tsize)
                slices.append(slice(0, tsize))
            slices = tuple(slices)
            self.print_debug("sub_tensor_shape", sub_tensor_shape)

            # drawing mutations
            mutations = B.randint(self.min_mutation_value,
                                  self.max_mutation_value + 1,
                                  shape=sub_tensor_shape)
            # blank mask
            mask = B.zeros(population.shape)

            # add mutations
            mask[slices] = mutations

            # shuffle mask every axis
            B.full_shuffle(mask)

            # mutate
            population = population + mask

            # normalize
            if self.max_gene_value or self.min_gene_value:
                self.print_debug("min_gen_val", self.min_gene_value)
                self.print_debug("max_gen_val", self.max_gene_value)

                population = B.clip(population,
                                    min_val=self.min_gene_value,
                                    max_val=self.max_gene_value)
            results.append(population)
        return results
Пример #7
0
def test_fittest_2d():

    INSERTION_POINTS = [0, 10, 20]  # where we copy the ref chromosome

    ref_chromosome = B.randint(0, 2, (32, 32))
    pop1 = B.randint(0, 2, (64, 32, 32))
    pop2 = B.randint(0, 2, (64, 32, 32))
    for idx in INSERTION_POINTS:
        pop1[idx] = ref_chromosome

    fitness_function = InvertedCosineSimilarity(ref_chromosome)
    selector = SelectFittest()
    selected_pop, fitness_scores = selector(fitness_function, pop1, pop2)
    print(selected_pop)
    assert selected_pop.shape == pop1.shape
    # check the exact chromosome is the three top choice
    assert B.tensor_equal(selected_pop[0], ref_chromosome)
    assert B.tensor_equal(selected_pop[1], ref_chromosome)
    assert B.tensor_equal(selected_pop[2], ref_chromosome)
Пример #8
0
def test_sum2d():
    t = B.randint(0, 10, (10, 10, 10))
    v = Sum().call(t)

    result = []
    for r in t:
        result.append(B.sum(r, axis=-1))
    result = B.tensor(result)

    assert v.shape == (10, )
    for idx, a in enumerate(v):
        assert v[idx].all() == result[idx].all()
Пример #9
0
def genRandIntPopulation(shape, max_value, min_value=0):
    """Generate a random population of Chromosome made of Integers

    Args:
        (set of ints): shape of the population. Its of the form
        (num_chromosomes, chromosome_dim_1, .... chromesome_dim_n)

        max_value (int): Maximum value taken by a given gene.

        min_value (int, optional): Min value a gene can take. Defaults to 0.

    Returns:
        Tensor: random population.
    """
    high = max_value + 1
    return B.randint(low=min_value, high=high, shape=shape)
Пример #10
0
    def compute(self, population):

        # mix genomes
        population_copy = B.copy(population)
        B.shuffle(population_copy)

        # how many chromosomes to crossover
        num_crossover_chromosomes = int(population.shape[0] *
                                        self.population_fraction)

        if self.debug:
            print('num chromosomes', num_crossover_chromosomes)

        if not self.has_cache:
            self.print_debug("Caching fancy indexing")
            self.has_cache = True

            # compute the shape needed for the mutation
            mutations_shape = [num_crossover_chromosomes]
            for idx, frac in enumerate(self.crossover_probability):
                num_genes = int(population.shape[idx + 1] * frac)
                mutations_shape.append(num_genes)
            self.mutations_shape = mutations_shape
            self.print_debug("population_shape:", population.shape)
            self.print_debug("mutation_shape:", self.mutations_shape)

        else:
            self.print_debug("Using cached fancy indexing")

        # compute the fancy indexing dynamlically
        # ! the start point must be randomized
        slices = [slice(0, num_crossover_chromosomes)]
        for idx, crossover_size in enumerate(self.mutations_shape[1:]):
            # ! making indexing explicit as its a huge pitfall
            mutation_dim = idx + 1
            max_start = population.shape[mutation_dim] - crossover_size + 1
            start = B.randint(0, max_start, 1)[0]
            slices.append(slice(start, crossover_size + start))

        slices = tuple(slices)
        self.print_debug(slices)

        # crossover
        cross_section = population_copy[slices]
        population[slices] = cross_section

        return population
Пример #11
0
def test_ND():
    "test various tensor size random"

    TEST_INPUTS = [
        [RandomMutations1D, (2, 4), 0.5],
        [RandomMutations2D, (2, 4, 4), (0.5, 0.5)],
        [RandomMutations3D, (2, 4, 4, 4), (0.5, 0.5, 0.5)],
    ]

    for inputs in TEST_INPUTS:
        OP = inputs[0]
        pop_shape = inputs[1]
        mutations_probability = inputs[2]

        max_gene_value = 10
        min_gene_value = 0
        population_fraction = 1
        min_mutation_value = 1
        max_mutation_value = 1

        population = B.randint(0, max_gene_value, pop_shape)

        # eager
        RM = OP(population_fraction=population_fraction,
                mutations_probability=mutations_probability,
                min_gene_value=min_gene_value,
                max_gene_value=max_gene_value,
                min_mutation_value=min_mutation_value,
                max_mutation_value=max_mutation_value)

        population = RM(population)
        assert B.is_tensor(population)
        assert population.shape == pop_shape

        # graph
        RM = OP(population_fraction=population_fraction,
                mutations_probability=mutations_probability,
                min_gene_value=min_gene_value,
                max_gene_value=max_gene_value,
                min_mutation_value=min_mutation_value,
                max_mutation_value=max_mutation_value)

        population = RM._call_from_graph(population)
        assert B.is_tensor(population)
        assert population.shape == pop_shape
Пример #12
0
def test_direct_2d():
    NUM_EVOLUTIONS = 2
    POPULATION_SIZE = 32
    GENE_SIZE = 10
    MAX_VAL = 256
    SHAPE = (POPULATION_SIZE, GENE_SIZE, GENE_SIZE)

    population = B.randint(0, MAX_VAL, SHAPE)
    inputs = Input(shape=SHAPE)
    x = RandomMutations2D(max_gene_value=1, min_gene_value=0)(inputs)
    outputs = UniformCrossover2D()(x)
    gf = GeneFlow(inputs, outputs)

    fitness_function = Sum(max_sum_value=GENE_SIZE)
    evolution_strategy = SelectFittest()

    gf.compile(evolution_strategy, fitness_function)
    gf.evolve(population, num_evolutions=NUM_EVOLUTIONS)
Пример #13
0
def test_uniform_distribution():
    """check that every gene of the tensor are going to be flipped equally
    Note:
    # ! We need enough iterations and chromosomes to reduce collision
    # ! and ensure numerical stability
    """

    NUM_ITERATIONS = 1000
    GENOME_SHAPE = (20, 4, 4)
    population = B.randint(0, 1024, GENOME_SHAPE)
    population_fraction = 1
    crossover_probability = (0.5, 0.5)

    # each gene proba of being mutated 0.5*0.5 > 0.25
    # each chromosome proba of being mutated 1
    # => gene average hit rate: 1000 / (1/4)  ~250
    MIN_DIFF_BOUND = 200
    MAX_DIFF_BOUND = 300

    OP = RandomMutations2D(population_fraction, crossover_probability)

    # diff matrix
    previous_population = copy(population)
    population = OP(population)
    diff = B.clip(abs(population - previous_population), 0, 1)
    for _ in range(NUM_ITERATIONS - 1):
        previous_population = copy(population)
        population = OP(population)

        curr_diff = B.clip(abs(population - previous_population), 0, 1)
        # acumulating diff matrix
        diff += curr_diff

    print(curr_diff)

    for c in diff:
        print(c)
        print('mean', B.mean(c), 'min', B.min(c), 'max', B.max(c))
        assert B.min(c) > MIN_DIFF_BOUND
        assert B.max(c) < MAX_DIFF_BOUND
        assert MIN_DIFF_BOUND < B.mean(c) < MAX_DIFF_BOUND
Пример #14
0
def test_1D_shape():
    POPULATION_SHAPE = (64, 16)
    population = B.randint(0, 1024, POPULATION_SHAPE)
    population_fraction = 0.5
    crossover_size_fraction = 0.2

    original_population = copy(population)
    population = SingleCrossover1D(population_fraction,
                                   crossover_size_fraction,
                                   debug=1)(population)

    cprint(population, 'cyan')
    cprint(original_population, 'yellow')

    assert population.shape == POPULATION_SHAPE
    # measuring mutation rate
    diff = B.clip(abs(population - original_population), 0, 1)
    print(diff, 'cyan')

    # row test
    num_ones_in_row = 0
    for col in diff:
        num_ones = list(col).count(1)
        print(num_ones)
        num_ones_in_row = max(num_ones, num_ones_in_row)

    max_one_in_row = POPULATION_SHAPE[1] * crossover_size_fraction
    assert num_ones_in_row <= max_one_in_row
    assert num_ones_in_row

    # col
    diff = diff.T
    num_ones_in_col = 0
    for col in diff:
        num_ones_in_col = max(list(col).count(1), num_ones_in_col)

    max_one_in_col = POPULATION_SHAPE[0] * population_fraction
    assert max_one_in_col - 2 <= num_ones_in_col <= max_one_in_col
Пример #15
0
def test_mutation2d_graph_mode():
    "make sure the boxing / unboxing works in graph mode"
    pop_shape = (2, 4, 4)
    max_gene_value = 10
    min_gene_value = 0
    population_fraction = 1
    mutations_probability = (0.5, 0.5)
    min_mutation_value = 1
    max_mutation_value = 1

    population = B.randint(0, max_gene_value, pop_shape)

    RM = RandomMutations2D(population_fraction=population_fraction,
                           mutations_probability=mutations_probability,
                           min_gene_value=min_gene_value,
                           max_gene_value=max_gene_value,
                           min_mutation_value=min_mutation_value,
                           max_mutation_value=max_mutation_value,
                           debug=True)

    population = RM._call_from_graph(population)
    assert B.is_tensor(population)
    assert population.shape == pop_shape
Пример #16
0
def test_mutation2d_eager():
    pop_shape = (2, 4, 4)
    max_gene_value = 10
    min_gene_value = 0
    population_fraction = 1
    mutations_probability = (0.5, 0.5)
    min_mutation_value = 1
    max_mutation_value = 1

    population = B.randint(0, max_gene_value, pop_shape)

    # save original
    original_population = copy(population)
    cprint('[Initial genepool]', 'blue')
    cprint(original_population, 'blue')

    RM = RandomMutations2D(population_fraction=population_fraction,
                           mutations_probability=mutations_probability,
                           min_gene_value=min_gene_value,
                           max_gene_value=max_gene_value,
                           min_mutation_value=min_mutation_value,
                           max_mutation_value=max_mutation_value,
                           debug=True)
    population = RM(population)

    cprint('\n[Mutated genepool]', 'yellow')
    cprint(population, 'yellow')

    cprint('\n[Diff]', 'magenta')
    diff = population - original_population
    cprint(diff, 'magenta')

    assert B.is_tensor(population)
    assert population.shape == pop_shape
    assert B.max(diff) <= max_mutation_value
    for chromosome in diff:
        assert B.sum(chromosome) == 4
Пример #17
0
def test_dualcrossover2d_distribution():
    """check that every gene of the tensor are going to be flipped equally
    Note:
    # ! We need enough iterations and chromosomes to reduce collision
    # ! and ensure numerical stability
    """
    NUM_ITERATIONS = 1000
    GENOME_SHAPE = (100, 4, 4)
    population = B.randint(0, 1024, GENOME_SHAPE)
    population_fraction = 1
    crossover_probability = (0.5, 0.5)

    OP = DualCrossover2D(population_fraction, crossover_probability)

    # diff matrix
    previous_population = copy(population)
    population = OP(population)
    diff = B.clip(abs(population - previous_population), 0, 1)
    print(diff)

    for _ in range(NUM_ITERATIONS - 1):
        previous_population = copy(population)
        population = OP(population)

        curr_diff = B.clip(abs(population - previous_population), 0, 1)
        # acumulating diff matrix
        diff += curr_diff

    # print(curr_diff)

    for c in diff:
        print(c)
        print('mean', B.mean(c), 'min', B.min(c), 'max', B.max(c))
        assert B.min(c) > 50
        assert B.max(c) < NUM_ITERATIONS / 2
        assert 200 < B.mean(c) < NUM_ITERATIONS / 2
Пример #18
0
def test_uniform_2Dcrossover_randomness_shape():
    GENOME_SHAPE = (10, 4, 4)
    population = B.randint(0, 1024, GENOME_SHAPE)
    population_fraction = 0.5
    crossover_probability = (0.5, 0.5)

    original_population = copy(population)
    OP = UniformCrossover2D(population_fraction, crossover_probability)
    population = OP(population)

    diff = B.clip(abs(population - original_population), 0, 1)
    print(diff)
    expected_mutations = original_population.shape[0] * population_fraction

    mutated_chromosomes = []
    for c in diff:
        if B.max(c):
            mutated_chromosomes.append(c)
    num_mutations = len(mutated_chromosomes)

    # sometime we have a collision so we use a delta
    assert abs(num_mutations - expected_mutations) < 2

    mutated_rows = crossover_probability[0] * GENOME_SHAPE[1]
    mutated_cells = crossover_probability[0] * GENOME_SHAPE[2]
    for cidx, c in enumerate(mutated_chromosomes):
        mr = 0
        mc = 0
        for r in c:
            s = B.sum(r)
            if s:
                mr += 1
                mc += s

        assert abs(mutated_rows - mr) < 2
        assert abs(mutated_cells - (mc // mutated_rows)) < 2
Пример #19
0
                             max_mutation_value=max_mutation_value,
                             **kwargs)


if __name__ == '__main__':
    from copy import copy

    pop_shape = (2, 4, 4)
    max_gene_value = 10
    min_gene_value = 0
    population_fraction = 1
    mutations_probability = (0.5, 0.5)
    min_mutation_value = 1
    max_mutation_value = 1

    population = B.randint(0, max_gene_value, pop_shape)
    RM = RandomMutations2D(population_fraction=population_fraction,
                           mutations_probability=mutations_probability,
                           min_gene_value=min_gene_value,
                           max_gene_value=max_gene_value,
                           min_mutation_value=min_mutation_value,
                           max_mutation_value=max_mutation_value,
                           debug=True)
    RM(population)

    chromosomes_sav = copy(population)
    cprint('[Initial genepool]', 'blue')
    cprint(chromosomes_sav, 'blue')
    population = RM(population)

    cprint('\n[Mutated genepool]', 'yellow')
Пример #20
0
def test_call_vs_get():
    shape = (128, 64)
    population = B.randint(1, 10, shape=shape)
    inputs = Input(shape)
    inputs.assign(population)
    assert inputs.get().all() == inputs.call('').all()
Пример #21
0
    def __init__(self,
                 population_fraction=0.9,
                 crossover_probability=(0.2, 0.2, 0.2),
                 **kwargs):

        if len(crossover_probability) != 3:
            raise ValueError('crossover_probability must be of form (x, y, z)')

        super(DualCrossover3D,
              self).__init__(population_fraction=population_fraction,
                             crossover_probability=crossover_probability,
                             **kwargs)


if __name__ == '__main__':
    from copy import copy
    print(B.backend())
    GENOME_SHAPE = (6, 4, 4)
    population = B.randint(0, 256, GENOME_SHAPE)
    population_fraction = 0.5
    max_crossover_size_fraction = (0.5, 0.5)
    print(population.shape)
    original_population = copy(population)
    population = DualCrossover2D(population_fraction,
                                 max_crossover_size_fraction,
                                 debug=True)(population)

    # diff matrix
    diff = B.clip(abs(population - original_population), 0, 1)
    print(diff)
Пример #22
0
                 crossover_probability=(0.2, 0.2, 0.2),
                 **kwargs):
        if len(crossover_probability) != 3:
            raise ValueError(
                'crossover_probability must be of form (x, y, z)')  # noqa
        super(UniformCrossover3D,
              self).__init__(population_fraction=population_fraction,
                             crossover_probability=crossover_probability,
                             **kwargs)


if __name__ == '__main__':
    from copy import copy
    print(B.backend())
    GENOME_SHAPE = (10, 4, 4)
    population = B.randint(0, 1024, GENOME_SHAPE)
    population_fraction = 0.5
    crossover_probability = (0.5, 0.5)

    print(population.shape)
    # peforming crossover
    original_population = copy(population)
    population = UniformCrossover2D(population_fraction,
                                    crossover_probability)(population)

    # diff matrix
    diff = B.clip(abs(population - original_population), 0, 1)
    print(diff)
    # expected mutated chromosomes
    expected_mutated = population.shape[0] * population_fraction
    cprint(
Пример #23
0
def test_2d():
    shape = (128, 64, 64)
    population = B.randint(1, 10, shape=shape)
    inputs = Input(shape)
    inputs.assign(population)
    assert inputs.get().all() == population.all()