def _combine_genomes(self, mom, dad): child_gene = {} mom_gene = mom.genome.geneparam dad_gene = dad.genome.geneparam # Choose the optimizer child_gene['optimizer'] = random.choice( [mom_gene['optimizer'], dad_gene['optimizer']]) # Combine the layers max_len = max(len(mom_gene['layers']), len(dad_gene['layers'])) child_layers = [] for pos in range(max_len): from_mom = bool(random.getrandbits(1)) # Add the layer from the correct parent IF it exists. Otherwise add nothing if from_mom and len(mom_gene['layers']) > pos: child_layers.append(mom_gene['layers'][pos]) elif not from_mom and len(dad_gene['layers']) > pos: child_layers.append(dad_gene['layers'][pos]) child_gene['layers'] = child_layers child = Genome(child_gene, mom_id=mom.id, dad_id=dad.id) # Randomly mutate one gene if MUTATE_CHANCE > random.random(): child.mutate_one_gene() return child
def create_population(self, count): """Create a population of random networks. Args: count (int): Number of networks to generate, aka the size of the population Returns: (list): Population of network objects """ assert_msg = ( f"Number of population must at least {math.ceil(3 / self.retain)} " f"but is {count}") assert int(count * self.retain) >= 3, assert_msg pop = [] i = 0 while i < count: # Initialize a new genome. genome = Genome(all_possible_genes=self.all_possible_genes, geneparam={}, u_id=self.ids.get_next_id(), mom_id=0, dad_id=0, gen=self.ids.get_gen()) # Set it to random parameters. genome.set_genes_random() if i == 0: # this is where we will store all genomes self.master = AllGenomes(genome) else: # Make sure it is unique.... while self.master.is_duplicate(genome): genome.mutate_one_gene() # Add the genome to our population. pop.append(genome) # and add to the master list if i > 0: self.master.add_genome(genome) i += 1 return pop
def create_population(self, count): """Create a population of random networks. Args: count (int): Number of networks to generate, aka the size of the population Returns: (list): Population of network objects """ pop = [] i = 0 while i < count: # Initialize a new genome. genome = Genome(self.all_possible_genes, {}, self.ids.get_next_ID(), 0, 0, self.ids.get_Gen()) # Set it to random parameters. genome.set_genes_random() if i == 0: #this is where we will store all genomes self.master = AllGenomes(genome) else: # Make sure it is unique.... while self.master.is_duplicate(genome): genome.mutate_one_gene() # Add the genome to our population. pop.append(genome) # and add to the master list if i > 0: self.master.add_genome(genome) i += 1 #self.master.print_all_genomes() #exit() return pop
def create_population(self, count): """Create a population of random networks. Args: count (int): Number of networks to generate, aka the size of the population Returns: (list): Population of network objects """ pop = [] i = 0 while i < count: # Initialize a new genome. genome = Genome( self.all_possible_genes, {}, self.ids.get_next_ID(), 0, 0, self.ids.get_Gen() ) # Set it to random parameters. genome.set_genes_random() if i == 0: #this is where we will store all genomes self.master = AllGenomes( genome ) else: # Make sure it is unique.... while self.master.is_duplicate( genome ): genome.mutate_one_gene() # Add the genome to our population. pop.append(genome) # and add to the master list if i > 0: self.master.add_genome(genome) i += 1 #self.master.print_all_genomes() #exit() return pop
def breed(self, mom, dad): """ Make a child from two parent genes :param mom: A genome parameter :param dad: A genome parameter :return: A child gene """ child_gene = {} mom_gene = mom.geneparam dad_gene = dad.geneparam # Choose the optimizer child_gene['optimizer'] = random.choice( [mom_gene['optimizer'], dad_gene['optimizer']]) # Combine the layers max_len = max(len(mom_gene['layers']), len(dad_gene['layers'])) child_layers = [] for pos in range(max_len): from_mom = bool(random.getrandbits(1)) # Add the layer from the correct parent IF it exists. Otherwise add nothing if from_mom and len(mom_gene['layers']) > pos: child_layers.append(mom_gene['layers'][pos]) elif not from_mom and len(dad_gene['layers']) > pos: child_layers.append(dad_gene['layers'][pos]) child_gene['layers'] = child_layers child = Genome(self.all_possible_genes, child_gene, self.ids.get_next_ID(), mom.u_ID, dad.u_ID, self.ids.get_Gen()) #at this point, there is zero guarantee that the genome is actually unique # Randomly mutate one gene if self.mutate_chance > random.random(): child.mutate_one_gene() #do we have a unique child or are we just retraining one we already have anyway? while self.master.is_duplicate(child): child.mutate_one_gene() self.master.add_genome(child) return child
def breed(self, mom, dad): """Make two children from parental genes. Args: mother (dict): genome parameters father (dict): genome parameters Returns: (list): Two network objects """ children = [] #where do we recombine? 0, 1, 2, 3, 4... N? #with four genes, there are three choices for the recombination # ___ * ___ * ___ * ___ #0 -> no recombination, and N == length of dictionary -> no recombination #0 and 4 just (re)create more copies of the parents #so the range is always 1 to len(all_possible_genes) - 1 pcl = len(self.all_possible_genes) recomb_loc = random.randint(1, pcl - 1) #for _ in range(2): #make _two_ children - could also make more child1 = {} child2 = {} #enforce defined genome order using list #keys = ['nb_neurons', 'nb_layers', 'activation', 'optimizer'] keys = list(self.all_possible_genes) keys = sorted( keys ) #paranoia - just to make sure we do not add unintentional randomization #*** CORE RECOMBINATION CODE **** for x in range(0, pcl): if x < recomb_loc: child1[keys[x]] = mom.geneparam[keys[x]] child2[keys[x]] = dad.geneparam[keys[x]] else: child1[keys[x]] = dad.geneparam[keys[x]] child2[keys[x]] = mom.geneparam[keys[x]] # Initialize a new genome # Set its parameters to those just determined # they both have the same mom and dad genome1 = Genome(self.all_possible_genes, child1, self.ids.get_next_ID(), mom.u_ID, dad.u_ID, self.ids.get_Gen()) genome2 = Genome(self.all_possible_genes, child2, self.ids.get_next_ID(), mom.u_ID, dad.u_ID, self.ids.get_Gen()) #at this point, there is zero guarantee that the genome is actually unique # Randomly mutate one gene if self.mutate_chance > random.random(): genome1.mutate_one_gene() if self.mutate_chance > random.random(): genome2.mutate_one_gene() #do we have a unique child or are we just retraining one we already have anyway? while self.master.is_duplicate(genome1): genome1.mutate_one_gene() self.master.add_genome(genome1) while self.master.is_duplicate(genome2): genome2.mutate_one_gene() self.master.add_genome(genome2) children.append(genome1) children.append(genome2) return children
def breed(self, mom, dad): """Make two children from parental genes. Args: mother (dict): genome parameters father (dict): genome parameters Returns: (list): Two genome objects """ children = [] nr_genes = len(self.all_possible_genes) #get a gene location for single-point crossover crossover_loc = random.randint(1, nr_genes - 1) child1 = {} child2 = {} #enforce defined genome order using list keys = list(self.all_possible_genes) keys = sorted(keys) #perform single-point crossover for x in range(0, nr_genes): if x < crossover_loc: child1[keys[x]] = mom.geneparam[keys[x]] child2[keys[x]] = dad.geneparam[keys[x]] else: child1[keys[x]] = dad.geneparam[keys[x]] child2[keys[x]] = mom.geneparam[keys[x]] #initialize a new genome #set its parameters to those just determined #they both have the same mom and dad genome1 = Genome(self.all_possible_genes, child1, self.ids.get_next_ID(), mom.u_ID, dad.u_ID, self.ids.get_Gen()) genome2 = Genome(self.all_possible_genes, child2, self.ids.get_next_ID(), mom.u_ID, dad.u_ID, self.ids.get_Gen()) #randomly mutate one gene if self.mutate_chance > random.random(): genome1.mutate_one_gene() if self.mutate_chance > random.random(): genome2.mutate_one_gene() #if child is a duplicate within the new generation, mutate a gene while self.master.is_duplicate(genome1): genome1.mutate_one_gene() self.master.add_genome(genome1) while self.master.is_duplicate(genome2): genome2.mutate_one_gene() self.master.add_genome(genome2) children.append(genome1) children.append(genome2) return children
def breed(self, mom, dad): """Make two children from parental genes. Args: mother (dict): genome parameters father (dict): genome parameters Returns: (list): Two network objects """ children = [] #where do we recombine? 0, 1, 2, 3, 4... N? #with four genes, there are three choices for the recombination # ___ * ___ * ___ * ___ #0 -> no recombination, and N == length of dictionary -> no recombination #0 and 4 just (re)create more copies of the parents #so the range is always 1 to len(all_possible_genes) - 1 pcl = len(self.all_possible_genes) recomb_loc = random.randint(1,pcl - 1) #for _ in range(2): #make _two_ children - could also make more child1 = {} child2 = {} #enforce defined genome order using list #keys = ['nb_neurons', 'nb_layers', 'activation', 'optimizer'] keys = list(self.all_possible_genes) keys = sorted(keys) #paranoia - just to make sure we do not add unintentional randomization #*** CORE RECOMBINATION CODE **** for x in range(0, pcl): if x < recomb_loc: child1[keys[x]] = mom.geneparam[keys[x]] child2[keys[x]] = dad.geneparam[keys[x]] else: child1[keys[x]] = dad.geneparam[keys[x]] child2[keys[x]] = mom.geneparam[keys[x]] # Initialize a new genome # Set its parameters to those just determined # they both have the same mom and dad genome1 = Genome( self.all_possible_genes, child1, self.ids.get_next_ID(), mom.u_ID, dad.u_ID, self.ids.get_Gen() ) genome2 = Genome( self.all_possible_genes, child2, self.ids.get_next_ID(), mom.u_ID, dad.u_ID, self.ids.get_Gen() ) #at this point, there is zero guarantee that the genome is actually unique # Randomly mutate one gene if self.mutate_chance > random.random(): genome1.mutate_one_gene() if self.mutate_chance > random.random(): genome2.mutate_one_gene() #do we have a unique child or are we just retraining one we already have anyway? while self.master.is_duplicate(genome1): genome1.mutate_one_gene() self.master.add_genome(genome1) while self.master.is_duplicate(genome2): genome2.mutate_one_gene() self.master.add_genome(genome2) children.append(genome1) children.append(genome2) return children