Answers.Body: <p>I believe NEAT just loops through the nodes in the order they appear in a list.</p>
  <p>Looking at the <a href="http://nn.cs.utexas.edu/?neat-c" rel="nofollow noreferrer">source (.cpp)</a> and removing time features it looks like this in JS:</p>
  <pre><code> do{
      // For each node, compute the sum of its incoming activation 
      for(let i=0;i&lt;nodes.length;i++){
          if(nodes[i].type!=='input'){
              nodes[i].sum=0;
              nodes[i].active=false;
              for(let f=0;f&lt;nodes[i].from.length;f++){
                  let {index,weight}=nodes[i].from[f];
                  if(nodes[index].activeCnt&gt;0)nodes[i].sum+=weight*nodes[index].activeValue;
                  if(nodes[index].active||nodes[index].type==='input')nodes[i].active=true;
              }
          }
      }
      // Now activate all the non-sensor nodes off their incoming activation 
      for(let i=0;i&lt;nodes.length;i++){
          if(nodes[i].type!=='input'&amp;&amp;nodes[i].active){
              nodes[i].activeValue=sigmoid(nodes[i].sum);
              nodes[i].activeCnt++;
          }
      }
  }while(!outputs.isActive());
  </code></pre>
  <p>On initialization the outer while loop might run &gt;1 times. After this it will only run once on every time step.</p>
  <p>From my understanding, on each time step NEAT does not &quot;push each input value fully from input to output&quot;, only &quot;pushes from one node to the next&quot; except at intialization.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-01-05T04:02:37.080Z
Answers.Text: From the `network.cpp(:170)` file: *Keep activating until all the outputs have become active*. Your assumption is only right after the first activation. However, it's propagation strategy does seem to be topology agnostic. I wonder how it responds to larger/more complex networks.
Answers.UserDisplayName: Hugo Aboud
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-07-23T14:02:36.813Z
Answers.Text: what is the point of tracking `activeCnt`?
Answers.UserDisplayName: Chechy Levas
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-01-03T22:06:56.473Z
Answers.LastActivityDate: 2022-01-04T05:10:31.410Z
Answers.LastEditDate: 2022-01-04T05:10:31.410Z
Answers.UserDisplayName: fooybar
Body: <p>I'm working on an implementation of NEAT, which evolves neural networks with small and sparse topologies.</p>
  <p>Evaluating a sparse and possibly recurrent network requires a different approach than the matrix operations of dense networks, and I'm trying to wrap my head around the order in which nodes should be evaluated.</p>
  <p>I've set up a simple example:</p>
  <ul>
  <li>Every node (except inputs) starts at 0. (t0)</li>
  <li>Every weight is 1. There's no activation function or biases.</li>
  </ul>
  <p><a href="https://i.sstatic.net/Vtye3.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/Vtye3.png" alt="enter image description here" /></a></p>
  <p>Assuming that the algorithm has the same intuition we humans do: evaluate the nodes connected to the input, then the &quot;aggregation&quot; node, then the output.
  How should it decide whether to evaluate node [3] before node [4] or vice-versa?</p>
  <p>By starting (t0) at [3], the value of [4] is 0. And vice-versa.</p>
  <p>The side-effect of this behavior appears when comparing two networks. Say you have the network above, and a copy of it where [3] and [4] are inverted. I feel like both should return the same result for the same input in order for evolution to work properly.</p>
  <p>Any thoughts?</p>
  
Tags: <recurrent-neural-networks><neat><neuroevolution>
Title: Order of operations on sparse recurrent network alters the output. How to deal with it?
UserDisplayName: Hugo Aboud
ThreadText: # Order of operations on sparse recurrent network alters the output. How to deal with it?
  
  (Asked by: username_0 on 2021-12-31)
  
  I'm working on an implementation of NEAT, which evolves neural networks with small and sparse topologies.
  
  Evaluating a sparse and possibly recurrent network requires a different approach than the matrix operations of dense networks, and I'm trying to wrap my head around the order in which nodes should be evaluated.
  
  I've set up a simple example:
  
  * Every node (except inputs) starts at 0. (t0)
  * Every weight is 1. There's no activation function or biases.
  
  [![enter image description here](https://i.sstatic.net/Vtye3.png)](https://i.sstatic.net/Vtye3.png)
  
  Assuming that the algorithm has the same intuition we humans do: evaluate the nodes connected to the input, then the "aggregation" node, then the output.
  How should it decide whether to evaluate node [3] before node [4] or vice-versa?
  
  By starting (t0) at [3], the value of [4] is 0. And vice-versa.
  
  The side-effect of this behavior appears when comparing two networks. Say you have the network above, and a copy of it where [3] and [4] are inverted. I feel like both should return the same result for the same input in order for evolution to work properly.
  
  Any thoughts?
  
  **Tags:** recurrent-neural-networks, neat, neuroevolution
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2022-01-03. Score: 2
  
  I believe NEAT just loops through the nodes in the order they appear in a list.
  
  Looking at the [source (.cpp)](http://nn.cs.utexas.edu/?neat-c) and removing time features it looks like this in JS:
  
  ```
   do{
      // For each node, compute the sum of its incoming activation 
      for(let i=0;i<nodes.length;i++){
          if(nodes[i].type!=='input'){
              nodes[i].sum=0;
              nodes[i].active=false;
              for(let f=0;f<nodes[i].from.length;f++){
                  let {index,weight}=nodes[i].from[f];
                  if(nodes[index].activeCnt>0)nodes[i].sum+=weight*nodes[index].activeValue;
                  if(nodes[index].active||nodes[index].type==='input')nodes[i].active=true;
              }
          }
      }
      // Now activate all the non-sensor nodes off their incoming activation 
      for(let i=0;i<nodes.length;i++){
          if(nodes[i].type!=='input'&&nodes[i].active){
              nodes[i].activeValue=sigmoid(nodes[i].sum);
              nodes[i].activeCnt++;
          }
      }
  }while(!outputs.isActive());
  
  ```
  
  On initialization the outer while loop might run >1 times. After this it will only run once on every time step.
  
  From my understanding, on each time step NEAT does not "push each input value fully from input to output", only "pushes from one node to the next" except at intialization.
  
  > **Comments:**
  > **username_0**: From the `network.cpp(:170)` file: *Keep activating until all the outputs have become active*. Your assumption is only right after the first activation. However, it's propagation strategy does seem to be topology agnostic. I wonder how it responds to larger/more complex networks.  
  > **username_2**: what is the point of tracking `activeCnt`?  
  
  ---
  
  