I’m studying Nengo simulator and I have some doubts about the input current J: in order to understand how it works, I have realized a very simple network with one RS Izhikevich neuron connected with a nengo.Node.
import numpy as np
from scipy import signal
import os
import nengo
model = nengo.Network()
with model:
#### INPUT
#Square wave at 10 Hz
stim_pre = nengo.Node(lambda t: 4*(signal.square(2 * np.pi * 10 * t, duty=0.5)+ 1))
#stim_pre = nengo.Node([.5])
ens = nengo.Ensemble(n_neurons=1, dimensions=1, neuron_type = nengo.Izhikevich())
nengo.Connection(stim_pre, ens.neurons)
### Probe
spike_pre = nengo.Probe(ens.neurons)
#Voltage
pre_voltage = nengo.Probe(ens.neurons, 'voltage')
#Stimuli
prestim=nengo.Probe(stim_pre)
with nengo.Simulator(model, dt = 0.001) as sim:
sim.run(1)
time=sim.trange()
I have assigned to the nengo.Node different values:
Constant value J = 8;
Constant value J = 0.5;
Square wave with amplitude J = 8;
I get some results that I cannot understand, as the attached figure shows: to understand what is going on, I have looked at the implementation of the neurons, considering that the voltage of the neurons has [mV] as order of magnitude.
dV = (0.04 * voltage ** 2 + 5 * voltage + 140 - recovery + J) * 1000
So, also the current J has some order of magnitude or I have misunderstood how the nengo.Node works and how it provides current to the neuron?
In general, if I had n neurons inside the ensemble and I created this connection nengo.Connection(input_node,ensemble) , each of them would receive the same current I have declared?
I looked at the code of the Izhikevich neurons and the membrane voltage gets reset to -65 whenever the neuron spikes (i.e. membrane voltage exceeds 30) in the same timestep. It seems that this is happening in every timestep which fixes the membrane voltage at the observed -65. You might want to probe the actual spikes to verify that this is what is happening.
J is a current and the units (I think that is what you mean here, not the magnitude?) are definitely not Hz, but Ampere (A) (= charge / time = Coulomb/second = C/s) with some magnitude prefix. Probably mA (milli Ampere), but the 1000 factor in the implementation confuses me. It’s purpose is not clear to me: Does it account for the voltages being in mV? (But shouldn’t it be a division by 1000 in that case?) Or does it account for the timestep? (Though, that seems to be done in the next line and why would the factor of 1000 be hard coded?)
if I wanted to provide directly 50 mA to the neurons in the ensemble, I should have to make a connection like this: nengo.Connection(input, ens.neurons) and the input is not encoded;
if I provided the input to the ensemble (nengo.Connection(input, ens) ) I should give the same encoded input to all the neurons in the ensemble.
Is it right or I don’t understand something?
I checked the spikes of the neuron, and the neuron seems to spike every time step: according to you, it fires every time steps and so the voltage is reset.
I thought that all the calculations for the voltage are in µV [micro Volt], and the 1000 factor was used to give the membrane potential in mV, as it does. Could this be true also for the J current? I mean, from µA [micro Ampere] to mA [milli Ampere]?
So, in order to give as input a generic quantity x with a unit prefix of µ [10-6], how do I declare the input? Of course, considering a direct link between the input and the neuron: nengo.Connection(stim_pre, ens.neurons[0])
I made some proofs considering an input equal to 15 and changing the order of magnitude, but I still don’t understand the correct behaviour.
If I give a stimulus whose amplitude is with a magnitude less or equal to 10-2, the neuron doesn’t fire, so the stimulus is low;
if I give a stimulus with a magnitude equal to 10-1 the neuron fires with a burst (it should fire single spikes due to the fact is RS - neuron) when the input is high.
if I give a stimulus with a magnitude equal exactly to 15, the neuron fires but after the falling edge.
If is it possible, could you tell me where I’m wrong and why the voltage decreases until -250 mV?
I figure it out what was wrong. If I want give a J current equal to the signal that the neuron should represent, I must fix properly the gain, bias and encoder values due to the fact J = αex + Jbias; so I fixed α = e = 1 and Jbias= 0. In this way I have J = x and I can give directly the current I declared in the neuron, as the figure shows.
In order to see if I understand how NEF works, are these the next steps of Nengo?
It computes the neural activity ai of the neuron (i.e. the spiking rate?)
It decodes the neural activity with the following equation, due to the fact that the input changes in time: x˜ = ai(t)* h(t)di.
If these two steps are right, I would have some questions.
How is it evaluated the neural activity from the neuron model? I know that ai = G [J(t)], where G is the neuron model. But how can I pass from the voltage equation to the firing rate of the neuron?
From the simulator, can I know the value of the decoder di?
To see if the output of the ensemble is x˜, I have to compute the convolution. Can I do that considering the following code? out_ens = nengo.Probe(ens, synapse = tau), where tau is the costant term of the postsynaptic filter?