Package topo :: Package projections :: Module basic
[hide private]
[frames] | no frames]

Source Code for Module topo.projections.basic

  1  """ 
  2  Repository for the basic Projection types, without any special 
  3  dependencies or requirements. 
  4   
  5  $Id: basic.py 8029 2008-02-19 15:16:24Z ceball $ 
  6  """ 
  7   
  8  __version__ = "$Revision: 8029 $" 
  9   
 10   
 11  from numpy import exp,ones,zeros,array,nonzero 
 12   
 13  # So all Projections are present in this package 
 14  from topo.base.projection import Projection 
 15  from topo.base.boundingregion import BoundingBox 
 16  from topo.base.sheet import activity_type 
 17  from topo.base.cf import CFProjection,ConnectionField,MaskedCFIter,\ 
 18       CFPLearningFn,CFPLF_Identity,CFPOutputFn 
 19  from topo.base.parameterclasses import Number,ClassSelectorParameter 
 20  from topo.base.patterngenerator import PatternGenerator,Constant 
 21  from topo.base.functionfamilies import CoordinateMapperFn,IdentityMF 
 22   
 23  from topo.misc.utils import rowcol2idx 
 24   
 25  from topo.outputfns.basic import OutputFn,IdentityOF 
 26  from topo.learningfns.basic import LearningFn,IdentityLF 
 27   
 28   
29 -class CFPOF_SharedWeight(CFPOutputFn):
30 """ 31 CFPOutputFn for use with SharedWeightCFProjections. 32 33 Applies the single_cf_fn to the single shared CF's weights. 34 """ 35 single_cf_fn = ClassSelectorParameter(OutputFn,default=IdentityOF()) 36
37 - def __call__(self, cfs, output_activity, norm_values=None, **params):
38 """Apply the specified single_cf_fn to every CF.""" 39 if type(self.single_cf_fn) is not IdentityOF: 40 cf = cfs[0][0] 41 self.single_cf_fn(cf.weights)
42 43 44
45 -class SharedWeightCF(ConnectionField):
46 47 # JAHACKALERT: This implementation copies some of the CEBHACKALERTS 48 # of the ConnectionField.__init__ function from which it is dervied
49 - def __init__(self,cf,input_sheet,x=0.0,y=0.0,bounds_template=BoundingBox(radius=0.1)):
50 """ 51 From an existing copy of ConnectionField (CF) that acts as a 52 template, create a new CF that shares weights with the 53 template CF. Copies all the properties of CF to stay 54 identical except the weights variable that actually contains 55 the data. 56 57 The only difference from a normal CF is that the weights of 58 the CF are implemented as a numpy view into the single master 59 copy of the weights stored in the CF template. 60 """ 61 self.x = x; self.y = y 62 self.input_sheet = input_sheet 63 64 # must be called to setup the input_sheet_slice 65 self.create_input_sheet_slice(bounds=bounds_template) 66 67 # must be called to setup the weights slice for this x,y 68 self.create_weights_slice(bounds=bounds_template) 69 70 self.weights = self.weights_slice.submatrix(cf.weights)
71 72 # JAHACKALERT the OutputFn cannot be applied in SharedWeightCF 73 # - another inconsistency in the class tree design - there 74 # should be nothing in the parent class that is ignored in its 75 # children. Probably need to extract some functionality of 76 # ConnectionField into a shared abstract parent class. 77 # We have agreed to make this right by adding a constant property that 78 # will be set true if the learning should be active 79 # The SharedWeightCFProjection class and its anccestors will 80 # have this property set to false which means that the 81 # learning will be deactivated 82 83 84
85 -class SharedWeightCFProjection(CFProjection):
86 """ 87 A Projection with a single set of weights, shared by all units. 88 89 Otherwise similar to CFProjection, except that learning is 90 currently disabled. 91 """ 92 93 ### JABHACKALERT: Set to be constant as a clue that learning won't 94 ### actually work yet, but we could certainly extend it to support 95 ### learning if desired, e.g. to learn position-independent responses. 96 learning_fn = ClassSelectorParameter(CFPLearningFn,CFPLF_Identity(),constant=True) 97 output_fn = ClassSelectorParameter(OutputFn,default=IdentityOF()) 98 weights_output_fn = ClassSelectorParameter( 99 CFPOutputFn,default=CFPOF_SharedWeight()) 100 101
102 - def __init__(self,**params):
103 """ 104 Initialize the Projection with a single cf_type object 105 (typically a ConnectionField), 106 """ 107 # We don't want the whole set of cfs initialized, but we 108 # do want anything that CFProjection defines. 109 super(SharedWeightCFProjection,self).__init__(initialize_cfs=False,**params) 110 111 # We want the sharedcf to be located on the grid, so 112 # pick a central unit and use its center 113 self.__sharedcf=self.cf_type(self.src, 114 self.center_unitxcenter, 115 self.center_unitycenter, 116 self.bounds_template, 117 self.weights_generator, 118 self.mask_template, 119 self.weights_output_fn.single_cf_fn) 120 121 cflist = [] 122 scf = self.__sharedcf 123 bounds_template = self.bounds_template 124 for y in self.dest.sheet_rows()[::-1]: 125 row = [] 126 for x in self.dest.sheet_cols(): 127 cf = SharedWeightCF(scf,self.src,x,y,bounds_template) 128 row.append(cf) 129 cflist.append(row) 130 self._cfs = cflist
131
132 - def change_bounds(self, nominal_bounds_template):
133 """ 134 Change the bounding box for all of the ConnectionFields in this Projection. 135 136 Not yet implemented. 137 """ 138 raise NotImplementedError
139 140
141 - def change_density(self, new_wt_density):
142 """ 143 Rescales the weight matrix in place, interpolating or resampling as needed. 144 145 Not yet implemented. 146 """ 147 raise NotImplementedError
148 149
150 - def learn(self):
151 """ 152 Because of how output functions are applied, it is not currently 153 possible to use learning functions and output functions for 154 SharedWeightCFProjections, so we disable them here. 155 """ 156 pass
157 158
159 - def apply_learn_output_fn(self,mask):
160 """ 161 Because of how output functions are applied, it is not currently 162 possible to use learning functions and output functions for 163 SharedWeightCFProjections, so we disable them here. 164 """ 165 pass
166 167 168
169 -class LeakyCFProjection(CFProjection):
170 """ 171 A projection that has a decay_rate parameter so that incoming 172 input is decayed over time as x(t) = input + x(t-1)*exp(-decay_rate), 173 and then the weighted sum of x(t) is calculated. 174 """ 175 176 decay_rate = Number(default=1.0,bounds=(0,None), 177 doc="Input decay rate for each leaky synapse") 178
179 - def __init__(self,**params):
180 super(LeakyCFProjection,self).__init__(**params) 181 self.leaky_input_buffer = zeros(self.src.activity.shape)
182
183 - def activate(self,input_activity):
184 """ 185 Retain input_activity from the previous step in leaky_input_buffer 186 and add a leaked version of it to the current input_activity. This 187 function needs to deal with a finer time-scale. 188 """ 189 self.leaky_input_buffer = input_activity + self.leaky_input_buffer*exp(-self.decay_rate) 190 super(LeakyCFProjection,self).activate(self.leaky_input_buffer)
191 192 193
194 -class ScaledCFProjection(CFProjection):
195 """ 196 Allows scaling of activity based on a specified target average activity. 197 198 An exponentially weighted average is used to calculate the average 199 activity. This average is then used to calculate scaling factors 200 for the current activity and for the learning rate. 201 202 The plastic parameter can be used to turn off updating of the average 203 activity, e.g. during map measurement. 204 """ 205 206 target = Number(default=0.045, doc="""Target average activity for the projection.""") 207 208 target_lr = Number(default=0.045, doc=""" 209 Target average activity for scaling the learning rate.""") 210 211