meta_controller (faber_neuroevolution v1.2.4)

View Source

LTC-based meta-controller for adaptive hyperparameter optimization.

This gen_server implements a meta-learning system that uses Liquid Time-Constant (LTC) neural networks to dynamically control neuroevolution hyperparameters.

Architecture

The meta-controller operates at a higher timescale than task networks. It receives training metrics as inputs and outputs hyperparameters: mutation_rate, mutation_strength, and selection_ratio.

LTC Advantage

LTC neurons maintain internal state that evolves continuously. This enables temporal memory of training dynamics, adaptive response speed based on signal magnitude, and smooth parameter transitions.

Usage

Create a config and start the meta-controller:

Config = #meta_config{network_topology = {8, [16, 8], 4}}, {ok, Pid} = meta_controller:start_link(Config), meta_controller:start_training(Pid), NewParams = meta_controller:update(Pid, GenerationStats).

Summary

Functions

Get current L1 guidance without updating (for monitoring).

Get L1 guidance based on generation statistics.

Get current hyperparameter values (legacy API).

Get current meta-controller state (for visualization).

Reset the meta-controller to initial state.

Start the meta-controller with given configuration.

Start the meta-controller with configuration and options.

Start the meta-learning training process.

Stop the meta-learning training process.

Update the meta-controller with new generation stats.

Types

fitness/0

-type fitness() :: float() | undefined.

generation/0

-type generation() :: non_neg_integer().

generation_stats/0

-type generation_stats() ::
          #generation_stats{generation :: generation(),
                            best_fitness :: fitness(),
                            avg_fitness :: fitness(),
                            worst_fitness :: fitness(),
                            best_individual_id :: individual_id(),
                            survivors :: [individual_id()],
                            eliminated :: [individual_id()],
                            offspring :: [individual_id()],
                            population_size :: non_neg_integer(),
                            survivor_count :: non_neg_integer(),
                            top_individuals ::
                                [#{id := individual_id(),
                                   fitness := fitness(),
                                   complexity := non_neg_integer()}]}.

individual_id/0

-type individual_id() :: term().

l2_guidance/0

-type l2_guidance() ::
          #l2_guidance{aggression_factor :: float(),
                       exploration_step :: float(),
                       stagnation_sensitivity :: float(),
                       topology_aggression :: float(),
                       exploitation_weight :: float(),
                       adaptation_momentum :: float(),
                       warning_threshold :: float(),
                       intervention_threshold :: float(),
                       critical_threshold :: float(),
                       velocity_window_size :: pos_integer(),
                       memory_high_threshold :: float(),
                       memory_critical_threshold :: float(),
                       cpu_high_threshold :: float(),
                       pressure_scale_factor :: float(),
                       min_scale_factor :: float(),
                       pressure_change_threshold :: float(),
                       generation :: non_neg_integer()}.

meta_config/0

-type meta_config() ::
          #meta_config{network_topology :: {pos_integer(), [pos_integer()], pos_integer()},
                       neuron_type :: ltc | cfc,
                       time_constant :: float(),
                       state_bound :: float(),
                       reward_weights :: #{reward_component() => float()},
                       learning_rate :: float(),
                       param_bounds :: #{meta_param() => {float(), float()}},
                       control_population_size :: boolean(),
                       control_topology :: boolean(),
                       history_window :: pos_integer(),
                       momentum :: float()}.

meta_param/0

-type meta_param() ::
          mutation_rate | mutation_strength | selection_ratio | evaluations_per_individual |
          max_concurrent_evaluations | population_size | add_node_rate | add_connection_rate |
          complexity_penalty.

reward_component/0

-type reward_component() ::
          convergence_speed | final_fitness | efficiency_ratio | diversity_aware | normative_structure.

Functions

get_current_guidance(ServerRef)

-spec get_current_guidance(pid() | atom()) -> l2_guidance().

Get current L1 guidance without updating (for monitoring).

get_l1_guidance(ServerRef, GenStats)

-spec get_l1_guidance(pid() | atom(), map()) -> l2_guidance().

Get L1 guidance based on generation statistics.

This is the primary L2→L1 interface. Called by task_silo to get meta-parameters that control L1's adjustment behavior.

Returns an #l2_guidance{} record with: - aggression_factor: How aggressive L1 adjustments should be - exploration_step: How fast exploration_boost increases - stagnation_sensitivity: Threshold for detecting stagnation - topology_aggression: How much to boost topology mutations - exploitation_weight: Balance between explore and exploit

get_params(ServerRef)

-spec get_params(pid() | atom()) -> #{atom() => float()}.

Get current hyperparameter values (legacy API).

get_state(ServerRef)

-spec get_state(pid() | atom()) -> {ok, map()}.

Get current meta-controller state (for visualization).

reset(ServerRef)

-spec reset(pid() | atom()) -> ok.

Reset the meta-controller to initial state.

start_link(Config)

-spec start_link(meta_config()) -> {ok, pid()} | {error, term()}.

Start the meta-controller with given configuration.

start_link(Config, Options)

-spec start_link(meta_config(), proplists:proplist()) -> {ok, pid()} | {error, term()}.

Start the meta-controller with configuration and options.

Options: - {id, Id} - Server identifier (default: make_ref()) - {name, Name} - Register with given name

start_training(ServerRef)

-spec start_training(pid() | atom()) -> {ok, started | already_running}.

Start the meta-learning training process.

stop_training(ServerRef)

-spec stop_training(pid() | atom()) -> ok.

Stop the meta-learning training process.

update(ServerRef, GenerationStats)

-spec update(pid() | atom(), generation_stats() | map()) -> #{atom() => float()}.

Update the meta-controller with new generation stats.

This is the main entry point called after each neuroevolution generation. Returns new hyperparameters to use for the next generation.