Tutorial: Learning the weights¶
In this tutorial the weights of our neuron network gets changed based on the STDP.
The idea of the STDP model is:
- if a spike arrives at a synapse, and shortly after the post-synaptic neuron fires, then the weight goes up
- if a spike arrives at a synapse, but the post-synaptic neuron has fired shortly before, then the weight goes down
This images visualizes this concept:
Importing the needed libraries¶
First thing we have to do is to import all the libraries we need:
import numpy as np
from neurons import learning
Setting up the STDP model¶
Now we have to set up the STDP model.
stdp_model = learning.STDP(eta=0.05, w_in=0.5, w_out=0.5, tau=10.0, window_size=5)
This tells our STDP model all the needed parameters:
- the learning rate eta (\(\eta\))
- the change rate for incoming and outgoing spikes \(w_{in}\) and \(w_{out}\).
- tau (\(tau\)) is a parameter for the learning window
- window_size tells us to look only at the last 5ms for calculating weight changes
Or if you are already familiar with the STDP equations;
Weight change:
Learning window:
Setting up the spiketrain and initial weights¶
For the weights, we use the same as in the last tutorial. As for the spiketrain, we use the resulting spiketrain of the last tutorial:
weights = np.array([[0, 0, 1.],
[0, 0, 1.],
[0, 0, 0]])
spiketrain = np.array([[0, 0, 1, 0, 0, 0, 1, 1, 0, 0],
[1, 0, 0, 0, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0]], dtype=bool)
Now we are ready to go!
Calculating the weight change at all times¶
Similar to the last tutorial, we calculate the weight change at every timestep:
for time in range(10):
stdp_model.weight_change(spiketrain, weights, time)
Look at that result¶
We print the result to the console:
print("Weights after")
print(weigths)
Which gives us:
[[ 0. 0. 1.18586337]
[ 0. 0. 1.17766241]
[ 0. 0. 0. ]]
As we can see, both weights did go up.
Exercise¶
What do you think happens when we use the following spiketrain?
spiketrain = np.array([[0, 0, 1, 0, 0, 0, 0, 0, 1, 1],
[1, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 1, 0, 0]], dtype=bool)
Do the weights:
- both go up
- 1 -> 3 goes up, while 2 -> 3 goes down
- 1 -> 3 goes down, while 2 -> 3 goes up
- both go down
Go and try it out yourself!
Conclusion¶
As you see, calculating the weight changes by STDP was really easy.
In the next tutorial, we see how we can combine both the SRM spiking and the STDP learning.
Sourcecode¶
The complete source code is as follows:
import numpy as np
from neurons import learning
stdp_model = learning.STDP(eta=0.05, w_in=0.5, w_out=0.5, tau=10.0, window_size=5)
weights = np.array([[0, 0, 1.], [0, 0, 1.], [0, 0, 0]])
spiketrain = np.array([[0, 0, 1, 0, 0, 0, 1, 1, 0, 0],
[1, 0, 0, 0, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0]], dtype=bool)
for time in range(10):
stdp_model.weight_change(spiketrain, weights, time)
print("Weights after")
print(weights)
Questions¶
Q: Do I have to check weight changes at every timestep?
A: Yes, I absolutely advise you to do so. One reason is that if you skip a few timesteps in between, then you’ll also lose the \(w_{in}\) and \(w_{out}\) terms of incoming and outgoing spikes at those times.