Description
Describe the bug
Currently I am running NEAT for a long time and inspect the growth of the network from time to time. I started to notice that NEAT creates many "dead ends" / "dangling nodes" -> Nodes that are not going anywhere and are not connected to another node or an output. Yesterday I found an example with quite a few in them.
I am unsure if that happened with older versions before (or to this extend).
Maybe that behavior is desired?
I would have expected, that "dangling" nodes are either removed too when the connected node(to the exit/next leading node) is removed or that the node is re-connected to the node that comes after the removed one.
There are also nodes that are "going out" of an output that are not recurrent?! I don't think that should happen either?
The longer you run the algorithm the more "crude" and broken the network gets, up to a point when you have almost no "functional" nodes anymore because they are not connected to an output anymore
To Reproduce
I used:
- gym 0.25.1 with 'Alien-v4'
- neat 0.93
- config see below
OS:
Linux Ubuntu-2204-jammy-amd64-base 5.15.0-46-generic #49-Ubuntu SMP Thu Aug 4 18:03:25 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Expected behavior
No "dangling" nodes and no nodes that "leave" an exit (maybe except of recurrent ones)
or
When nodes get removed and would leave a dangling node behind then they should either be removed too or be connected to the nodes that come after the now removed node
Screenshots with problematic nodes
Used Config
[NEAT]
pop_size = 300
fitness_criterion = max
fitness_threshold = 1000.0
reset_on_extinction = 0
no_fitness_termination = True
[DefaultGenome]
num_inputs = 128
num_hidden = 0
num_outputs = 18
initial_connection = unconnected
feed_forward = True
compatibility_disjoint_coefficient = 1.0
compatibility_weight_coefficient = 1.0
conn_add_prob = 0.35
conn_delete_prob = 0.25
node_add_prob = 0.35
node_delete_prob = 0.25
activation_default = random
activation_options = clamped relu sigmoid sin tanh
activation_mutate_rate = 0.05
aggregation_default = sum
aggregation_options = sum min max mean
aggregation_mutate_rate = 0.15
bias_init_type = gaussian
bias_init_mean = 0.0
bias_init_stdev = 1.0
bias_replace_rate = 0.15
bias_mutate_rate = 0.8
bias_mutate_power = 0.4
bias_max_value = 30.0
bias_min_value = -30.0
response_init_mean = 1.0
response_init_stdev = 0.0
response_replace_rate = 0.15
response_mutate_rate = 0.15
response_mutate_power = 0.15
response_max_value = 30.0
response_min_value = -30.0
weight_init_type = gaussian
weight_max_value = 30
weight_min_value = -30
weight_init_mean = 0.0
weight_init_stdev = 1.0
weight_mutate_rate = 0.8
weight_replace_rate = 0.02
weight_mutate_power = 0.4
enabled_default = True
enabled_mutate_rate = 0.01
single_structural_mutation = false
structural_mutation_surer = default
response_init_type = gaussian
enabled_rate_to_true_add = 0.0
enabled_rate_to_false_add = 0.0
[DefaultSpeciesSet]
compatibility_threshold = 5
[DefaultStagnation]
species_fitness_func = mean
max_stagnation = 50
species_elitism = 4
[DefaultReproduction]
elitism = 2
survival_threshold = 0.2
min_species_size = 50