Ejemplo n.º 1
0
    def mutate_add_node(self, genome: Genome) -> bool:
        if len(genome.connection_gene_list) == 0:
            return False

        genome.last_mutation = "Add node"

        connection_to_replace = numpy.random.choice(
            genome.connection_gene_list)
        genome.connection_gene_list.remove(connection_to_replace)
        neuron_id = 0

        if connection_to_replace.inno_id in self.connection_replaced:
            neuron_id = self.connection_replaced[connection_to_replace.inno_id]
        else:
            neuron_id = self.next_neuron_innovation()
            self.connection_replaced[connection_to_replace.inno_id] = neuron_id

        new_neuron = NeuronGene(
            neuron_id, self.activation_fn_library.get_random_function(),
            NeuronType.HIDDEN)

        self.neuron_innovation[new_neuron.inno_id] = new_neuron

        new_connection1 = self.create_connection(connection_to_replace.from_id,
                                                 neuron_id,
                                                 connection_to_replace.weight)
        new_connection2 = self.create_connection(neuron_id,
                                                 connection_to_replace.to_id,
                                                 1.0)

        from_neuron = genome.neuron_gene_dict[connection_to_replace.from_id]
        to_neuron = genome.neuron_gene_dict[connection_to_replace.to_id]

        from_neuron.target_neurons.remove(to_neuron)
        to_neuron.source_neurons.remove(from_neuron)

        new_neuron.target_neurons.append(
            genome.neuron_gene_dict[connection_to_replace.to_id])
        new_neuron.source_neurons.append(
            genome.neuron_gene_dict[connection_to_replace.from_id])

        genome.neuron_gene_dict[new_neuron.inno_id] = new_neuron
        genome.neuron_gene_list.append(new_neuron)

        from_neuron.target_neurons.append(new_neuron)
        to_neuron.source_neurons.append(new_neuron)

        genome.connection_gene_list.append(new_connection1)
        genome.connection_gene_list.append(new_connection2)

        return True
Ejemplo n.º 2
0
    def mutate_weights(self, genome: Genome) -> bool:
        num_connection_mutation: float = numpy.sin(
            random.random() *
            (numpy.pi / 2)) * len(genome.connection_gene_list)
        connections_to_mutate: List[ConnectionGene] = random.sample(
            genome.connection_gene_list, int(num_connection_mutation))
        for conn in connections_to_mutate:
            conn.weight = numpy.clip(
                conn.weight + (random.random() - 0.5),
                -self.genome_params.connection_weight_range,
                self.genome_params.connection_weight_range)

        genome.last_mutation = "Mutate weights"

        return num_connection_mutation > 0
Ejemplo n.º 3
0
    def mutate_delete_connection(self, genome: Genome) -> bool:
        if len(genome.connection_gene_list) < 2:
            return False

        connection_to_delete: ConnectionGene = random.choice(
            genome.connection_gene_list)
        from_neuron = genome.neuron_gene_dict[connection_to_delete.from_id]
        to_neuron = genome.neuron_gene_dict[connection_to_delete.to_id]

        from_neuron.target_neurons.remove(to_neuron)
        to_neuron.source_neurons.remove(from_neuron)

        genome.connection_gene_list.remove(connection_to_delete)

        genome.last_mutation = "Delete"

        return True
Ejemplo n.º 4
0
    def mutate_add_connection(self, genome: Genome) -> bool:
        neuron_count = len(genome.neuron_gene_list)
        hidden_output_neuron_count = neuron_count - self.input_count
        input_bias_hidden_neuron_count = neuron_count - self.output_count

        genome.last_mutation = "Add"

        if self.genome_params.feed_forward_only:
            for attempts in range(5):
                source_neuron_idx = random.randint(
                    0, input_bias_hidden_neuron_count - 1)
                if self.input_count + self.output_count > source_neuron_idx >= self.input_count:
                    source_neuron_idx += self.output_count

                target_neuron_idx = self.input_count + random.randint(
                    0, hidden_output_neuron_count - 1)
                if source_neuron_idx == target_neuron_idx:
                    target_neuron_idx += 1
                    if target_neuron_idx == neuron_count:
                        continue

                source_neuron = genome.neuron_gene_list[source_neuron_idx]
                target_neuron = genome.neuron_gene_list[target_neuron_idx]

                if target_neuron.type == NeuronType.BIAS or target_neuron in source_neuron.target_neurons or genome.is_connection_cyclic(
                        source_neuron.inno_id, target_neuron.inno_id):
                    continue

                self.mutate_add_create_connection(genome, source_neuron,
                                                  target_neuron)
                return True
        else:
            for attempts in range(5):
                source_neuron_idx = random.randint(0, neuron_count - 1)
                target_neuron_idx = self.input_count + random.randint(
                    0, hidden_output_neuron_count - 1)

                source_neuron = genome.neuron_gene_list[source_neuron_idx]
                target_neuron = genome.neuron_gene_list[target_neuron_idx]

                self.mutate_add_create_connection(genome, source_neuron,
                                                  target_neuron)
                return True