genotype_to_network (faber_tweann v2.4.0)

View Source

Convert an evolved genotype into a network_evaluator network, carrying the weights, or REFUSE when the topology cannot be represented.

ROADMAP item 8a. The function this replaces reported success and handed back a brain-dead network: it counted the neurons, invented a layer shape and filled it with random weights, under a public doc claiming it read the structure "and weights" from Mnesia. There is no Mnesia, and there were no weights. An evolved champion came back the right size and knowing nothing, and nothing raised.

========================================================================== REFUSE, NEVER APPROXIMATE ==========================================================================

A genotype is an arbitrary graph. A network_evaluator network is a stack of dense layers. Most graphs are not stacks, and the only honest answers are a faithful conversion or an error naming what stopped it. An approximation behind an ok tuple is the defect this module exists to remove, so it is not reintroduced here in a tidier form.

Missing connections are NOT an approximation and are filled with 0.0. A weight of zero contributes nothing to a dot product, so a sparse layer expressed densely computes the same function exactly.

========================================================================== THE FIVE THINGS THAT MAKE A GENOTYPE UNCONVERTIBLE ==========================================================================

1. RECURRENCE. Any neuron with a recurrent output edge. A dense stack has no cycle to put it in. 2. A CONNECTION THAT SKIPS OR CROSSES A LAYER. Every input to a neuron in layer N must come from layer N-1, or from the sensors when N is the first layer. Skip connections and lateral connections have no matrix position. 3. MIXED ACTIVATION FUNCTIONS. The network record carries ONE activation for every hidden layer and one for the output layer, not one per neuron. 4. AN ACTIVATION network_evaluator DOES NOT IMPLEMENT. It handles exactly tanh, sigmoid, relu and linear, and its private apply_activation/2 ends in a catch-all that silently returns math:tanh/1. So a genotype carrying gaussian, sin, cos, absolute, sgn, quadratic, cubic, sqrt, log, bin, trinary, multiquadric or sigmoid1 would convert to something that computes a different function without saying so. Refused by name instead. 5. AN LTC NEURON. The evaluator's neuron metadata admits standard and cfc. There is no ltc there, and mapping one onto the other would be a guess.

Summary

Functions

Convert an agent's genotype into an equivalent network, weights included.

The activations a genotype may carry and still be convertible.

Types

reason/0

-type reason() :: {not_layerable, why()} | {missing, atom(), term()}.

why/0

-type why() ::
          recurrent |
          {unsupported_activation, atom()} |
          {mixed_activations, hidden | output, [atom()]} |
          {unsupported_neuron_type, atom()} |
          {source_not_in_previous_layer, term(), term()} |
          {weight_count_mismatch, term(), non_neg_integer(), non_neg_integer()} |
          no_neurons.

Functions

convert(AgentId)

-spec convert(term()) -> {ok, network_evaluator:network()} | {error, reason()}.

Convert an agent's genotype into an equivalent network, weights included.

supported_activations()

-spec supported_activations() -> [atom()].

The activations a genotype may carry and still be convertible.