Package topo :: Package sheet :: Module slissom
[hide private]
[frames] | no frames]

Source Code for Module topo.sheet.slissom

  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   
24 -class SLISSOM(LISSOM):
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 # configurable parameters 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 # logging facility for debugging 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 # matrices and vectors for internal use 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
69 - def __init__(self,**params):
70 """ 71 SLISSOM-specific init, where dynamic threshold stuff 72 gets initialized. 73 """ 74 super(SLISSOM,self).__init__(**params) 75 self.dynamic_threshold = \ 76 Numeric.zeros(self.activity.shape).astype(activity_type) 77 self.spike = Numeric.zeros(self.activity.shape) 78 self.spike_history = Numeric.zeros(self.activity.shape) 79 self.membrane_potential = \ 80 Numeric.zeros(self.activity.shape).astype(activity_type) 81 82 num_traces = len(self.trace_coords) 83 self.membrane_potential_trace = \ 84 Numeric.zeros((num_traces,self.trace_n)).astype(activity_type)
85
86 - def activate(self):
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 # Add noise, based on the noise_rate. 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 # Thresholding: baseline + dynamic threshold + absolute refractory 110 # period 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 # Calculate membrane potential 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 # set absolute refractory period for "next" timestep 125 # (hence the "-1") 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 # Append spike to the membrane potential 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
138 - def input_event(self,conn,data):
139 """ 140 SLISSOM-specific input_event handeling: 141 On a new afferent input, DO NOT clear the activity matrix unless 142 reset_on_new_iteration is True. 143 """ 144 if self.new_iteration and self.reset_on_new_iteration: 145 self.new_iteration = False 146 self.activity *= 0.0 147 for proj in self.in_connections: 148 proj.activity *= 0.0 149 self.mask.reset() 150 super(LISSOM,self).input_event(conn,data)
151
152 - def plot_trace(self):
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
163 - def vectorplot_trace(self):
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
171 - def matrixplot_trace(self):
172 """ 173 Matrixplot membrane potential trace of the unit designated by the 174 trace_coords list. 175 """ 176 matrixplot(self.membrane_potential_trace,aspect=40)
177
178 - def _update_trace(self):
179 """ 180 Update membrane potential trace for sheet coordinate (x,y). 181 """ 182 183 trace_id=0 184 185 for coord in self.trace_coords: 186 (trace_r, trace_c) = self.sheet2matrix(coord[0],coord[1]) 187 self.membrane_potential_trace[trace_id][self.trace_count]=\ 188 self.membrane_potential[trace_r,trace_c] 189 trace_id += 1 190 191 self.trace_count = (self.trace_count+1)%self.trace_n
192