agent_trainer (faber_neuroevolution v1.2.4)

View Source

Agent Trainer - Integration between Agent SDK and Neuroevolution.

This module bridges the gap between domain-defined agent behaviours and the neuroevolution engine. It provides convenience functions to configure, train, and evaluate agents without manual boilerplate.

Overview

The trainer eliminates manual wiring between agent_bridge and neuroevolution_server:

  %% WITHOUT agent_trainer (manual boilerplate):
  {ok, Bridge} = agent_bridge:new(Config),
  {Inputs, _, Outputs} = my_agent:network_topology(),
  FitnessFn = fun(Network) ->
      {ok, Fitness, _} = agent_bridge:run_episode(Bridge, Network, EnvConfig),
      Fitness
  end,
  NeuroConfig = neuro_config:new(#{
      population_size => 100,
      input_count => Inputs,
      output_count => Outputs,
      fitness_function => FitnessFn
  }),
  {ok, Pid} = neuroevolution_server:start_link(NeuroConfig),
  neuroevolution_server:evolve(Pid, 100).
 
  %% WITH agent_trainer (one line):
  {ok, Best, Stats} = agent_trainer:train(Bridge, #{generations => 100}).

Quick Start

  %% 1. Create bridge with all components (including evaluator!)
  {ok, Bridge} = agent_bridge:new(#{
      definition => my_agent,
      sensors => [my_sensor],
      actuators => [my_actuator],
      environment => my_environment,
      evaluator => my_evaluator  %% Required for training!
  }),
 
  %% 2. Train
  {ok, BestNetwork, Stats} = agent_trainer:train(Bridge, #{
      generations => 100,
      population_size => 50
  }).

Configuration Options

Training options passed to train/2:

  • generations - Number of generations (default: 100)
  • population_size - Population size (default: 100)
  • strategy - Evolution strategy (default: generational)
  • env_config - Environment configuration (default: #{})
  • episodes_per_eval - Episodes to average (default: 1)
  • Any other neuro_config options

See also: agent_bridge, neuro_config, neuroevolution_server.

Summary

Types

Fitness function type.

Result of training: best network and final statistics.

Functions

Evaluates a single network using the bridge.

Evaluates a network over multiple episodes and averages fitness.

Creates a fitness function from a bridge.

Creates a neuro_config from a bridge.

Creates a neuro_config with custom options.

Trains an agent using neuroevolution.

Trains an agent with explicit environment configuration.

Types

fitness_fn/0

-type fitness_fn() :: fun((term()) -> float()).

Fitness function type.

train_options/0

-type train_options() ::
          #{generations => pos_integer(),
            population_size => pos_integer(),
            strategy => atom(),
            env_config => map(),
            episodes_per_eval => pos_integer(),
            atom() => term()}.

train_result/0

-type train_result() :: {ok, Network :: term(), Stats :: map()} | {error, term()}.

Result of training: best network and final statistics.

Functions

evaluate(Bridge, Network, EnvConfig)

-spec evaluate(Bridge, Network, EnvConfig) -> {ok, float(), map()} | {error, term()}
                  when Bridge :: agent_bridge:validated_bridge(), Network :: term(), EnvConfig :: map().

Evaluates a single network using the bridge.

Runs one episode and returns fitness and metrics.

Example:

  {ok, Fitness, Metrics} = agent_trainer:evaluate(Bridge, Network, EnvConfig).

evaluate_many(Bridge, Network, EnvConfig, Episodes)

-spec evaluate_many(Bridge, Network, EnvConfig, Episodes) -> {ok, float(), [map()]} | {error, term()}
                       when
                           Bridge :: agent_bridge:validated_bridge(),
                           Network :: term(),
                           EnvConfig :: map(),
                           Episodes :: pos_integer().

Evaluates a network over multiple episodes and averages fitness.

Useful for stochastic environments where single-episode fitness may have high variance.

Example:

  {ok, AvgFitness, AllMetrics} = agent_trainer:evaluate_many(Bridge, Network, EnvConfig, 10).

to_fitness_fn(Bridge, EnvConfig)

-spec to_fitness_fn(Bridge, EnvConfig) -> fitness_fn()
                       when Bridge :: agent_bridge:validated_bridge(), EnvConfig :: map().

Creates a fitness function from a bridge.

The returned function can be used with neuro_config directly for advanced users who want manual control.

Example:

  FitnessFn = agent_trainer:to_fitness_fn(Bridge, EnvConfig),
  Config = neuro_config:new(#{
      fitness_function => FitnessFn,
      ...
  }).

to_neuro_config(Bridge, EnvConfig)

-spec to_neuro_config(Bridge, EnvConfig) -> {ok, term()} | {error, term()}
                         when Bridge :: agent_bridge:validated_bridge(), EnvConfig :: map().

Creates a neuro_config from a bridge.

Extracts topology from the bridge definition and creates appropriate neuroevolution configuration.

Example:

  {ok, Config} = agent_trainer:to_neuro_config(Bridge, EnvConfig),
  {ok, Pid} = neuroevolution_server:start_link(Config).

to_neuro_config(Bridge, EnvConfig, Options)

-spec to_neuro_config(Bridge, EnvConfig, Options) -> {ok, term()} | {error, term()}
                         when
                             Bridge :: agent_bridge:validated_bridge(),
                             EnvConfig :: map(),
                             Options :: map().

Creates a neuro_config with custom options.

Options are merged with defaults extracted from the bridge. Returns a #neuro_config{} record suitable for neuroevolution_server.

train(Bridge, Options)

-spec train(Bridge, Options) -> train_result()
               when Bridge :: agent_bridge:validated_bridge(), Options :: train_options().

Trains an agent using neuroevolution.

This is the main entry point for training. It: 1. Creates a fitness function from the bridge 2. Configures neuroevolution from the bridge topology 3. Runs evolution for the specified generations 4. Returns the best network and statistics

Example:

  {ok, Bridge} = agent_bridge:new(#{
      definition => my_agent,
      sensors => [my_sensor],
      actuators => [my_actuator],
      environment => my_env,
      evaluator => my_evaluator
  }),
  {ok, BestNetwork, Stats} = agent_trainer:train(Bridge, #{
      generations => 100,
      population_size => 50
  }).

train(Bridge, EnvConfig, Options)

-spec train(Bridge, EnvConfig, Options) -> train_result()
               when
                   Bridge :: agent_bridge:validated_bridge(),
                   EnvConfig :: map(),
                   Options :: train_options().

Trains an agent with explicit environment configuration.

Same as train/2 but with environment config as separate argument.