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