tuning_selection (faber_tweann v2.4.0)

View Source

Tuning selection: which neurons to perturb each memetic attempt.

DXNN's memetic weight tuner does not perturb every neuron every attempt. It perturbs a SUBSET, biased toward neurons added or mutated recently, each with its own annealed spread. Old, stable neurons are left alone so their already-tuned weights are not disturbed. This is what makes the hill-climber efficient: it concentrates search where the topology just changed.

faber-tweann's tuner previously perturbed all neurons every attempt with one shared range (equivalent to all here). That was the blunt-instrument cost flagged in insight 013.

Ported from Gene Sher's DXNN2 (Handbook Ch 8). Each function returns a list of {NeuronId, Spread}: the neurons to perturb and by how much.

Summary

Functions

Neurons changed within a fixed recent window of 3 generations.

Every neuron, each with the base spread. This is the pre-013 behaviour, kept for ablation: all plus a const duration is the crude tuner.

Only the neurons of the current generation.

Recently-changed neurons within a randomly chosen age limit.

As dynamic/4, then keep a random subset of the result.

Dispatch by strategy name. Unknown strategy falls back to dynamic, the efficient default.

Types

id_spread/0

-type id_spread() :: {term(), float()}.

Functions

active(Ids, Generation, PR, AP)

-spec active([term()], non_neg_integer(), float(), float()) -> [id_spread()].

Neurons changed within a fixed recent window of 3 generations.

all(Ids, Generation, PR, AP)

-spec all([term()], non_neg_integer(), float(), float()) -> [id_spread()].

Every neuron, each with the base spread. This is the pre-013 behaviour, kept for ablation: all plus a const duration is the crude tuner.

current(Ids, Generation, PR, AP)

-spec current([term()], non_neg_integer(), float(), float()) -> [id_spread()].

Only the neurons of the current generation.

dynamic(Ids, Generation, PR, AP)

-spec dynamic([term()], non_neg_integer(), float(), float()) -> [id_spread()].

Recently-changed neurons within a randomly chosen age limit.

The age limit is sqrt(1/rand:uniform()), which is >=1 and usually small (about 75% of the time two or fewer), so most attempts perturb only the last generation or two of neurons, but occasionally reach deeper. Each chosen neuron's spread is annealed by its age: PR * pi * AnnealingParameter^Age. If nothing qualifies, perturb the first neuron with full spread.

dynamic_random(Ids, Generation, PR, AP)

-spec dynamic_random([term()], non_neg_integer(), float(), float()) -> [id_spread()].

As dynamic/4, then keep a random subset of the result.

select(Other, Ids, Gen, PR, AP)

-spec select(atom(), [term()], non_neg_integer(), float(), float()) -> [id_spread()].

Dispatch by strategy name. Unknown strategy falls back to dynamic, the efficient default.