genome_factory (faber_neuroevolution v1.2.4)
View SourceNEAT-style genome factory for topology-evolving neural networks.
This module implements genome operations for NEAT (NeuroEvolution of Augmenting Topologies) style evolution. It provides: - Minimal genome creation (starting point for NEAT) - Genome to network conversion (for evaluation) - NEAT-style crossover (gene alignment by innovation number) - Structural and weight mutations
The module delegates to faber_tweann's innovation.erl and genome_crossover.erl for core NEAT operations.
Reference: Stanley, K.O. and Miikkulainen, R. (2002). Evolving Neural Networks through Augmenting Topologies. Evolutionary Computation, 10(2).
Summary
Functions
Create a minimal NEAT genome.
Perform NEAT-style crossover between two genomes.
Apply mutations to a genome (structural + weight).
Convert a genome to a NIF-compiled network for fast evaluation.
Convert a genome to a network for evaluation.
Types
-type genome() :: #genome{connection_genes :: [#connection_gene{innovation :: pos_integer() | undefined, from_id :: term(), to_id :: term(), weight :: float(), enabled :: boolean()}], input_count :: non_neg_integer(), hidden_count :: non_neg_integer(), output_count :: non_neg_integer()}.
-type mutation_config() :: #mutation_config{weight_mutation_rate :: float(), weight_perturb_rate :: float(), weight_perturb_strength :: float(), add_node_rate :: float(), add_connection_rate :: float(), toggle_connection_rate :: float(), add_sensor_rate :: float(), add_actuator_rate :: float(), mutate_neuron_type_rate :: float(), mutate_time_constant_rate :: float()}.
-type neuro_config() :: #neuro_config{population_size :: pos_integer(), evaluations_per_individual :: pos_integer(), selection_ratio :: float(), mutation_rate :: float(), mutation_strength :: float(), reservoir_mutation_rate :: float() | undefined, reservoir_mutation_strength :: float() | undefined, readout_mutation_rate :: float() | undefined, readout_mutation_strength :: float() | undefined, topology_mutation_config :: mutation_config() | undefined, max_evaluations :: pos_integer() | infinity, max_generations :: pos_integer() | infinity, target_fitness :: float() | undefined, network_topology :: {pos_integer(), [pos_integer()], pos_integer()}, evaluator_module :: module(), evaluator_options :: map(), event_handler :: {module(), term()} | undefined, meta_controller_config :: term() | undefined, speciation_config :: speciation_config() | undefined, realm :: binary(), publish_events :: boolean(), evaluation_mode :: direct | distributed | mesh, mesh_config :: map() | undefined, evaluation_timeout :: pos_integer(), max_concurrent_evaluations :: pos_integer() | undefined, strategy_config :: term() | undefined, lc_chain_config :: term() | undefined, checkpoint_interval :: pos_integer() | undefined, checkpoint_config :: map() | undefined, seed_networks :: [term()]}.
-type speciation_config() :: #speciation_config{enabled :: boolean(), compatibility_threshold :: float(), c1_excess :: float(), c2_disjoint :: float(), c3_weight_diff :: float(), target_species :: pos_integer(), threshold_adjustment_rate :: float(), min_species_size :: pos_integer(), max_stagnation :: non_neg_integer(), species_elitism :: float(), interspecies_mating_rate :: float()}.
Functions
-spec create_minimal(neuro_config()) -> genome().
Create a minimal NEAT genome.
Creates a genome where all inputs connect directly to all outputs. This is the NEAT starting point - networks grow from this minimal structure.
Perform NEAT-style crossover between two genomes.
Aligns genes by innovation number and: - Matching genes: randomly inherit from either parent - Disjoint/Excess genes: inherit from fitter parent
-spec mutate(genome(), mutation_config()) -> genome().
Apply mutations to a genome (structural + weight).
Mutations are applied based on the mutation_config probabilities: - Weight mutation: Perturb or replace weights - Add node: Split an existing connection - Add connection: Add new connection between unconnected nodes - Toggle connection: Enable/disable a connection
-spec to_compiled_network(genome()) -> {ok, nif_network:compiled_network()} | {error, term()}.
Convert a genome to a NIF-compiled network for fast evaluation.
This is the optimized path: compile once, evaluate many times. Uses the native path when configured (speedup unmeasured; see ROADMAP.md).
-spec to_network(genome()) -> network_evaluator:network().
Convert a genome to a network for evaluation.
Builds a neural network from the genome's connection genes. Disabled connections are excluded from the network.
Note: For variable topology, we create a network that matches the genome structure. Since network_evaluator uses dense layers with biases, we create a network topology and then set the weights to match the genome.