def __init__(self, config): super().__init__(config=config, config_fields=[ 'memory_min_size', 'memory_max_size', 'neuron_inter_mincount', 'neuron_inter_maxcount', 'neuron_edges_mincount', 'neuron_edges_maxcount', 'mutator', ]) self.neuron_types = NeuronType.xano()
def mutate(self, nb_intermediate_neuron:int, nb_total_neuron:int, neuron_types:iter, edges:iter): """Return the data received in input, modified according to mutation settings. nb_intermediate_neuron: integer equal to number of intermediate neuron. nb_total_neuron: integer equal to total number of neuron. neuron_types: iterable of NeuronType. edges: iterable of 2-tuple describing links between neurons. """ MUTATION_RATE = self.mutation_rate mutation = lambda: random() <= MUTATION_RATE mutate_nb_neuron = mutation(), mutation() mutate_neuron_type = mutation(), mutation() mutate_edges = mutation(), mutation() del mutation if any(mutate_nb_neuron): add, rmv = mutate_nb_neuron neuron_types = list(neuron_types) # allow modifications if add: nb_total_neuron += 1 nb_intermediate_neuron += 1 neuron_types.append(random_choice(NeuronType.xano())) if commons.log_level() >= logging.INFO: LOGGER.info('Mutator ' + str(self) + ' add new neuron of type ' + neuron_types[-1].name + '.') if rmv and nb_intermediate_neuron > 0: nb_total_neuron -= 1 nb_intermediate_neuron -= 1 target_idx = randrange(0, len(neuron_types)) if commons.log_level() >= logging.INFO: LOGGER.info('Mutator ' + str(self) + ' remove neuron ' + str(target_idx) + ' (' + neuron_types[target_idx].name + ').') del neuron_types[target_idx] if any(mutate_neuron_type): modify, swap = mutate_neuron_type neuron_types = list(neuron_types) # allow modifications if modify: # modify just one type target_idx = randrange(0, len(neuron_types)) new_type = random_choice(NeuronType.xano()) if commons.log_level() >= logging.INFO: LOGGER.info('Mutator ' + str(self) + ' modify type of ' + str(target_idx) + ' from ' + neuron_types[target_idx].name + ' to ' + new_type.name + '.' ) neuron_types[target_idx] = new_type if swap: # swap two types in the list target1_idx = randrange(0, len(neuron_types)) target2_idx = randrange(0, len(neuron_types)) neuron_types[target1_idx], neuron_types[target2_idx] = ( neuron_types[target2_idx], neuron_types[target1_idx] ) if commons.log_level() >= logging.INFO: LOGGER.info('Mutator ' + str(self) + ' swaps ' + str(target1_idx) + ' (' + neuron_types[target2_idx].name + ') and ' + str(target1_idx) + ' (' + neuron_types[target2_idx].name + ').' ) if any(mutate_edges): add, rmv = mutate_edges edges = list(edges) # allow modifications if add: # add one new edge target1_idx = randrange(1, nb_total_neuron + 1) target2_idx = randrange(1, nb_total_neuron + 1) edges.append((target1_idx, target2_idx)) if commons.log_level() >= logging.INFO: LOGGER.info('Mutator ' + str(self) + ' get an edge ' + str((target1_idx, target2_idx)) + '.') if rmv: # remove one existing edge idx = randrange(0, len(edges)) if commons.log_level() >= logging.INFO: LOGGER.info('Mutator ' + str(self) + ' lose its edge ' + str(edges[idx]) + '.') neuron_types = tuple(neuron_types) edges = tuple(edges) return nb_intermediate_neuron, neuron_types, edges