Step by step network setup and simulation - simonbe/nexa GitHub Wiki

A network model can be setup and run in two ways. Either by calling library functions straight away (similarly to other simulators) or to inherit from the Network class and override specific functions. We suggest using the latter case, which promotes a clear separation of network setup and simulation and allows for using the built-in parameter handling. Below we go through the steps needed to run a simple recurrent network:

  1. Setup a class inheriting from Network. Override the functions NetworkSetupStructure, NetworkSetupMeters and NetworkRun.
#include "Network.h"

class NetworkDemo0 : public Network
{
public:

private:

	void NetworkSetupStructure(); // Define your model here
	void NetworkSetupMeters(); // Add meters for recording of e.g. network activity
	void NetworkRun(); // Main simulation function
};
  1. Define your model. Here a columnar population (10 columns with 100 rate units in each column) fully connected to itself is defined. Each column performs a winner-take-all function over the activity values of its rate units.
void NetworkDemo0::NetworkSetupStructure()
{
	// total nrHypercolumns*nrRateUnits neural units
	int nrHypercolumns = 10;
	int nrRateUnits = 100;

	// define population, sett units as rate units (PopulationColumns::Graded)
	PopulationColumns* pop1 = new PopulationColumns(this,nrHypercolumns,nrRateUnits,PopulationColumns::Graded);
	this->AddPopulation(pop1); // this population/layer will have index 0

	// Population fully connected to itself by random synaptic weights
	FullConnectivity* full1 = new FullConnectivity();
	full1->SetRandomWeights(0,10);
	pop1->AddPre(pop1,full1);

	// use a linear transfer function
	TransferLinear* transferLin = new TransferLinear();
	pop1->AddUnitsModifier(transferLin);

	// Winner-take-all operation on the values in each column
	WTA* wta = new WTA();
	pop1->AddPopulationModifier(wta);
}
  1. Add meters to do recording of e.g. network activity.
void NetworkDemo0::NetworkSetupMeters()
{
	// example of file output
	Meter* meter1 = new Meter("activity.csv",Storage::CSV,Storage::Standard);
	meter1->AttachPopulation(this->GetLayer(0));
	this->AddMeter(meter1);

	// also check simulation times, this can be done on any network object
	this->SetTiming(true,this);
}
  1. Define simulation behavior.
void NetworkDemo0::NetworkRun()
{
	int nrTimeSteps = 100; // total nr of simulation time steps
	int n = 10; // inject data every nth iteration
	
	// how to get access to specific units
	vector<RateUnit*> units = ((PopulationColumns*)this->GetLayer(0))->GetRateUnits();
	
	// simulate loop
	for(int i=0;i<nrTimeSteps;i++)
	{
		if(i % n == 0)
		{
			// inject some random data
			vector<float> randData(units.size());
			for(int m=0;m<randData.size();m++) randData[m] = rand()/(float(RAND_MAX)+1);
			this->GetPopulation(0)->SetValuesAll(randData, true);
		}

		this->Simulate(); // simulates 1 timestep
	}
}
  1. Run simulation. From main file, handle MPI and call the Run() function of the setup network.
#include <mpi.h>
#include "NetworkDemo0.h"

int main(int argc, char *argv[])
{
	MPI_Init(&argc,&argv);
	
	NetworkDemo0 demo0;
	demo0.Run();

	MPI_Finalize();
	return 0;
}
⚠️ **GitHub.com Fallback** ⚠️