def network_atoms_to_graphviz(network_atoms): """Create a pygraphviz.AGraph object from the given network_atoms.""" atoms = (atoms_split(a) for a in network_atoms.split('.') if a != '') graph = defaultdict(str) # ID: type edges = [] # list of 2-tuple for name, args in atoms: if name == 'output' and len(args) == 1: # output/1 # If already in graph, then idn is an output # node already set as neuron. graph[args] += '\n(output)' elif name == 'neuron' and len(args) == 2: # neuron/2 idn, ntype = args graph[idn] = NeuronType(ntype).name + graph.get(idn, '') elif name == 'edge' and len(args) == 2: # edge/2 ida, idb = args edges.append((ida, idb)) else: # some received atoms are not handled… # see logs for details LOGGER.error('converter.network_atoms_to_graphviz:' ' UNHANDLED ATOMS: ' + str((name, args)) + '.') # Create and return the dot from graph and edges dot = pgv.AGraph(strict=False, directed=True) [dot.add_node(idn, label=str(idn) + '\n' + label) for idn, label in graph.items()] [dot.add_edge(a, b) for a, b in edges] return dot
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