Hi @diogohmsilva . Thanks for sharing the runnable code. Regarding the duration of the inhibition: you are modelling the inhibitory current with an exponential decay, the constant tauinh
is therefore not setting the total duration but the time constant of the decay (i.e. the time until the signal reaches 1/e of the original value). You can use a more artifical inhibitory current, where the current stays up for a certain time and then goes down, i.e. a rectangular current:
inhibitory = Synapses(neurons, neurons,
on_pre={'up' : 'inhIN_post += 1', 'down': 'inhIN_post -=1'},
delay={'down': tauinh})
When a spike arrives, inhIN
is increased by 1, and after a delay of tauinh
, it is reduced by 1.
Now, regardless of the parameters, the scheduling that you set with when
, etc., this model can never completely avoid that two neurons fire within the same time step. This is because the thresholding phase which determines which neuron fires is run for all neurons as a block, so if two neurons happen to cross the threshold, both will emit spikes and inhibit the other neurons. The only way to fix this would be with a network_operation
(or a user-defined function written in Cython, but that’s much more complicated), which intervenes after the thresholding stage and forces only a single neuron to spike. Usually, models with a WTA mechanism (like the one you referenced) simply ignore this problem, since it is very unlikely that two neurons spike in the exact same time step. This is not the case for your model, since your transformation into spike times will lead to most input spikes arriving in the first or last time step of the pattern window (corresponding to black or white pixels, I guess). The weights to the neurons might be random, but if each neuron sums up 100s of random weights, the summed result will be almost the same.
I can think of some ways you could deal with this:
- change your encoding into spike times: currently, you encode space into “input lines” and intensity into spike time, but you could also add an encoding of space into the spike times (e.g. pixels spike earlier on the left than on the right). I think a number of people have thought of spike-time encodings of the MNIST dataset, in the extreme case you could use the spikes recorded from a spike-based camera that scans the displayed number with simulated saccades: Garrick Orchard - N-MNIST
- Make your weights smaller, so that they are just enough to evoke a spike (actually, in that case you’d probably not even need an inhibition mechanism to only make a single neuron spike, but it has the disadvantage that you might not get any spikes for some presented digits).
- use synaptic current input instead of the “delta synapse” implementation that directly increases the membrane potential. With your current model, there is no difference between a strong super-threshold input and an input that is barely super-threshold – both will make a neuron spike. With a synaptic current input, a strong input will make the neuron spike very soon, and a weak input will only make it spike after a certain delay.
- Add random delays to your inputs (not sure that’s really a good idea)
Hope that gives you some ideas, best
Marcel