예제 #1
0
  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)
예제 #2
0
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