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:
- 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
};
- 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);
}
- 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);
}
- 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
}
}
- 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;
}