示例#1
0
 def test_crossover(self):
     parent_1, parent_2 = NetworkGenotype(schema), NetworkGenotype(schema)
     child = crossover(parent_1, parent_2)
     # Child must be different from both parents
     self.assertFalse(
         torch.equal(parent_1.chromosomes['conv.weight'], child.chromosomes['conv.weight']) and
         torch.equal(parent_1.chromosomes['conv.bias'], child.chromosomes['conv.bias']) and
         torch.equal(parent_1.chromosomes['fc.weight'], child.chromosomes['fc.weight']) and
         torch.equal(parent_1.chromosomes['fc.bias'], child.chromosomes['fc.bias'])
     )
     self.assertFalse(
         torch.equal(parent_2.chromosomes['conv.weight'], child.chromosomes['conv.weight']) and
         torch.equal(parent_2.chromosomes['conv.bias'], child.chromosomes['conv.bias']) and
         torch.equal(parent_2.chromosomes['fc.weight'], child.chromosomes['fc.weight']) and
         torch.equal(parent_2.chromosomes['fc.bias'], child.chromosomes['fc.bias'])
     )
     # Child must get chromosome from one of parents
     self.assertTrue(
         torch.equal(parent_1.chromosomes['conv.weight'], child.chromosomes['conv.weight']) or 
         torch.equal(parent_2.chromosomes['conv.weight'], child.chromosomes['conv.weight'])
     )
     self.assertTrue(
         torch.equal(parent_1.chromosomes['conv.bias'], child.chromosomes['conv.bias']) or 
         torch.equal(parent_2.chromosomes['conv.bias'], child.chromosomes['conv.bias'])
     )
     self.assertTrue(
         torch.equal(parent_1.chromosomes['fc.weight'], child.chromosomes['fc.weight']) or 
         torch.equal(parent_2.chromosomes['fc.weight'], child.chromosomes['fc.weight'])
     )
     self.assertTrue(
         torch.equal(parent_1.chromosomes['fc.bias'], child.chromosomes['fc.bias']) or 
         torch.equal(parent_2.chromosomes['fc.bias'], child.chromosomes['fc.bias'])
     )
示例#2
0
 def test_network_genotype_clone(self):
     network_schema = {
         'conv1': ConvChromosome(3, 16, 4, 2),
         'fc1': LinearChromosome(12, 2)
     }
     genotype = NetworkGenotype(network_schema)
     chromosomes = genotype.chromosomes
     clone_genotype = genotype.clone()
     cloned_chromosomes = clone_genotype.chromosomes
     self.assertTrue(genotype.schema == clone_genotype.schema)
     self.assertTrue(
         torch.equal(chromosomes['conv1.weight'],
                     cloned_chromosomes['conv1.weight']))
     self.assertTrue(
         torch.equal(chromosomes['conv1.bias'],
                     cloned_chromosomes['conv1.bias']))
     self.assertTrue(
         torch.equal(chromosomes['fc1.weight'],
                     cloned_chromosomes['fc1.weight']))
     self.assertTrue(
         torch.equal(chromosomes['fc1.bias'],
                     cloned_chromosomes['fc1.bias']))
     clone_genotype.chromosomes['fc1.bias'][0] = 0.
     self.assertFalse(
         torch.equal(chromosomes['fc1.bias'],
                     cloned_chromosomes['fc1.bias']))  # Ensure deepcopy
示例#3
0
def crossover(a: NetworkGenotype, b:NetworkGenotype, random_generator: RandomGenerator) -> NetworkGenotype:
    c1, c2 = a.clone(), b.clone()
    gene_length = len(a.genes)
    idx_to_cross = random_generator.randint(gene_length, int(0.5 * gene_length)) # Uniform crossover w. 50% of genes from each parent
    for i in idx_to_cross: 
        c1.genes[i] = b.genes[i]
        c2.genes[i] = a.genes[i]
    return (c1, c2)
示例#4
0
    def eval_fitness(self,
                     genotype: NetworkGenotype,
                     max_iterations,
                     num_episodes=1,
                     visualize=False):
        env = self.env_manger(**self.env_args)
        with torch.no_grad():
            model = genotype.to_network().to(env.device)
            fitness = 0.

            for ep in range(num_episodes):
                state = env.reset()
                done = False
                num_iterations = 0

                while not done and (max_iterations is None
                                    or num_iterations < max_iterations):
                    if visualize: env.render()
                    action = model(state.unsqueeze(0)).argmax().item()
                    state, _, done, _ = env.step(action)
                    num_iterations += 1

                if self.logger is not None: self.logger.log_data(env)

        dist_travel = env.maze.dist_from_start()
        env.close()
        return dist_travel
示例#5
0
 def test_mutation(self):
     parent = NetworkGenotype(schema)
     child = mutate(parent, mutation_power=1.)
     self.assertFalse(torch.equal(parent.chromosomes['conv.weight'], child.chromosomes['conv.weight']))
     self.assertFalse(torch.equal(parent.chromosomes['conv.bias'], child.chromosomes['conv.weight']))
     self.assertFalse(torch.equal(parent.chromosomes['fc.weight'], child.chromosomes['fc.weight']))
     self.assertFalse(torch.equal(parent.chromosomes['fc.bias'], child.chromosomes['fc.weight']))
示例#6
0
 def test_select_elites(self):
     genotypes = [NetworkGenotype(schema) for i in range(7)]
     fitnesses = [0.01, 1.0, 0.8, 0.2, 0.9, 0.75, 0.2]
     elites = select_elites(genotypes, fitnesses, 3)
     self.assertEqual(elites[0], genotypes[2])
     self.assertEqual(elites[1], genotypes[4])
     self.assertEqual(elites[2], genotypes[1])
示例#7
0
def crossover(a: NetworkGenotype, b: NetworkGenotype) -> NetworkGenotype:
    c = a.clone()
    for name in a.chromosomes.keys():
        a_chromosome, b_chromosome = a.chromosomes[name], b.chromosomes[name]
        c.chromosomes[name] = a_chromosome.clone(
        ) if np.random.rand() <= 0.5 else b_chromosome.clone()
    return c
    def eval_fitness(self,
                     genotype: NetworkGenotype,
                     max_iterations,
                     num_episodes=1,
                     visualize=False):
        env = self.env_manger(**self.env_args)
        with torch.no_grad():
            model = genotype.to_network().to(env.device)
            fitness = 0.

            for ep in range(num_episodes):
                state = env.reset()
                done = False
                total_reward = 0.
                num_iterations = 0

                while not done and (max_iterations is None
                                    or num_iterations < max_iterations):
                    if visualize: env.render()
                    action = model(state.unsqueeze(0)).argmax().item()
                    state, reward, done, _ = env.step(action)
                    total_reward += reward
                    num_iterations += 1

                fitness += total_reward / float(num_episodes)
                if self.logger is not None: self.logger.log_data(env)

        env.close()
        return fitness, {}
示例#9
0
def mutate(genotype: NetworkGenotype, random_generator: RandomGenerator, mutation_rate, mutation_power=1.) -> NetworkGenotype:
    child = genotype.clone()
    gene_length = len(genotype.genes)
    idx_to_mutate = random_generator.randint(gene_length, int(mutation_rate * gene_length))
    for i in idx_to_mutate: 
        pertubation = mutation_power * torch.randn_like(child.genes[i])
        child.genes[i] += pertubation
    return child
示例#10
0
 def test_gen_new_population(self):
     ga = SimpleGA(SimpleCNN,
                   10,
                   FitnessEvaluator(),
                   selection_pressure=0.2)
     old_gen = [NetworkGenotype(schema) for i in range(10)]
     fitnesses = [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.]
     new_gen = ga.new_generation(old_gen, fitnesses)
     self.assertEqual(len(new_gen), ga.num_populations)
     self.assertTrue(old_gen[5] in new_gen)  # Best individual survive
     self.assertTrue(True)
示例#11
0
 def test_create_network_weight(self):
     genotype = NetworkGenotype(TestModel.genetic_schema())
     model = TestModel(genotype)
     self.assertTrue(
         torch.equal(model.conv.weight,
                     genotype.chromosomes['conv.weight']))
     self.assertTrue(
         torch.equal(model.conv.bias, genotype.chromosomes['conv.bias']))
     self.assertTrue(
         torch.equal(model.fc.weight, genotype.chromosomes['fc.weight']))
     self.assertTrue(
         torch.equal(model.fc.bias, genotype.chromosomes['fc.bias']))
示例#12
0
 def test_network_genotype_parameter_dimension(self):
     network_schema = {
         'conv1': ConvChromosome(3, 16, 4, 2),
         'fc1': LinearChromosome(12, 2)
     }
     network_genotype = NetworkGenotype(network_schema)
     conv1_weight = network_genotype.chromosomes['conv1.weight']
     conv1_bias = network_genotype.chromosomes['conv1.bias']
     fc1_weight = network_genotype.chromosomes['fc1.weight']
     fc1_bias = network_genotype.chromosomes['fc1.bias']
     self.assertTrue(torch.Size([16, 3, 4, 4]) == conv1_weight.shape)
     self.assertTrue(torch.Size([16]) == conv1_bias.shape)
     self.assertTrue(torch.Size([2, 12]) == fc1_weight.shape)
     self.assertTrue(torch.Size([2]) == fc1_bias.shape)
示例#13
0
 def test_network_genotype_create_parameters(self):
     network_schema = {
         'conv1': ConvChromosome(3, 16, 4, 4),
         'conv2': ConvChromosome(16, 32, 5, 2),
         'fc1': LinearChromosome(12, 8),
         'fc2': LinearChromosome(8, 2),
     }
     network_genotype = NetworkGenotype(network_schema)
     self.assertTrue('conv1.weight' in network_genotype.chromosomes)
     self.assertTrue('conv1.bias' in network_genotype.chromosomes)
     self.assertTrue('conv2.weight' in network_genotype.chromosomes)
     self.assertTrue('conv2.bias' in network_genotype.chromosomes)
     self.assertTrue('fc1.weight' in network_genotype.chromosomes)
     self.assertTrue('fc1.bias' in network_genotype.chromosomes)
     self.assertTrue('fc2.weight' in network_genotype.chromosomes)
     self.assertTrue('fc2.bias' in network_genotype.chromosomes)
示例#14
0
    def run(self, num_generations):
        populations = [
            NetworkGenotype(self.model_type.genetic_schema())
            for i in range(self.num_populations)
        ]
        fitnesses = np.zeros(self.num_populations)
        for gen in range(num_generations):
            with tqdm(total=len(populations), desc=f'Generation {gen+1}') as t:
                for i, p in enumerate(populations):
                    fitnesses[i] = self.fitness_evaluator.eval_fitness(
                        self.model_type, p)
                    t.update()
                t.set_postfix(max_f=fitnesses.max(),
                              min_f=fitnesses.min(),
                              avg_f=fitnesses.mean())

            best = populations[np.argmax(fitnesses)]
            new_gen = self.new_generation(populations, fitnesses)
            populations = new_gen

        return best
示例#15
0
 def test_create_network_from_schema(self):
     genotype = NetworkGenotype(TestModel.genetic_schema())
     model = TestModel(genotype)
     self.assertTrue(isinstance(getattr(model, 'conv'), nn.Conv2d))
     self.assertTrue(isinstance(getattr(model, 'fc'), nn.Linear))
示例#16
0
def mutate(genotype: NetworkGenotype, mutation_power) -> NetworkGenotype:
    child = genotype.clone()
    for _, chromosome in child.chromosomes.items():
        chromosome += mutation_power * torch.randn(chromosome.shape)
    return child
 def set_weigths(self, genotype: NetworkGenotype):
     self.load_state_dict(genotype.to_state_dict())
示例#18
0
 def test_gen_population_mutation(self):
     parents = [NetworkGenotype(schema) for i in range(5)]
     children = gen_population_mutation(parents, 50)
     self.assertEqual(len(children), 50)
示例#19
0
 def test_gen_population_crossover(self):
     parents = [NetworkGenotype(schema) for i in range(5)]
     children = gen_population_crossover(parents, 10)
     self.assertEqual(len(children), 10)