1 """
2 The SLISSOM class.
3
4 $Id: slissom.py 11111 2010-07-05 10:53:13Z ceball $
5 """
6 __version__='$Revision: 11111 $'
7
8 from math import exp
9
10 import numpy.oldnumeric as Numeric
11 import numpy.oldnumeric.random_array as RandomArray
12
13 import param
14
15 from topo.command.pylabplot import vectorplot, matrixplot
16
17 from lissom import LISSOM
18
19
20
21
22 activity_type = Numeric.Float32
23
25 """
26 A Sheet class implementing the SLISSOM algorithm
27 (Choe and Miikkulainen, Neurocomputing 21:139-157, 1998).
28
29 A SLISSOM sheet is a LISSOM sheet extended to include spiking
30 neurons using dynamic synapses.
31 """
32
33
34 threshold = param.Number(default=0.3,bounds=(0,None), doc="Baseline threshold")
35
36 threshold_decay_rate = param.Number(default=0.01,bounds=(0,None),
37 doc="Dynamic threshold decay rate")
38
39 absolute_refractory = param.Number(default=1.0,bounds=(0,None),
40 doc="Absolute refractory period")
41
42 dynamic_threshold_init = param.Number(default=2.0,bounds=(0,None),
43 doc="Initial value for dynamic threshold when spike occurs")
44
45 spike_amplitude = param.Number(default=1.0,bounds=(0,None),
46 doc="Amplitude of spike at the moment of spiking")
47
48 reset_on_new_iteration = param.Boolean(default=False,
49 doc="Reset activity and projection activity when new iteration starts")
50
51 noise_rate = param.Number(default=0.0,bounds=(0,1.0),
52 doc="Noise added to the on-going activity")
53
54
55 trace_coords = param.List(default=[],
56 doc="List of coord(s) of membrane potential(s) to track over time")
57
58 trace_n = param.Number(default=400,bounds=(1,None),
59 doc="Number of steps to track neuron's membrane potential")
60
61
62 dynamic_threshold = None
63 spike = None
64 spike_history= None
65 membrane_potential = None
66 membrane_potential_trace = None
67 trace_count = 0
68
85
87 """
88 For now, this is the same as the parent's activate(), plus
89 fixed+dynamic thresholding. Overloading was necessary to
90 avoid self.send_output() being invoked before thresholding.
91 This function also updates and maintains internal values such as
92 membrane_potential, spike, etc.
93 """
94
95 self.activity *= 0.0
96
97 for proj in self.in_connections:
98 self.activity += proj.activity
99
100 if self.apply_output_fns:
101 for of in self.output_fns:
102 of(self.activity)
103
104
105 if self.noise_rate > 0.0:
106 self.activity = self.activity * (1.0-self.noise_rate) \
107 + RandomArray.random(self.activity.shape) * self.noise_rate
108
109
110
111 rows,cols = self.activity.shape
112
113 for r in xrange(rows):
114 for c in xrange(cols):
115
116 thresh = self.threshold + self.dynamic_threshold[r,c]
117
118
119 self.membrane_potential[r,c] = self.activity[r,c] - thresh
120
121 if (self.activity[r,c] > thresh and self.spike_history[r,c]<=0):
122 self.activity[r,c] = self.spike_amplitude
123 self.dynamic_threshold[r,c] = self.dynamic_threshold_init
124
125
126 self.spike_history[r,c] = self.absolute_refractory-1.0
127 else:
128 self.activity[r,c] = 0.0
129 self.dynamic_threshold[r,c] = self.dynamic_threshold[r,c] * exp(-(self.threshold_decay_rate))
130 self.spike_history[r,c] -= 1.0
131
132
133 self.membrane_potential[r,c] += self.activity[r,c]
134
135 self._update_trace()
136 self.send_output(src_port='Activity',data=self.activity)
137
151
153 """
154 Plot membrane potential trace of the unit designated by the
155 trace_coords list. This plot has trace_n data points.
156 """
157 trace_offset=0
158 for trace in self.membrane_potential_trace:
159 vectorplot(trace+trace_offset,style="b-")
160 vectorplot(trace+trace_offset,style="rx")
161 trace_offset += 3
162
164 """
165 Plot membrane potential trace of the unit designated by the
166 trace_coords list. This plot has trace_n data points.
167 This method simply calls plot_trace().
168 """
169 self.plot_trace()
170
177
192