To answer your questions:
- To probe spiking data from let’s say Motor state, we need to put model.motor.state_ensembles.add_neuron_output(), right?
For the HBB CH5 question-control example, if you want to probe the spikes from the
motor state, you’ll want to do:
motor_spike_probe = nengo.Probe(motor.neuron_output)
- After probing, I am having spikes at every instant of time (dt=0.001) which will not be useful, as inter-spiking time would be just 0.001 for all neurons at all instances.
This is not an easy question to answer since the inter-spike interval measurement can depend on the specifics of the behaviour you want to replicate. There are a few things you can try to achieve your goal.
- The interspike interval is typically measured for a single neuron. However the spike data gathered using the spike probe above is for all of the neurons in the ensemble. You can isolate the spikes from a single neuron like so:
neuron_0_spikes = motor_spike_probe[:, 0]
neuron_1_spikes = motor_spike_probe[:, 1]
The data returned like this will look something like:
[0, 0, 0, 0, 1000.0, 0, 0, 0, .... 0, 0]
Each element corresponds to whether or not the specific neuron spiked for a specific timestep, where
0 indicates no spikes occurring during that timestep, and a value of
1 / sim.dt when a spike did occur during that timestep. To convert this data into an array of timestamps where a spike happened, you’ll need to multiply by
sim.dt, and then strip out all of the zeros:
neuron_0_spike_times = neuron_0_spikes * sim.trange() * sim.dt # Mulitply by trange and dt
neuron_0_spike_times = neuron_0_spike_times[neuron_0_spike_times > 0] # Strip out zeros
Once you have the spike data for individual neurons, you can then proceed to compute the distribution of interspike intervals for each neuron, and then across the entire model to get the distribution for all of the neurons.
2. The default neuron firing rates in Nengo are pretty high (200-400Hz), while biological neurons fire at a much lower frequency. This can be done by passing in a
max_rates parameter to the initialization of the Ensemble or EnsembleArray:
from nengo import Uniform
# Example EnsembleArray with neurons firing from 10-50 Hz
motor = nengo.networks.EnsembleArray(n_neurons=N, n_ensembles=dim, max_rates=Uniform(10, 50), label='Motor')
# Example ensemble with neurons firing from 5-20 Hz
ens = nengo.Ensemble(n_neurons=N, max_rates=Uniform(5, 20))
3. Changing the neuron type from the default LIF neuron to the adaptive LIF neuron (
nengo.neurons.AdaptiveLIF) type may also help achieve the desired ISI distribution. Unlike the LIF neuron which has a fixed firing rate for a constant input, for a constant input, the adaptive LIF neuron starts a high firing rate, but the rate falls as it adapts the the constant input. The details of the adaptive LIF neuron can be found here.
To use the adaptive LIF neuron, specify the
neuron_type parameter when creating your ensemble or ensemble array:
from nengo import Uniform
# Example EnsembleArray with ALIF neurons
motor = nengo.networks.EnsembleArray(n_neurons=N, n_ensembles=dim, neuron_type=nengo.AdaptiveLIF(...), label='Motor')
# Example ensemble with ALIF neurons
ens = nengo.Ensemble(n_neurons=N, , neuron_type=nengo.AdaptiveLIF(...))
I hope these suggestions help with your query!