def experiment(numColumns, sampleSize):
  locationSDRsByColumn = [dict((name,
                                set(random.sample(xrange(1024), 40)))
                               for name in LOCATIONS)
                          for _ in xrange(numColumns)]

  featureSDRsByColumn = [dict((name,
                               set(random.sample(xrange(1024), 40)))
                              for name in FEATURES)
                         for _ in xrange(numColumns)]

  exp = L4L2Experiment(
    "Hello",
    numCorticalColumns=numColumns,
    L2Overrides={
      "sampleSizeDistal": sampleSize,
    },
    seed=random.randint(2048, 4096)
  )

  exp.learnObjects(dict((objectName,
                         [dict((column,
                                (locationSDRsByColumn[column][location],
                                 featureSDRsByColumn[column][features[location]]))
                               for column in xrange(numColumns))
                          for location in LOCATIONS])
                        for objectName, features in OBJECTS.iteritems()))

  objectName = "Object 1"
  features = OBJECTS[objectName]
  inferredL2 = exp.objectL2Representations[objectName]

  touchCount = 0

  for sensorPositions in greedySensorPositions(numColumns, len(LOCATIONS)):
    sensation = dict(
      (column,
       (locationSDRsByColumn[column][sensorPositions[column]],
        featureSDRsByColumn[column][features[sensorPositions[column]]]))
      for column in xrange(numColumns))
    exp.infer([sensation]*TIMESTEPS_PER_SENSATION,
              reset=False, objectName=objectName)

    touchCount += 1

    if exp.getL2Representations() == inferredL2:
      print "Inferred object after %d touches" % touchCount
      return touchCount

    if touchCount >= 60:
      print "Never inferred object"
      return None
Example #2
0
def experiment(numColumns, sampleSize):
    locationSDRsByColumn = [
        dict((name, set(random.sample(xrange(1024), 40)))
             for name in LOCATIONS) for _ in xrange(numColumns)
    ]

    featureSDRsByColumn = [
        dict((name, set(random.sample(xrange(1024), 40))) for name in FEATURES)
        for _ in xrange(numColumns)
    ]

    exp = L4L2Experiment("Hello",
                         numCorticalColumns=numColumns,
                         L2Overrides={
                             "sampleSizeDistal": sampleSize,
                         },
                         seed=random.randint(2048, 4096))

    exp.learnObjects(
        dict((objectName, [
            dict((column, (locationSDRsByColumn[column][location],
                           featureSDRsByColumn[column][features[location]]))
                 for column in xrange(numColumns)) for location in LOCATIONS
        ]) for objectName, features in OBJECTS.iteritems()))

    objectName = "Object 1"
    features = OBJECTS[objectName]
    inferredL2 = exp.objectL2Representations[objectName]

    touchCount = 0

    for sensorPositions in greedySensorPositions(numColumns, len(LOCATIONS)):
        sensation = dict(
            (column,
             (locationSDRsByColumn[column][sensorPositions[column]],
              featureSDRsByColumn[column][features[sensorPositions[column]]]))
            for column in xrange(numColumns))
        exp.infer([sensation] * TIMESTEPS_PER_SENSATION,
                  reset=False,
                  objectName=objectName)

        touchCount += 1

        if exp.getL2Representations() == inferredL2:
            print "Inferred object after %d touches" % touchCount
            return touchCount

        if touchCount >= 60:
            print "Never inferred object"
            return None
Example #3
0
def doExperiment(numColumns, l2Overrides, objectDescriptions, noiseMu,
                 noiseSigma, numInitialTraversals, noiseEverywhere):
    """
  Touch every point on an object 'numInitialTraversals' times, then evaluate
  whether it has inferred the object by touching every point once more and
  checking the number of correctly active and incorrectly active cells.

  @param numColumns (int)
  The number of sensors to use

  @param l2Overrides (dict)
  Parameters for the ColumnPooler

  @param objectDescriptions (dict)
  A mapping of object names to their feature-locations.
  See 'createRandomObjectDescriptions'.

  @param noiseMu (float)
  The average amount of noise in a feedforward input. The noise level for each
  column's input is determined once per touch. It is a gaussian distribution
  with mean 'noiseMu' and sigma 'noiseSigma'.

  @param noiseSigma (float)
  The sigma for the gaussian distribution of noise levels. If the noiseSigma is
  0, then the noise level will always be 'noiseMu'.

  @param numInitialTraversals (int)
  The number of times to traverse the object before testing whether the object
  has been inferred.

  @param noiseEverywhere (bool)
  If true, add noise to every column's input, and record accuracy of every
  column. If false, add noise to one column's input, and only record accuracy
  of that column.
  """

    # For each column, keep a mapping from feature-location names to their SDRs
    layer4sdr = lambda: np.array(
        sorted(random.sample(xrange(L4_CELL_COUNT), 40)), dtype="uint32")
    featureLocationSDRs = [defaultdict(layer4sdr) for _ in xrange(numColumns)]

    params = {
        "inputWidth": L4_CELL_COUNT,
        "lateralInputWidths": [4096] * (numColumns - 1),
        "seed": random.randint(0, 1024)
    }
    params.update(l2Overrides)

    l2Columns = [ColumnPooler(**params) for _ in xrange(numColumns)]

    # Learn the objects
    objectL2Representations = {}
    for objectName, featureLocations in objectDescriptions.iteritems():
        for featureLocationName in featureLocations:
            # Touch it enough times for the distal synapses to reach the
            # connected permanence, and then once more.
            for _ in xrange(4):
                allLateralInputs = [l2.getActiveCells() for l2 in l2Columns]
                for columnNumber, l2 in enumerate(l2Columns):
                    feedforwardInput = featureLocationSDRs[columnNumber][
                        featureLocationName]
                    lateralInputs = [
                        lateralInput
                        for i, lateralInput in enumerate(allLateralInputs)
                        if i != columnNumber
                    ]
                    l2.compute(feedforwardInput, lateralInputs, learn=True)
        objectL2Representations[objectName] = [
            set(l2.getActiveCells()) for l2 in l2Columns
        ]
        for l2 in l2Columns:
            l2.reset()

    results = []

    # Try to infer the objects
    for objectName, featureLocations in objectDescriptions.iteritems():
        for l2 in l2Columns:
            l2.reset()

        sensorPositionsIterator = greedySensorPositions(
            numColumns, len(featureLocations))

        # Touch each location at least numInitialTouches times, and then touch it
        # once more, testing it. For each traversal, touch each point on the object
        # ~once. Not once per sensor -- just once. So we translate the "number of
        # traversals" into a "number of touches" according to the number of sensors.
        numTouchesPerTraversal = len(featureLocations) / float(numColumns)
        numInitialTouches = int(
            math.ceil(numInitialTraversals * numTouchesPerTraversal))

        if noiseEverywhere:
            numTestTouches = int(math.ceil(1 * numTouchesPerTraversal))
        else:
            numTestTouches = len(featureLocations)

        for touch in xrange(numInitialTouches + numTestTouches):
            sensorPositions = next(sensorPositionsIterator)

            # Give the system a few timesteps to settle, allowing lateral connections
            # to cause cells to be inhibited.
            for _ in xrange(3):
                allLateralInputs = [l2.getActiveCells() for l2 in l2Columns]
                for columnNumber, l2 in enumerate(l2Columns):
                    position = sensorPositions[columnNumber]
                    featureLocationName = featureLocations[position]
                    feedforwardInput = featureLocationSDRs[columnNumber][
                        featureLocationName]

                    if noiseEverywhere or columnNumber == 0:
                        noiseLevel = random.gauss(noiseMu, noiseSigma)
                        noiseLevel = max(0.0, min(1.0, noiseLevel))
                        feedforwardInput = noisy(feedforwardInput, noiseLevel,
                                                 L4_CELL_COUNT)

                    lateralInputs = [
                        lateralInput
                        for i, lateralInput in enumerate(allLateralInputs)
                        if i != columnNumber
                    ]

                    l2.compute(feedforwardInput, lateralInputs, learn=False)

            if touch >= numInitialTouches:
                if noiseEverywhere:
                    for columnNumber, l2 in enumerate(l2Columns):
                        activeCells = set(l2.getActiveCells())
                        correctCells = objectL2Representations[objectName][
                            columnNumber]
                        results.append((len(activeCells & correctCells),
                                        len(activeCells - correctCells)))
                else:
                    activeCells = set(l2Columns[0].getActiveCells())
                    correctCells = objectL2Representations[objectName][0]
                    results.append((len(activeCells & correctCells),
                                    len(activeCells - correctCells)))

    return results
Example #4
0
def doExperiment(numColumns, l2Overrides, objectDescriptions, noiseMu,
                 noiseSigma, numInitialTraversals):
  """
  Touch every point on an object 'numInitialTraversals' times, then evaluate
  whether it has inferred the object by touching every point once more and
  checking the number of correctly active and incorrectly active cells.

  @param numColumns (int)
  The number of sensors to use

  @param l2Overrides (dict)
  Parameters for the ColumnPooler

  @param objectDescriptions (dict)
  A mapping of object names to their feature-locations.
  See 'createRandomObjectDescriptions'.

  @param noiseMu (float)
  The average amount of noise in a feedforward input. The noise level for each
  column's input is determined once per touch. It is a gaussian distribution
  with mean 'noiseMu' and sigma 'noiseSigma'.

  @param noiseSigma (float)
  The sigma for the gaussian distribution of noise levels. If the noiseSigma is
  0, then the noise level will always be 'noiseMu'.

  @param numInitialTraversals (int)
  The number of times to traverse the object before testing whether the object
  has been inferred.
  """

  # For each column, keep a mapping from feature-location names to their SDRs
  layer4sdr = lambda : set(random.sample(xrange(L4_CELL_COUNT), 40))
  featureLocationSDRs = [defaultdict(layer4sdr) for _ in xrange(numColumns)]

  params = {"inputWidth": L4_CELL_COUNT,
            "lateralInputWidths": [4096]*(numColumns-1),
            "seed": random.randint(0, 1024)}
  params.update(l2Overrides)

  l2Columns = [ColumnPooler(**params)
               for _ in xrange(numColumns)]

  # Learn the objects
  objectL2Representations = {}
  for objectName, featureLocations in  objectDescriptions.iteritems():
    for featureLocationName in featureLocations:
      # Touch it enough times for the distal synapses to reach the
      # connected permanence, and then once more.
      for _ in xrange(4):
        allLateralInputs = [l2.getActiveCells() for l2 in l2Columns]
        for columnNumber, l2 in enumerate(l2Columns):
          feedforwardInput = featureLocationSDRs[columnNumber][featureLocationName]
          lateralInputs = [lateralInput
                           for i, lateralInput in enumerate(allLateralInputs)
                           if i != columnNumber]
          l2.compute(feedforwardInput, lateralInputs, learn=True)
    objectL2Representations[objectName] = [set(l2.getActiveCells())
                                           for l2 in l2Columns]
    for l2 in l2Columns:
      l2.reset()

  results = []

  # Try to infer the objects
  for objectName, featureLocations in objectDescriptions.iteritems():
    for l2 in l2Columns:
      l2.reset()

    sensorPositionsIterator = greedySensorPositions(numColumns, len(featureLocations))

    # Touch each location at least numInitialTouches times, and then touch it
    # once more, testing it. For each traversal, touch each point on the object
    # ~once. Not once per sensor -- just once. So we translate the "number of
    # traversals" into a "number of touches" according to the number of sensors.
    numTouchesPerTraversal = len(featureLocations) / float(numColumns)
    numInitialTouches = int(math.ceil(numInitialTraversals * numTouchesPerTraversal))
    numTestTouches = int(math.ceil(1 * numTouchesPerTraversal))
    for touch in xrange(numInitialTouches + numTestTouches):
      sensorPositions = next(sensorPositionsIterator)

      # Give the system a few timesteps to settle, allowing lateral connections
      # to cause cells to be inhibited.
      for _ in xrange(3):
        allLateralInputs = [l2.getActiveCells() for l2 in l2Columns]
        for columnNumber, l2 in enumerate(l2Columns):
          noiseLevel = random.gauss(noiseMu, noiseSigma)
          noiseLevel = max(0.0, min(1.0, noiseLevel))

          position = sensorPositions[columnNumber]
          featureLocationName = featureLocations[position]
          feedforwardInput = featureLocationSDRs[columnNumber][featureLocationName]
          feedforwardInput = noisy(feedforwardInput, noiseLevel, L4_CELL_COUNT)

          lateralInputs = [lateralInput
                           for i, lateralInput in enumerate(allLateralInputs)
                           if i != columnNumber]

          l2.compute(feedforwardInput, lateralInputs, learn=False)

      if touch >= numInitialTouches:
        for columnNumber, l2 in enumerate(l2Columns):
          activeCells = set(l2.getActiveCells())
          correctCells = objectL2Representations[objectName][columnNumber]

          results.append((len(activeCells & correctCells),
                          len(activeCells - correctCells)))

  return results
def doExperiment(numColumns, objects, l2Overrides, noiseLevels, numInitialTraversals,
                 noisyFeature, noisyLocation):
  """
  Touch every point on an object 'numInitialTraversals' times, then evaluate
  whether it has inferred the object by touching every point once more and
  checking the number of correctly active and incorrectly active cells.

  @param numColumns (int)
  The number of sensors to use

  @param l2Overrides (dict)
  Parameters for the ColumnPooler

  @param objects (dict)
  A mapping of object names to their features.
  See 'createRandomObjects'.

  @param noiseLevels (list of floats)
  The noise levels to experiment with. The experiment is run once per noise
  level. Noise is applied at a constant rate to exactly one cortical column.
  It's applied to the same cortical column every time, and this is the cortical
  column that is measured.

  @param noisyFeature (bool)
  Whether to use a noisy feature

  @param noisyLocation (bool)
  Whether to use a noisy location
  """

  featureSDR = lambda : set(random.sample(xrange(NUM_L4_COLUMNS), 40))
  locationSDR = lambda : set(random.sample(xrange(1024), 40))

  featureSDRsByColumn = [defaultdict(featureSDR) for _ in xrange(numColumns)]
  locationSDRsByColumn = [defaultdict(locationSDR) for _ in xrange(numColumns)]

  exp = L4L2Experiment(
    "Experiment",
    numCorticalColumns=numColumns,
    inputSize=NUM_L4_COLUMNS,
    externalInputSize=1024,
    seed=random.randint(2048, 4096)
  )

  exp.learnObjects(
    dict((objectName,
          [dict((column,
                 (locationSDRsByColumn[column][location],
                  featureSDRsByColumn[column][features[location]]))
                for column in xrange(numColumns))
           for location in xrange(len(features))])
         for objectName, features in objects.iteritems()))

  results = defaultdict(list)

  for noiseLevel in noiseLevels:
    # Try to infer the objects
    for objectName, features in objects.iteritems():
      exp.sendReset()

      inferredL2 = exp.objectL2Representations[objectName]

      sensorPositionsIterator = greedySensorPositions(numColumns, len(features))

      # Touch each location at least numInitialTouches times, and then touch it
      # once more, testing it. For each traversal, touch each point on the object
      # ~once. Not once per sensor -- just once. So we translate the "number of
      # traversals" into a "number of touches" according to the number of sensors.
      numTouchesPerTraversal = len(features) / float(numColumns)
      numInitialTouches = int(math.ceil(numInitialTraversals * numTouchesPerTraversal))
      numTestTouches = len(features)

      for touch in xrange(numInitialTouches + numTestTouches):
        sensorPositions = next(sensorPositionsIterator)

        sensation = dict(
          (column,
           (locationSDRsByColumn[column][sensorPositions[column]],
            featureSDRsByColumn[column][features[sensorPositions[column]]]))
          for column in xrange(1, numColumns))

        # Add noise to the first column.
        featureSDR = featureSDRsByColumn[0][features[sensorPositions[0]]]
        if noisyFeature:
          featureSDR = noisy(featureSDR, noiseLevel, NUM_L4_COLUMNS)

        locationSDR = locationSDRsByColumn[0][sensorPositions[0]]
        if noisyLocation:
          locationSDR = noisy(locationSDR, noiseLevel, 1024)

        sensation[0] = (locationSDR, featureSDR)

        exp.infer([sensation]*TIMESTEPS_PER_SENSATION, reset=False,
                  objectName=objectName)

        if touch >= numInitialTouches:
          activeCells = exp.getL2Representations()[0]
          correctCells = inferredL2[0]
          results[noiseLevel].append((len(activeCells & correctCells),
                                      len(activeCells - correctCells)))

  return results
  def inferObjects(self, bodyPlacement, maxTouches=2):
    """
    Touch each object with multiple sensors twice.

    :returns: dict mapping the number of touches required to the number of
        objects that took that many touches to be uniquely inferred. The 'None'
        key is reserved for objects not recognized after `maxTouches` touches
    """
    for monitor in self.monitors.itervalues():
      monitor.afterBodyWorldLocationChanged(bodyPlacement)

    numTouchesRequired = collections.defaultdict(int)
    for objectName, objectFeatures in self.objects.iteritems():
      self.reset()

      objectPlacement = self.objectPlacements[objectName]

      featureIndexByColumnIterator = (
        greedySensorPositions(self.numCorticalColumns, len(objectFeatures)))

      for touch in xrange(maxTouches):
        # Choose where to place each sensor.
        featureIndexByColumn = featureIndexByColumnIterator.next()
        sensedFeatures = [objectFeatures[i] for i in featureIndexByColumn]
        featureSDRByColumn = [self.features[(iCol, feature["name"])]
                              for iCol, feature in enumerate(sensedFeatures)]
        worldLocationByColumn = np.array([
          [objectPlacement[0] + feature["top"] + feature["height"]/2,
           objectPlacement[1] + feature["left"] + feature["width"]/2]
          for feature in sensedFeatures])

        for monitor in self.monitors.itervalues():
          monitor.afterSensorWorldLocationChanged(worldLocationByColumn)

        egocentricLocationByColumn = worldLocationByColumn - bodyPlacement

        prevCellActivity = None

        for t in xrange(self.maxSettlingTime):
          for monitor in self.monitors.itervalues():
            monitor.beforeCompute(egocentricLocationByColumn, featureSDRByColumn,
                                  isRepeat=(t > 0))
          self.compute(egocentricLocationByColumn, featureSDRByColumn, learn=False)

          cellActivity = (
            tuple(c.getAllCellActivity()
                  for c in self.corticalColumns),
            tuple(set(module.activeCells)
                  for module in self.bodyToSpecificObjectModules))

          if cellActivity == prevCellActivity:
            # It settled. Cancel logging this timestep.
            for monitor in self.monitors.itervalues():
              monitor.clearUnflushedData()
            break
          else:
            prevCellActivity = cellActivity
            for monitor in self.monitors.itervalues():
              monitor.flush()

        # Check if the object is narrowed down
        if self.isObjectClassified(objectName):
          numTouchesRequired[touch + 1] += 1
          break
      else:
        numTouchesRequired[None] += 1

    return numTouchesRequired
Example #7
0
def doExperiment(numColumns, objects, l2Overrides, noiseLevels,
                 numInitialTraversals, noisyFeature, noisyLocation):
    """
  Touch every point on an object 'numInitialTraversals' times, then evaluate
  whether it has inferred the object by touching every point once more and
  checking the number of correctly active and incorrectly active cells.

  @param numColumns (int)
  The number of sensors to use

  @param l2Overrides (dict)
  Parameters for the ColumnPooler

  @param objects (dict)
  A mapping of object names to their features.
  See 'createRandomObjects'.

  @param noiseLevels (list of floats)
  The noise levels to experiment with. The experiment is run once per noise
  level. Noise is applied at a constant rate to exactly one cortical column.
  It's applied to the same cortical column every time, and this is the cortical
  column that is measured.

  @param noisyFeature (bool)
  Whether to use a noisy feature

  @param noisyLocation (bool)
  Whether to use a noisy location
  """

    featureSDR = lambda: set(random.sample(xrange(NUM_L4_COLUMNS), 40))
    locationSDR = lambda: set(random.sample(xrange(1024), 40))

    featureSDRsByColumn = [defaultdict(featureSDR) for _ in xrange(numColumns)]
    locationSDRsByColumn = [
        defaultdict(locationSDR) for _ in xrange(numColumns)
    ]

    exp = L4L2Experiment("Experiment",
                         numCorticalColumns=numColumns,
                         inputSize=NUM_L4_COLUMNS,
                         externalInputSize=1024,
                         seed=random.randint(2048, 4096))

    exp.learnObjects(
        dict((objectName, [
            dict((column, (locationSDRsByColumn[column][location],
                           featureSDRsByColumn[column][features[location]]))
                 for column in xrange(numColumns))
            for location in xrange(len(features))
        ]) for objectName, features in objects.iteritems()))

    results = defaultdict(list)

    for noiseLevel in noiseLevels:
        # Try to infer the objects
        for objectName, features in objects.iteritems():
            exp.sendReset()

            inferredL2 = exp.objectL2Representations[objectName]

            sensorPositionsIterator = greedySensorPositions(
                numColumns, len(features))

            # Touch each location at least numInitialTouches times, and then touch it
            # once more, testing it. For each traversal, touch each point on the object
            # ~once. Not once per sensor -- just once. So we translate the "number of
            # traversals" into a "number of touches" according to the number of sensors.
            numTouchesPerTraversal = len(features) / float(numColumns)
            numInitialTouches = int(
                math.ceil(numInitialTraversals * numTouchesPerTraversal))
            numTestTouches = len(features)

            for touch in xrange(numInitialTouches + numTestTouches):
                sensorPositions = next(sensorPositionsIterator)

                sensation = dict(
                    (column,
                     (locationSDRsByColumn[column][sensorPositions[column]],
                      featureSDRsByColumn[column][features[
                          sensorPositions[column]]]))
                    for column in xrange(1, numColumns))

                # Add noise to the first column.
                featureSDR = featureSDRsByColumn[0][features[
                    sensorPositions[0]]]
                if noisyFeature:
                    featureSDR = noisy(featureSDR, noiseLevel, NUM_L4_COLUMNS)

                locationSDR = locationSDRsByColumn[0][sensorPositions[0]]
                if noisyLocation:
                    locationSDR = noisy(locationSDR, noiseLevel, 1024)

                sensation[0] = (locationSDR, featureSDR)

                exp.infer([sensation] * TIMESTEPS_PER_SENSATION,
                          reset=False,
                          objectName=objectName)

                if touch >= numInitialTouches:
                    activeCells = exp.getL2Representations()[0]
                    correctCells = inferredL2[0]
                    results[noiseLevel].append(
                        (len(activeCells & correctCells),
                         len(activeCells - correctCells)))

    return results