def __init__(self, # Constructor arguments for FDRSpatial and FDRTemporal are # picked up automatically. There is no need to add them anywhere # in CLARegion, unless you need to do something special with them. # See docstring above. # These args are used by CLARegion only or need special handling disableSpatial=False, disableTemporal=False, orColumnOutputs=False, nCellsPerCol=1, trainingStep = 'temporal', cellsSavePath='', statelessMode=False, storeDenseOutput=False, #DEPRECATED outputCloningWidth=0, outputCloningHeight=0, saveMasterCoincImages = 0, temporalImp='py', #'py', 'simple' or 'cpp' spatialImp=getDefaultSPImp(), #'py', 'cpp', or 'oldpy' computeTopDown = 0, nMultiStepPrediction = 0, # We have separate seeds for spatial and temporal spSeed=-1, tpSeed=-1, # Needed for vision framework bottomUpOut=None, **kwargs): #if disableSpatial and disableTemporal: # raise RuntimeError("Disable both the spatial and temporal components? " # "That would make it too easy.") # Make sure our tuple arguments are integers for name in ['coincidencesShape', 'inputShape']: if name in kwargs: (height, width) = kwargs[name] kwargs[name] = (int(height), int(width)) # Which FDR Temporal implementation? FDRCSpatialClass = getSPClass(spatialImp) FDRTemporalClass = _getTPClass(temporalImp) # Pull out the spatial and temporal arguments automatically # These calls whittle down kwargs and create instance variables of CLARegion sArgTuples = _buildArgs(FDRCSpatialClass.__init__, self, kwargs) tArgTuples = _buildArgs(FDRTemporalClass.__init__, self, kwargs) # Make a list of automatic spatial and temporal arg names for later use self._spatialArgNames = [t[0] for t in sArgTuples] self._temporalArgNames = [t[0] for t in tArgTuples] # Start out in stage learn self.learningMode = True self.inferenceMode = False PyRegion.__init__(self, **kwargs) # Initialize all non-persistent base members, as well as give # derived class an opportunity to do the same. self._loaded = False self._initialize() # Debugging support, used in _conditionalBreak self.breakPdb = False self.breakKomodo = False # CLARegion only, or special handling self.disableSpatial = disableSpatial self.saveMasterCoincImages = saveMasterCoincImages self.disableTemporal = disableTemporal self.orColumnOutputs = orColumnOutputs self.nCellsPerCol = nCellsPerCol # Modified in initInNetwork self.coincidenceCount = self.coincidencesShape[0] * self.coincidencesShape[1] self.temporalImp = temporalImp self.spatialImp = spatialImp self.computeTopDown = computeTopDown self.nMultiStepPrediction = nMultiStepPrediction # Handle -1 for cloning sizes, which essentially just means no cloning... # ...also handle 0, since that's the new default... if outputCloningWidth in (0, -1): outputCloningWidth = self.coincidencesShape[1] if outputCloningHeight in (0, -1): outputCloningHeight = self.coincidencesShape[0] self.outputCloningWidth = outputCloningWidth self.outputCloningHeight = outputCloningHeight # Make the clone map, which is used by both spatial and temporal components. self._cloneMap, self._numCloneMasters = self.makeCloneMap( self.coincidencesShape, outputCloningWidth, outputCloningHeight ) # Both FDRCSpatial and FDRTemporal self.tpSeed = tpSeed self.spSeed = spSeed self.trainingStep = trainingStep self.logPathSPInput = '' self.logPathSP = '' self.logPathSPDense = '' self.logPathTP = '' # Used to save TP cells data structure to auxiliary file self.cellsSavePath = cellsSavePath # Instructs node to ignore past temporal state when operating in # inference mode; i.e., tells node to ignore the actual resetSignal # input and treat it as if the resetSignal was *always* set (in # inference mode only) self.statelessMode = statelessMode self._hasRunInference = False # Variables set up in initInNetwork() self._sfdr = None # FDRCSpatial instance self._tfdr = None # FDRTemporal instance self._numOutputs = None # Number of outputs allocated per node self._spatialPoolerOutput = None # Hang on to this output for debugging self._tpSeqOutput = None # Hang on to this for supporting the # tpSeqOutputNonZeros parameter self._spatialPoolerInput = None # Hang on to this for supporting the # spInputNonZeros parameter self._rfOutput = None # Hang on to this for supporting the # tpOutputNonZeros parameter # Read-only node parameters self.activeOutputCount = None self.cppOutput = None self.file = None # For inspector usage #from dbgp.client import brk; brk(port=9019) self._spatialSpec, self._temporalSpec, self._otherSpec = \ _getAdditionalSpecs(spatialImp=self.spatialImp, temporalImp=self.temporalImp)
def _getAdditionalSpecs(spatialImp, temporalImp, kwargs={}): """Build the additional specs in three groups (for the inspector) Use the type of the default argument to set the Spec type, defaulting to 'Byte' for None and complex types Determines the spatial parameters based on the selected implementation. It defaults to FDRCSpatial. Determines the temporal parameters based on the temporalImp """ typeNames = {int: 'UInt32', float: 'Real32', str: 'Byte', bool: 'bool', tuple: 'tuple'} def getArgType(arg): t = typeNames.get(type(arg), 'Byte') count = 0 if t == 'Byte' else 1 if t == 'tuple': t = typeNames.get(type(arg[0]), 'Byte') count = len(arg) if t == 'bool': t = 'UInt32' return (t, count) def getConstraints(arg): t = typeNames.get(type(arg), 'Byte') if t == 'Byte': return 'multiple' elif t == 'bool': return 'bool' else: return '' FDRSpatialClass = getSPClass(spatialImp) FDRTemporalClass = _getTPClass(temporalImp) spatialSpec = {} sArgTuples = _buildArgs(FDRSpatialClass.__init__) tArgTuples = _buildArgs(FDRTemporalClass.__init__) for argTuple in sArgTuples: d = dict( description=argTuple[1], accessMode='ReadWrite', dataType=getArgType(argTuple[2])[0], count=getArgType(argTuple[2])[1], constraints=getConstraints(argTuple[2])) spatialSpec[argTuple[0]] = d temporalSpec = {} for argTuple in tArgTuples: d = dict( description=argTuple[1], accessMode='ReadWrite', dataType=getArgType(argTuple[2])[0], count=getArgType(argTuple[2])[1], constraints=getConstraints(argTuple[2])) temporalSpec[argTuple[0]] = d # Add special parameters that weren't handled automatically # Spatial parameters only! spatialSpec.update(dict( disableSpatial=dict( description='Disable the spatial FDR (become a temporal nregion)', accessMode='ReadWrite', dataType='UInt32', count=1, constraints='bool'), coincidenceCount=dict( description='Total number of coincidences.', accessMode='Read', dataType='UInt32', count=1, constraints=''), spInputNonZeros=dict( description='The indices of the non-zero inputs to the spatial pooler', accessMode='Read', dataType='UInt32', count=0, constraints=''), spOutputNonZeros=dict( description='The indices of the non-zero outputs from the spatial pooler', accessMode='Read', dataType='UInt32', count=0, constraints=''), spOverlapDistribution=dict( description="""The overlaps between the active output coincidences and the input. The overlap amounts for each coincidence are sorted from highest to lowest. """, accessMode='Read', dataType='Real32', count=0, constraints=''), sparseCoincidenceMatrix=dict( description='The coincidences, as a SparseMatrix', accessMode='Read', dataType='Byte', count=0, constraints=''), spatialPoolerInput=dict( description='Input to the spatial pooler.', accessMode='Read', dataType='Real32', count=0, constraints=''), spatialPoolerOutput=dict( description='Output of the spatial pooler.', accessMode='Read', dataType='Real32', count=0, constraints=''), spNumActiveOutputs=dict( description='Number of active spatial pooler outputs', accessMode='Read', dataType='UInt32', count=1, constraints=''), denseOutput=dict( description='Score for each coincidence.', accessMode='Read', dataType='Real32', count=0, constraints=''), outputCloningWidth=dict( description="""The number of columns you'd have to move horizontally (or vertically) before you get back to the same the same clone that you started with.""", accessMode='Read', dataType='UInt32', count=1, constraints=''), outputCloningHeight=dict( description="""If non-negative, can be used to make rectangular (instead of square) cloning fields.""", accessMode='Read', dataType='UInt32', count=1, constraints=''), saveMasterCoincImages=dict( description="""If non-zero, saves an image of the master coincidences every N iterations.""", accessMode='Read', dataType='UInt32', count=1, constraints='', defaultValue=0), spLearningStatsStr=dict( description="""String representation of dictionary containing a number of statistics related to learning.""", accessMode='Read', dataType='Byte', count=0, constraints='handle'), )) # Add temporal parameters that weren't handled automatically temporalSpec.update(dict( disableTemporal=dict( description='Disable the temporal FDR (become a spatial region)', accessMode='Read', dataType='UInt32', count=1, constraints='bool'), orColumnOutputs=dict( description="""OR together the cell outputs from each column to produce the temporal pooler output. When this mode is enabled, the number of cells per column must also be specified (via the 'nCellsPerCol' creation parameter) and the output size of the node should be set the same as the number of spatial pooler coincidences ('coincidenceCount')""", accessMode='Read', dataType='UInt32', count=1, constraints='bool'), nCellsPerCol=dict( description="""The number of cells, or states, allocated per column (the number of columns is the same as the number of coincidences).""", accessMode='Read', dataType='UInt32', count=1, constraints=''), maxSegmentsPerCell=dict( description='Max allowed number of segments per cellf.', accessMode='ReadWrite', dataType='Int32', count=1, constraints=''), maxSynapsesPerSegment=dict( description='Max allowed number of segments per cellf.', accessMode='ReadWrite', dataType='Int32', count=1, constraints=''), tpOutputNonZeros=dict( description='The indices of the non-zero outputs from the temporal pooler', accessMode='Read', dataType='UInt32', count=0, constraints=''), tpNumSynapses=dict( description='Total number of synapses learned in the temporal pooler.', accessMode='Read', dataType='UInt32', count=1, constraints=''), tpNumSynapsesPerSegmentMax=dict( description='Max number of synapses found in any one dendritic segment of the temporal pooler.', accessMode='Read', dataType='UInt32', count=1, constraints=''), tpNumSynapsesPerSegmentAvg=dict( description='Average number of synapses learned per dendritic segment.', accessMode='Read', dataType='Real32', count=1, constraints=''), tpNumSegments=dict( description='Total number of dendritic segments present in the temporal pooler.', accessMode='Read', dataType='UInt32', count=1, constraints=''), tpNumCells=dict( description='Total number of cells present in the temporal pooler.', accessMode='Read', dataType='UInt32', count=1, constraints=''), tpNumActiveCells=dict( description='Total number of active cells in the temporal pooler output.', accessMode='Read', dataType='UInt32', count=1, constraints=''), tpNumActiveColumns=dict( description='Total number of active columns in the temporal pooler output.', accessMode='Read', dataType='UInt32', count=1, constraints=''), tpNumBurstingColumns=dict( description='Total number of bursting columns in the temporal pooler output.', accessMode='Read', dataType='UInt32', count=1, constraints=''), )) # The last group is for parameters that aren't strictly spatial or temporal otherSpec = dict( learningMode=dict( description='1 if the node is learning (default 1).', accessMode='ReadWrite', dataType='UInt32', count=1, constraints='bool'), trainingStep=dict( description="""Controls which pooler is trained when learningMode is true. Set to 'spatial' to train spatial pooler, 'temporal' to train temporal pooler, or 'both' to train both simultaneously.""", accessMode='ReadWrite', dataType='Byte', count=0, constraints='enum: spatial,temporal,both'), inferenceMode=dict( description='1 if the node is inferring (default 0).', accessMode='ReadWrite', dataType='UInt32', count=1, constraints='bool'), activeOutputCount=dict( description='Number of active elements in bottomUpOut output.', accessMode='Read', dataType='UInt32', count=1, constraints=''), spSeed=dict( description='Random seed for the spatial pooler.', accessMode='Read', dataType='UInt32', count=1, constraints=''), tpSeed=dict( description='Random seed for the temporal pooler.', accessMode='Read', dataType='UInt32', count=1, constraints=''), logPathSPInput=dict( description='Optional name of spatial pooler input log file.', accessMode='ReadWrite', dataType='Byte', count=0, constraints=''), logPathSP=dict( description='Optional name of spatial pooler output log file.', accessMode='ReadWrite', dataType='Byte', count=0, constraints=''), logPathSPDense=dict( description='Optional name of spatial pooler dense output log file.', accessMode='ReadWrite', dataType='Byte', count=0, constraints=''), logPathTP=dict( description='Optional name of temporal pooler output log file.', accessMode='ReadWrite', dataType='Byte', count=0, constraints=''), cellsSavePath=dict( description="""Optional path to file in which large temporal pooler cells data structure is to be saved.""", accessMode='ReadWrite', dataType='Byte', count=0, constraints=''), statelessMode=dict( description='Ignores temporal state when in inference mode.', accessMode='ReadWrite', dataType='UInt32', count=1, constraints='bool'), temporalImp=dict( description="""Which temporal pooler implementation to use. Set to either 'simple', 'py' or 'cpp'. The 'simple' implementation supports only 1 cell per column and is typically only used for vision spatial invariance applications. The 'cpp' implementation is optimized for speed in C++. The 'trivial' implementation makes random or zeroth order predictions.""", accessMode='ReadWrite', dataType='Byte', count=0, constraints='enum: simple, full, cpp, trivial'), computeTopDown=dict( description='1 to compute and output the topDownOut output', accessMode='ReadWrite', dataType='UInt32', count=1, constraints='bool'), nMultiStepPrediction=dict( description="""The number of time steps to be predicted in future.""", accessMode='ReadWrite', dataType='UInt32', count=1, constraints=''), ) return spatialSpec, temporalSpec, otherSpec