Description of problem
Hello everyone,
I’ve been trying to implement a winner-take-all mechanism similar to the one used in this paper. Here, the author implemented a winner-take-all mechanism that led the neurons to fire sequentially and each one at a time.
In my code, each neuron has two types of connections, excitatory and inhibitory. The first is shared between the input (28x28 inputs) and the neurons, and the second is shared between each neuron and all the other neurons (except the source neuron with itself). Each time a neuron fires, it increases the variable inhIN, by 1, of all the post-neurons through the inhibitory synapses. The variable inhibited is equal to 1 if inhIN < 0. On the excitatory connections, each time a pre-neuron/input fires, the potential of the post-neurons is increased as ‘v_post += w x inhibited_post’. My idea would be for a neuron to inhibit all its post-neurons (via inhibitory synapses) by increasing their inhIN by 1 resulting in inhibited = 0 and v_post += w*0 += 0. In other words it would make the post-neurons disregard the input. This actually happens when I feed the net but not totally as wanted. See ‘Actual output’ for a brief explanation of what isn’t working as expected.
My question is, how could I make neurons, from the neurons group, fire each one at a time? Should I adopt another model for the neuron?
Any help would be much appreciated!
Minimal code to reproduce problem
wmax = 1
Apre = 0.4
taupre = 10 * ms
taupos = 10 * ms
Apost = -Apre * 0.2
tau_inh = 5 * ms
eqs_neurons = '''
dv/dt = (-v/tau) : 1 (unless refractory)
dinhIN/dt = (-inhIN/tau_inh) : 1
inhibited = int(not(inhIN > 0.001)) : 1
'''
neurons = NeuronGroup(n_neurons, eqs, threshold='v>1', refractory=5*ms, reset='v=0', method='exact')
(...)
spikes = intensity_to_temporal(train_X)
In = SpikeGeneratorGroup(28*28, [0], [0*ms] , sorted = True)
(...)
inhibitory = Synapses(neurons, neurons,
on_pre='''inhIN_post = inhIN_post + inhibited_post
''')
inhibitory.connect('i!=j')
stdp = Synapses(In, neurons,'''
w : 1
dapre/dt = -apre/taupre : 1 (event-driven)
dapost/dt = -apost/taupost : 1 (event-driven)
''',
on_pre='''
v_post += w*inhibited_post
apre += Apre*inhibited_post
''',
on_post='''
apost += Apost
w = w + w * (wmax - w)*(apre+apost)
''')
stdp.connect()
stdp.w = 'rand()/20'
(...)
#feed the neurons group with the MINST dataset
(...)
spi = StateMonitor(neurons, ['v','inhIN', 'inhibited'], record=True)
spi_dts = SpikeMonitor(neurons)
run(pattern_dt)
for ni in range(Nneurons):
plt.plot(spi.t/ms, spi.v[ni], label=f'Neuron {ni} inhibited')
plt.fill_between(spi.t/ms, 0, 1, where=(spi.inhibited[ni]==0), facecolor=colors[ni], alpha=0.1, hatch=hat[ni], label=f'Neuron {ni} inhibited')
plt.plot(spi.t/ms, spi.inhIN[ni], label=f'inhIN [{ni}]')
for spik in spi_dts.t:
plt.axvline(spik/ms, ls=':')
plt.xlabel('')
plt.legend()
plt.show()
What you have aready tried
I have tried to increase the defaultclock.dt to 0.01*ms.
Expected output (if relevant)
Have each neuron to fire at a time, by inhibiting the post-neurons when it fires, as shown below. This is the actual and expected output, but not always (in this simulation rate encoding was used).
Attention: the legend is partially incorrect. The blue and green lines correspond to the neurons 0 and 1 potential, respectively.
Actual output (if relevant)
-
I intend to set the inhibition duration (the time while inhIN > 0 <=> inhibited = 0) through the variable tau_inh. But when I plot these variables during simulation, I get longer periods than the value set for this variable. Also, to update the value of the variable ‘inhibited’, I had to use the condition ‘inhIN > 0.001’ instead of ‘inhIN > 0’ because the inhibited period would be even bigger. For the simulation shown below, tau_inh and pattern_dt (duration of the pattern) are equal to 0.5 and 10 ms, respectively.
-
Neurons still fire at the same time. For the simulation show below, I’m using temporal encoding (each value is converted into a spike-time, higher values correspond to earlier spikes) on the MINST dataset. This results on having several inputs firing at the same time (same input values for set of pixels = same spike-times for set of pixels).
Attention: the legend is partially incorrect. The blue and green lines correspond to the neurons 0 and 1 potential, respectively.
e