nevopy.neat package¶
Submodules¶
nevopy.neat.config module¶
This module implements the NeatConfig
class, used to handle the
settings of the NEAT algorithm.
-
class
nevopy.neat.config.
NeatConfig
(file_pathname=None, **kwargs)¶ Bases:
nevopy.genetic_algorithm.config.GeneticAlgorithmConfig
Stores the settings of the NEAT algorithm.
Individual configurations can be ignored (default values will be used), set in the arguments of this class constructor or written in a file (pathname passed as an argument).
Some parameters/attributes related to mutation chances expects a tuple with two floats, indicating the minimum and the maximum chance of the mutation occurring. A value within the given interval is chosen based on the “mass extinction factor” (mutation chances increases as the number of consecutive generations in which the population has shown no improvement increases). If you want a fixed mutation chance, just place the same value on both positions of the tuple.
- Parameters
file_pathname (Optional[str]) – The pathname of a file from where the settings should be loaded.
**kwargs – Accepts any of the attributes listed for this class. When the value of an attribute isn’t passed as argument, a default value is used. The default values are defined in
NeatConfig.ATTRIBUTES
.
-
out_nodes_activation
¶ Activation function to be used by the output nodes of the networks. It should receive a float as input and return a float (the resulting activation) as output.
- Type
Callable[[float], float]
Activation function to be used by the hidden nodes of the networks. It should receive a float as input and return a float (the resulting activation) as output.
- Type
Callable[[float], float]
-
bias_value
¶ Constant activation value to be used by the bias nodes. If None, bias nodes won’t be used.
- Type
Optional[float]
-
weak_genomes_removal_pc
¶ Percentage of the least fit individuals to be deleted from the population before the reproduction step.
- Type
float
-
weight_mutation_chance
¶ Tuple containing, respectively, the minimum and maximum chance of mutating a connection gene.
- Type
Tuple[float, float]
-
new_node_mutation_chance
¶ Tuple containing, respectively, the minimum and maximum chance of a new hidden node being added to a newly born genome.
- Type
Tuple[float, float]
-
new_connection_mutation_chance
¶ Tuple containing, respectively, the minimum and maximum chance of a new connection being added to a newly born genome.
- Type
Tuple[float, float]
-
enable_connection_mutation_chance
¶ Tuple containing, respectively, the minimum and maximum chance of enabling a disabled connection in a newly born genome.
- Type
Tuple[float, float]
-
disable_inherited_connection_chance
¶ During a sexual reproduction between two genomes, this constant specifies the chance of a connection in the newly born genome being disabled if it’s disabled on at least one of the parent genomes.
- Type
float
-
mating_chance
¶ Chance of a genome reproducing sexually, i.e., by mating / crossing-over with another genome. Decreasing this value increases the chance of a genome reproducing asexually, through binary fission (copy + mutation).
- Type
float
-
interspecies_mating_chance
¶ Chance for a sexual reproduction (mating / cross-over) to be between genomes of different species.
- Type
float
-
rank_prob_dist_coefficient
¶ Coefficient \(\alpha\) used to calculate the probability distribution used to select genomes for reproduction. Basically, the value of this constant can be interpreted as follows: the genome, within a species, with the highest fitness has \(\times \alpha\) more chance of being selected for reproduction than the second best genome, which, in turn, has \(\times \alpha\) more chance of being selected than the third best genome, and so forth. This approach to reproduction is called rank-based selection. Note that this is applied to individuals within the same species.
- Type
float
-
weight_perturbation_pc
¶ Tuple containing, respectively, the minimum and maximum value for the maximum absolute percentage of the perturbation value of the weights. When a connection gene is being mutated, it has a chance of having a value (the perturbation) added to its weight. This can me summarized as follows (p is the weight perturbation percentage): current weight <- current weight * (1 + random[-p, p]).
- Type
Tuple[float, float]
-
weight_reset_chance
¶ Tuple containing, respectively, the minimum and maximum chance of resetting a connection’s weight during the mutation of a connection gene. The reset connection is assigned a new random weight.
- Type
Tuple[float, float]
-
new_weight_interval
¶ Interval from which the value of a new random connection weight will be picked from.
- Type
Tuple[float, float]
-
mass_extinction_threshold
¶ If the population’s fitness doesn’t improve for this amount of generations, the whole population, with the exception of its most fit genome, will be extinct/deleted and replaced by new randomly generated genomes. Here the fitness of a population in a given generation is considered to be equal to the fitness of the population’s most fit genome in that generation. As the number of generations without improvements increases, the mutations chances (as specified in the settings) also increase. This simulates the increase of the evolutionary pressure acting on the population.
- Type
int
-
maex_improvement_threshold_pc
¶ It’s considered that the fitness of a population improved if, and only if, the population’s fitness had an increase equivalent to this percentage. As an example, suppose that the fitness \(f_g\) of a population on generation \(g\) is 100 and that this parameter is set to 0.05 (5%). The fitness \(f_{g+1}\) of the population in the next generation (g + 1) is considered to have improved if, and only if, \(f_{g+1} \geq 1.05 \cdot f_g = 105\).
- Type
float
-
infanticide_output_nodes
¶ If True, newborn genomes with no enabled connections incoming to one or more output nodes will be deleted and replaced by a new randomly generated genome. Note that the term “infanticide” is being used here without any political or cultural connotation. It’s used because it is the word that best describe the phenomenon at hand and is widely used in the scientific field of zoology (see this article).
- Type
bool
-
infanticide_input_nodes
¶ If True, newborn genomes with no enabled connections leaving one or more input nodes will be deleted and replaced by a new randomly generated genome. Note that the term “infanticide” is being used here without any political or cultural connotation. It’s used because it is the word that best describe the phenomenon at hand and is widely used in the scientific field of zoology (see this article).
- Type
bool
-
random_genome_bonus_nodes
¶ Let h_bonus be the argument passed to this parameter and h_max the maximum number of hidden nodes within individuals of the population. When a random genome is created to replace one of the population’s genomes, the number of hidden nodes in it will be a random number picked from the interval [0, h_max + h_bonus].
- Type
int
-
random_genome_bonus_connections
¶ The same as
NeatConfig.random_genome_max_bonus_hnodes
, except it refers to the number of connections involving hidden nodes in the new randomly generated genome.- Type
int
-
excess_genes_coefficient
¶ Used in the formula that calculates the distance between two genomes. It’s the \(c_1\) coefficient in (1).
- Type
float
-
disjoint_genes_coefficient
¶ Used in the formula that calculates the distance between two genomes. It’s the \(c_2\) coefficient in (1).
- Type
float
-
weight_difference_coefficient
¶ Used in the formula that calculates the distance between two genomes. It’s the \(c_3\) coefficient in (1).
- Type
float
-
species_distance_threshold
¶ Minimum distance, as calculated by (1), between two genomes for them to be considered as being of the same species. A lower threshold will make new species easier to appear, increasing the number of species throughout the evolutionary process.
- Type
float
-
species_elitism_threshold
¶ Species with a number of members superior to this threshold will have their fittest member copied unchanged to the next generation.
- Type
int
-
species_no_improvement_limit
¶ If a species doesn’t show improvement in its best fitness for this amount of generations, it will be extinct.
- Type
int
-
reset_innovations_period
¶ If None, the innovation IDs of the new genes will never be reset. If an int, the innovation IDs will be reset periodically with a period (number of generations passed) equal to the value specified. As long as the id handler isn’t reset, a hidden node can’t be inserted more than once in a connection between two given nodes.
- Type
Optional[int]
-
allow_self_connections
¶ Whether to allow or not connections connecting a node to itself. If a node is connected to itself, it considers its last output when calculating its new output.
- Type
bool
-
initial_node_activation
¶ Initial activation value cached by a node when it’s created or reset.
- Type
float
-
ATTRIBUTES
= {'allow_self_connections': True, 'bias_value': 1, 'disable_inherited_connection_chance': 0.75, 'disjoint_genes_coefficient': 1, 'enable_connection_mutation_chance': (0.03, 0.3), 'excess_genes_coefficient': 1, 'hidden_nodes_activation': <function steepened_sigmoid>, 'infanticide_input_nodes': True, 'infanticide_output_nodes': True, 'initial_node_activation': 0, 'interspecies_mating_chance': 0.05, 'maex_improvement_threshold_pc': 0.03, 'mass_extinction_threshold': 15, 'mating_chance': 0.7, 'new_connection_mutation_chance': (0.03, 0.3), 'new_node_mutation_chance': (0.03, 0.3), 'new_weight_interval': (-2, 2), 'out_nodes_activation': <function steepened_sigmoid>, 'random_genome_bonus_connections': -2, 'random_genome_bonus_nodes': -2, 'rank_prob_dist_coefficient': 1.75, 'reset_innovations_period': 5, 'species_distance_threshold': 2, 'species_elitism_threshold': 5, 'species_no_improvement_limit': 15, 'weak_genomes_removal_pc': 0.75, 'weight_difference_coefficient': 0.5, 'weight_mutation_chance': (0.7, 0.9), 'weight_perturbation_pc': (0.1, 0.4), 'weight_reset_chance': (0.1, 0.3)}¶ Attributes supported by the class and their default values. Each attribute can passed as a kwarg in the class’ constructor or be specified in a config file. Attributes not specified will be initialized with a default value.
-
MAEX_KEYS
= {'enable_connection_mutation_chance', 'new_connection_mutation_chance', 'new_node_mutation_chance', 'weight_mutation_chance', 'weight_perturbation_pc', 'weight_reset_chance'}¶ Name of the attributes whose values change according to the mass extinction counter (type: Tuple[float, float]).
nevopy.neat.genes module¶
Implements the nodes (neurons) and edges (connections) of a genome.
-
class
nevopy.neat.genes.
ConnectionGene
(cid, from_node, to_node, weight, enabled=True)¶ Bases:
object
A connection between two nodes.
A connection gene represents/encodes a connection (edge) between two nodes (neurons) of a neural network (phenotype of a genome).
- Parameters
cid (int) – The innovation number of the connection. As described in the original NEAT paper [SM02], this serves as a historical marker for the gene, helping to identify homologous genes.
from_node (NodeGene) – Node from where the connection is originated. The source node of the connection.
to_node (NodeGene) – Node to where the connection is headed. The destination node of the connection.
weight (float) – The weight of the connection.
enabled (bool) – Whether the initial state of the newly created connection should enabled or disabled.
-
weight
¶ The weight of the connection.
- Type
float
-
enabled
¶ Whether the connection is enabled or not. A disabled connection won’t be considered during the computations of the neural network.
- Type
bool
-
property
id
¶ Innovation number of the connection gene.
As described in the original NEAT paper [SM02], this value serves as a historical marker for the gene, helping to identify homologous genes. Although must of the identification is based on the nodes that form the connection, this ID is helpful to increase the speed of certain comparisons.
- Return type
int
-
self_connecting
()¶ Returns True if the connection is connecting a node to itself and False otherwise.
- Return type
bool
-
exception
nevopy.neat.genes.
ConnectionIdException
¶ Bases:
Exception
Indicates that an attempt has been made to assign a new ID to a connection gene that already has an ID.
-
class
nevopy.neat.genes.
NodeGene
(node_id, node_type, activation_func, initial_activation)¶ Bases:
object
A gene that represents/encodes a neuron (node) in a neural network.
A
NodeGene
is the portion of aNeatGenome
that encodes a neuron (node) of the neural network encoded by theNeatGenome
. It has an activation function, which is applied to inputs received from other nodes of the network.- Parameters
node_id (int) – The node’s identifier / innovation number.
node_type (NodeGene.Type) – The node’s type.
activation_func (Callable[[float], float]) – Activation function to be used by the node. It should receive a float as input and return a float (the resulting activation) as output.
initial_activation (float) – initial value of the node’s activation (used when processing recurrent connections between nodes).
-
in_connections
¶ List with the connections (
ConnectionGene
) leaving this node, i.e., connections that have this node as the source.- Type
List[ConnectionGene]
-
out_connections
¶ List with the connections (
ConnectionGene
) coming to this node, i.e., connections that have this node as the destination.- Type
List[ConnectionGene]
-
class
Type
(value)¶ Bases:
enum.Enum
Specifies the possible types of node genes.
-
BIAS
= 1¶
-
HIDDEN
= 2¶
-
INPUT
= 0¶
-
OUTPUT
= 3¶
-
-
activate
(x)¶ Applies the node’s activation function to the given input.
The node’s activation value, i.e., the node’s cached output, is updated by this call and can be later be accessed through the property
activation
.- Return type
None
- Returns
None. The node’s output is updated internally.
-
property
activation
¶ The node’s cached activation value, i.e., the node’s output when it was last processed.
- Return type
float
-
property
id
¶ Innovation ID of the gene.
This ID is used to mate genomes and to calculate their difference.
“The innovation numbers are historical markers that identify the original historical ancestor of each gene. New genes are assigned new increasingly higher numbers.” - [SM02]
- Return type
int
-
reset_activation
()¶ Resets the node’s activation value (it’s cached output) to its initial value.
- Return type
None
-
simple_copy
()¶ Makes and returns a simple copy of this node.
Wraps a call to this class’ constructor.
The copied node shares the same values for all the attributes of the source node, except for the connections. The copied node is created without any connections.
- Return type
- Returns
A copy of this node without any connection.
-
exception
nevopy.neat.genes.
NodeIdException
¶ Bases:
Exception
Indicates that an attempt has been made to assign a new ID to a gene node that already has an ID.
-
exception
nevopy.neat.genes.
NodeParentsException
¶ Bases:
Exception
Indicates that an attempt has been made to get the parents of a non-hidden node.
-
nevopy.neat.genes.
align_connections
(con_list1, con_list2, print_alignment=False)¶ Aligns the matching connection genes of the given lists.
In the context of NEAT [SM02], aligning homologous connections genes is required both to compare the similarity of a pair of genomes and to perform sexual reproduction. Two connection genes are said to match or to be homologous if they have the same innovation ID, meaning that they represent the same structure.
Genes that do not match are either disjoint or excess, depending on whether they occur within or outside the range of the other parent’s innovation numbers. They represent a structure that is not present in the other genome.
- Parameters
con_list1 (List[ConnectionGene]) – The first list of connection genes.
con_list2 (List[ConnectionGene]) – The second list of connection genes.
print_alignment (
bool
) – Whether to print the generated alignment or not. Used for debugging.
- Return type
Tuple
[List
[Optional
[ConnectionGene
]],List
[Optional
[ConnectionGene
]]]- Returns
A tuple containing two lists of the same size. Index 0 corresponds to the first list and index 1 to the second list. The returned lists contain connection genes or None. The order of the genes is preserved in the returned lists (but not their indices!).
If, given a position, there are two genes (one in each list), the genes match. On the other hand, if, in the position, there is only one gene (on one of the lists) and a None value (on the other list), the genes are either disjoint or excess.
nevopy.neat.genomes module¶
Implements the genome and its main operations.
A genome is a collection of genes that encode a neural network (the genome’s phenotype). In this implementation, there is no distinction between a genome and the network it encodes. In NEAT, the genome is the entity subject to evolution.
-
exception
nevopy.neat.genomes.
ConnectionExistsError
¶ Bases:
Exception
Exception that indicates that a connection between two given nodes already exists.
-
exception
nevopy.neat.genomes.
ConnectionToBiasNodeError
¶ Bases:
Exception
Exception that indicates that an attempt has been made to create a connection containing a bias node as destination.
-
class
nevopy.neat.genomes.
FixTopNeatGenome
(fito_genome, num_neat_inputs, num_neat_outputs, config, initial_neat_connections=True)¶ Bases:
nevopy.neat.genomes.NeatGenome
Integration of a NEAT genome with a fixed topology genome.
This class defines a new type of NEAT genome that integrates the default
NeatGenome with a :class:
.FixedTopologyGenome`. It can be used withNeatPopulation
.When an input is received, it’s first processed by the layers of the fixed topology genome. The output is, then, processed using NEAT, which generates the final output.
Note
This class is useful when the inputs that will be fed to the genome have high dimensions. Since NEAT doesn’t scale well with such lengthy inputs (like images), a fixed topology genome (that can contain, for instance, convolutional layers) can be used to reduce the dimensionality of the input before feeding it to NEAT’s nodes.
- Parameters
fito_genome (FixedTopologyGenome) – Instance of
FixedTopologyGenome
to be used to pre-process the inputs. It will also be evolved.num_neat_inputs (int) – Length of the flattened outputs of the fixed topology genome. It’s also the number of input nodes of the NEAT genome.
num_neat_outputs (int) – Number of output nodes of the NEAT genome.
config (NeatConfig) – Settings of the current evolutionary session.
initial_neat_connections (bool) – Whether to create connections connecting each input node of the NEAT genome to each of its output nodes.
-
deep_copy
()¶ Makes an exact/deep copy of the genome.
All the nodes and connections (including their weights) of the parent genome are copied to the new genome.
- Return type
- Returns
An exact/deep copy of the genome.
-
distance
(other)¶ Sums, to the default distance calculated by
NeatGenome.distance()
, the sum of the absolute difference between the fixed topology layers weights.- Return type
float
-
mate
(other)¶ Mates two genomes to produce a new genome (offspring).
Sexual reproduction. Follows the idea described in the original paper of the NEAT algorithm:
“When crossing over, the genes in both genomes with the same innovation numbers are lined up. These genes are called matching genes. (…). Matching genes are inherited randomly, whereas disjoint genes (those that do not match in the middle) and excess genes (those that do not match in the end) are inherited from the more fit parent. (…) [If the parents fitness are equal] the disjoint and excess genes are also inherited randomly. (…) there’s a preset chance that an inherited gene is disabled if it is disabled in either parent.” - [SM02]
- Parameters
other (NeatGenome) – The second genome. Currently,
NeatGenome
is only compatible for mating with instances ofNeatGenome
or of one of its subclasses.- Return type
- Returns
A new genome (the offspring born from the sexual reproduction between the current genome and the genome passed as argument.
- Raises
IncompatibleGenomesError – If the genome passed as argument to
other
is incompatible with the current genome (self).
-
mutate_weights
()¶ Randomly mutates the weights of the genome’s connections.
Each connection gene in the genome has a chance to be perturbed, reset or to remain unchanged.
- Return type
None
-
process
(x)¶ Feeds the input to the fixed topology genome and uses the output as input to the NEAT genome.
- Return type
ndarray
-
random_copy
()¶ Makes a deep copy of the genome, but with random weights.
- Return type
- Returns
A deep copy of the genome with the same topology of the original genome, but random connections weights.
-
simple_copy
()¶ Makes a simple copy of the genome.
Wraps a call to this class’ constructor. The new genome’s is initialized without a fixed topology genome (
fito_genome
) - the value of this attribute is None.- Return type
- Returns
A copy of the genome without any of its connections (including the ones between input and output nodes) and hidden nodes. The attribute
fito_genome
is set to None.
-
class
nevopy.neat.genomes.
NeatGenome
(num_inputs, num_outputs, config, initial_connections=True)¶ Bases:
nevopy.base_genome.BaseGenome
Linear representation of a neural network’s connectivity.
In the context of NEAT, a genome is a collection of genes that encode a neural network (the genome’s phenotype). In this implementation, there is no distinction between a genome and the network it encodes. A genome processes inputs based on its nodes and connections in order to produce an output, emulating a neural network.
Note
The instances of this class are the entities subject to evolution by the NEAT algorithm.
Note
The encoded networks are Graph Neural Networks (GNNs), connectionist models that capture the dependence of graphs via message passing between the nodes of graphs.
Note
When declaring a subclass of this class, you should always override the methods
simple_copy()
,deep_copy()
andrandom_copy()
, so that they return an instance of your subclass and not ofNeatGenome
. It’s recommended (although optional) to also override the methodsdistance()
andmate()
.- Parameters
num_inputs (int) – Number of input nodes in the network.
num_outputs (int) – Number of output nodes in the network.
config (NeatConfig) – Settings of the current evolution session.
initial_connections (bool) – If True, connections between the input nodes and the output nodes of the network will be created.
-
species_id
¶ Indicates the species to which the genome belongs.
- Type
int
-
fitness
¶ The last calculated fitness of the genome.
- Type
float
-
adj_fitness
¶ The last calculated adjusted fitness of the genome.
- Type
float
List with all the node genes of the type
NodeGene.Type.HIDDEN
in the genome.- Type
list
ofNodeGene
-
connections
¶ List with all the connection genes in the genome.
- Type
list
ofConnectionGene
-
_existing_connections_dict
¶ Used as a fast lookup table to consult existing connections in the network. Given a node N, it maps N’s ID to the IDs of all the nodes that have a connection with N as the source.
- Type
Dict[int, Set]
-
add_connection
(cid, src_node, dest_node, enabled=True, weight=None)¶ Adds a new connection gene to the genome.
- Parameters
cid (int) – ID of the connection. It’s used as a historical marker of the connection’s creation, acting as an “innovation number”.
src_node (NodeGene) – Node from where the connection leaves (source node).
dest_node (NodeGene) – Node to where the connection is headed (destination node).
enabled (bool) – Whether the new connection should be enabled or not.
weight (Optional[float]) – The weight of the connection. If None, a random value (within the interval specified in the settings) will be chosen.
- Raises
ConnectionExistsError – If the connection src_node->dest_node already exists in the genome.
ConnectionToBiasNodeError – If dest_node is an input or bias node (nodes of these types do not process inputs!).
- Return type
None
-
add_random_connection
(id_handler)¶ Adds a new connection between two random nodes in the genome.
This is an implementation of the add connection mutation, described in the original NEAT paper [SM02].
- Parameters
id_handler (IdHandler) – ID handler that will be used to assign an ID to the new connection. The handler’s internal cache of existing connections will be updated accordingly.
- Return type
- Returns
A tuple containing the source node and the destination node of the connection, if a new connection was successfully created. None, if there is no space in the genome for a new connection.
Adds a new hidden node to the genome in a random position.
This method implements the add node mutation procedure described in the original NEAT paper:
“An existing connection is split and the new node placed where the old connection used to be. The old connection is disabled and two new connections are added to the genome. The new connection leading into the new node receives a weight of 1, and the new connection leading out receives the same weight as the old connection.” - [SM02]
Only currently enabled connections are considered eligible to “host” the new hidden node.
- Parameters
id_handler (IdHandler) – ID handler that will be used to assign an ID to the new hidden node. The handler’s internal cache of existing nodes and connections will be updated accordingly.
- Return type
Optional
[NodeGene
]- Returns
The new hidden node, if it was successfully created. None if it wasn’t possible to find a connection to “host” the new node. This usually happens when the ID handler hasn’t been reset in a while.
-
property
config
¶ Settings of the current evolutionary session.
If None, a config object hasn’t been assigned to this genome yet.
- Return type
Any
-
connection_exists
(src_id, dest_id)¶ Checks whether a connection between the given nodes exists.
- Parameters
src_id (int) – ID of the connection’s source node.
dest_id (int) – ID of the connection’s destination node.
- Return type
bool
- Returns
True if the specified connection exists in the genome’s network and False otherwise.
-
deep_copy
()¶ Makes an exact/deep copy of the genome.
All the nodes and connections (including their weights) of the parent genome are copied to the new genome.
- Return type
- Returns
An exact/deep copy of the genome.
-
distance
(other)¶ Calculates the distance between two genomes.
The shorter the distance between two genomes, the greater the similarity between them is. In the context of NEAT, the similarity between genomes increases as:
the number of matching connection genes increases;
the absolute difference between the matching connections weights decreases;
The distance between genomes is used for speciation and for sexual reproduction (mating).
The formula used is shown below. It’s the same as the one presented in the original NEAT paper [SM02]. All the coefficients are configurable.
(1)¶\[\delta = c_1 \cdot \frac{E}{N} + c_2 \cdot \frac{D}{N} \ + c_3 \cdot W\]- Parameters
other (NeatGenome) – The other genome (an instance of
NeatGenome
or one of its subclasses).- Return type
float
- Returns
The distance between the genomes.
-
enable_random_connection
()¶ Randomly activates a disabled connection gene.
- Return type
None
-
info
()¶ Returns a string with the genome’s nodes activations and connections. Used mostly for debugging purposes.
- Return type
str
-
property
input_shape
¶ Number of input nodes in the genome.
- Return type
int
-
mate
(other)¶ Mates two genomes to produce a new genome (offspring).
Sexual reproduction. Follows the idea described in the original paper of the NEAT algorithm:
“When crossing over, the genes in both genomes with the same innovation numbers are lined up. These genes are called matching genes. (…). Matching genes are inherited randomly, whereas disjoint genes (those that do not match in the middle) and excess genes (those that do not match in the end) are inherited from the more fit parent. (…) [If the parents fitness are equal] the disjoint and excess genes are also inherited randomly. (…) there’s a preset chance that an inherited gene is disabled if it is disabled in either parent.” - [SM02]
- Parameters
other (NeatGenome) – The second genome. Currently,
NeatGenome
is only compatible for mating with instances ofNeatGenome
or of one of its subclasses.- Return type
- Returns
A new genome (the offspring born from the sexual reproduction between the current genome and the genome passed as argument.
- Raises
IncompatibleGenomesError – If the genome passed as argument to
other
is incompatible with the current genome (self).
-
mutate_weights
()¶ Randomly mutates the weights of the genome’s connections.
Each connection gene in the genome has a chance to be perturbed, reset or to remain unchanged.
- Return type
None
-
nodes
()¶ Returns all the genome’s node genes. Order: inputs, bias, outputs and hidden.
- Return type
List
[NodeGene
]
-
property
output_shape
¶ Number of output nodes in the genome.
- Return type
int
-
process
(x)¶ Feeds the given input to the neural network.
In this implementation, there is no distinction between a genome and the neural network it encodes. The genome will emulate a neural network (its phenotype) in order to process the given input. The encoded network is a Graph Neural Networks (GNN).
Note
The processing is done recursively, starting from the output nodes (top-down approach). Because of that, nodes not connected to at least one of the network’s output nodes won’t be processed.
- Parameters
x (Sequence[float]) – A sequence object (like a list or numpy array) containing the inputs to be fed to the neural network input nodes. It represents a single training sample. The value in the index i of X will be fed to the \(i^{th}\) input node of the neural network.
- Return type
ndarray
- Returns
A numpy array containing the outputs of the network’s output nodes. The index i contains the activation value of the \(i^{th}\) output node of the network.
- Raises
InvalidInputError – If the number of elements in X doesn’t match the number of input nodes in the network.
-
process_node
(n)¶ Recursively processes the activation of the given node.
Unless it’s a bias or input node (that have a fixed output), a node must process the input it receives from other nodes in order to produce an activation. This is done recursively: if n receives input from a node m that haven’t had its activation calculated yet, the activation of m will be calculated recursively before the activation of n is computed. Recurrences are solved by using the previous activation of the “problematic” node.
Let \(w_i\) be the weight of the \(i^{\text{th}}\) connection that has n as destination node. Let \(a_i\) be the current cached output of the source node of \(c_i\). Let \(\sigma\) be the activation function of n. The activation (output) a of n is computed as follows:
\(a = \sigma (\sum \limits_{i} w_i \cdot a_i)\)
- Parameters
n (NodeGene) – The node to be processed.
- Return type
float
- Returns
The activation value (output) of the node.
-
random_copy
()¶ Makes a deep copy of the genome, but with random weights.
- Return type
- Returns
A deep copy of the genome with the same topology of the original genome, but random connections weights.
-
reset
()¶ Wrapper for
reset_activations()
.- Return type
None
-
reset_activations
()¶ Resets cached activations of the genome’s nodes.
It restores the current activation value of all the nodes in the network to their initial value.
- Return type
None
-
simple_copy
()¶ Makes a simple copy of the genome.
Wraps a call to this class’ constructor.
- Return type
- Returns
A copy of the genome without any of its connections (including the ones between input and output nodes) and hidden nodes.
-
valid_in_nodes
()¶ Checks if all the genome’s input nodes are valid.
An input node is considered to be valid if it has at least one enabled connection leaving it, i.e., its activation is used as input by at least one other node.
- Return type
bool
- Returns
True if all the genome’s input nodes are valid and False otherwise.
-
valid_out_nodes
()¶ Checks if all the genome’s output nodes are valid.
An output node is considered to be valid if it receives, during its processing, at least one input, i.e., the node has at least one enabled incoming connection. Invalid output nodes simply outputs a fixed default value and are, in many cases, undesirable.
- Return type
bool
- Returns
True if all the genome’s output nodes have at least one enabled incoming connection and False otherwise. Self-connecting connections are not considered.
-
visualize
(**kwargs)¶ Simple wrapper for the
nevopy.neat.visualization.visualize_genome()
function. Please refer to its documentation for more information.- Return type
None
-
visualize_activations
(**kwargs)¶ Simple wrapper for the
nevopy.neat.visualization.visualize_activations()
function. Please refer to its documentation for more information.- Return type
Any
nevopy.neat.id_handler module¶
This module implements the ID handler, use to assign IDs to species, genomes, hidden nodes and connections. In the case of nodes and connections genes, the ID can also be interpreted as an innovation number.
-
class
nevopy.neat.id_handler.
IdHandler
(num_inputs, num_outputs, has_bias)¶ Bases:
object
Handles the assignment of IDs.
An ID handler manages the assignment of IDs to species, genomes, hidden nodes and connections. In the case of nodes and connections genes, the ID can also be interpreted as an innovation number.
“The innovation numbers are historical markers that identify the original historical ancestor of each gene. New genes are assigned new increasingly higher numbers.” - [SM02]
The ID handler implements the following solution:
“A possible problem is that the same structural innovation will receive different innovation numbers in the same generation if it occurs by chance more than once. However, by keeping a list of the innovations that occurred in the current generation, it is possible to ensure that when the same structure arises more than once through independent mutations in the same generation, each identical mutation is assigned the same innovation number. Thus, there is no resultant explosion of innovation numbers.” - [SM02]
In NEvoPy, it’s possible to configure the rate at which innovation numbers are reset (see
NeatConfig.reset_innovations_period
).Warning
This class isn’t compatible with parallel processing.
- Parameters
num_inputs (int) – Number of input nodes in the genomes.
num_outputs (int) – Number of output nodes in the genomes.
has_bias (bool) – Whether the genomes have a bias node.
-
next_connection_id
(src_id, dest_id)¶ Returns an ID / innovation number for a connection gene.
The new connection is identified through the IDs of its source and destination nodes. While the ID handler isn’t reset, connections that have the same source and destination nodes will be assigned the same ID.
- Parameters
src_id (int) – ID of the new connection’s source node.
dest_id (int) – ID of the new connection’s destination node.
- Return type
int
- Returns
An ID for the new connection.
Returns an ID / innovation number for a hidden node.
A hidden node is created by breaking an existing connection of the genome in two. Consider two nodes A and B, both of which are present in multiple genomes of the population. While the ID handler isn’t reset, hidden nodes created by breaking the connection A->B will be assigned the same ID / innovation number.
- Parameters
src_id (int) – ID of the source node of the connection being broken to create the new hidden node.
dest_id (int) – ID of the destination node of the connection being broken to create the new hidden node.
- Return type
int
- Returns
An ID for the new hidden node.
-
next_species_id
()¶ Returns a new unique ID for a species.
-
reset
()¶ Resets the cache of new nodes and connections.
This resets the handler’s cached innovations.
- Return type
None
nevopy.neat.population module¶
Implementation of the main mechanisms of the NEAT algorithm.
This is the main module of NEvoPy’s implementation of the NEAT algorithm. It
implements the NeatPopulation
class, which handles the evolution of a
population/community of NEAT genomes.
-
class
nevopy.neat.population.
NeatPopulation
(size, num_inputs=None, num_outputs=None, base_genome=None, config=None, processing_scheduler=None)¶ Bases:
nevopy.base_population.BasePopulation
Population of individuals (genomes) to be evolved by the NEAT algorithm.
Main class of NEvoPy’s implementation of the NEAT algorithm. It represents a population of individuals (genomes) to be evolved. The correct term, in NEAT’s case, is actually “community” (group of populations of two or more different species) rather than “population” (subset of individuals of one species), since NEAT divides its genomes into species. However, to maintain consistency with the neuroevolution literature, the term “population” is used.
To use NEAT, most users will need to use only this class. It’s main method,
evolve()
, starts the evolutionary process. By providing a processing scheduler, the user is able to specify how the computation of the fitness of the population’s genomes will occur (whether to use serial or parallel processing, CPU or GPU, etc).By default, a
PoolProcessingScheduler
is used. It implements parallel processing using (by default) all the CPU cores of the machine where the program is running. Alternatively, if you want to run the evolution process on multiple machines (cluster) you should check out theRayProcessingScheduler
.Example
Suppose you have already defined a function called fitness_func that takes a genome as input and calculates its fitness. If the networks take 10 input values and outputs 3 values, here is how you can proceed to create and evolve a population of 100 genomes using the default settings and processing scheduler:
def fitness_func(genome): """ Function that takes a genome as input and returns the genome's fitness (a float) as output. """ # ... # Creating and evolving a population: population = NeatPopulation(size=100, num_inputs=10, num_outputs=3) history = population.evolve(generations=100, fitness_function=fitness_func) # Visualizing the progression of the population's fitness: history.visualize() # Retrieving and visualizing the fittest genome of the population: best_genome = population.fittest() best_genome.visualize()
- Parameters
size (int) – Number of genomes in the population (constant value).
num_inputs (Optional[int]) – Number of input nodes in each genome. If None, the number of inputs will be inferred from the base genome.
num_outputs (Optional[int]) – Number of output nodes in each genome. If None, the number of outputs will be inferred from the base genome.
base_genome (Optional[NeatGenome]) – Genome that will serve as a base for the randomly generated genomes of the population. If None, a new genome of the class
NeatGenome
will be used as the base genome.config (NeatConfig) – The settings of the evolutionary process. If None the default settings will be used.
processing_scheduler (Optional[ProcessingScheduler]) – Processing scheduler to be used to compute the fitness of the population’s genomes. If None, the default scheduler will be used
PoolProcessingScheduler
.
-
species
¶ List with the currently alive species in the population.
- Type
List[NeatSpecies]
-
DEFAULT_SCHEDULER
¶ alias of
nevopy.processing.pool_processing.PoolProcessingScheduler
-
property
config
¶ Config object that stores the settings used by the population.
- Return type
Any
-
evolve
(generations, fitness_function, callbacks=None, verbose=2, **kwargs)¶ Evolves the population of genomes using the NEAT algorithm.
- Parameters
generations (int) – Number of generations for the algorithm to run. A generation is completed when all the population’s genomes have been processed and reproduction and speciation has occurred.
fitness_function (Callable[[NeatGenome], float]) – Fitness function to be used to evaluate the fitness of individual genomes. It must receive a genome as input and produce a float (the genome’s fitness) as output.
callbacks (Optional[List[Callback]]) – List with instances of
Callback
that will be called during the evolutionary session. By default, aHistory
callback is always included in the list. ACompleteStdOutLogger
or aSimpleStdOutLogger
might also be included, depending on the value passed to theverbose
param.verbose (int) – Verbose level (logging on stdout). Options: 0 (no verbose), 1 (light verbose) and 2 (heavy verbose).
- Return type
- Returns
A
History
object containing useful information recorded during the evolutionary process.
-
generate_offspring
(species, rank_prob_dist)¶ Generates a new genome from one or more genomes of the species.
The offspring can be generated either by mating two randomly chosen genomes (sexual reproduction) or by cloning a single genome (asexual reproduction / binary fission). After the newly born genome is created, it has a chance of mutating. The possible mutations are:
. Enabling a disabled connection;. Changing the weights of one or more connections;. Creating a new connection between two random nodes;. Creating a new random hidden node.- Parameters
species (NeatSpecies) – Species from which the offspring will be generated.
rank_prob_dist (Sequence) – Sequence (usually a numpy array) containing the chances of each of the species genomes being the first parent of the newborn genome.
- Return type
- Returns
A newly generated genome.
-
info
()¶ Returns a string containing relevant information about the population.
- Return type
str
-
offspring_proportion
(num_offspring)¶ Calculates the number of descendants each species will leave for the next generation.
Every species is assigned a potentially different number of offspring in proportion to the sum of adjusted fitnesses of its member organisms [SM02]. This selection method is called roulette wheel selection.
- Parameters
num_offspring (int) – Number of genomes to be generated by all the species combined.
- Returns
A dictionary mapping the ID of each of the population’s species to the number of descendants it will leave for the next generation.
- Return type
Dict
[int
,int
]
-
reproduction
()¶ Handles the reproduction of the population’s genomes.
This method implements the reproduction mechanism described in the original paper of the NEAT algorithm [SM02].
First, the most fit genomes of each species with more than a pre-defined number of individuals are selected to be passed unchanged to the next generation (elitism). Next, the least fit genomes of each species are discarded (reverse elitism). After that, the number of descendants of each species is calculated based on the proportion between the total fitness of the population and the adjusted fitness of the species (roulette wheel selection). Finally, the reproduction of individuals of the same species (and, on rare occasions, between genomes of different species as well) occurs.
Genomes with a higher fitness have a higher chance of leaving offspring. Within a species, the chance of a genome reproducing is given by the position it occupies in the species fitness rank (rank-based selection). This means that the reproduction chance of a genome is not directly calculated from the genome’s fitness, but rather from how well positioned is the genome in the fitness rank.
Most of the behaviour described above can be adjusted by changing the settings of the evolutionary process (see
NeatConfig
).- Return type
None
-
speciation
(generation)¶ Divides the population’s genomes into species.
The importance of speciation for NEAT:
“Speciating the population allows organisms to compete primarily within their own niches instead of with the population at large. This way, topological innovations are protected in a new niche where they have time to optimize their structure through competition within the niche. The idea is to divide the population into species such that similar topologies are in the same species.” - [SM02]
The distance (compatibility) between a pair of genomes is calculated based on to the number of excess and disjoint genes between them. See
NeatGenome.distance()
for more information.About the speciation process:
“Each existing species is represented by a random genome inside the species from the previous generation. A given genome g in the current generation is placed in the first species in which g is compatible with the representative genome of that species. This way, species do not overlap. If g is not compatible with any existing species, a new species is created with g as its representative.” - [SM02]
Species that haven’t improved their fitness for a pre-defined number of generations are extinct, i.e., they are removed from the population and aren’t considered for the speciation process. This number is configurable.
- Parameters
generation (int) – Current generation number.
- Return type
None
nevopy.neat.species module¶
Implementation of the NeatSpecies
class.
-
class
nevopy.neat.species.
NeatSpecies
(species_id, generation)¶ Bases:
object
Represents a species within NEAT’s evolutionary environment.
- Parameters
species_id (int) – Unique identifier of the species.
generation (int) – Current generation. The generation in which the species is born.
-
representative
¶ Genome used to represent the species.
- Type
Optional[NeatGenome]
-
members
¶ List with the genomes that belong to the species.
- Type
List[NeatGenome]
-
last_improvement
¶ Generation in which the species last showed improvement of its fitness. The species fitness in a given generation is equal to the fitness of the species most fit genome on that generation.
- Type
int
-
best_fitness
¶ The last calculated fitness of the species most fit genome.
- Type
Optional[float]
-
avg_fitness
()¶ Returns the average fitness of the species genomes.
- Return type
float
-
fittest
()¶ Returns the fittest member of the species.
- Return type
-
property
id
¶ Unique identifier of the species.
- Return type
int
-
random_representative
()¶ Randomly chooses a new representative for the species.
- Return type
None
nevopy.neat.visualization module¶
This module implements visualization utilities related to the NEAT algorithm.
-
class
nevopy.neat.visualization.
NodeVisualizationInfo
(label='', activation_threshold=0.5, mode='greater', equality_precision=0.01)¶ Bases:
object
Stores information about an input or output node of a
NeatGenome
to be visualized with theneat.visualize_activations()
function.- Parameters
label (str) – Label to be drawn next to the node.
activation_threshold (float) – Value to be taken as reference when checking if the node is activated or not.
mode (str) – Name of the method to be used to check if the node is activated or not. Currently available modes: “greater”, “less”, “equal” and “diff”.
-
is_activated
(activation)¶ Checks whether the node is activated or not.
- Return type
bool
-
nevopy.neat.visualization.
columns_graph_layout
(genome, width, height, node_size, horizontal_pad_pc=(0.03, 0.03), vertical_pad_pc=(0.03, 0.03), ideal_h_nodes_per_col=4, consider_bias_node=True)¶ Positions the network’s nodes in columns.
The input nodes are placed in the left-most column and the output nodes are placed in the right-most columns. The hidden nodes are placed in columns located between those two columns. For big networks, try using a smaller node size for better quality.
- Parameters
genome (NeatGenome) – The genome to be visualized.
width (float) – Width of the figure / surface.
height (float) – Height of the figure / surface.
node_size (float) – Size of the drawn nodes.
horizontal_pad_pc (Tuple[float, float]) – Tuple containing the size of the padding on the left and on the right of the surface. Unit: the width of the surface.
vertical_pad_pc (Tuple[float, float]) – Tuple containing the size of the padding below and above the surface. Unit: the height of the surface.
ideal_h_nodes_per_col (int) – Preferred number of hidden nodes per column (the algorithm will try to draw columns with this amount of hidden nodes when possible).
consider_bias_node (bool) – Whether the bias node should be considered or not when calculating the positions.
- Return type
Dict
[int
,Tuple
[float
,float
]]- Returns
Dictionary mapping the ID of each node to a tuple containing its position in the figure.
-
nevopy.neat.visualization.
visualize_activations
(genome, surface_size=(700, 450), node_radius=14, node_deactivated_color=(190, 190, 190), node_activated_color=(2, 68, 144), bias_node_color='yellow', node_border_color='black', edge_activated_color=(0, 120, 233), edge_deactivated_color=(100, 100, 100), activated_edge_width=2, deactivated_edge_width=1, horizontal_pad_pc=(0.015, 0.015), vertical_pad_pc=(0.015, 0.015), hidden_activation_threshold=0.5, input_visualization_info=None, output_visualization_info=None, output_activate_greatest_only=True, show_input_values=False, show_output_values=False, labels_color='white', labels_config=None, show_activation_light=True, activation_light_color=(104, 179, 235), activation_light_radius_pc=2, ideal_h_nodes_per_col=4, background_color='black', node_border_thickness=2, draw_bias_node=False, return_rgb_array=False)¶ Draws the network using different colors for activated and deactivated nodes and edges.
Note
This method requires
pygame
installed. You can install it using the command:$ pip install pygame
- Parameters
genome (NeatGenome) – The genome to be visualized.
surface_size (Tuple[int, int]) – Width and height of the pygame surface to be drawn.
node_radius (float) – Radius (size) of the drawn nodes.
node_deactivated_color (Union[str, Tuple[int, int, int]]) – Color of deactivated nodes.
node_activated_color (Union[str, Tuple[int, int, int]]) – Color of activated nodes.
bias_node_color (Union[str, Tuple[int, int, int]]) – Color of the bias node.
node_border_color (Union[str, Tuple[int, int, int]]) – Color of the nodes’ borders.
edge_activated_color (Union[str, Tuple[int, int, int]]) – Color of activated edges.
edge_deactivated_color (Union[str, Tuple[int, int, int]]) – Color of deactivated edges.
activated_edge_width (int) – The width/thickness of activated edges.
deactivated_edge_width (int) – The width/thickness of deactivated edges.
horizontal_pad_pc (Tuple[float, float]) – Tuple containing the size of the padding on the left and on the right of the surface. Unit: the width of the surface.
vertical_pad_pc (Tuple[float, float]) – Tuple containing the size of the padding below and above the surface. Unit: the height of the surface.
hidden_activation_threshold (float) – Activation threshold for hidden nodes. If the activation value of a hidden node is greater than this threshold, the node is considered to be activated.
(Optional[Union[ (output_visualization_info) – List[NodeVisualizationInfo], List[str]]]): If it’s a list of strings, each string will be the label of an input node and default settings will be used to determine if an input node is activated or not. If it’s a list of
NodeVisualizationInfo
objects, then the information provided in the objects will be used instead. IfNone
, default settings will be used to determine if an input node is activated or not and no labels will be drawn for the input nodes.(Optional[Union[ – List[NodeVisualizationInfo], List[str]]]): If it’s a list of strings, each string will be the label of an output node and default settings will be used to determine if an output node is activated or not. If it’s a list of
NodeVisualizationInfo
objects, then the information provided in the objects will be used instead. IfNone
, default settings will be used to determine if an output node is activated or not and no labels will be drawn for the output nodes.show_input_values (bool) – If
True
andinput_visualization_info
is notNone
, then the input values will be drawn next to each input node.show_output_values (bool) – If
True
andoutput_visualization_info
is notNone
, then the output values will be drawn next to each output node.output_activate_greatest_only (bool) – If
True
, only one output node can be activated at a time (the node with the greatest activation value). Otherwise, more than one node can be activated at a time.labels_color (Union[str, Tuple[int, int, int]]) – Color of the labels.
labels_config (Dict[str, Any]) – Keyword arguments to be passed to the
pygame.SysFont()
constructor.show_activation_light (bool) – Whether or not to show a “light ring” around activated nodes.
activation_light_color (Optional[Union[str, Tuple[int, int, int]]]) – The color of the light ring to be shown around activated nodes.
activation_light_radius_pc (float) – Radius of the light ring to be drawn around activated nodes. Unit: the node’s radius.
ideal_h_nodes_per_col (int) – Preferred number of hidden nodes per column (the algorithm will try to draw columns with this amount of hidden nodes whenever possible).
background_color (Union[str, Tuple[int, int, int]]) – The background color of the surface.
node_border_thickness (Optional[float]) – Thickness of the nodes’ borders. If
None
or 0, no border will be drawn.draw_bias_node (bool) – Whether to draw the network’s bias node or not.
return_rgb_array (bool) – If
True
, returns a numpy array with the generated image instead of a pygame surface.
- Return type
Union
[ForwardRef
,ndarray
]- Returns
If
return_rgb_array
isFalse
, an instance ofpygame.Surface
with the drawings is returned. You can display it usingpygame
:screen_size = 700, 450 display = pygame.display.set_mode(screen_size) # ... s = genome.visualize_activations(surface_size=screen_size) display.blit(s, [0, 0]) pygame.display.update()
If
return_rgb_array
isTrue
, a numpy array with the generated image is returned instead.- Raises
ModuleNotFoundError – If
pygame
is not found.
-
nevopy.neat.visualization.
visualize_genome
(genome, layout_name='columns', layout_kwargs=None, show=True, block_thread=True, save_to=None, save_transparent=False, figsize=(10, 6), node_size=300, pad=1, legends=True, nodes_ids=True, node_id_color='black', edge_curviness=0.1, edges_ids=False, edge_id_color='black', background_color='snow', legend_box_color='honeydew', input_color='deepskyblue', output_color='mediumseagreen', hidden_color='silver', bias_color='khaki')¶ Plots the neural network (phenotype) encoded by the genome.
The network is drawn as a graph, with nodes and edges. An edge’s color is chosen according to the edge’s weight. Edges with greater weights are drawn with more intense / stronger colors. Edges connecting a node to itself aren’t be drawn.
This method uses NetworkX to handle the drawings. It positions the network’s nodes according to a layout, whose name you can specify in the parameter
layout_name
. The currently available layouts are:All the standard NetworkX’s layouts available in this link;
The graphviz layout; it’s really good, but to use it you must have Graphviz-Dev and pygraphviz installed on your machine;
The columns layout (used by default), implemented exclusively for NEvoPy; it positions the nodes in columns (see
NeatGenome.columns_graph_layout()
, specially the parameterideal_h_nodes_per_col
).
For the colors parameters, it’s possible to pass a string with the color HEX value or a string with the color’s name (names available here: https://matplotlib.org/3.1.0/gallery/color/named_colors.html).
- Parameters
genome (NeatGenome) – The genome to be visualized.
layout_name (str) – The name of the layout to be used to position the network’s nodes.
layout_kwargs (Optional[Dict[str, Any]]) – Keyed arguments to be passed to the layout. Check each layout documentation for more information about the accepted arguments.
show (bool) – Whether to show the generated image or not. If True, a window will be created by matplotlib to show the image.
block_thread (bool) – Whether to block the execution’s thread while showing the image. Useful for visualizing multiple networks at once. In this case, you should call
NeatGenome.visualize()
with this parameter set to False on all genomes except for the last one, so all the windows are shown simultaneously.save_to (Optional[str]) – Path to save the image. If None, the image won’t be automatically saved.
save_transparent (
bool
) – Whether the saved image should have a transparent background or not.figsize (Tuple[int, int]) – Size of the matplotlib figure.
node_size (int) – Size of the drawn nodes, in points**2 (the area of each node). Default size is 300. See the parameter
s
of matplotlib.axes.Axes.scatter for more information.pad (int) – The image’s padding (distance between the figure of the network and the image’s border).
legends (bool) – If True, a box with legends describing the nodes colors will be drawn.
nodes_ids (bool) – If True, the nodes will have their ID drawn inside them.
node_id_color (str) – Color of the drawn nodes ids.
edge_curviness (float) – Angle, in radians, of the edges arcs. A value of 0 indicates a straight line.
edges_ids (bool) – If True, each connection/edge will have its ID drawn on it. Keep in mind that some labels might overlap with each other, making only one of them visible.
edge_id_color (str) – Color of the drawn connections/edges ids.
background_color (str) – Color of the figure’s background.
legend_box_color (str) – Color of the legend box.
input_color (str) – Color of the input nodes.
output_color (str) – Color of the output nodes.
hidden_color (str) – Color of the hidden nodes.
bias_color (str) – Color of the bias node.
- Raises
RuntimeError – If both show and save_to parameters are set to False (in which case the function wouldn’t be doing anything but wasting computation).
- Return type
None
Module contents¶
Imports core names of nevopy.neat
.