def get(self): index = self.context['experiment']['index'] - 1 index %= len(self.population) origin = self.population[index] dna = DNASequence() dna.fromstring(origin['dna']) mutate(dna, self.data['mutations']) return dna
def decode(dna: DNASequence) -> float: r = (-1.0, 0.0, 1.0) while not dna.finish: c = dna.any(_SELECT_FIRST_HALF, _SELECT_SECOND_HALF, _INCREASE_RANGE, _SELECT_RANGE_START, _SELECT_RANGE_CENTER, _SELECT_RANGE_END) if c == _SELECT_FIRST_HALF: r = (r[0], r[0] + (r[1] - r[0]) * 0.5, r[1]) continue elif c == _SELECT_SECOND_HALF: r = (r[1], r[1] + (r[2] - r[1]) * 0.5, r[2]) continue elif c == _INCREASE_RANGE: r = (r[0] * 2, r[1], r[2] * 2) continue elif c == _SELECT_RANGE_START: return r[0] elif c == _SELECT_RANGE_CENTER: return r[1] elif c == _SELECT_RANGE_END: return r[2] else: break return r[1]
def _create_neuron(dna: DNASequence, network: NeuralNetwork, neuron: NeuralNetworkNeuron): dna.extend(DNASequences.NEURON_CREATE) neuron_layer_index = network.layers.index(neuron.layer) # write bias float_encode(dna, neuron.bias) for connection in neuron.connections: dna.extend(DNASequences.NEURON_CREATE_LINK) node = connection.node # type: NeuralNetworkNeuron layer_size = len(node.layer.neurons) - 1 if layer_size == 0: layer_size = 1 node_index = node.layer.neurons.index(node) / layer_size * __NEURON_INDEX_REMAP if node.layer == network.input: link_layer_index = -1 else: link_layer_index = network.layers.index(node.layer) relative_index = neuron_layer_index - link_layer_index - 1 float_encode(dna, relative_index + node_index) float_encode(dna, connection.weight)
def assemble(dna: DNASequence, network: NeuralNetwork): connections = [] while not dna.finish: c = dna.any(DNASequences.NEURON_CREATE_LAYER, DNASequences.NEURON_CREATE, DNASequences.NEURON_CREATE_LINK) if c == DNASequences.NEURON_CREATE_LAYER: # skip layer creation if previous empty if network.layers and not network.layers[-1].neurons: continue network.layers.append(NeuralNetworkLayer(0)) elif c == DNASequences.NEURON_CREATE: if not network.layers: continue current_layer = network.layers[-1] bias = float_decode(dna) neuron = NeuralNetworkNeuron(current_layer) neuron.bias = bias current_layer.neurons.append(neuron) elif c == DNASequences.NEURON_CREATE_LINK: if not network.layers or not network.layers[-1].neurons: continue neuron = network.layers[-1].neurons[-1] link_data = float_decode(dna) weight = float_decode(dna) connections.append(NeuronDNAConnection(neuron, link_data, weight)) while not network.layers[-1].neurons: del network.layers[-1] network.outputs = network.layers[-1] layers = list() layers.append(network.input) layers.extend(network.layers) for connection in connections: neuron = connection.neuron # type: NeuralNetworkNeuron layer_index = layers.index(neuron.layer) link_neuron_address, link_layer_address = math.modf(connection.link_data) layer_index -= math.trunc(link_layer_address + __ROUND_VALUE) + 1 if len(layers) >= layer_index < 0: continue link_layer = layers[layer_index] # type: NeuralNetworkLayer link_neuron_index = (len(link_layer.neurons)-1) * (link_neuron_address / __NEURON_INDEX_REMAP) neuron.add_connection(link_layer.neurons[math.trunc(link_neuron_index + __ROUND_VALUE)], connection.weight)
def encode(dna: DNASequence, value: float, accuracy: float = EPS): r = (-1.0, 0.0, 1.0) while True: # check for match and range control values if abs(r[0] - value) <= accuracy: dna.extend(_SELECT_RANGE_START) break if abs(r[1] - value) <= accuracy: dna.extend(_SELECT_RANGE_CENTER) break if abs(r[2] - value) <= accuracy: dna.extend(_SELECT_RANGE_END) break if value < r[0] or value > r[2]: dna.extend(_INCREASE_RANGE) r = (r[0] * 2, r[1], r[2] * 2) continue if r[0] < value < r[1]: dna.extend(_SELECT_FIRST_HALF) r = (r[0], r[0] + (r[1] - r[0]) * 0.5, r[1]) continue if r[1] < value < r[2]: dna.extend(_SELECT_SECOND_HALF) r = (r[1], r[1] + (r[2] - r[1]) * 0.5, r[2]) continue assert False and "Problem"
def mutate(dna: DNASequence, mutation_count: int) -> None: while mutation_count: mutation_count -= 1 index = random.randint(0, len(dna)-1) shift = random.randint(DNA.A, DNA.G) dna.insert(index, shift)
def decompile(network: NeuralNetwork): dna = DNASequence() for layer in network.layers: _create_layer(dna, network, layer) return dna
def _create_layer(dna: DNASequence, network: NeuralNetwork, layer: NeuralNetworkLayer): dna.extend(DNASequences.NEURON_CREATE_LAYER) for neuron in layer.neurons: _create_neuron(dna, network, neuron)