Bardo.AgentManager.TuningSelection (Bardo v0.1.0)

View Source

The TuningSelection module contains all the tuning selection functions, which accept as input four parameters:

  1. All NIds belonging to the NN.
  2. The agent's generation, which is the number of topological mutation phases that it has undergone.
  3. The perturbation range, the multiplier of math:pi(), which when used produces the spread value.
  4. The annealing parameter, which is used to indicate how the perturbation range decays with the age of the neuron to which synaptic weight perturbation is applied.

It makes less sense to perturb the more stable elements of the NN system, less so than those elements which have just recently been added to the NN system, and which still need to be tuned and modified to work well with the already existing larger system. The concept is that of simulated annealing.

We gather all these selection functions in their own module because there are many ways to select neurons which should be perturbed in local search during the tuning phase. This makes it easier for us to add new selection functions later on, and see if a new function can improve the performance.

The tuning selection function must not only select the neuron ids for synaptic perturbation, but also compute the perturbation intensity, the available range of the perturbation intensity, from which the neuron will then randomly generate a weight perturbation value. Thus, the selection_function creates a list of tuples rather than simply a list of neuron ids. The selection_function outputs a list of the following form: [{NId, Spread},...], where NId is the neuron id, and Spread is the spread above and below 0, the value within which the neuron generates the actual perturbation. The Spread equals the perturbation_range value if there is no annealing, if annealing is present (annealing_parameter =< 1), then the Spread is further modified. The annealing factor must scale the Spread, proportional to the age of the neuron whose synaptic weights are to be perturbed. In tuning selection algorithms, the spread value is calculated as follows:

Spread = PerurbationRange * math:pi() * math:pow(AnnealingParam, NAge)

When AnnealingParameter = 1, there is no annealing. But when the AnnealingParameter is set to a number lower than 1, then annealing is exponentially proportional to the neuron's age.

Summary

Functions

active selection algorithm composes a neuron id pool from all neurons who are younger than 3 generations.

active_random is a selection algorithm that composes an id pool by first creating a list of all neurons who are younger than 3 generations, and then composing a sub list from it by randomly choosing elements from this list with a probability of 1/math:sqrt(Tot_Neurons).

all returns a list of tuples composed of all ids (and their spread values) belonging to the NN, to the caller.

all_random first composes a list of tuples from NIds and their spreads, and then creates a sublist by choosing each element with a probability of 1/math:sqrt(Tot_neurons).

current is a selection algorithm that returns a list of all neurons which have been added to the NN, or affected by mutation, during the last generation.

current_random composes the list of tuples in the same way as current does, but then composes a sublist by randomly selecting elements from that list with a probability of 1/math:sqrt(Tot_Neurons), and returning that to the caller.

The dynamic selection function randomly selects an age limit for its neuron id pool. The age limit is chosen by executing math:sqrt(1/rand:uniform()), which creates a value between 1 and infinity. Using this function there is 75% that the number will be =< 2, 25% that it will be >= 2, 11% that it will be >= 3...Every time this selection function is executed, the AgeLimit is generated anew, thus different times it will produce different neuron id pools for tuning.

dyanimic_random selection function composes the neuron id pool the same way as the dynamic/4 selection function, but after this id pool is generated, this selection function extracts ids from it randomly with a probability of 1/math:sqrt(Tot_Neurons). Thus the probability of a neuron being selected from this pool is proportional to the number of ids in that pool. If through chance no ids are selected, then the first element in the id pool is automatically selected, and given the highest spread.

Functions

active(ids, agent_generation, perturbation_range, annealing_parameter)

@spec active([{:actuator | :neuron, {float()}}], integer(), float(), float()) :: [
  {Bardo.Models.neuron_id(), float()}
]

active selection algorithm composes a neuron id pool from all neurons who are younger than 3 generations.

active_random(ids, agent_generation, perturbation_range, annealing_parameter)

@spec active_random([{:actuator | :neuron, {float()}}], integer(), float(), float()) ::
  [
    {Bardo.Models.neuron_id(), float()}
  ]

active_random is a selection algorithm that composes an id pool by first creating a list of all neurons who are younger than 3 generations, and then composing a sub list from it by randomly choosing elements from this list with a probability of 1/math:sqrt(Tot_Neurons).

all(ids, agent_generation, perturbation_range, annealing_parameter)

@spec all([{:actuator | :neuron, {float()}}], integer(), float(), float()) :: [
  {Bardo.Models.neuron_id(), float()}
]

all returns a list of tuples composed of all ids (and their spread values) belonging to the NN, to the caller.

all_random(ids, agent_generation, perturbation_range, annealing_parameter)

@spec all_random([{:actuator | :neuron, {float()}}], integer(), float(), float()) :: [
  {Bardo.Models.neuron_id(), float()}
]

all_random first composes a list of tuples from NIds and their spreads, and then creates a sublist by choosing each element with a probability of 1/math:sqrt(Tot_neurons).

current(ids, agent_generation, perturbation_range, annealing_parameter)

@spec current([{:actuator | :neuron, {float()}}], integer(), float(), float()) :: [
  {Bardo.Models.neuron_id(), float()}
]

current is a selection algorithm that returns a list of all neurons which have been added to the NN, or affected by mutation, during the last generation.

current_random(ids, agent_generation, perturbation_range, annealing_parameter)

@spec current_random([{:actuator | :neuron, {float()}}], integer(), float(), float()) ::
  [
    {Bardo.Models.neuron_id(), float()}
  ]

current_random composes the list of tuples in the same way as current does, but then composes a sublist by randomly selecting elements from that list with a probability of 1/math:sqrt(Tot_Neurons), and returning that to the caller.

dynamic(ids, agent_generation, perturbation_range, annealing_parameter)

@spec dynamic([{:actuator | :neuron, {float()}}], integer(), float(), float()) :: [
  {Bardo.Models.neuron_id(), float()}
]

The dynamic selection function randomly selects an age limit for its neuron id pool. The age limit is chosen by executing math:sqrt(1/rand:uniform()), which creates a value between 1 and infinity. Using this function there is 75% that the number will be =< 2, 25% that it will be >= 2, 11% that it will be >= 3...Every time this selection function is executed, the AgeLimit is generated anew, thus different times it will produce different neuron id pools for tuning.

dynamic_random(ids, agent_generation, perturbation_range, annealing_parameter)

@spec dynamic_random([{:actuator | :neuron, {float()}}], integer(), float(), float()) ::
  [
    {Bardo.Models.neuron_id(), float()}
  ]

dyanimic_random selection function composes the neuron id pool the same way as the dynamic/4 selection function, but after this id pool is generated, this selection function extracts ids from it randomly with a probability of 1/math:sqrt(Tot_Neurons). Thus the probability of a neuron being selected from this pool is proportional to the number of ids in that pool. If through chance no ids are selected, then the first element in the id pool is automatically selected, and given the highest spread.