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
|
#!/usr/bin/env python
"""
This code contains an adapted version of the voltage-dependent triplet STDP rule from:
Clopath et al., Connectivity reflects coding: a model of voltage-based STDP with homeostasis, Nature Neuroscience, 2010
(http://dx.doi.org/10.1038/nn.2479)
The plasticity rule is adapted for a leaky integrate & fire model in Brian2.
More specifically, the filters ``v_lowpass1`` and ``v_lowpass2`` are
incremented by a constant at every post-synaptic spike time, to
compensate for the lack of an actual spike in the integrate & fire model.
As an illustration of the rule, we simulate the competition between
inputs projecting on a downstream neuron. We would like to note that the
parameters have been chosen arbitrarily to qualitatively reproduce the
behavior of the original work, but need additional fitting.
We kindly ask to cite the article when using the model presented below.
This code was written by Jacopo Bono, 12/2015
"""
from brian2 import *
################################################################################
# PLASTICITY MODEL
################################################################################
#### Plasticity Parameters
V_rest = -70.*mV # resting potential
V_thresh = -55.*mV # spiking threshold
Theta_low = V_rest # depolarization threshold for plasticity
x_reset = 1. # spike trace reset value
taux = 15.*ms # spike trace time constant
A_LTD = 1.5e-4 # depression amplitude
A_LTP = 1.5e-2 # potentiation amplitude
tau_lowpass1 = 40*ms # timeconstant for low-pass filtered voltage
tau_lowpass2 = 30*ms # timeconstant for low-pass filtered voltage
tau_homeo = 1000*ms # homeostatic timeconstant
v_target = 12*mV**2 # target depolarisation
#### Plasticity Equations
# equations executed at every timestepC
Syn_model = ('''
w_ampa:1 # synaptic weight (ampa synapse)
''')
# equations executed only when a presynaptic spike occurs
Pre_eq = ('''
g_ampa_post += w_ampa*ampa_max_cond # increment synaptic conductance
A_LTD_u = A_LTD*(v_homeo**2/v_target) # metaplasticity
w_minus = A_LTD_u*(v_lowpass1_post/mV - Theta_low/mV)*int(v_lowpass1_post/mV - Theta_low/mV > 0) # synaptic depression
w_ampa = clip(w_ampa-w_minus, 0, w_max) # hard bounds
''' )
# equations executed only when a postsynaptic spike occurs
Post_eq = ('''
v_lowpass1 += 10*mV # mimics the depolarisation effect due to a spike
v_lowpass2 += 10*mV # mimics the depolarisation effect due to a spike
v_homeo += 0.1*mV # mimics the depolarisation effect due to a spike
w_plus = A_LTP*x_trace_pre*(v_lowpass2_post/mV - Theta_low/mV)*int(v_lowpass2_post/mV - Theta_low/mV > 0) # synaptic potentiation
w_ampa = clip(w_ampa+w_plus, 0, w_max) # hard bounds
''' )
################################################################################
# I&F Parameters and equations
################################################################################
#### Neuron parameters
gleak = 30.*nS # leak conductance
C = 300.*pF # membrane capacitance
tau_AMPA = 2.*ms # AMPA synaptic timeconstant
E_AMPA = 0.*mV # reversal potential AMPA
ampa_max_cond = 5.e-8*siemens # Ampa maximal conductance
w_max = 1. # maximal ampa weight
#### Neuron Equations
# We connect 10 presynaptic neurons to 1 downstream neuron
# downstream neuron
eqs_neurons = '''
dv/dt = (gleak*(V_rest-v) + I_ext + I_syn)/C: volt # voltage
dv_lowpass1/dt = (v-v_lowpass1)/tau_lowpass1 : volt # low-pass filter of the voltage
dv_lowpass2/dt = (v-v_lowpass2)/tau_lowpass2 : volt # low-pass filter of the voltage
dv_homeo/dt = (v-V_rest-v_homeo)/tau_homeo : volt # low-pass filter of the voltage
I_ext : amp # external current
I_syn = g_ampa*(E_AMPA-v): amp # synaptic current
dg_ampa/dt = -g_ampa/tau_AMPA : siemens # synaptic conductance
dx_trace/dt = -x_trace/taux :1 # spike trace
'''
# input neurons
eqs_inputs = '''
dv/dt = gleak*(V_rest-v)/C: volt # voltage
dx_trace/dt = -x_trace/taux :1 # spike trace
rates : Hz # input rates
selected_index : integer (shared) # active neuron
'''
################################################################################
# Simulation
################################################################################
#### Parameters
defaultclock.dt = 500.*us # timestep
Nr_neurons = 1 # Number of downstream neurons
Nr_inputs = 5 # Number of input neurons
input_rate = 35*Hz # Rates
init_weight = 0.5 # initial synaptic weight
final_t = 20.*second # end of simulation
input_time = 100.*ms # duration of an input
#### Create neuron objects
Nrn_downstream = NeuronGroup(Nr_neurons, eqs_neurons, threshold='v>V_thresh',
reset='v=V_rest;x_trace+=x_reset/(taux/ms)',
method='euler')
Nrns_input = NeuronGroup(Nr_inputs, eqs_inputs, threshold='rand()<rates*dt',
reset='v=V_rest;x_trace+=x_reset/(taux/ms)',
method='exact')
#### create Synapses
Syn = Synapses(Nrns_input, Nrn_downstream,
model=Syn_model,
on_pre=Pre_eq,
on_post=Post_eq
)
Syn.connect(i=numpy.arange(Nr_inputs), j=0)
#### Monitors and storage
W_evolution = StateMonitor(Syn, 'w_ampa', record=True)
#### Run
# Initial values
Nrn_downstream.v = V_rest
Nrn_downstream.v_lowpass1 = V_rest
Nrn_downstream.v_lowpass2 = V_rest
Nrn_downstream.v_homeo = 0
Nrn_downstream.I_ext = 0.*amp
Nrn_downstream.x_trace = 0.
Nrns_input.v = V_rest
Nrns_input.x_trace = 0.
Syn.w_ampa = init_weight
# Switch on a different input every 100ms
Nrns_input.run_regularly('''
selected_index = int(floor(rand()*Nr_inputs))
rates = input_rate * int(selected_index == i) # All rates are zero except for the selected neuron
''', dt=input_time)
run(final_t, report='text')
################################################################################
# Plots
################################################################################
stitle = 'Synaptic Competition'
fig = figure(figsize=(8, 5))
for kk in range(Nr_inputs):
plt.plot(W_evolution.t, W_evolution.w_ampa[kk], '-', linewidth=2)
xlabel('Time [ms]', fontsize=22)
ylabel('Weight [a.u.]', fontsize=22)
plt.subplots_adjust(bottom=0.2, left=0.15, right=0.95, top=0.85)
title(stitle, fontsize=22)
plt.show()
|