-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy paththalamusFC.py
243 lines (189 loc) · 8.69 KB
/
thalamusFC.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
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Rewriting in python of the basal ganglia CBG model (Girard et al., 2008, Neural Netwk.)
# This is the thalamus-frontal cortex module
# author : Benoît Girard <[email protected]>
# 9th March 2009
import math
import numpy
#-------------------------------------------
class thalamusFC:
#-----------------------------------------
def __init__(self,model,NbChannels,opt_params=[]):
self.NbChannels = NbChannels # number of channels in competition
self.model = model # model type, can be :
# * GPR : the (Prescott et al., 2006, Neural Netwk) model,
# * CBG : the (Girard et al., 2008, Neural Netwk.) model,
# * CBGcustom : a model with the CBG connections, using lPDS neurons,
# whose precise parameters are specified by the opt_param list.
self.paramInit(opt_params) # parameter initialisation (connection weights, neuron biases)
self.stateReset() # reset to 0 of all the internal variables
self.f=open('log/ThFC_'+model,'w') # log file where the internal state will be stored if logAll function is used
#-----------------------------------------
def __del__(self):
self.f.close()
#-----------------------------------------
def stateReset(self):
self.Th = numpy.zeros((self.NbChannels)) # Neurons of the thalamic nucleus implied in the considered loop
self.FC = numpy.zeros((self.NbChannels)) # Neurons of the frontal cortex area implied in the considered loop
# Variables named "variable_old" are buffers used to store the previous output of the considered neurons
self.old_Th = numpy.zeros((self.NbChannels))
self.old_FC = numpy.zeros((self.NbChannels))
# TRN: Thalmic Reticular Nucleus
# The TRN is made of NbChannels neurons in the GPR,
# while it is one neuron only in the CBG:
if (self.model == 'CBG') or (self.model == 'customCBG'):
self.old_TRN = 0
self.TRN = 0
elif self.model =='GPR':
self.TRN = numpy.zeros((self.NbChannels))
self.old_TRN = numpy.zeros((self.NbChannels))
else:
print 'stateReset(): ', self.model, ' model type unknown'
#-----------------------------------------
def paramInit(self,opt_params):
# invTau are 1/tau, tau being the neurons' time constants
# W_A_B is the projection weight from neuron A to neuron B
# I_A is the bias applied to neuron A
if self.model == 'CBG':
self.invTau = 1./0.080
self.invTauSmall = 1./0.005
self.W_BG_Th = 0.18
self.W_BG_TRN = 0
self.W_FC_Th = 0.6
self.W_FC_TRN = 0.35
self.W_Th_FC = 0.6
self.W_Th_TRN = 0.35
self.W_TRN_Th = 0.35
self.W_TRN_Th_self = 0
self.I_Th = 0.1
elif self.model == 'customCBG':
if len(opt_params)<7:
print 'customBG : parameter list absent or incomplete.'
exit()
self.invTau = 1./0.080
self.invTauSmall = 1./0.005
self.W_BG_Th = opt_params[0]
self.W_FC_Th = opt_params[1]
self.W_FC_TRN = opt_params[2]
self.W_Th_FC = opt_params[3]
self.W_Th_TRN = opt_params[4]
self.W_TRN_Th = opt_params[5]
self.I_Th = opt_params[6]
elif self.model =='GPR':
self.invTau = 1./0.040
self.W_BG_Th = 1
self.W_BG_TRN= 0.2
self.W_FC_Th = 1
self.W_FC_TRN = 1
self.W_Th_FC = 1
self.W_Th_TRN = 1
self.W_TRN_Th = 0.4
self.W_TRN_Th_self = 0.125
self.I_Th = 0.
self.I_FC = 0.
self.I_TRN = 0.
else:
print 'paramInit(): ', self.model, ' model type unknown'
exit()
#-----------------------------------------
# updates the model state, integrating over timestep "dt" and salience input "salience",
# using the (very) basic Euler method.
# "BG_Input" : inhibitory input from the BG (from the GPi/SNr)
# the update for the CBG and CBGcustom is based on lPDS neurons
# the update for the GPR is based on leaky-integrator neurons
def stepCompute(self,dt,saliences,BG_Input):
#-----------------------------
if (self.model == 'CBG') or (self.model == 'customCBG'):
saturation = 2 # set it to 1 for the original model, use 2 to have sound contrast amplification scores
self.TRN = min(max(self.TRN + self.invTauSmall * ( self.W_FC_TRN * self.old_FC.sum()
+ self.W_Th_TRN * self.old_Th.sum()
- self.TRN
) * dt,0),saturation)
self.Th = numpy.minimum(
numpy.maximum(self.Th + self.invTauSmall * ( self.W_FC_Th * self.old_FC
- self.W_TRN_Th * self.old_TRN
- self.W_BG_Th * BG_Input
- self.Th + self.I_Th
) * dt,
numpy.zeros(self.NbChannels)),
numpy.ones(self.NbChannels)*saturation)
self.FC = numpy.minimum(
numpy.maximum(self.FC + self.invTau * ( self.W_Th_FC * self.old_Th
+ saliences
- self.FC
) * dt,
numpy.zeros(self.NbChannels)),
numpy.ones(self.NbChannels)*saturation)
self.old_TRN = self.TRN
self.old_Th = numpy.copy(self.Th)
self.old_FC = numpy.copy(self.FC)
#-----------------------------
elif self.model =='GPR':
# Computation of tau da/dt = I - a
sumTRN = self.old_TRN.sum()
self.Th = self.Th + self.invTau * ( self.W_FC_Th * self.old_FC
- self.W_TRN_Th * sumTRN
- (self.W_TRN_Th_self - self.W_TRN_Th) * self.old_TRN
- self.W_BG_Th * BG_Input
- self.Th
) * dt
self.FC = self.FC + self.invTau * ( self.W_Th_FC * self.old_Th
+ saliences
- self.FC
) * dt
self.TRN = self.TRN + self.invTau * ( self.W_FC_TRN * self.old_FC
+ self.W_Th_TRN * self.old_Th
- self.W_BG_TRN * BG_Input
- self.TRN
) * dt
# Computation of y=f(a)
self.old_Th = numpy.minimum(
numpy.maximum( self.Th + numpy.ones(self.NbChannels) * self.I_Th,
numpy.zeros(self.NbChannels)
),
numpy.ones(self.NbChannels))
self.old_FC = numpy.minimum(
numpy.maximum( self.FC + numpy.ones(self.NbChannels) * self.I_FC,
numpy.zeros(self.NbChannels)
),
numpy.ones(self.NbChannels))
self.old_TRN = numpy.minimum(
numpy.maximum( self.TRN + numpy.ones(self.NbChannels) * self.I_TRN,
numpy.zeros(self.NbChannels)
),
numpy.ones(self.NbChannels))
#-----------------------------
else:
print 'paramInit(): ', self.model, ' model type unknown'
#-----------------------------------------
def readFC(self):
return self.FC
#-----------------------------------------
def logAll(self):
# logs the internal state of the module
# easily visualized with gnuplot : splot 'log/BG' matriw with lines
self.f.writelines(str(self.old_TRN)+' ')
self.f.writelines(' '.join([str(self.old_Th[i]) for i in range(self.NbChannels)])+' ')
self.f.writelines(' '.join([str(self.old_FC[i]) for i in range(self.NbChannels)])+'\n')
#---------------------------
def main():
dt = 0.001
THFC = thalamusFC('CBG',6)
saliences = numpy.zeros((6))
saliences[0] = 0.4
BG_Input = numpy.zeros((6))
for t in range(200):
THFC.stepCompute(dt,saliences,BG_Input)
THFC.logAll()
#---------------------------
if __name__ == '__main__':
# Import Psyco if available
try:
import psyco
psyco.log()
psyco.profile()
psyco.full()
except ImportError:
print 'Psyco not available.'
main()