-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path2-Neuromodulation_and_plasticity_with_special_input.py
248 lines (174 loc) · 10.8 KB
/
2-Neuromodulation_and_plasticity_with_special_input.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# ============================================================================================================
# ============================================================================================================
# 2-Neuromodulation_and_plasticity_with_special_input.py -- Simulates a feedforward network of excitatory
# neurons as in
#
# Ref: Pedrosa V and Clopath C (2017) The Role of Neuromodulators in Cortical Plasticity.
# A Computational Perspective. Front. Synaptic Neurosci. 8:38. doi: 10.3389/fnsyn.2016.00038
# -----------------------------------------------------------------------
#
# Author: Victor Pedrosa <v.pedrosa15@imperial.ac.uk>
# Imperial College London, London, UK - Dec 2016
# -----------------------------------------------------------------------
#
# Arguments to call the code:
# arg1 = a_plus -> Amplitude of plasticity for pre-post events
# arg2 = a_minus -> Amplitude of plasticity for post-pre events
# ============================================================================================================
# ------------------------------------- Import modules -------------------------------------------------------
import numpy as np
import scipy.io as sio
import multiprocessing as mp
from time import time as time_now
import sys as sys
import Filt_Gaussian_Noise as FGN
args = sys.argv
time_in = time_now()
# ============================================================================================================
# +++++++++++++++++++++++++++++++++++++++++ Parameters +++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ============================================================================================================
# Parameters +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
NE = 10 # Number of presynaptic neurons
NT = NE+1 # Total number of neurons (presynaptic + 1 postsynaptic)
tau_m = 50. # [ms] Membrane voltage time constant
R = 1. # [Ohm] Resistance of the leaky I-F model for excitatory neurons
t_max = 1.e6 # [ms] Max time of simulation
El = 0. # [mV] Resting potential (leaky)
Vth = 10. # [mV] Threshold potential
Vres = 0. # [mV] Reset potential
Vspike = 10. # [mV] Extra potential to indicate a spike
# Parameters for STDP (excitatory):
a0 = -0.00000 # Activity independent term
a1_pre = 0.0 # Pre-synaptic activity term (non-Hebbian)
a1_post = -0.0 # Post-synaptic activity term
a_plus = float(args[1]) # Coefficient related to pre->post activity
a_minus = float(args[2]) # Coefficient related to post->pre activity
tau1 = 8. # [ms] Decay time for pre->post activity
tau2 = 8. # [ms] Decay time for post->pre activity
# Simulation parameters ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dt = 1. # [ms] Simulation time step
numSteps = np.int(t_max/dt) # Number of steps in simulation
# Connections (synapses) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EsynE = 30. # [mV] Reversal potential for synaptic
# Synaptic conductance
tauSynEx = 15. # [ms] Time constant for postsynaptic potential
gBarEx = 1. # Peak amplitude for EPSPs
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ++++++++++++++ Define the parameters for the time dependent firing rate of presynaptic neurons +++++++++++++
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tauFilt = 5. # [ms] Time constant for filtering the Gaussian noise
Mean_FRate = 30. # [Hz] Mean firing rate for the input neurons
# Define the training input
SpecialInput = 1.*np.ones(NE)
SpecialInput[3] = 2.
# ============================================================================================================
# ++++++++++++++++++++++ Calculate all the currents on the postsynaptic neuron +++++++++++++++++++++++++++++++
# ============================================================================================================
# Total synaptic current - vector with the total synaptic current --------------------------------------------
def Isyn(u_in,g_synE,W):
alphaE = (-1)*g_synE*(u_in-EsynE) # For excitatory synapses
Itotal = np.sum(W*alphaE) # For all the synapses
return Itotal
# External current on the postsynaptic neuron ----------------------------------------------------------------
I_pre = 0.
def Iext(I_pre):
I = I_pre - (I_pre - np.random.normal(0,50))/5.
return I
# ============================================================================================================
# ++++++++++++++ Define the calculations to be used in each step of simulation +++++++++++++++++++++++++++++++
# ============================================================================================================
# Define new parameters for speeding up the simulation -------------------------------------------------------
step_tauSynEx = dt/tauSynEx
step_tau_m = dt/tau_m
step_tau1 = dt/tau1
step_tau2 = dt/tau2
A_plus = np.ones(NE)*a_plus
A_minus = np.ones(NE)*a_minus
# Simulation step (one integration step) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
def SimuStep(u_in,g_synE,Delta_pre_post,Delta_post_pre,W,t,I_pre,PreFiring_t):
u_inPost = u_in # Membrane potential for the postsynaptic neuron
# Verify which input neurons fired at this step:
pre_spikes_test_Ex = PreFiring_t
# ============================== Synaptic conductance ==================================================
# Update the synaptic conductances for the neurons that fired:
g_synE_out = g_synE + gBarEx*pre_spikes_test_Ex
# Evolve the synaptic conductances for all the neurons:
g_synE_out = g_synE_out - g_synE_out*step_tauSynEx
# ============================== Membrane Potential ====================================================
I_now = Iext(I_pre)
# Reset the potential for the neurons that fired and Evolve all the potentials:
Isyn_total = Isyn(u_inPost,g_synE,W) # save the synaptic currents
u_in_new = u_in - u_in*(u_in>Vth) + Vres*(u_in>Vth)
u_out = u_in_new + (-u_in_new + R*I_now + Isyn_total)*step_tau_m
# For those that fired, make them fire!
u_out = u_out + Vspike*(u_out>Vth)
# ======================= Synaptic traces for STDP =====================================================
Delta_pre_post_out = Delta_pre_post - Delta_pre_post*step_tau2 + (u_inPost>Vth)
Delta_post_pre_out = Delta_post_pre - Delta_post_pre*step_tau1 + pre_spikes_test_Ex
# =============================== Synaptic weight ======================================================
# Define the vectors to update the synaptic weights vector (excitatory)
W_out = W + Delta_pre_post*pre_spikes_test_Ex*A_minus \
+ Delta_post_pre*(u_inPost>Vth)*A_plus
# Use hard bounds to assure that 0 < W < 2
up_bound = 2.
W_out = W_out - (W_out - up_bound)*(W_out>up_bound) - (W_out)*(W_out<0.)
return u_out , g_synE_out, Delta_pre_post_out, Delta_post_pre_out , W_out, I_now
# ============================================================================================================
# +++++++++++++++++++++++++++++++++++++++ Run the main program +++++++++++++++++++++++++++++++++++++++++++++++
# ============================================================================================================
subsampling = 5000
def OneTrial(void):
# Function to run the simulation for one trial
# ====================================================================================================
# +++++++++++++++++++++++++++++++++ Initialization of variables ++++++++++++++++++++++++++++++++++++++
# ====================================================================================================
Delta_pre_post = 0. # Synaptic traces for pre-post activity
Delta_post_pre = np.zeros(NE) # Synaptic traces for post-pre activity
Vmemb = 0. # [mV] Initial membrane potential for the postsynaptic neuron
W = np.load('W0_new.npy') # Initial synaptic weights
g_synE = np.zeros(NE) # [mS] Initial value for the g function
I_pre = 0.
Ws = np.zeros((int(numSteps/subsampling)+1,NE))# Matrix to track the evolution of the weight matrix
Ws[0,:] = W
# ====================================================================================================
# +++++++++++++++++++++++ Generation of presynaptic spike trains +++++++++++++++++++++++++++++++++++++
# ====================================================================================================
np.random.seed() # to ensure randomness when using multiple processes
# Generate NE independent filtered gaussian noise series
FilteredGaussianNoise = FGN.FiltGNoise(Mean_FRate,tauFilt,NE,numSteps,dt)
FilteredGaussianNoise = FilteredGaussianNoise*SpecialInput
# Re-scale the Filtered Gaussian noise to the time bin (in order to calculate the probability of firing):
FilteredGaussianNoise = FilteredGaussianNoise*dt
# Create correlation between the inputs ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
FilteredGaussianNoiseFinal = 1.*FilteredGaussianNoise
sigma = .5
for i in range(NE):
NormDist = 1./np.sum(np.array([np.exp(-(x-i)**2/((2.*sigma)**2)) for x in range(NE)]))
InputWeights = NormDist*np.array([np.exp(-(x-i)**2/((2.*sigma)**2)) for x in range(NE)])
FilteredGaussianNoiseFinal[:,i] = np.dot(FilteredGaussianNoise,InputWeights)
# Finally generate the presynaptic spike trains
PreFiring = np.random.random((numSteps,NE)) < FilteredGaussianNoiseFinal
# ====================================================================================================
# +++++++++++++++++ Calculate the evolution of the variables +++++++++++++++++++++++++++++++++++++++++
# ====================================================================================================
for l in range(numSteps-1):
time = dt*l
Vmemb, g_synE, Delta_pre_post, Delta_post_pre, W , I_pre\
= SimuStep(Vmemb,g_synE,Delta_pre_post,Delta_post_pre,W,time,I_pre,PreFiring[l])
if np.mod(l,subsampling)==0:
Ws[int(l/subsampling)+1,:] = W
return Ws
# Using parallel computing
NTrials = 20
quant_proc = np.max((mp.cpu_count()-1,1))
pool = mp.Pool(processes=quant_proc)
# run the main code for NTrials trials -----------------------------------------------------------------------
print('\n Running simulation (training input):')
print(' a_plus = {0:.4f} \t a_minus = {1:.4f}'.format(a_plus,a_minus))
AllTrials = pool.map(OneTrial,np.zeros(NTrials))
WsAllTrials = np.array([AllTrials[i] for i in range(NTrials)])
# save the data ----------------------------------------------------------------------------------------------
np.save('Data_RF_shift/Syn_weights_all_trials_aplus={0:07.4f}_aminus={1:07.4f}'.format(a_plus,a_minus,subsampling),WsAllTrials)
time_out = time_now()
time_total = time_out - time_in
print(' Total time = {0:.3f} segundos'.format(time_total))