Class Genome<T>
- Namespace
- AiDotNet.NeuralNetworks
- Assembly
- AiDotNet.dll
Represents a genome in a neuroevolutionary algorithm, containing a collection of connections between nodes.
public class Genome<T>
Type Parameters
TThe numeric type used for calculations, typically float or double.
- Inheritance
-
Genome<T>
- Inherited Members
Remarks
A Genome is a fundamental data structure in neuroevolutionary algorithms like NEAT (NeuroEvolution of Augmenting Topologies). It encodes the structure and weights of a neural network as a set of connections between nodes. Each connection has a weight, an enabled/disabled state, and an innovation number that tracks its evolutionary history. Genomes can be mutated, crossed over, and evaluated for fitness, allowing neural networks to evolve over generations rather than being trained through traditional gradient-based methods.
For Beginners: A Genome is like a blueprint for a neural network.
Think of a Genome as:
- A DNA-like structure that defines how a neural network is built
- A collection of connections (wires) between nodes (neurons)
- Each connection has a weight (strength) and can be enabled or disabled
- Instead of training this network with examples, it evolves through generations
Just as biological organisms evolve through natural selection, these neural network blueprints can evolve to solve problems through a process of selection, mutation, and reproduction. The best-performing blueprints are selected to create the next generation.
Constructors
Genome(int, int)
Initializes a new instance of the Genome<T> class with the specified network dimensions.
public Genome(int inputSize, int outputSize)
Parameters
inputSizeintThe number of input nodes in the neural network.
outputSizeintThe number of output nodes in the neural network.
Remarks
This constructor creates a new Genome with the specified number of input and output nodes. It initializes an empty list of connections and sets the initial fitness to zero. This creates a bare neural network structure that can be populated with connections through mutation or other means.
For Beginners: This creates a new, empty neural network blueprint.
When creating a new Genome:
- You specify how many inputs and outputs the network will have
- It starts with no connections between neurons (an empty blueprint)
- Its fitness score starts at zero since it hasn't been tested yet
This is like starting with a blank canvas before drawing the neural network. Connections will be added later through the evolution process.
Properties
Connections
Gets the list of connections that make up this genome.
public List<Connection<T>> Connections { get; }
Property Value
- List<Connection<T>>
A list of connections between nodes.
Remarks
The Connections property contains all the connection genes that define the structure and weights of the neural network encoded by this genome. Each connection specifies a link between two nodes, with a weight determining the strength of the connection, an enabled/disabled state, and an innovation number for tracking its evolutionary history.
For Beginners: This is the collection of all wires connecting the neurons.
Think of Connections as:
- All the wires connecting different neurons in the network
- Each connection defines which neurons are connected
- Each connection has a strength (weight) and can be turned on or off
- Each connection also has an ID number (innovation) that tracks when it first appeared
This is the core of what makes each neural network unique - which neurons are connected, how strongly, and which connections are active.
Fitness
Gets or sets the fitness score of this genome.
public T Fitness { get; set; }
Property Value
- T
A value representing how well this genome performs on its task.
Remarks
The Fitness property represents how well this genome (the neural network it encodes) performs on its intended task. Higher fitness values typically indicate better performance. This fitness score is used during the evolutionary process to determine which genomes are selected for reproduction and which are eliminated.
For Beginners: This is the score that shows how well this network performs.
Think of Fitness as:
- A scorecard that rates how good this neural network is at its job
- Higher scores mean better performance
- This score determines which networks get to "reproduce" and pass on their features
- Low-scoring networks are eliminated, just like natural selection
For example, if the network is controlling a game character, the fitness might be the score achieved in the game. The highest-scoring networks would be selected to create the next generation.
InputSize
Gets the number of input nodes in the neural network.
public int InputSize { get; }
Property Value
- int
An integer representing the number of input nodes.
Remarks
The InputSize property defines how many input nodes the neural network has. These are the nodes that receive external input data. In the context of neuroevolution, the input size is typically fixed throughout evolution, as it is determined by the dimensionality of the problem's input data.
For Beginners: This is how many data points the network takes as input.
Think of InputSize as:
- The number of sensory neurons that receive information from outside
- Each input neuron handles one piece of data
- For a game AI, inputs might include position, speed, obstacle distances, etc.
- For image processing, inputs might be pixel values
This value is usually fixed and determined by what kind of data the network needs to process.
OutputSize
Gets the number of output nodes in the neural network.
public int OutputSize { get; }
Property Value
- int
An integer representing the number of output nodes.
Remarks
The OutputSize property defines how many output nodes the neural network has. These are the nodes that produce the network's output or decisions. In the context of neuroevolution, the output size is typically fixed throughout evolution, as it is determined by the dimensionality of the problem's output data.
For Beginners: This is how many results the network produces as output.
Think of OutputSize as:
- The number of action neurons that produce decisions or predictions
- Each output neuron represents one aspect of the network's response
- For a game AI, outputs might be movement directions or action choices
- For classification, outputs might represent different categories
Like InputSize, this value is usually fixed and determined by what kind of decisions or predictions the network needs to make.
Methods
Activate(Vector<T>)
Activates the neural network encoded by this genome with the given input vector.
public Vector<T> Activate(Vector<T> input)
Parameters
inputVector<T>The input vector to process.
Returns
- Vector<T>
The output vector produced by the neural network.
Remarks
This method performs a forward pass through the neural network encoded by this genome. It first validates that the input vector has the correct size, then initializes node values for input and output nodes. It sorts the connections topologically to ensure they are processed in the correct order (from inputs toward outputs), then processes each connection by multiplying the source node's value by the connection weight and adding the result to the target node's value. Finally, it applies activation functions and collects the output values.
For Beginners: This runs data through the neural network to get an output.
The activation process works like this:
- First, it checks that you've provided the right number of inputs
- It sets up all the neurons with their initial values
- It sorts the connections to ensure signals flow in the right direction
- For each connection, it multiplies the signal by the connection's weight
- It applies activation functions to introduce non-linearity
- Finally, it collects the values from the output neurons
This is how the network actually processes information and makes decisions, similar to how signals flow through neurons in a brain.
Exceptions
- ArgumentException
Thrown when the input vector's length doesn't match the expected input size.
- InvalidOperationException
Thrown when a cycle is detected in the network during topological sorting.
AddConnection(int, int, T, bool, int)
Adds a new connection to this genome.
public void AddConnection(int fromNode, int toNode, T weight, bool isEnabled, int innovation)
Parameters
fromNodeintThe identifier of the source node.
toNodeintThe identifier of the target node.
weightTThe weight of the connection.
isEnabledboolA value indicating whether the connection is enabled.
innovationintThe innovation number of the connection.
Remarks
This method adds a new connection to the genome, specifying the source and target nodes, the connection weight, whether the connection is enabled, and its innovation number. In neuroevolutionary algorithms, connections can be added through mutation operations, allowing the neural network's structure to evolve over time.
For Beginners: This creates a new wire connecting two neurons in the network.
When adding a connection:
- fromNode and toNode specify which neurons to connect
- weight determines the strength of the connection
- isEnabled determines if the connection is active or inactive
- innovation is a unique ID number that helps track the connection's history
This is how the neural network's structure grows during evolution. New connections allow more complex behavior to emerge.
Clone()
Creates a deep copy of this genome.
public Genome<T> Clone()
Returns
- Genome<T>
A new Genome instance that is a copy of this instance.
Remarks
This method creates a deep copy of the genome, including all its connections. The new genome has the same input size, output size, and connections as the original, but it is a separate instance that can be modified independently. Cloning is often used in neuroevolutionary algorithms when creating offspring genomes that will then be mutated or otherwise modified.
For Beginners: This creates an exact copy of the neural network blueprint.
When cloning a genome:
- A new, independent copy of the genome is created
- The copy has the same input size, output size, and connections
- The copy can be modified without affecting the original
- This is useful during reproduction when creating offspring
Think of it like photocopying a blueprint - you get an identical copy that you can then modify independently.
Deserialize(BinaryReader)
Deserializes this genome from a binary stream.
public void Deserialize(BinaryReader reader)
Parameters
readerBinaryReaderThe binary reader to read from.
Remarks
This method restores the state of the genome from a binary stream. It reads the input size, output size, connection count, and then the details of each connection. This allows a previously saved genome to be restored from disk with all its structural information intact.
For Beginners: This loads a neural network blueprint from a file.
When deserializing a genome:
- It reads the number of inputs and outputs
- It reads how many connections the network has
- For each connection, it reads all its details (source, target, weight, etc.)
This is like loading a blueprint from disk so you can use it or continue modifying it.
DisableConnection(int)
Disables a connection with the specified innovation number.
public void DisableConnection(int innovation)
Parameters
innovationintThe innovation number of the connection to disable.
Remarks
This method disables a connection in the genome by setting its IsEnabled property to false. This allows the network's structure to be modified without removing connections entirely. In neuroevolutionary algorithms, disabling connections is a common mutation operation that allows the network to explore different structural configurations while preserving the genetic information for potential future use.
For Beginners: This turns off a specific connection in the network.
When disabling a connection:
- The connection is identified by its innovation number (unique ID)
- The connection isn't removed, just deactivated
- This is like turning off a specific wire in the network
- The connection can be re-enabled later if needed
This is important in evolution because sometimes temporarily disabling a connection leads to better performance, and the connection's information is preserved for possible future use.
Serialize(BinaryWriter)
Serializes this genome to a binary stream.
public void Serialize(BinaryWriter writer)
Parameters
writerBinaryWriterThe binary writer to write to.
Remarks
This method saves the state of the genome to a binary stream. It writes the input size, output size, connection count, and then the details of each connection. This allows the genome to be saved to disk and later restored with all its structural information intact.
For Beginners: This saves the neural network blueprint to a file.
When serializing a genome:
- It saves the number of inputs and outputs
- It saves how many connections the network has
- For each connection, it saves all its details (source, target, weight, etc.)
This is like saving a blueprint to disk so you can reload it later or share it with others.