I want to use NEAT's neural network by itself so I can control how the selection of the fittest(training) is done along with other things, but the source code for NEAT's feed forward network can't be used alone(to create one I have to have a config file, and a genome).
Source code for nn.feed_forward
:
from neat.graphs import feed_forward_layers
class FeedForwardNetwork(object):
def __init__(self, inputs, outputs, node_evals):
self.input_nodes = inputs
self.output_nodes = outputs
self.node_evals = node_evals
self.values = dict((key, 0.0) for key in inputs + outputs)
def activate(self, inputs):
if len(self.input_nodes) != len(inputs):
raise RuntimeError("Expected {0:n} inputs, got {1:n}".format(len(self.input_nodes), len(inputs)))
for k, v in zip(self.input_nodes, inputs):
self.values[k] = v
for node, act_func, agg_func, bias, response, links in self.node_evals:
node_inputs = []
for i, w in links:
node_inputs.append(self.values[i] * w)
s = agg_func(node_inputs)
self.values[node] = act_func(bias + response * s)
return [self.values[i] for i in self.output_nodes]
@staticmethod
def create(genome, config): # I don't want to have to pass in either arguments to create a network
""" Receives a genome and returns its phenotype (a FeedForwardNetwork). """
# Gather expressed connections.
connections = [cg.key for cg in genome.connections.values() if cg.enabled]
layers = feed_forward_layers(config.genome_config.input_keys, config.genome_config.output_keys, connections)
node_evals = []
for layer in layers:
for node in layer:
inputs = []
for conn_key in connections:
inode, onode = conn_key
if onode == node:
cg = genome.connections[conn_key]
inputs.append((inode, cg.weight))
ng = genome.nodes[node]
aggregation_function = config.genome_config.aggregation_function_defs.get(ng.aggregation)
activation_function = config.genome_config.activation_defs.get(ng.activation)
node_evals.append((node, activation_function, aggregation_function, ng.bias, ng.response, inputs))
return FeedForwardNetwork(config.genome_config.input_keys, config.genome_config.output_keys, node_evals)
Also I want to be able to mutate the neural network(connections, weights, ect).
To create a FeedForwardNetwork
, you need to use the create
method or set the inputs, outputs, node_evals
manually.
The input
is the list of the "key"(refer to the doc) of the input nodes. It is a list
of int
, like [-1, -2, ...,-num_inputs]
, where num_inputs is the number of input nodes you set in the config_file.
The output
is the list of the "key" of the output nodes. It is a list
of int
, like [0, 1, 2, ..., (num_outputs-1)]
, where num_outputs is the number of output nodes you set in the config_file.
The node_evals
is a list of tuple.
The size of the tuple:
Each element in the tuple correpsonds to one node that have "in" connections, so the tuple size is num_of_hiddens+num_of_outputs in the network. (Note, this is decided by the genome instead of the config, so the "num_of_outputs" and "num_of_hiddens" can be different from the "num_outputs" and "num_hidden" in the config_file).
The elements in the tuple:
As you can see in the create
method and the activate
method, an element in the tuple includes:
tuple[0]
: The key of corresponding node.tuple[1]
: The activation_function of the node. I think it is a function that input a float and output a float.tuple[2]
: The aggregation_function of the node. I think it can be any function that input a list of float, and output another float. For example, compute the sum of the elements in the list.tuple[3]
: Bias of the node, float.tuple[4]
: Response of the node, float.tuple[5]
: Links that provide inputs for this neuron(node), denoted as node i
. It is a list of tuple. The length of tuple[5]
is the number of input neuron of current neuron i
. As for the sub-tuple inside tuple[5]
, sub_tuple[0]
is the key of a input neuron (here "input" means a node that input to node i
, instead of the "input" of the whole network), and the sub_tuple[1]
(it's of float
type) is the connection weight between the certain input neuron and node i
.If you take a look at the implementation of activate
, you may have a better understanding of the physical meaning of "activation_function", "aggregation_function", "bias", "response" and "links".
I would also suggest you to run an example over here, add a breakpoint at the creatation of the FeedForwardNetwork
and inspect the data type.