genome_factory (faber_neuroevolution v1.2.4)

View Source

NEAT-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

genome/0

-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()}.

mutation_config/0

-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()}.

neuro_config/0

-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()]}.

speciation_config/0

-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

create_minimal(Config)

-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.

crossover(Genome1, Genome2, FitterParent)

-spec crossover(genome(), genome(), 1 | 2 | equal) -> genome().

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

mutate(Genome, Config)

-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

to_compiled_network(Genome)

-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).

to_network(Genome)

-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.