Thank you for writing in and addressing this issue. Because of the way that the data structures are laid out in NEST, normalising the weights per neuron is a costly operation (in terms of time spent). One has to iterate over all the neurons, then for each neuron fetch all of its connections, calculate the vector norm and perform the actual normalisation, and finally to write back the new weights.
This would look something like:
for neur in neurons_to_be_normalised:
connect = nest.GetConnections(target=[neur]], synapse_model="stdp_synapse")
w = nest.GetStatus(connect, "weight")
nest.SetStatus(connect, "weight", np.array(w/np.sum(w)))
The next question is then, how often should this normalisation be carried out? To be formally correct, it should be done at each simulation timestep, but weights typically evolve on a much longer timescale than the network is simulated at, so this would be very inefficient. Depending on how fast your weights change, you may want to perform this update, say, every 100 ms of simulated time, or every 1 s (or even less frequently).
So, the basic strategy is to divide your total simulation time into chunks of, say, 100 ms. You simulate for 100 ms, then you stop simulating and update the weights (using the code above), and then continue simulating the next chunk.
Please let us know in case you have any remaining questions.
With kind regards,
On Thu, Jun 4, 2020, at 21:03, Keiko Fujii wrote:
I would like to ask how to normalize synaptic weights during STDP learning.
What I want to do is keeping the total amount of synaptic weights to/from each neuron constant.
I try to describe my goal a bit more precisely:
i: The index of a pre-synaptic neuron.
j: The index of a post-synaptic neuron.
w_ij(t): The synaptic weight from i-th neuron to j-th neuron at time=t.
s_i(t): the sum of all incoming synaptic weights to i-th neuron at time=t. i.e. the sum of w_ij(t) over j.
The goal is to set the sum of incoming weights (s_i(*)) to 1 by normalization (1 is just for simplicity).
By STDP, we can get updated synaptic weight matrix w_ij(t+1), and the sum s_i(t+1) is not necessarily 1. So, I want to set
w_ij(t+1) <- w_ij(t+1) / s_i(t+1)
I briefly read the documentation for synaptic models(https://nest-simulator.readthedocs.io/en/stable/models/synapses.html).
I am not very confident if my understanding is correct, but it seems that existing synaptic models handle only one synaptic weight.
How can I gather data of all incoming(or outgoing as well) weights to a neuron and use the summation value inside of the STDP synapse model?