Exemple #1
0
  def testRecycleWeakestSynapseToMakeRoomForNewSynapse(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=1,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.50,
      minThreshold=1,
      maxNewSynapseCount=3,
      permanenceIncrement=.02,
      permanenceDecrement=.02,
      predictedSegmentDecrement=0.0,
      seed=42,
      maxSynapsesPerSegment=3)

    prevActiveColumns = [0, 1, 2]
    prevWinnerCells = [0, 1, 2]
    activeColumns = [4]

    matchingSegment = tm.connections.createSegment(4)
    tm.connections.createSynapse(matchingSegment, 81, .6)

    weakestSynapse = tm.connections.createSynapse(matchingSegment, 0, .11)

    tm.compute(prevActiveColumns)
    self.assertEqual(prevWinnerCells, tm.getWinnerCells())
    tm.compute(activeColumns)

    synapseData = tm.connections.dataForSynapse(weakestSynapse)
    self.assertNotEqual(0, synapseData.presynapticCell)

    self.assertFalse(synapseData._destroyed)

    self.assertAlmostEqual(.21, synapseData.permanence)
Exemple #2
0
  def testMatchingSegmentAddSynapsesToSubsetOfWinnerCells(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=1,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.50,
      minThreshold=1,
      maxNewSynapseCount=3,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.0,
      seed=42)

    previousActiveColumns = [0, 1, 2, 3]
    prevWinnerCells = [0, 1, 2, 3]
    activeColumns = [4]

    matchingSegment = tm.connections.createSegment(4)
    tm.connections.createSynapse(matchingSegment, 0, .5)

    tm.compute(previousActiveColumns, True)
    self.assertEqual(prevWinnerCells, tm.getWinnerCells())
    tm.compute(activeColumns, True)

    synapses = list(tm.connections.synapsesForSegment(matchingSegment))
    self.assertEqual(3, len(synapses))

    synapses = synapses[1:] # only test the synapses added by compute
    for synapse in synapses:
      synapseData = tm.connections.dataForSynapse(synapse)
      self.assertAlmostEqual(.21, synapseData.permanence)
      self.assertTrue(synapseData.presynapticCell == prevWinnerCells[1] or
                      synapseData.presynapticCell == prevWinnerCells[2] or
                      synapseData.presynapticCell == prevWinnerCells[3])
  def testDestroyWeakSynapseOnWrongPrediction(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.2,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=4,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.02,
      seed=42)

    previousActiveColumns = [0]
    previousActiveCells = [0, 1, 2, 3]
    activeColumns = [2]
    expectedActiveCells = [5]

    activeSegment = tm.connections.createSegment(expectedActiveCells[0])
    tm.connections.createSynapse(activeSegment, previousActiveCells[0], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[1], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[2], .5)
    weakActiveSynapse = tm.connections.createSynapse(activeSegment,
                                                     previousActiveCells[3],
                                                     .015)

    tm.compute(previousActiveColumns, True)
    tm.compute(activeColumns, True)

    self.assertTrue(tm.connections.dataForSynapse(weakActiveSynapse).destroyed)
  def testZeroActiveColumns(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.5,
      minThreshold=2,
      maxNewSynapseCount=3,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.0,
      seed=42)

    previousActiveColumns = [0]
    previousActiveCells = [0, 1, 2, 3]
    expectedActiveCells = [4]

    segment = tm.connections.createSegment(expectedActiveCells[0])
    tm.connections.createSynapse(segment, previousActiveCells[0], .5)
    tm.connections.createSynapse(segment, previousActiveCells[1], .5)
    tm.connections.createSynapse(segment, previousActiveCells[2], .5)
    tm.connections.createSynapse(segment, previousActiveCells[3], .5)

    tm.compute(previousActiveColumns, True)
    self.assertFalse(len(tm.getActiveCells()) == 0)
    self.assertFalse(len(tm.getWinnerCells()) == 0)
    self.assertFalse(len(tm.getPredictiveCells()) == 0)

    zeroColumns = []
    tm.compute(zeroColumns, True)

    self.assertTrue(len(tm.getActiveCells()) == 0)
    self.assertTrue(len(tm.getWinnerCells()) == 0)
    self.assertTrue(len(tm.getPredictiveCells()) == 0)
  def testReinforceCorrectlyActiveSegments(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.2,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=4,
      permanenceIncrement=.10,
      permanenceDecrement=.08,
      predictedSegmentDecrement=0.02,
      seed=42)

    prevActiveColumns = [0]
    prevActiveCells = [0,1,2,3]
    activeColumns = [1]
    activeCell = 5

    activeSegment = tm.connections.createSegment(activeCell)
    as1 = tm.connections.createSynapse(activeSegment, prevActiveCells[0], .5)
    as2 = tm.connections.createSynapse(activeSegment, prevActiveCells[1], .5)
    as3 = tm.connections.createSynapse(activeSegment, prevActiveCells[2], .5)
    is1 = tm.connections.createSynapse(activeSegment, 81, .5) #inactive synapse

    tm.compute(prevActiveColumns, True)
    tm.compute(activeColumns, True)

    self.assertAlmostEqual(.6, tm.connections.dataForSynapse(as1).permanence)
    self.assertAlmostEqual(.6, tm.connections.dataForSynapse(as2).permanence)
    self.assertAlmostEqual(.6, tm.connections.dataForSynapse(as3).permanence)
    self.assertAlmostEqual(.42, tm.connections.dataForSynapse(is1).permanence)
  def testNewSegmentAddSynapsesToSubsetOfWinnerCells(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=2,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.0,
      seed=42)

    previousActiveColumns = [0, 1, 2]
    activeColumns = [4]

    tm.compute(previousActiveColumns, True)

    prevWinnerCells = tm.getWinnerCells() #[0, 8, 7]
    self.assertEqual(3, len(prevWinnerCells))

    tm.compute(activeColumns, True)

    winnerCells = tm.getWinnerCells() #[18]
    self.assertEqual(1, len(winnerCells))
    segments = list(tm.connections.segmentsForCell(winnerCells[0]))
    self.assertEqual(1, len(segments))
    synapses = list(tm.connections.synapsesForSegment(segments[0]))
    self.assertEqual(2, len(synapses))

    for synapse in synapses:
      synapseData = tm.connections.dataForSynapse(synapse)
      self.assertAlmostEqual(.21, synapseData.permanence)
      self.assertTrue(synapseData.presynapticCell in prevWinnerCells)
  def testMatchingSegmentAddSynapsesToAllWinnerCells(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=1,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.50,
      minThreshold=1,
      maxNewSynapseCount=3,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.0,
      seed=42)

    previousActiveColumns = [0, 1]
    prevWinnerCells = [0, 1]
    activeColumns = [4]

    matchingSegment = tm.connections.createSegment(4)
    tm.connections.createSynapse(matchingSegment, 0, .5)

    tm.compute(previousActiveColumns, True)
    self.assertEqual(prevWinnerCells, tm.getWinnerCells())

    tm.compute(activeColumns)

    synapses = tm.connections.synapsesForSegment(matchingSegment)
    self.assertEqual(2, len(synapses))

    for synapse in synapses:
      synapseData = tm.connections.dataForSynapse(synapse)
      if synapseData.presynapticCell != 0:
        self.assertAlmostEqual(.21, synapseData.permanence)
        self.assertEqual(prevWinnerCells[1], synapseData.presynapticCell)
  def testActivateCorrectlyPredictiveCells(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.5,
      minThreshold=2,
      maxNewSynapseCount=3,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.0,
      seed=42)

    previousActiveColumns = [0]
    activeColumns = [1]
    previousActiveCells = [0,1,2,3]
    expectedActiveCells = [4]

    activeSegment = tm.connections.createSegment(expectedActiveCells[0])
    tm.connections.createSynapse(activeSegment, previousActiveCells[0], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[1], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[2], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[3], .5)

    tm.compute(previousActiveColumns, True)
    self.assertEqual(expectedActiveCells, tm.getPredictiveCells())
    tm.compute(activeColumns, True)
    self.assertEqual(expectedActiveCells, tm.getActiveCells())
  def testNoGrowthOnCorrectlyActiveSegments(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.2,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=3,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.02,
      seed=42)

    previousActiveColumns = [0]
    previousActiveCells = [0,1,2,3]
    activeColumns = [1]
    activeCell = 5

    activeSegment = tm.connections.createSegment(activeCell)
    tm.connections.createSynapse(activeSegment, previousActiveCells[0], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[1], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[2], .5)

    tm.compute(previousActiveColumns, True)
    tm.compute(activeColumns, True)

    self.assertEqual(3, len(tm.connections.synapsesForSegment(activeSegment)))
  def testDestroyWeakSynapseOnActiveReinforce(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.2,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=4,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.02,
      seed=42)

    previousActiveColumns = [0]
    previousActiveCells = [0, 1, 2, 3]
    activeColumns = [2]
    activeCell = 5

    activeSegment = tm.connections.createSegment(activeCell)
    tm.connections.createSynapse(activeSegment, previousActiveCells[0], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[1], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[2], .5)

    # Weak inactive synapse.
    tm.connections.createSynapse(activeSegment, previousActiveCells[3], .009)

    tm.compute(previousActiveColumns, True)
    tm.compute(activeColumns, True)

    self.assertEqual(3, tm.connections.numSynapses(activeSegment))
  def testRecycleWeakestSynapseToMakeRoomForNewSynapse(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=1,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.50,
      minThreshold=1,
      maxNewSynapseCount=3,
      permanenceIncrement=.02,
      permanenceDecrement=.02,
      predictedSegmentDecrement=0.0,
      seed=42,
      maxSynapsesPerSegment=3)

    prevActiveColumns = [0, 1, 2]
    prevWinnerCells = [0, 1, 2]
    activeColumns = [4]

    matchingSegment = tm.connections.createSegment(4)
    tm.connections.createSynapse(matchingSegment, 81, .6)

    weakestSynapse = tm.connections.createSynapse(matchingSegment, 0, .11)

    tm.compute(prevActiveColumns)
    self.assertEqual(prevWinnerCells, tm.getWinnerCells())
    tm.compute(activeColumns)

    synapses = tm.connections.synapsesForSegment(matchingSegment)
    self.assertEqual(3, len(synapses))
    presynapticCells = set(synapse.presynapticCell for synapse in synapses)
    self.assertFalse(0 in presynapticCells)
  def testDestroySegmentsWithTooFewSynapsesToBeMatching(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.2,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=4,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.02,
      seed=42)

    prevActiveColumns = [0]
    prevActiveCells = [0, 1, 2, 3]
    activeColumns = [2]
    expectedActiveCell = 5

    matchingSegment = tm.connections.createSegment(expectedActiveCell)
    tm.connections.createSynapse(matchingSegment, prevActiveCells[0], .015)
    tm.connections.createSynapse(matchingSegment, prevActiveCells[1], .015)
    tm.connections.createSynapse(matchingSegment, prevActiveCells[2], .015)
    tm.connections.createSynapse(matchingSegment, prevActiveCells[3], .015)

    tm.compute(prevActiveColumns, True)
    tm.compute(activeColumns, True)

    self.assertEqual(0, tm.connections.numSegments(expectedActiveCell))
  def testNoChangeToMatchingSegmentsInPredictedActiveColumn(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=3,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.0,
      seed=42)

    previousActiveColumns = [0]
    activeColumns = [1]
    previousActiveCells = [0,1,2,3]
    expectedActiveCells = [4]
    otherburstingCells = [5,6,7]

    activeSegment = tm.connections.createSegment(expectedActiveCells[0])
    tm.connections.createSynapse(activeSegment, previousActiveCells[0], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[1], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[2], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[3], .5)

    matchingSegmentOnSameCell = tm.connections.createSegment(
      expectedActiveCells[0])
    s1 = tm.connections.createSynapse(matchingSegmentOnSameCell,
                                      previousActiveCells[0], .3)
    s2 = tm.connections.createSynapse(matchingSegmentOnSameCell,
                                      previousActiveCells[1], .3)

    matchingSegmentOnOtherCell = tm.connections.createSegment(
      otherburstingCells[0])
    s3 = tm.connections.createSynapse(matchingSegmentOnOtherCell,
                                      previousActiveCells[0], .3)
    s4 = tm.connections.createSynapse(matchingSegmentOnOtherCell,
                                      previousActiveCells[1], .3)


    tm.compute(previousActiveColumns, True)
    self.assertEqual(expectedActiveCells, tm.getPredictiveCells())
    tm.compute(activeColumns, True)

    self.assertAlmostEqual(.3, tm.connections.dataForSynapse(s1).permanence)
    self.assertAlmostEqual(.3, tm.connections.dataForSynapse(s2).permanence)
    self.assertAlmostEqual(.3, tm.connections.dataForSynapse(s3).permanence)
    self.assertAlmostEqual(.3, tm.connections.dataForSynapse(s4).permanence)
Exemple #14
0
  def testNoChangeToMatchingSegmentsInPredictedActiveColumn(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=3,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.0,
      seed=42)

    previousActiveColumns = [0]
    activeColumns = [1]
    previousActiveCells = [0,1,2,3]
    expectedActiveCells = [4]
    otherburstingCells = [5,6,7]

    activeSegment = tm.connections.createSegment(expectedActiveCells[0])
    tm.connections.createSynapse(activeSegment, previousActiveCells[0], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[1], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[2], .5)
    tm.connections.createSynapse(activeSegment, previousActiveCells[3], .5)

    matchingSegmentOnSameCell = tm.connections.createSegment(
      expectedActiveCells[0])
    s1 = tm.connections.createSynapse(matchingSegmentOnSameCell,
                                      previousActiveCells[0], .3)
    s2 = tm.connections.createSynapse(matchingSegmentOnSameCell,
                                      previousActiveCells[1], .3)

    matchingSegmentOnOtherCell = tm.connections.createSegment(
      otherburstingCells[0])
    s3 = tm.connections.createSynapse(matchingSegmentOnOtherCell,
                                      previousActiveCells[0], .3)
    s4 = tm.connections.createSynapse(matchingSegmentOnOtherCell,
                                      previousActiveCells[1], .3)


    tm.compute(previousActiveColumns, True)
    self.assertEqual(expectedActiveCells, tm.getPredictiveCells())
    tm.compute(activeColumns, True)

    self.assertAlmostEqual(.3, tm.connections.dataForSynapse(s1).permanence)
    self.assertAlmostEqual(.3, tm.connections.dataForSynapse(s2).permanence)
    self.assertAlmostEqual(.3, tm.connections.dataForSynapse(s3).permanence)
    self.assertAlmostEqual(.3, tm.connections.dataForSynapse(s4).permanence)
Exemple #15
0
  def testPunishMatchingSegmentsInInactiveColumns(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.2,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=4,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.02,
      seed=42)

    previousActiveColumns = [0]
    previousActiveCells = [0, 1, 2, 3]
    activeColumns = [1]
    previousInactiveCell = 81

    activeSegment = tm.connections.createSegment(42)
    as1 = tm.connections.createSynapse(activeSegment,
                                       previousActiveCells[0], .5)
    as2 = tm.connections.createSynapse(activeSegment,
                                       previousActiveCells[1], .5)
    as3 = tm.connections.createSynapse(activeSegment,
                                       previousActiveCells[2], .5)
    is1 = tm.connections.createSynapse(activeSegment,
                                       previousInactiveCell, .5)

    matchingSegment = tm.connections.createSegment(43)
    as4 = tm.connections.createSynapse(matchingSegment,
                                       previousActiveCells[0], .5)
    as5 = tm.connections.createSynapse(matchingSegment,
                                       previousActiveCells[1], .5)
    is2 = tm.connections.createSynapse(matchingSegment,
                                       previousInactiveCell, .5)

    tm.compute(previousActiveColumns, True)
    tm.compute(activeColumns, True)

    self.assertAlmostEqual(.48, tm.connections.dataForSynapse(as1).permanence)
    self.assertAlmostEqual(.48, tm.connections.dataForSynapse(as2).permanence)
    self.assertAlmostEqual(.48, tm.connections.dataForSynapse(as3).permanence)
    self.assertAlmostEqual(.48, tm.connections.dataForSynapse(as4).permanence)
    self.assertAlmostEqual(.48, tm.connections.dataForSynapse(as5).permanence)
    self.assertAlmostEqual(.50, tm.connections.dataForSynapse(is1).permanence)
    self.assertAlmostEqual(.50, tm.connections.dataForSynapse(is2).permanence)
  def testPunishMatchingSegmentsInInactiveColumns(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.2,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=4,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.02,
      seed=42)

    previousActiveColumns = [0]
    previousActiveCells = [0, 1, 2, 3]
    activeColumns = [1]
    previousInactiveCell = 81

    activeSegment = tm.connections.createSegment(42)
    as1 = tm.connections.createSynapse(activeSegment,
                                       previousActiveCells[0], .5)
    as2 = tm.connections.createSynapse(activeSegment,
                                       previousActiveCells[1], .5)
    as3 = tm.connections.createSynapse(activeSegment,
                                       previousActiveCells[2], .5)
    is1 = tm.connections.createSynapse(activeSegment,
                                       previousInactiveCell, .5)

    matchingSegment = tm.connections.createSegment(43)
    as4 = tm.connections.createSynapse(matchingSegment,
                                       previousActiveCells[0], .5)
    as5 = tm.connections.createSynapse(matchingSegment,
                                       previousActiveCells[1], .5)
    is2 = tm.connections.createSynapse(matchingSegment,
                                       previousInactiveCell, .5)

    tm.compute(previousActiveColumns, True)
    tm.compute(activeColumns, True)

    self.assertAlmostEqual(.48, tm.connections.dataForSynapse(as1).permanence)
    self.assertAlmostEqual(.48, tm.connections.dataForSynapse(as2).permanence)
    self.assertAlmostEqual(.48, tm.connections.dataForSynapse(as3).permanence)
    self.assertAlmostEqual(.48, tm.connections.dataForSynapse(as4).permanence)
    self.assertAlmostEqual(.48, tm.connections.dataForSynapse(as5).permanence)
    self.assertAlmostEqual(.50, tm.connections.dataForSynapse(is1).permanence)
    self.assertAlmostEqual(.50, tm.connections.dataForSynapse(is2).permanence)
Exemple #17
0
    def testReinforceSelectedMatchingSegmentInBurstingColumn(self):
        tm = TemporalMemory(columnDimensions=[32],
                            cellsPerColumn=4,
                            activationThreshold=3,
                            initialPermanence=.21,
                            connectedPermanence=.50,
                            minThreshold=2,
                            maxNewSynapseCount=3,
                            permanenceIncrement=.10,
                            permanenceDecrement=.08,
                            predictedSegmentDecrement=0.0,
                            seed=42)

        previousActiveColumns = [0]
        previousActiveCells = [0, 1, 2, 3]
        activeColumns = [1]
        burstingCells = [4, 5, 6, 7]

        selectedMatchingSegment = tm.connections.createSegment(
            burstingCells[0])
        as1 = tm.connections.createSynapse(selectedMatchingSegment,
                                           previousActiveCells[0], .3)
        as2 = tm.connections.createSynapse(selectedMatchingSegment,
                                           previousActiveCells[1], .3)
        as3 = tm.connections.createSynapse(selectedMatchingSegment,
                                           previousActiveCells[2], .3)
        is1 = tm.connections.createSynapse(selectedMatchingSegment, 81, .3)

        otherMatchingSegment = tm.connections.createSegment(burstingCells[1])
        tm.connections.createSynapse(otherMatchingSegment,
                                     previousActiveCells[0], .3)
        tm.connections.createSynapse(otherMatchingSegment,
                                     previousActiveCells[1], .3)
        tm.connections.createSynapse(otherMatchingSegment, 81, .3)

        tm.compute(previousActiveColumns, True)
        tm.compute(activeColumns, True)

        self.assertAlmostEqual(.4,
                               tm.connections.dataForSynapse(as1).permanence)
        self.assertAlmostEqual(.4,
                               tm.connections.dataForSynapse(as2).permanence)
        self.assertAlmostEqual(.4,
                               tm.connections.dataForSynapse(as3).permanence)
        self.assertAlmostEqual(.22,
                               tm.connections.dataForSynapse(is1).permanence)
Exemple #18
0
    def testBurstUnpredictedColumns(self):
        tm = TemporalMemory(columnDimensions=[32],
                            cellsPerColumn=4,
                            activationThreshold=3,
                            initialPermanence=.21,
                            connectedPermanence=.5,
                            minThreshold=2,
                            maxNewSynapseCount=3,
                            permanenceIncrement=.10,
                            permanenceDecrement=.10,
                            predictedSegmentDecrement=0.0,
                            seed=42)

        activeColumns = [0]
        burstingCells = [0, 1, 2, 3]

        tm.compute(activeColumns, True)

        self.assertEqual(burstingCells, tm.getActiveCells())
  def testActiveSegmentGrowSynapsesAccordingToPotentialOverlap(self):
    """
    When a segment becomes active, grow synapses to previous winner cells.

    The number of grown synapses is calculated from the "matching segment"
    overlap, not the "active segment" overlap.
    """
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=1,
      activationThreshold=2,
      initialPermanence=.21,
      connectedPermanence=.50,
      minThreshold=1,
      maxNewSynapseCount=4,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.0,
      seed=42)

    # Use 1 cell per column so that we have easy control over the winner cells.
    previousActiveColumns = [0, 1, 2, 3, 4]
    prevWinnerCells = [0, 1, 2, 3, 4]
    activeColumns = [5]

    activeSegment = tm.connections.createSegment(5)
    tm.connections.createSynapse(activeSegment, 0, .5)
    tm.connections.createSynapse(activeSegment, 1, .5)
    tm.connections.createSynapse(activeSegment, 2, .2)

    tm.compute(previousActiveColumns, True)
    self.assertEqual(prevWinnerCells, tm.getWinnerCells())
    tm.compute(activeColumns, True)

    synapses = tm.connections.synapsesForSegment(activeSegment)
    self.assertEqual(4, len(synapses))

    synapse = synapses[3];
    synapseData = tm.connections.dataForSynapse(synapse)
    self.assertAlmostEqual(.21, synapseData.permanence)
    self.assertTrue(synapseData.presynapticCell == prevWinnerCells[3] or
                    synapseData.presynapticCell == prevWinnerCells[4])
Exemple #20
0
    def testConnectionsNeverChangeWhenLearningDisabled(self):
        tm = TemporalMemory(columnDimensions=[32],
                            cellsPerColumn=4,
                            activationThreshold=3,
                            initialPermanence=.2,
                            connectedPermanence=.50,
                            minThreshold=2,
                            maxNewSynapseCount=4,
                            permanenceIncrement=.10,
                            permanenceDecrement=.10,
                            predictedSegmentDecrement=0.02,
                            seed=42)

        prevActiveColumns = [0]
        prevActiveCells = [0, 1, 2, 3]
        activeColumns = [1, 2]  #1 is predicted, 2 is bursting
        prevInactiveCell = 81
        expectedActiveCells = [4]

        correctActiveSegment = tm.connections.createSegment(
            expectedActiveCells[0])
        tm.connections.createSynapse(correctActiveSegment, prevActiveCells[0],
                                     .5)
        tm.connections.createSynapse(correctActiveSegment, prevActiveCells[1],
                                     .5)
        tm.connections.createSynapse(correctActiveSegment, prevActiveCells[2],
                                     .5)

        wrongMatchingSegment = tm.connections.createSegment(43)
        tm.connections.createSynapse(wrongMatchingSegment, prevActiveCells[0],
                                     .5)
        tm.connections.createSynapse(wrongMatchingSegment, prevActiveCells[1],
                                     .5)
        tm.connections.createSynapse(wrongMatchingSegment, prevInactiveCell,
                                     .5)

        before = copy.deepcopy(tm.connections)

        tm.compute(prevActiveColumns, False)
        tm.compute(activeColumns, False)

        self.assertEqual(before, tm.connections)
  def testReinforceSelectedMatchingSegmentInBurstingColumn(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=3,
      permanenceIncrement=.10,
      permanenceDecrement=.08,
      predictedSegmentDecrement=0.0,
      seed=42)

    previousActiveColumns = [0]
    previousActiveCells = [0,1,2,3]
    activeColumns = [1]
    burstingCells = [4,5,6,7]

    selectedMatchingSegment = tm.connections.createSegment(burstingCells[0])
    as1 = tm.connections.createSynapse(selectedMatchingSegment,
                                       previousActiveCells[0], .3)
    as2 = tm.connections.createSynapse(selectedMatchingSegment,
                                       previousActiveCells[1], .3)
    as3 = tm.connections.createSynapse(selectedMatchingSegment,
                                       previousActiveCells[2], .3)
    is1 = tm.connections.createSynapse(selectedMatchingSegment, 81, .3)

    otherMatchingSegment = tm.connections.createSegment(burstingCells[1])
    tm.connections.createSynapse(otherMatchingSegment,
                                 previousActiveCells[0], .3)
    tm.connections.createSynapse(otherMatchingSegment,
                                 previousActiveCells[1], .3)
    tm.connections.createSynapse(otherMatchingSegment, 81, .3)

    tm.compute(previousActiveColumns, True)
    tm.compute(activeColumns, True)

    self.assertAlmostEqual(.4, tm.connections.dataForSynapse(as1).permanence)
    self.assertAlmostEqual(.4, tm.connections.dataForSynapse(as2).permanence)
    self.assertAlmostEqual(.4, tm.connections.dataForSynapse(as3).permanence)
    self.assertAlmostEqual(.22, tm.connections.dataForSynapse(is1).permanence)
  def testBurstUnpredictedColumns(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.5,
      minThreshold=2,
      maxNewSynapseCount=3,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.0,
      seed=42)

    activeColumns = [0]
    burstingCells = [0, 1, 2, 3]

    tm.compute(activeColumns, True)

    self.assertEqual(burstingCells, tm.getActiveCells())
Exemple #23
0
    def testNoNewSegmentIfNotEnoughWinnerCells(self):
        tm = TemporalMemory(columnDimensions=[32],
                            cellsPerColumn=4,
                            activationThreshold=3,
                            initialPermanence=.21,
                            connectedPermanence=.50,
                            minThreshold=2,
                            maxNewSynapseCount=3,
                            permanenceIncrement=.10,
                            permanenceDecrement=.10,
                            predictedSegmentDecrement=0.0,
                            seed=42)

        zeroColumns = []
        activeColumns = [0]

        tm.compute(zeroColumns, True)
        tm.compute(activeColumns, True)

        self.assertEqual(0, tm.connections.numSegments())
Exemple #24
0
    def testActiveSegmentGrowSynapsesAccordingToPotentialOverlap(self):
        """
    When a segment becomes active, grow synapses to previous winner cells.

    The number of grown synapses is calculated from the "matching segment"
    overlap, not the "active segment" overlap.
    """
        tm = TemporalMemory(columnDimensions=[32],
                            cellsPerColumn=1,
                            activationThreshold=2,
                            initialPermanence=.21,
                            connectedPermanence=.50,
                            minThreshold=1,
                            maxNewSynapseCount=4,
                            permanenceIncrement=.10,
                            permanenceDecrement=.10,
                            predictedSegmentDecrement=0.0,
                            seed=42)

        # Use 1 cell per column so that we have easy control over the winner cells.
        previousActiveColumns = [0, 1, 2, 3, 4]
        prevWinnerCells = [0, 1, 2, 3, 4]
        activeColumns = [5]

        activeSegment = tm.connections.createSegment(5)
        tm.connections.createSynapse(activeSegment, 0, .5)
        tm.connections.createSynapse(activeSegment, 1, .5)
        tm.connections.createSynapse(activeSegment, 2, .2)

        tm.compute(previousActiveColumns, True)
        self.assertEqual(prevWinnerCells, tm.getWinnerCells())
        tm.compute(activeColumns, True)

        synapses = tm.connections.synapsesForSegment(activeSegment)
        self.assertEqual(4, len(synapses))

        synapse = synapses[3]
        synapseData = tm.connections.dataForSynapse(synapse)
        self.assertAlmostEqual(.21, synapseData.permanence)
        self.assertTrue(synapseData.presynapticCell == prevWinnerCells[3]
                        or synapseData.presynapticCell == prevWinnerCells[4])
  def testNoNewSegmentIfNotEnoughWinnerCells(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=3,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.0,
      seed=42)

    zeroColumns = []
    activeColumns = [0]

    tm.compute(zeroColumns, True)
    tm.compute(activeColumns, True)

    self.assertEqual(0, tm.connections.numSegments())
Exemple #26
0
    def testReinforceCorrectlyActiveSegments(self):
        tm = TemporalMemory(columnDimensions=[32],
                            cellsPerColumn=4,
                            activationThreshold=3,
                            initialPermanence=.2,
                            connectedPermanence=.50,
                            minThreshold=2,
                            maxNewSynapseCount=4,
                            permanenceIncrement=.10,
                            permanenceDecrement=.08,
                            predictedSegmentDecrement=0.02,
                            seed=42)

        prevActiveColumns = [0]
        prevActiveCells = [0, 1, 2, 3]
        activeColumns = [1]
        activeCell = 5

        activeSegment = tm.connections.createSegment(activeCell)
        as1 = tm.connections.createSynapse(activeSegment, prevActiveCells[0],
                                           .5)
        as2 = tm.connections.createSynapse(activeSegment, prevActiveCells[1],
                                           .5)
        as3 = tm.connections.createSynapse(activeSegment, prevActiveCells[2],
                                           .5)
        is1 = tm.connections.createSynapse(activeSegment, 81,
                                           .5)  #inactive synapse

        tm.compute(prevActiveColumns, True)
        tm.compute(activeColumns, True)

        self.assertAlmostEqual(.6,
                               tm.connections.dataForSynapse(as1).permanence)
        self.assertAlmostEqual(.6,
                               tm.connections.dataForSynapse(as2).permanence)
        self.assertAlmostEqual(.6,
                               tm.connections.dataForSynapse(as3).permanence)
        self.assertAlmostEqual(.42,
                               tm.connections.dataForSynapse(is1).permanence)
Exemple #27
0
    def testPredictedActiveCellsAreAlwaysWinners(self):
        tm = TemporalMemory(columnDimensions=[32],
                            cellsPerColumn=4,
                            activationThreshold=3,
                            initialPermanence=.21,
                            connectedPermanence=.5,
                            minThreshold=2,
                            maxNewSynapseCount=3,
                            permanenceIncrement=.10,
                            permanenceDecrement=.10,
                            predictedSegmentDecrement=0.0,
                            seed=42)

        previousActiveColumns = [0]
        activeColumns = [1]
        previousActiveCells = [0, 1, 2, 3]
        expectedWinnerCells = [4, 6]

        activeSegment1 = tm.connections.createSegment(expectedWinnerCells[0])
        tm.connections.createSynapse(activeSegment1, previousActiveCells[0],
                                     .5)
        tm.connections.createSynapse(activeSegment1, previousActiveCells[1],
                                     .5)
        tm.connections.createSynapse(activeSegment1, previousActiveCells[2],
                                     .5)

        activeSegment2 = tm.connections.createSegment(expectedWinnerCells[1])
        tm.connections.createSynapse(activeSegment2, previousActiveCells[0],
                                     .5)
        tm.connections.createSynapse(activeSegment2, previousActiveCells[1],
                                     .5)
        tm.connections.createSynapse(activeSegment2, previousActiveCells[2],
                                     .5)

        tm.compute(previousActiveColumns, False)
        tm.compute(activeColumns, False)

        self.assertEqual(expectedWinnerCells, tm.getWinnerCells())
Exemple #28
0
  def testNewSegmentAddSynapsesToAllWinnerCells(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.21,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=4,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.0,
      seed=42)

    previousActiveColumns = [0, 1, 2]
    activeColumns = [4]

    tm.compute(previousActiveColumns)
    prevWinnerCells = sorted(tm.getWinnerCells())
    self.assertEqual(3, len(prevWinnerCells))

    tm.compute(activeColumns)

    winnerCells = tm.getWinnerCells()
    self.assertEqual(1, len(winnerCells))
    segments = list(tm.connections.segmentsForCell(winnerCells[0]))
    self.assertEqual(1, len(segments))
    synapses = list(tm.connections.synapsesForSegment(segments[0]))
    self.assertEqual(3, len(synapses))

    presynapticCells = []
    for synapse in synapses:
      synapseData = tm.connections.dataForSynapse(synapse)
      self.assertAlmostEqual(.21, synapseData.permanence)
      presynapticCells.append(synapseData.presynapticCell)

    presynapticCells = sorted(presynapticCells)
    self.assertEqual(prevWinnerCells, presynapticCells)
  def testConnectionsNeverChangeWhenLearningDisabled(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=4,
      activationThreshold=3,
      initialPermanence=.2,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=4,
      permanenceIncrement=.10,
      permanenceDecrement=.10,
      predictedSegmentDecrement=0.02,
      seed=42)

    prevActiveColumns = [0]
    prevActiveCells = [0, 1, 2, 3]
    activeColumns = [1, 2] #1 is predicted, 2 is bursting
    prevInactiveCell = 81
    expectedActiveCells = [4]

    correctActiveSegment = tm.connections.createSegment(expectedActiveCells[0])
    tm.connections.createSynapse(correctActiveSegment, prevActiveCells[0], .5)
    tm.connections.createSynapse(correctActiveSegment, prevActiveCells[1], .5)
    tm.connections.createSynapse(correctActiveSegment, prevActiveCells[2], .5)

    wrongMatchingSegment = tm.connections.createSegment(43)
    tm.connections.createSynapse(wrongMatchingSegment, prevActiveCells[0], .5)
    tm.connections.createSynapse(wrongMatchingSegment, prevActiveCells[1], .5)
    tm.connections.createSynapse(wrongMatchingSegment, prevInactiveCell, .5)

    before = copy.deepcopy(tm.connections)

    tm.compute(prevActiveColumns, False)
    tm.compute(activeColumns, False)

    self.assertEqual(before, tm.connections)
Exemple #30
0
  def testWriteRead(self):
    tm1 = TemporalMemory(
      columnDimensions=[100],
      cellsPerColumn=4,
      activationThreshold=7,
      initialPermanence=0.37,
      connectedPermanence=0.58,
      minThreshold=4,
      maxNewSynapseCount=18,
      permanenceIncrement=0.23,
      permanenceDecrement=0.08,
      seed=91
    )

    # Run some data through before serializing
    self.patternMachine = PatternMachine(100, 4)
    self.sequenceMachine = SequenceMachine(self.patternMachine)
    sequence = self.sequenceMachine.generateFromNumbers(range(5))
    for _ in range(3):
      for pattern in sequence:
        tm1.compute(pattern)

    proto1 = TemporalMemoryProto_capnp.TemporalMemoryProto.new_message()
    tm1.write(proto1)

    # Write the proto to a temp file and read it back into a new proto
    with tempfile.TemporaryFile() as f:
      proto1.write(f)
      f.seek(0)
      proto2 = TemporalMemoryProto_capnp.TemporalMemoryProto.read(f)

    # Load the deserialized proto
    tm2 = TemporalMemory.read(proto2)

    # Check that the two temporal memory objects have the same attributes
    self.assertEqual(tm1, tm2)

    # Run a couple records through after deserializing and check results match
    tm1.compute(self.patternMachine.get(0))
    tm2.compute(self.patternMachine.get(0))
    self.assertEqual(set(tm1.getActiveCells()), set(tm2.getActiveCells()))
    self.assertEqual(set(tm1.getPredictiveCells()),
                     set(tm2.getPredictiveCells()))
    self.assertEqual(set(tm1.getWinnerCells()), set(tm2.getWinnerCells()))
    self.assertEqual(tm1.connections, tm2.connections)

    tm1.compute(self.patternMachine.get(3))
    tm2.compute(self.patternMachine.get(3))
    self.assertEqual(set(tm1.getActiveCells()), set(tm2.getActiveCells()))
    self.assertEqual(set(tm1.getPredictiveCells()),
                     set(tm2.getPredictiveCells()))
    self.assertEqual(set(tm1.getWinnerCells()), set(tm2.getWinnerCells()))
    self.assertEqual(tm1.connections, tm2.connections)
Exemple #31
0
  def testWrite(self):
    tm1 = TemporalMemory(
      columnDimensions=[100],
      cellsPerColumn=4,
      activationThreshold=7,
      initialPermanence=0.37,
      connectedPermanence=0.58,
      minThreshold=4,
      maxNewSynapseCount=18,
      permanenceIncrement=0.23,
      permanenceDecrement=0.08,
      seed=91
    )

    # Run some data through before serializing
    self.patternMachine = PatternMachine(100, 4)
    self.sequenceMachine = SequenceMachine(self.patternMachine)
    sequence = self.sequenceMachine.generateFromNumbers(range(5))
    for _ in range(3):
      for pattern in sequence:
        tm1.compute(pattern)

    proto1 = TemporalMemoryProto_capnp.TemporalMemoryProto.new_message()
    tm1.write(proto1)

    # Write the proto to a temp file and read it back into a new proto
    with tempfile.TemporaryFile() as f:
      proto1.write(f)
      f.seek(0)
      proto2 = TemporalMemoryProto_capnp.TemporalMemoryProto.read(f)

    # Load the deserialized proto
    tm2 = TemporalMemory.read(proto2)

    # Check that the two temporal memory objects have the same attributes
    self.assertEqual(tm1, tm2)

    # Run a couple records through after deserializing and check results match
    tm1.compute(self.patternMachine.get(0))
    tm2.compute(self.patternMachine.get(0))
    self.assertEqual(tm1.activeCells, tm2.activeCells)
    self.assertEqual(tm1.predictiveCells, tm2.predictiveCells)
    self.assertEqual(tm1.winnerCells, tm2.winnerCells)
    self.assertEqual(tm1.connections, tm2.connections)

    tm1.compute(self.patternMachine.get(3))
    tm2.compute(self.patternMachine.get(3))
    self.assertEqual(tm1.activeCells, tm2.activeCells)
    self.assertEqual(tm1.predictiveCells, tm2.predictiveCells)
    self.assertEqual(tm1.winnerCells, tm2.winnerCells)
    self.assertEqual(tm1.connections, tm2.connections)
Exemple #32
0
def runHotgym(numRecords):
  with open(_PARAMS_PATH, "r") as f:
    modelParams = yaml.safe_load(f)["modelParams"]
    enParams = modelParams["sensorParams"]["encoders"]
    spParams = modelParams["spParams"]
    tmParams = modelParams["tmParams"]

  timeOfDayEncoder = DateEncoder(
    timeOfDay=enParams["timestamp_timeOfDay"]["timeOfDay"])
  weekendEncoder = DateEncoder(
    weekend=enParams["timestamp_weekend"]["weekend"])
  scalarEncoder = RandomDistributedScalarEncoder(
    enParams["consumption"]["resolution"])

  encodingWidth = (timeOfDayEncoder.getWidth()
                   + weekendEncoder.getWidth()
                   + scalarEncoder.getWidth())

  sp = SpatialPooler(
    # How large the input encoding will be.
    inputDimensions=(encodingWidth),
    # How many mini-columns will be in the Spatial Pooler.
    columnDimensions=(spParams["columnCount"]),
    # What percent of the columns"s receptive field is available for potential
    # synapses?
    potentialPct=spParams["potentialPct"],
    # This means that the input space has no topology.
    globalInhibition=spParams["globalInhibition"],
    localAreaDensity=spParams["localAreaDensity"],
    # Roughly 2%, giving that there is only one inhibition area because we have
    # turned on globalInhibition (40 / 2048 = 0.0195)
    numActiveColumnsPerInhArea=spParams["numActiveColumnsPerInhArea"],
    # How quickly synapses grow and degrade.
    synPermInactiveDec=spParams["synPermInactiveDec"],
    synPermActiveInc=spParams["synPermActiveInc"],
    synPermConnected=spParams["synPermConnected"],
    # boostStrength controls the strength of boosting. Boosting encourages
    # efficient usage of SP columns.
    boostStrength=spParams["boostStrength"],
    # Random number generator seed.
    seed=spParams["seed"],
    # TODO: is this useful?
    # Determines if inputs at the beginning and end of an input dimension should
    # be considered neighbors when mapping columns to inputs.
    wrapAround=False
  )

  tm = TemporalMemory(
    # Must be the same dimensions as the SP
    columnDimensions=(tmParams["columnCount"],),
    # How many cells in each mini-column.
    cellsPerColumn=tmParams["cellsPerColumn"],
    # A segment is active if it has >= activationThreshold connected synapses
    # that are active due to infActiveState
    activationThreshold=tmParams["activationThreshold"],
    initialPermanence=tmParams["initialPerm"],
    # TODO: This comes from the SP params, is this normal
    connectedPermanence=spParams["synPermConnected"],
    # Minimum number of active synapses for a segment to be considered during
    # search for the best-matching segments.
    minThreshold=tmParams["minThreshold"],
    # The max number of synapses added to a segment during learning
    maxNewSynapseCount=tmParams["newSynapseCount"],
    permanenceIncrement=tmParams["permanenceInc"],
    permanenceDecrement=tmParams["permanenceDec"],
    predictedSegmentDecrement=0.0,
    maxSegmentsPerCell=tmParams["maxSegmentsPerCell"],
    maxSynapsesPerSegment=tmParams["maxSynapsesPerSegment"],
    seed=tmParams["seed"]
  )

  classifier = SDRClassifierFactory.create()
  results = []
  with open(_INPUT_FILE_PATH, "r") as fin:
    reader = csv.reader(fin)
    headers = reader.next()
    reader.next()
    reader.next()

    for count, record in enumerate(reader):

      if count >= numRecords: break

      # Convert data string into Python date object.
      dateString = datetime.datetime.strptime(record[0], "%m/%d/%y %H:%M")
      # Convert data value string into float.
      consumption = float(record[1])

      # To encode, we need to provide zero-filled numpy arrays for the encoders
      # to populate.
      timeOfDayBits = numpy.zeros(timeOfDayEncoder.getWidth())
      weekendBits = numpy.zeros(weekendEncoder.getWidth())
      consumptionBits = numpy.zeros(scalarEncoder.getWidth())

      # Now we call the encoders create bit representations for each value.
      timeOfDayEncoder.encodeIntoArray(dateString, timeOfDayBits)
      weekendEncoder.encodeIntoArray(dateString, weekendBits)
      scalarEncoder.encodeIntoArray(consumption, consumptionBits)

      # Concatenate all these encodings into one large encoding for Spatial
      # Pooling.
      encoding = numpy.concatenate(
        [timeOfDayBits, weekendBits, consumptionBits]
      )

      # Create an array to represent active columns, all initially zero. This
      # will be populated by the compute method below. It must have the same
      # dimensions as the Spatial Pooler.
      activeColumns = numpy.zeros(spParams["columnCount"])

      # Execute Spatial Pooling algorithm over input space.
      sp.compute(encoding, True, activeColumns)
      activeColumnIndices = numpy.nonzero(activeColumns)[0]

      # Execute Temporal Memory algorithm over active mini-columns.
      tm.compute(activeColumnIndices, learn=True)

      activeCells = tm.getActiveCells()

      # Get the bucket info for this input value for classification.
      bucketIdx = scalarEncoder.getBucketIndices(consumption)[0]

      # Run classifier to translate active cells back to scalar value.
      classifierResult = classifier.compute(
        recordNum=count,
        patternNZ=activeCells,
        classification={
          "bucketIdx": bucketIdx,
          "actValue": consumption
        },
        learn=True,
        infer=True
      )

      # Print the best prediction for 1 step out.
      oneStepConfidence, oneStep = sorted(
        zip(classifierResult[1], classifierResult["actualValues"]),
        reverse=True
      )[0]
      print("1-step: {:16} ({:4.4}%)".format(oneStep, oneStepConfidence * 100))
      results.append([oneStep, oneStepConfidence * 100, None, None])

    return results
Exemple #33
0
    def testAddSegmentToCellWithFewestSegments(self):
        grewOnCell1 = False
        grewOnCell2 = False
        for seed in xrange(100):
            tm = TemporalMemory(columnDimensions=[32],
                                cellsPerColumn=4,
                                activationThreshold=3,
                                initialPermanence=.2,
                                connectedPermanence=.50,
                                minThreshold=2,
                                maxNewSynapseCount=4,
                                permanenceIncrement=.10,
                                permanenceDecrement=.10,
                                predictedSegmentDecrement=0.02,
                                seed=seed)

            prevActiveColumns = [1, 2, 3, 4]
            activeColumns = [0]
            prevActiveCells = [4, 5, 6, 7]
            nonMatchingCells = [0, 3]
            activeCells = [0, 1, 2, 3]

            segment1 = tm.connections.createSegment(nonMatchingCells[0])
            tm.connections.createSynapse(segment1, prevActiveCells[0], .5)
            segment2 = tm.connections.createSegment(nonMatchingCells[1])
            tm.connections.createSynapse(segment2, prevActiveCells[1], .5)

            tm.compute(prevActiveColumns, True)
            tm.compute(activeColumns, True)

            self.assertEqual(activeCells, tm.getActiveCells())

            self.assertEqual(3, tm.connections.numSegments())
            self.assertEqual(1, len(tm.connections.segmentsForCell(0)))
            self.assertEqual(1, len(tm.connections.segmentsForCell(3)))
            self.assertEqual(1,
                             len(tm.connections.synapsesForSegment(segment1)))
            self.assertEqual(1,
                             len(tm.connections.synapsesForSegment(segment2)))

            segments = tm.connections.segmentsForCell(1)
            if len(segments) == 0:
                segments2 = tm.connections.segmentsForCell(2)
                self.assertFalse(len(segments2) == 0)
                grewOnCell2 = True
                segments.append(segments2[0])
            else:
                grewOnCell1 = True

            self.assertEqual(1, len(segments))
            synapses = tm.connections.synapsesForSegment(segments[0])
            self.assertEqual(4, len(synapses))

            columnChecklist = set(prevActiveColumns)

            for synapse in synapses:
                synapseData = tm.connections.dataForSynapse(synapse)
                self.assertAlmostEqual(.2, synapseData.permanence)

                column = tm.columnForCell(synapseData.presynapticCell)
                self.assertTrue(column in columnChecklist)
                columnChecklist.remove(column)
            self.assertTrue(len(columnChecklist) == 0)

        self.assertTrue(grewOnCell1)
        self.assertTrue(grewOnCell2)
  def testAddSegmentToCellWithFewestSegments(self):
    grewOnCell1 = False
    grewOnCell2 = False
    for seed in xrange(100):
      tm = TemporalMemory(
        columnDimensions=[32],
        cellsPerColumn=4,
        activationThreshold=3,
        initialPermanence=.2,
        connectedPermanence=.50,
        minThreshold=2,
        maxNewSynapseCount=4,
        permanenceIncrement=.10,
        permanenceDecrement=.10,
        predictedSegmentDecrement=0.02,
        seed=seed)

      prevActiveColumns = [1, 2, 3, 4]
      activeColumns = [0]
      prevActiveCells = [4, 5, 6, 7]
      nonMatchingCells = [0, 3]
      activeCells = [0, 1, 2, 3]

      segment1 = tm.connections.createSegment(nonMatchingCells[0])
      tm.connections.createSynapse(segment1, prevActiveCells[0], .5)
      segment2 = tm.connections.createSegment(nonMatchingCells[1])
      tm.connections.createSynapse(segment2, prevActiveCells[1], .5)

      tm.compute(prevActiveColumns, True)
      tm.compute(activeColumns, True)

      self.assertEqual(activeCells, tm.getActiveCells())

      self.assertEqual(3, tm.connections.numSegments())
      self.assertEqual(1, tm.connections.numSegments(0))
      self.assertEqual(1, tm.connections.numSegments(3))
      self.assertEqual(1, tm.connections.numSynapses(segment1))
      self.assertEqual(1, tm.connections.numSynapses(segment2))

      segments = list(tm.connections.segmentsForCell(1))
      if len(segments) == 0:
        segments2 = list(tm.connections.segmentsForCell(2))
        self.assertFalse(len(segments2) == 0)
        grewOnCell2 = True
        segments.append(segments2[0])
      else:
        grewOnCell1 = True

      self.assertEqual(1, len(segments))
      synapses = list(tm.connections.synapsesForSegment(segments[0]))
      self.assertEqual(4, len(synapses))

      columnChecklist = set(prevActiveColumns)

      for synapse in synapses:
        synapseData = tm.connections.dataForSynapse(synapse)
        self.assertAlmostEqual(.2, synapseData.permanence)

        column = tm.columnForCell(synapseData.presynapticCell)
        self.assertTrue(column in columnChecklist)
        columnChecklist.remove(column)
      self.assertTrue(len(columnChecklist) == 0)

    self.assertTrue(grewOnCell1)
    self.assertTrue(grewOnCell2)
Exemple #35
0
class Region(Node):
  """
  A class only to group properties related to regions.
  """

  #region Constructor

  def __init__(self, name):
    """
    Initializes a new instance of this class.
    """

    Node.__init__(self, name, NodeType.region)

    #region Instance fields

    self.columns = []
    """List of columns that compose this region"""

    self._inputMap = []
    """An array representing the input map for this region."""

    #region Spatial Parameters

    self.enableSpatialLearning = True
    """Switch for spatial learning"""

    self.potentialRadius = 0
    """This parameter determines the extent of the input that each column can potentially be connected to. This can be thought of as the input bits that are visible to each column, or a 'receptiveField' of the field of vision. A large enough value will result in 'global coverage', meaning that each column can potentially be connected to every input bit. This parameter defines a square (or hyper square) area: a column will have a max square potential pool with sides of length 2 * potentialRadius + 1."""

    self.potentialPct = 0.5
    """The percent of the inputs, within a column's potential radius, that a column can be connected to. If set to 1, the column will be connected to every input within its potential radius. This parameter is used to give each column a unique potential pool when a large potentialRadius causes overlap between the columns. At initialization time we choose ((2*potentialRadius + 1)^(# inputDimensions) * potentialPct) input bits to comprise the column's potential pool."""

    self.globalInhibition = False
    """If true, then during inhibition phase the winning columns are selected as the most active columns from the region as a whole. Otherwise, the winning columns are selected with respect to their local neighborhoods. Using global inhibition boosts performance x60."""

    self.localAreaDensity = -1.0
    """The desired density of active columns within a local inhibition area (the size of which is set by the internally calculated inhibitionRadius, which is in turn determined from the average size of the connected potential pools of all columns). The inhibition logic will insure that at most N columns remain ON within a local inhibition area, where N = localAreaDensity * (total number of columns in inhibition area)."""

    self.numActiveColumnsPerInhArea = int(0.02 * (self.width * self.height))
    """An alternate way to control the density of the active columns. If numActiveColumnsPerInhArea is specified then localAreaDensity must be less than 0, and vice versa. When using numActiveColumnsPerInhArea, the inhibition logic will insure that at most 'numActiveColumnsPerInhArea' columns remain ON within a local inhibition area (the size of which is set by the internally calculated inhibitionRadius, which is in turn determined from the average size of the connected receptive fields of all columns). When using this method, as columns learn and grow their effective receptive fields, the inhibitionRadius will grow, and hence the net density of the active columns will *decrease*. This is in contrast to the localAreaDensity method, which keeps the density of active columns the same regardless of the size of their receptive fields."""

    self.stimulusThreshold = 0
    """This is a number specifying the minimum number of synapses that must be on in order for a columns to turn ON. The purpose of this is to prevent noise input from activating columns. Specified as a percent of a fully grown synapse."""

    self.proximalSynConnectedPerm = 0.10
    """The default connected threshold. Any synapse whose permanence value is above the connected threshold is a "connected synapse", meaning it can contribute to the cell's firing."""

    self.proximalSynPermIncrement = 0.1
    """The amount by which an active synapse is incremented in each round. Specified as a percent of a fully grown synapse."""

    self.proximalSynPermDecrement = 0.01
    """The amount by which an inactive synapse is decremented in each round. Specified as a percent of a fully grown synapse."""

    self.minPctOverlapDutyCycle = 0.001
    """A number between 0 and 1.0, used to set a floor on how often a column should have at least stimulusThreshold active inputs. Periodically, each column looks at the overlap duty cycle of all other columns within its inhibition radius and sets its own internal minimal acceptable duty cycle to:
      minPctDutyCycleBeforeInh * max(other columns' duty cycles).
    On each iteration, any column whose overlap duty cycle falls below this computed value will get all of its permanence values boosted up by synPermActiveInc. Raising all permanences in response to a sub-par duty cycle before inhibition allows a cell to search for new inputs when either its previously learned inputs are no longer ever active, or when the vast majority of them have been "hijacked" by other columns."""

    self.minPctActiveDutyCycle = 0.001
    """A number between 0 and 1.0, used to set a floor on how often a column should be activate. Periodically, each column looks at the activity duty cycle of all other columns within its inhibition radius and sets its own internal minimal acceptable duty cycle to:
      minPctDutyCycleAfterInh * max(other columns' duty cycles).
    On each iteration, any column whose duty cycle after inhibition falls below this computed value will get its internal boost factor increased."""

    self.dutyCyclePeriod = 1000
    """The period used to calculate duty cycles. Higher values make it take longer to respond to changes in boost or synPerConnectedCell. Shorter values make it more unstable and likely to oscillate."""

    self.maxBoost = 10.0
    """The maximum overlap boost factor. Each column's overlap gets multiplied by a boost factor before it gets considered for inhibition. The actual boost factor for a column is number between 1.0 and maxBoost. A boost factor of 1.0 is used if the duty cycle is >= minOverlapDutyCycle, maxBoost is used if the duty cycle is 0, and any duty cycle in between is linearly extrapolated from these 2 endpoints."""

    self.spSeed = -1
    """Seed for generate random values"""

    #endregion

    #region Temporal Parameters

    self.enableTemporalLearning = True
    """Switch for temporal learning"""

    self.numCellsPerColumn = 10
    """Number of cells per column. More cells, more contextual information"""

    self.distalSynInitialPerm = 0.11
    """The initial permanence of an distal synapse."""

    self.distalSynConnectedPerm = 0.50
    """The default connected threshold. Any synapse whose permanence value is above the connected threshold is a "connected synapse", meaning it can contribute to the cell's firing."""

    self.distalSynPermIncrement = 0.10
    """The amount by which an active synapse is incremented in each round. Specified as a percent of a fully grown synapse."""

    self.distalSynPermDecrement = 0.10
    """The amount by which an inactive synapse is decremented in each round. Specified as a percent of a fully grown synapse."""

    self.minThreshold = 8
    """If the number of synapses active on a segment is at least this threshold, it is selected as the best matching cell in a bursing column."""

    self.activationThreshold = 12
    """If the number of active connected synapses on a segment is at least this threshold, the segment is said to be active."""

    self.maxNumNewSynapses = 15
    """The maximum number of synapses added to a segment during learning."""

    self.tpSeed = 42
    """Seed for generate random values"""

    #endregion

    self.spatialPooler = None
    """Spatial Pooler instance"""

    self.temporalPooler = None
    """Temporal Pooler instance"""

    #endregion

    #region Statistics properties

    self.statsPrecisionRate = 0.

    #endregion

  #endregion

  #region Methods

  def getColumn(self, x, y):
    """
    Return the column located at given position
    """

    column = self.columns[(y * self.width) + x]

    return column

  def getInputSize(self):
    """
    Return the sum of sizes of all feeder nodes.
    """

    sumSizes = 0
    for feeder in Global.project.network.getFeederNodes(self):
      sumSizes += feeder.width * feeder.height

    return sumSizes

  def initialize(self):
    """
    Initialize this node.
    """

    # Check if this region has nodes that feed it
    numFeeders = len(Global.project.network.getFeederNodes(self))
    if numFeeders == 0:
      QtGui.QMessageBox.warning(None, "Warning", "Region '" + self.name + "' does not have any child!")
      return

    # Initialize this node and the nodes that feed it
    Node.initialize(self)

    # Create the input map
    # An input map is a set of input elements (cells or sensor bits) that should are grouped
    # For example, if we have 2 nodes that feed this region (#1 and #2) with dimensions 6 and 12 respectively,
    # a input map would be something like:
    #   111111222222222222
    self._inputMap = []
    elemIdx = 0
    for feeder in Global.project.network.getFeederNodes(self):

      # Arrange input from feeder into input map of this region
      if feeder.type == NodeType.region:
        for column in feeder.columns:
          inputElem = column.cells[0]
          self._inputMap.append(inputElem)
      else:
        for bit in feeder.bits:
          inputElem = bit
          self._inputMap.append(inputElem)
      elemIdx += 1

    # Initialize elements
    self.columns = []
    colIdx = 0
    for x in range(self.width):
      for y in range(self.height):
        column = Column()
        column.x = x
        column.y = y
        for z in range(self.numCellsPerColumn):
          cell = Cell()
          cell.index = (colIdx * self.numCellsPerColumn) + z
          cell.z = z
          column.cells.append(cell)
        self.columns.append(column)
        colIdx += 1

    # Create Spatial Pooler instance with appropriate parameters
    self.spatialPooler = SpatialPooler(
      inputDimensions = (self.getInputSize(), 1),
      columnDimensions = (self.width, self.height),
      potentialRadius = self.potentialRadius,
      potentialPct = self.potentialPct,
      globalInhibition = self.globalInhibition,
      localAreaDensity = self.localAreaDensity,
      numActiveColumnsPerInhArea = self.numActiveColumnsPerInhArea,
      stimulusThreshold = self.stimulusThreshold,
      synPermInactiveDec = self.proximalSynPermDecrement,
      synPermActiveInc = self.proximalSynPermIncrement,
      synPermConnected = self.proximalSynConnectedPerm,
      minPctOverlapDutyCycle = self.minPctOverlapDutyCycle,
      minPctActiveDutyCycle = self.minPctActiveDutyCycle,
      dutyCyclePeriod = self.dutyCyclePeriod,
      maxBoost = self.maxBoost,
      seed = self.spSeed,
      spVerbosity = False)

    # Create Temporal Pooler instance with appropriate parameters
    self.temporalPooler = TemporalPooler(
      columnDimensions = (self.width, self.height),
      cellsPerColumn = self.numCellsPerColumn,
      initialPermanence = self.distalSynInitialPerm,
      connectedPermanence = self.distalSynConnectedPerm,
      minThreshold = self.minThreshold,
      maxNewSynapseCount = self.maxNumNewSynapses,
      permanenceIncrement = self.distalSynPermIncrement,
      permanenceDecrement = self.distalSynPermDecrement,
      activationThreshold = self.activationThreshold,
      seed = self.tpSeed)

    return True

  def nextStep(self):
    """
    Perfoms actions related to time step progression.
    """

    Node.nextStep(self)
    for column in self.columns:
      column.nextStep()

    # Get input from sensors or lower regions and put into a single input map.
    input = self.getInput()

    # Send input to Spatial Pooler and get processed output (i.e. the active columns)
    # First initialize the vector for representing the current record
    columnDimensions = (self.width, self.height)
    columnNumber = numpy.array(columnDimensions).prod()
    activeColumns = numpy.zeros(columnNumber)
    self.spatialPooler.compute(input, self.enableSpatialLearning, activeColumns)

    # Send active columns to Temporal Pooler and get processed output (i.e. the predicting cells)
    # First convert active columns from float array to integer set
    activeColumnsSet = set()
    for colIdx in range(len(activeColumns)):
      if activeColumns[colIdx] == 1:
        activeColumnsSet.add(colIdx)
    self.temporalPooler.compute(activeColumnsSet, self.enableTemporalLearning)

    # Update elements regarding spatial pooler
    self.updateSpatialElements(activeColumns)

    # Update elements regarding temporal pooler
    self.updateTemporalElements()

    # Get the predicted values
    self.getPredictions()

    #TODO: self._output = self.temporalPooler.getPredictedState()

  def getPredictions(self):
    """
    Get the predicted values after an iteration.
    """

    for feeder in Global.project.network.getFeederNodes(self):
      feeder.getPredictions()

  def calculateStatistics(self):
    """
    Calculate statistics after an iteration.
    """

    # The region's prediction precision is the average between the nodes that feed it
    precisionRate = 0.
    numFeeders = 0
    for feeder in Global.project.network.getFeederNodes(self):
      precisionRate += feeder.statsPrecisionRate
      numFeeders += 1
    self.statsPrecisionRate = precisionRate / numFeeders

    for column in self.columns:
      column.calculateStatistics()

  def getInput(self):
    """
    Get input from sensors or lower regions and put into a single input map.
    """

    # Initialize the vector for representing the current input map
    inputList = []
    for inputElem in self._inputMap:
      if inputElem.isActive.atCurrStep():
        inputList.append(1)
      else:
        inputList.append(0)
    input = numpy.array(inputList)

    return input

  def updateSpatialElements(self, activeColumns):
    """
    Update elements regarding spatial pooler
    """

    # Update proximal segments and synapses according to active columns
    for colIdx in range(len(self.columns)):
      column = self.columns[colIdx]

      # Update proximal segment
      segment = column.segment
      if activeColumns[colIdx] == 1:
        segment.isActive.setForCurrStep(True)
      else:
        segment.isActive.setForCurrStep(False)

      # Check if proximal segment is predicted by check if the column has any predicted cell
      for cell in column.cells:
        if cell.index in self.temporalPooler.predictiveCells:
          segment.isPredicted.setForCurrStep(True)

      # Update proximal synapses
      if segment.isActive.atCurrStep() or segment.isPredicted.atCurrStep():
        permanencesSynapses = []
        self.spatialPooler.getPermanence(colIdx, permanencesSynapses)
        connectedSynapses = []
        self.spatialPooler.getConnectedSynapses(colIdx, connectedSynapses)
        for synIdx in range(len(permanencesSynapses)):
          # Get the proximal synapse given its position in the input map
          # Create a new one if it doesn't exist
          synapse = segment.getSynapse(synIdx)

          # Update proximal synapse
          if permanencesSynapses[synIdx] > 0.:
            if synapse == None:
              # Create a new synapse to a input element
              # An input element is a column if feeder is a region
              # or then a bit if feeder is a sensor
              synapse = Synapse()
              synapse.inputElem = self._inputMap[synIdx]
              synapse.indexSP = synIdx
              segment.synapses.append(synapse)

            # Update state
            synapse.isRemoved.setForCurrStep(False)
            synapse.permanence.setForCurrStep(permanencesSynapses[synIdx])
            if connectedSynapses[synIdx] == 1:
              synapse.isConnected.setForCurrStep(True)
            else:
              synapse.isConnected.setForCurrStep(False)
          else:
            if synapse != None:
              synapse.isRemoved.setForCurrStep(True)

  def updateTemporalElements(self):
    """
    Update elements regarding temporal pooler
    """

    # Update cells, distal segments and synapses according to active columns
    for colIdx in range(len(self.columns)):
      column = self.columns[colIdx]

      # Mark proximal segment and its connected synapses as predicted
      if column.segment.isPredicted.atCurrStep():
        for synapse in column.segment.synapses:
          if synapse.isConnected.atCurrStep():
            synapse.isPredicted.setForCurrStep(True)
            synapse.inputElem.isPredicted.setForCurrStep(True)

      # Mark proximal segment and its connected synapses that were predicted but are not active now
      if column.segment.isPredicted.atPreviousStep():
        if not column.segment.isActive.atCurrStep():
          column.segment.isFalselyPredicted.setForCurrStep(True)
        for synapse in column.segment.synapses:
          if (synapse.isPredicted.atPreviousStep() and not synapse.isConnected.atCurrStep()) or (synapse.isConnected.atCurrStep() and synapse.inputElem.isFalselyPredicted.atCurrStep()):
            synapse.isFalselyPredicted.setForCurrStep(True)

      for cell in column.cells:
        cellIdx = cell.index

        # Update cell's states
        if cellIdx in self.temporalPooler.winnerCells:
          cell.isLearning.setForCurrStep(True)
        if cellIdx in self.temporalPooler.activeCells:
          cell.isActive.setForCurrStep(True)
        if cellIdx in self.temporalPooler.predictiveCells:
          cell.isPredicted.setForCurrStep(True)
        if cell.isPredicted.atPreviousStep() and not cell.isActive.atCurrStep():
          cell.isFalselyPredicted.setForCurrStep(True)

        # Get the indexes of the distal segments of this cell
        segmentsForCell = self.temporalPooler.connections.segmentsForCell(cellIdx)

        # Add the segments that appeared after last iteration
        for segIdx in segmentsForCell:
          # Check if segment already exists in the cell
          segFound = False
          for segment in cell.segments:
            if segment.indexTP == segIdx:
              segFound = True
              break

          # If segment is new, add it to cell
          if not segFound:
            segment = Segment(SegmentType.distal)
            segment.indexTP = segIdx
            cell.segments.append(segment)

        # Update distal segments
        for segment in cell.segments:
          segIdx = segment.indexTP

          # If segment not found in segments indexes returned in last iteration mark it as removed
          if segIdx in segmentsForCell:

            # Update segment's state
            if segIdx in self.temporalPooler.activeSegments:
              segment.isActive.setForCurrStep(True)
            else:
              segment.isActive.setForCurrStep(False)

            # Get the indexes of the synapses of this segment
            synapsesForSegment = self.temporalPooler.connections.synapsesForSegment(segIdx)

            # Add the synapses that appeared after last iteration
            for synIdx in synapsesForSegment:
              # Check if synapse already exists in the segment
              synFound = False
              for synapse in segment.synapses:
                if synapse.indexTP == synIdx:
                  synFound = True
                  break

              # If synapse is new, add it to segment
              if not synFound:
                synapse = Synapse()
                synapse.indexTP = synIdx
                segment.synapses.append(synapse)

            # Update synapses
            for synapse in segment.synapses:
              synIdx = synapse.indexTP

              # If synapse not found in synapses indexes returned in last iteration mark it as removed
              if synIdx in synapsesForSegment:

                # Update synapse's state
                (_, sourceCellAbsIdx, permanence) = self.temporalPooler.connections.dataForSynapse(synIdx)
                synapse.permanence.setForCurrStep(permanence)
                if permanence >= self.distalSynConnectedPerm:
                  synapse.isConnected.setForCurrStep(True)
                else:
                  synapse.isConnected.setForCurrStep(False)

                # Get cell given cell's index
                sourceColIdx = sourceCellAbsIdx / self.numCellsPerColumn
                sourceCellRelIdx = sourceCellAbsIdx % self.numCellsPerColumn
                sourceCell = self.columns[sourceColIdx].cells[sourceCellRelIdx]
                synapse.inputElem = sourceCell
              else:
                synapse.isRemoved.setForCurrStep(True)
          else:
            segment.isRemoved.setForCurrStep(True)
  def testRecycleLeastRecentlyActiveSegmentToMakeRoomForNewSegment(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=1,
      activationThreshold=3,
      initialPermanence=.50,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=3,
      permanenceIncrement=.02,
      permanenceDecrement=.02,
      predictedSegmentDecrement=0.0,
      seed=42,
      maxSegmentsPerCell=2)

    prevActiveColumns1 = [0, 1, 2]
    prevActiveColumns2 = [3, 4, 5]
    prevActiveColumns3 = [6, 7, 8]
    activeColumns = [9]

    tm.compute(prevActiveColumns1)
    tm.compute(activeColumns)

    self.assertEqual(1, tm.connections.numSegments(9))
    oldestSegment = list(tm.connections.segmentsForCell(9))[0]
    tm.reset()
    tm.compute(prevActiveColumns2)
    tm.compute(activeColumns)

    self.assertEqual(2, tm.connections.numSegments(9))

    oldPresynaptic = \
      set(synapse.presynapticCell
          for synapse in tm.connections.synapsesForSegment(oldestSegment))

    tm.reset()
    tm.compute(prevActiveColumns3)
    tm.compute(activeColumns)
    self.assertEqual(2, tm.connections.numSegments(9))

    # Verify none of the segments are connected to the cells the old
    # segment was connected to.

    for segment in tm.connections.segmentsForCell(9):
      newPresynaptic = set(synapse.presynapticCell
                           for synapse
                           in tm.connections.synapsesForSegment(segment))
      self.assertEqual([], list(oldPresynaptic & newPresynaptic))
Exemple #37
0
    #        tm.reset()
    #        recordNum = 0

    for dataList in trainingData2:

        print("----------dataList = {}----------".format(dataList[0]))
        for data in dataList[0]:
            spIn.fill(0)
            spIn[:sp.getInputDimensions()[1]] = numpy.resize(
                encoder1.encode(data),
                sp.getInputDimensions()[1])

            sp.compute(spIn, True, spOut)

            tmIn = set(numpy.where(spOut > 0)[0])
            tm.compute(tmIn, True)

            retVal = cla.compute(
                recordNum,
                tm.activeCells,
                {
                    'bucketIdx': encoder1.getBucketIndices(data)[0],
                    'actValue': data
                },
                True,
                True,
                lambda x: x.endswith('x') or x.endswith('y') or x.endswith('z')\
                    or x.endswith('a')
            )

            recordNum += 1
  def testRecycleLeastRecentlyActiveSegmentToMakeRoomForNewSegment(self):
    tm = TemporalMemory(
      columnDimensions=[32],
      cellsPerColumn=1,
      activationThreshold=3,
      initialPermanence=.50,
      connectedPermanence=.50,
      minThreshold=2,
      maxNewSynapseCount=3,
      permanenceIncrement=.02,
      permanenceDecrement=.02,
      predictedSegmentDecrement=0.0,
      seed=42,
      maxSegmentsPerCell=2)

    prevActiveColumns1 = [0, 1, 2]
    prevActiveColumns2 = [3, 4, 5]
    prevActiveColumns3 = [6, 7, 8]
    activeColumns = [9]

    tm.compute(prevActiveColumns1)
    tm.compute(activeColumns)

    self.assertEqual(1, len(tm.connections.segmentsForCell(9)))
    oldestSegment = tm.connections.segmentsForCell(9)[0]
    tm.reset()
    tm.compute(prevActiveColumns2)
    tm.compute(activeColumns)

    self.assertEqual(2, len(tm.connections.segmentsForCell(9)))

    tm.reset()
    tm.compute(prevActiveColumns3)
    tm.compute(activeColumns)
    self.assertEqual(2, len(tm.connections.segmentsForCell(9)))


    synapses = tm.connections.synapsesForSegment(oldestSegment)
    self.assertEqual(3, len(synapses))
    presynapticCells = set()

    for synapseData in tm.connections.dataForSegment(oldestSegment).synapses:
      presynapticCells.add(synapseData.presynapticCell)

    expected = set([6,7,8])
    self.assertEqual(expected, presynapticCells)
Exemple #39
0
class Region(Node):
  """
  A class only to group properties related to regions.
  """

  #region Constructor

  def __init__(self, name):
    """
    Initializes a new instance of this class.
    """

    Node.__init__(self, name, NodeType.region)

    #region Instance fields

    self.columns = []
    """List of columns that compose this region"""

    self._inputMap = []
    """An array representing the input map for this region."""

    #region Spatial Parameters

    self.enableSpatialLearning = True
    """Switch for spatial learning"""

    self.potentialRadius = 0
    """This parameter determines the extent of the input that each column can potentially be connected to. This can be thought of as the input bits that are visible to each column, or a 'receptiveField' of the field of vision. A large enough value will result in 'global coverage', meaning that each column can potentially be connected to every input bit. This parameter defines a square (or hyper square) area: a column will have a max square potential pool with sides of length 2 * potentialRadius + 1."""

    self.potentialPct = 0.5
    """The percent of the inputs, within a column's potential radius, that a column can be connected to. If set to 1, the column will be connected to every input within its potential radius. This parameter is used to give each column a unique potential pool when a large potentialRadius causes overlap between the columns. At initialization time we choose ((2*potentialRadius + 1)^(# inputDimensions) * potentialPct) input bits to comprise the column's potential pool."""

    self.globalInhibition = False
    """If true, then during inhibition phase the winning columns are selected as the most active columns from the region as a whole. Otherwise, the winning columns are selected with respect to their local neighborhoods. Using global inhibition boosts performance x60."""

    self.localAreaDensity = -1.0
    """The desired density of active columns within a local inhibition area (the size of which is set by the internally calculated inhibitionRadius, which is in turn determined from the average size of the connected potential pools of all columns). The inhibition logic will insure that at most N columns remain ON within a local inhibition area, where N = localAreaDensity * (total number of columns in inhibition area)."""

    self.numActiveColumnsPerInhArea = int(0.02 * (self.width * self.height))
    """An alternate way to control the density of the active columns. If numActiveColumnsPerInhArea is specified then localAreaDensity must be less than 0, and vice versa. When using numActiveColumnsPerInhArea, the inhibition logic will insure that at most 'numActiveColumnsPerInhArea' columns remain ON within a local inhibition area (the size of which is set by the internally calculated inhibitionRadius, which is in turn determined from the average size of the connected receptive fields of all columns). When using this method, as columns learn and grow their effective receptive fields, the inhibitionRadius will grow, and hence the net density of the active columns will *decrease*. This is in contrast to the localAreaDensity method, which keeps the density of active columns the same regardless of the size of their receptive fields."""

    self.stimulusThreshold = 0
    """This is a number specifying the minimum number of synapses that must be on in order for a columns to turn ON. The purpose of this is to prevent noise input from activating columns. Specified as a percent of a fully grown synapse."""

    self.proximalSynConnectedPerm = 0.10
    """The default connected threshold. Any synapse whose permanence value is above the connected threshold is a "connected synapse", meaning it can contribute to the cell's firing."""

    self.proximalSynPermIncrement = 0.1
    """The amount by which an active synapse is incremented in each round. Specified as a percent of a fully grown synapse."""

    self.proximalSynPermDecrement = 0.01
    """The amount by which an inactive synapse is decremented in each round. Specified as a percent of a fully grown synapse."""

    self.minPctOverlapDutyCycle = 0.001
    """A number between 0 and 1.0, used to set a floor on how often a column should have at least stimulusThreshold active inputs. Periodically, each column looks at the overlap duty cycle of all other columns within its inhibition radius and sets its own internal minimal acceptable duty cycle to:
      minPctDutyCycleBeforeInh * max(other columns' duty cycles).
    On each iteration, any column whose overlap duty cycle falls below this computed value will get all of its permanence values boosted up by synPermActiveInc. Raising all permanences in response to a sub-par duty cycle before inhibition allows a cell to search for new inputs when either its previously learned inputs are no longer ever active, or when the vast majority of them have been "hijacked" by other columns."""

    self.minPctActiveDutyCycle = 0.001
    """A number between 0 and 1.0, used to set a floor on how often a column should be activate. Periodically, each column looks at the activity duty cycle of all other columns within its inhibition radius and sets its own internal minimal acceptable duty cycle to:
      minPctDutyCycleAfterInh * max(other columns' duty cycles).
    On each iteration, any column whose duty cycle after inhibition falls below this computed value will get its internal boost factor increased."""

    self.dutyCyclePeriod = 1000
    """The period used to calculate duty cycles. Higher values make it take longer to respond to changes in boost or synPerConnectedCell. Shorter values make it more unstable and likely to oscillate."""

    self.maxBoost = 10.0
    """The maximum overlap boost factor. Each column's overlap gets multiplied by a boost factor before it gets considered for inhibition. The actual boost factor for a column is number between 1.0 and maxBoost. A boost factor of 1.0 is used if the duty cycle is >= minOverlapDutyCycle, maxBoost is used if the duty cycle is 0, and any duty cycle in between is linearly extrapolated from these 2 endpoints."""

    self.spSeed = -1
    """Seed for generate random values"""

    #endregion

    #region Temporal Parameters

    self.enableTemporalLearning = True
    """Switch for temporal learning"""

    self.numCellsPerColumn = 10
    """Number of cells per column. More cells, more contextual information"""

    self.distalSynInitialPerm = 0.11
    """The initial permanence of an distal synapse."""

    self.distalSynConnectedPerm = 0.50
    """The default connected threshold. Any synapse whose permanence value is above the connected threshold is a "connected synapse", meaning it can contribute to the cell's firing."""

    self.distalSynPermIncrement = 0.10
    """The amount by which an active synapse is incremented in each round. Specified as a percent of a fully grown synapse."""

    self.distalSynPermDecrement = 0.10
    """The amount by which an inactive synapse is decremented in each round. Specified as a percent of a fully grown synapse."""

    self.minThreshold = 8
    """If the number of synapses active on a segment is at least this threshold, it is selected as the best matching cell in a bursing column."""

    self.activationThreshold = 12
    """If the number of active connected synapses on a segment is at least this threshold, the segment is said to be active."""

    self.maxNumNewSynapses = 15
    """The maximum number of synapses added to a segment during learning."""

    self.tpSeed = 42
    """Seed for generate random values"""

    #endregion

    self.spatialPooler = None
    """Spatial Pooler instance"""

    self.temporalPooler = None
    """Temporal Pooler instance"""

    #endregion

    #region Statistics properties

    self.statsPrecisionRate = 0.

    #endregion

  #endregion

  #region Methods

  def getColumn(self, x, y):
    """
    Return the column located at given position
    """

    column = self.columns[(y * self.width) + x]

    return column

  def getInputSize(self):
    """
    Return the sum of sizes of all feeder nodes.
    """

    sumSizes = 0
    for feeder in Global.project.network.getFeederNodes(self):
      sumSizes += feeder.width * feeder.height

    return sumSizes

  def initialize(self):
    """
    Initialize this node.
    """

    # Check if this region has nodes that feed it
    numFeeders = len(Global.project.network.getFeederNodes(self))
    if numFeeders == 0:
      QtGui.QMessageBox.warning(None, "Warning", "Region '" + self.name + "' does not have any child!")
      return

    # Initialize this node and the nodes that feed it
    Node.initialize(self)

    # Create the input map
    # An input map is a set of input elements (cells or sensor bits) that should are grouped
    # For example, if we have 2 nodes that feed this region (#1 and #2) with dimensions 6 and 12 respectively,
    # a input map would be something like:
    #   111111222222222222
    self._inputMap = []
    elemIdx = 0
    for feeder in Global.project.network.getFeederNodes(self):

      # Arrange input from feeder into input map of this region
      if feeder.type == NodeType.region:
        for column in feeder.columns:
          inputElem = column.cells[0]
          self._inputMap.append(inputElem)
      else:
        for bit in feeder.bits:
          inputElem = bit
          self._inputMap.append(inputElem)
      elemIdx += 1

    # Initialize elements
    self.columns = []
    colIdx = 0
    for x in range(self.width):
      for y in range(self.height):
        column = Column()
        column.x = x
        column.y = y
        for z in range(self.numCellsPerColumn):
          cell = Cell()
          cell.index = (colIdx * self.numCellsPerColumn) + z
          cell.z = z
          column.cells.append(cell)
        self.columns.append(column)
        colIdx += 1

    # Create Spatial Pooler instance with appropriate parameters
    self.spatialPooler = SpatialPooler(
      inputDimensions = (self.getInputSize(), 1),
      columnDimensions = (self.width, self.height),
      potentialRadius = self.potentialRadius,
      potentialPct = self.potentialPct,
      globalInhibition = self.globalInhibition,
      localAreaDensity = self.localAreaDensity,
      numActiveColumnsPerInhArea = self.numActiveColumnsPerInhArea,
      stimulusThreshold = self.stimulusThreshold,
      synPermInactiveDec = self.proximalSynPermDecrement,
      synPermActiveInc = self.proximalSynPermIncrement,
      synPermConnected = self.proximalSynConnectedPerm,
      minPctOverlapDutyCycle = self.minPctOverlapDutyCycle,
      minPctActiveDutyCycle = self.minPctActiveDutyCycle,
      dutyCyclePeriod = self.dutyCyclePeriod,
      maxBoost = self.maxBoost,
      seed = self.spSeed,
      spVerbosity = False)

    # Create Temporal Pooler instance with appropriate parameters
    self.temporalPooler = TemporalPooler(
      columnDimensions = (self.width, self.height),
      cellsPerColumn = self.numCellsPerColumn,
      initialPermanence = self.distalSynInitialPerm,
      connectedPermanence = self.distalSynConnectedPerm,
      minThreshold = self.minThreshold,
      maxNewSynapseCount = self.maxNumNewSynapses,
      permanenceIncrement = self.distalSynPermIncrement,
      permanenceDecrement = self.distalSynPermDecrement,
      activationThreshold = self.activationThreshold,
      seed = self.tpSeed)

    return True

  def nextStep(self):
    """
    Perfoms actions related to time step progression.
    """

    Node.nextStep(self)
    for column in self.columns:
      column.nextStep()

    # Get input from sensors or lower regions and put into a single input map.
    input = self.getInput()

    # Send input to Spatial Pooler and get processed output (i.e. the active columns)
    # First initialize the vector for representing the current record
    columnDimensions = (self.width, self.height)
    columnNumber = numpy.array(columnDimensions).prod()
    activeColumns = numpy.zeros(columnNumber)
    self.spatialPooler.compute(input, self.enableSpatialLearning, activeColumns)

    # Send active columns to Temporal Pooler and get processed output (i.e. the predicting cells)
    # First convert active columns from float array to integer set
    activeColumnsSet = set()
    for colIdx in range(len(activeColumns)):
      if activeColumns[colIdx] == 1:
        activeColumnsSet.add(colIdx)
    self.temporalPooler.compute(activeColumnsSet, self.enableTemporalLearning)

    # Update elements regarding spatial pooler
    self.updateSpatialElements(activeColumns)

    # Update elements regarding temporal pooler
    self.updateTemporalElements()

    # Get the predicted values
    self.getPredictions()

    #TODO: self._output = self.temporalPooler.getPredictedState()

  def getPredictions(self):
    """
    Get the predicted values after an iteration.
    """

    for feeder in Global.project.network.getFeederNodes(self):
      feeder.getPredictions()

  def calculateStatistics(self):
    """
    Calculate statistics after an iteration.
    """

    # The region's prediction precision is the average between the nodes that feed it
    precisionRate = 0.
    numFeeders = 0
    for feeder in Global.project.network.getFeederNodes(self):
      precisionRate += feeder.statsPrecisionRate
      numFeeders += 1
    self.statsPrecisionRate = precisionRate / numFeeders

    for column in self.columns:
      column.calculateStatistics()

  def getInput(self):
    """
    Get input from sensors or lower regions and put into a single input map.
    """

    # Initialize the vector for representing the current input map
    inputList = []
    for inputElem in self._inputMap:
      if inputElem.isActive.atCurrStep():
        inputList.append(1)
      else:
        inputList.append(0)
    input = numpy.array(inputList)

    return input

  def updateSpatialElements(self, activeColumns):
    """
    Update elements regarding spatial pooler
    """

    # Update proximal segments and synapses according to active columns
    for colIdx in range(len(self.columns)):
      column = self.columns[colIdx]

      # Update proximal segment
      segment = column.segment
      if activeColumns[colIdx] == 1:
        segment.isActive.setForCurrStep(True)
      else:
        segment.isActive.setForCurrStep(False)

      # Check if proximal segment is predicted by check if the column has any predicted cell
      for cell in column.cells:
        if cell.index in self.temporalPooler.predictiveCells:
          segment.isPredicted.setForCurrStep(True)

      # Update proximal synapses
      if segment.isActive.atCurrStep() or segment.isPredicted.atCurrStep():
        permanencesSynapses = []
        self.spatialPooler.getPermanence(colIdx, permanencesSynapses)
        connectedSynapses = []
        self.spatialPooler.getConnectedSynapses(colIdx, connectedSynapses)
        for synIdx in range(len(permanencesSynapses)):
          # Get the proximal synapse given its position in the input map
          # Create a new one if it doesn't exist
          synapse = segment.getSynapse(synIdx)

          # Update proximal synapse
          if permanencesSynapses[synIdx] > 0.:
            if synapse == None:
              # Create a new synapse to a input element
              # An input element is a column if feeder is a region
              # or then a bit if feeder is a sensor
              synapse = Synapse()
              synapse.inputElem = self._inputMap[synIdx]
              synapse.indexSP = synIdx
              segment.synapses.append(synapse)

            # Update state
            synapse.isRemoved.setForCurrStep(False)
            synapse.permanence.setForCurrStep(permanencesSynapses[synIdx])
            if connectedSynapses[synIdx] == 1:
              synapse.isConnected.setForCurrStep(True)
            else:
              synapse.isConnected.setForCurrStep(False)
          else:
            if synapse != None:
              synapse.isRemoved.setForCurrStep(True)

  def updateTemporalElements(self):
    """
    Update elements regarding temporal pooler
    """

    # Update cells, distal segments and synapses according to active columns
    for colIdx in range(len(self.columns)):
      column = self.columns[colIdx]

      # Mark proximal segment and its connected synapses as predicted
      if column.segment.isPredicted.atCurrStep():
        for synapse in column.segment.synapses:
          if synapse.isConnected.atCurrStep():
            synapse.isPredicted.setForCurrStep(True)
            synapse.inputElem.isPredicted.setForCurrStep(True)

      # Mark proximal segment and its connected synapses that were predicted but are not active now
      if column.segment.isPredicted.atPreviousStep():
        if not column.segment.isActive.atCurrStep():
          column.segment.isFalselyPredicted.setForCurrStep(True)
        for synapse in column.segment.synapses:
          if (synapse.isPredicted.atPreviousStep() and not synapse.isConnected.atCurrStep()) or (synapse.isConnected.atCurrStep() and synapse.inputElem.isFalselyPredicted.atCurrStep()):
            synapse.isFalselyPredicted.setForCurrStep(True)

      for cell in column.cells:
        cellIdx = cell.index

        # Update cell's states
        if cellIdx in self.temporalPooler.winnerCells:
          cell.isLearning.setForCurrStep(True)
        if cellIdx in self.temporalPooler.activeCells:
          cell.isActive.setForCurrStep(True)
        if cellIdx in self.temporalPooler.predictiveCells:
          cell.isPredicted.setForCurrStep(True)
        if cell.isPredicted.atPreviousStep() and not cell.isActive.atCurrStep():
          cell.isFalselyPredicted.setForCurrStep(True)

        # Get the indexes of the distal segments of this cell
        segmentsForCell = self.temporalPooler.connections.segmentsForCell(cellIdx)

        # Add the segments that appeared after last iteration
        for segIdx in segmentsForCell:
          # Check if segment already exists in the cell
          segFound = False
          for segment in cell.segments:
            if segment.indexTP == segIdx:
              segFound = True
              break

          # If segment is new, add it to cell
          if not segFound:
            segment = Segment(SegmentType.distal)
            segment.indexTP = segIdx
            cell.segments.append(segment)

        # Update distal segments
        for segment in cell.segments:
          segIdx = segment.indexTP

          # If segment not found in segments indexes returned in last iteration mark it as removed
          if segIdx in segmentsForCell:

            # Update segment's state
            if segIdx in self.temporalPooler.activeSegments:
              segment.isActive.setForCurrStep(True)
            else:
              segment.isActive.setForCurrStep(False)

            # Get the indexes of the synapses of this segment
            synapsesForSegment = self.temporalPooler.connections.synapsesForSegment(segIdx)

            # Add the synapses that appeared after last iteration
            for synIdx in synapsesForSegment:
              # Check if synapse already exists in the segment
              synFound = False
              for synapse in segment.synapses:
                if synapse.indexTP == synIdx:
                  synFound = True
                  break

              # If synapse is new, add it to segment
              if not synFound:
                synapse = Synapse()
                synapse.indexTP = synIdx
                segment.synapses.append(synapse)

            # Update synapses
            for synapse in segment.synapses:
              synIdx = synapse.indexTP

              # If synapse not found in synapses indexes returned in last iteration mark it as removed
              if synIdx in synapsesForSegment:

                # Update synapse's state
                synapseData = self.temporalPooler.connections.dataForSynapse(synIdx)
                synapse.permanence.setForCurrStep(synapseData.permanence)
                if synapseData.permanence >= self.distalSynConnectedPerm:
                  synapse.isConnected.setForCurrStep(True)
                else:
                  synapse.isConnected.setForCurrStep(False)

                # Get cell given cell's index
                sourceColIdx = synapseData.presynapticCell / self.numCellsPerColumn
                sourceCellRelIdx = synapseData.presynapticCell % self.numCellsPerColumn
                sourceCell = self.columns[sourceColIdx].cells[sourceCellRelIdx]
                synapse.inputElem = sourceCell
              else:
                synapse.isRemoved.setForCurrStep(True)
          else:
            segment.isRemoved.setForCurrStep(True)
Exemple #40
0
x[2, 20:30] = 1  # Input SDR representing "C", corresponding to columns 20-29
x[3, 30:40] = 1  # Input SDR representing "D", corresponding to columns 30-39
x[4, 40:50] = 1  # Input SDR representing "E", corresponding to columns 40-49

# Step 3: send this simple sequence to the temporal memory for learning
# We repeat the sequence 10 times
for i in range(10):

    # Send each letter in the sequence in order
    for j in range(5):
        activeColumns = set([i for i, j in zip(count(), x[j]) if j == 1])

        # The compute method performs one step of learning and/or inference. Note:
        # here we just perform learning but you can perform prediction/inference and
        # learning in the same step if you want (online learning).
        tm.compute(activeColumns, learn=True)

        # The following print statements can be ignored.
        # Useful for tracing internal states
        print("active cells " + str(tm.getActiveCells()))
        print("predictive cells " + str(tm.getPredictiveCells()))
        print("winner cells " + str(tm.getWinnerCells()))
        print("# of active segments " + str(tm.connections.numSegments()))

    # The reset command tells the TP that a sequence just ended and essentially
    # zeros out all the states. It is not strictly necessary but it's a bit
    # messier without resets, and the TP learns quicker with resets.
    tm.reset()

#######################################################################
#
Exemple #41
0
    def testRecycleLeastRecentlyActiveSegmentToMakeRoomForNewSegment(self):
        tm = TemporalMemory(columnDimensions=[32],
                            cellsPerColumn=1,
                            activationThreshold=3,
                            initialPermanence=.50,
                            connectedPermanence=.50,
                            minThreshold=2,
                            maxNewSynapseCount=3,
                            permanenceIncrement=.02,
                            permanenceDecrement=.02,
                            predictedSegmentDecrement=0.0,
                            seed=42,
                            maxSegmentsPerCell=2)

        prevActiveColumns1 = [0, 1, 2]
        prevActiveColumns2 = [3, 4, 5]
        prevActiveColumns3 = [6, 7, 8]
        activeColumns = [9]

        tm.compute(prevActiveColumns1)
        tm.compute(activeColumns)

        self.assertEqual(1, len(tm.connections.segmentsForCell(9)))
        oldestSegment = tm.connections.segmentsForCell(9)[0]
        tm.reset()
        tm.compute(prevActiveColumns2)
        tm.compute(activeColumns)

        self.assertEqual(2, len(tm.connections.segmentsForCell(9)))

        tm.reset()
        tm.compute(prevActiveColumns3)
        tm.compute(activeColumns)
        self.assertEqual(2, len(tm.connections.segmentsForCell(9)))

        synapses = tm.connections.synapsesForSegment(oldestSegment)
        self.assertEqual(3, len(synapses))
        presynapticCells = set()

        for synapseData in tm.connections.dataForSegment(
                oldestSegment).synapses:
            presynapticCells.add(synapseData.presynapticCell)

        expected = set([6, 7, 8])
        self.assertEqual(expected, presynapticCells)
Exemple #42
0
    def testRecycleLeastRecentlyActiveSegmentToMakeRoomForNewSegment(self):
        tm = TemporalMemory(columnDimensions=[32],
                            cellsPerColumn=1,
                            activationThreshold=3,
                            initialPermanence=.50,
                            connectedPermanence=.50,
                            minThreshold=2,
                            maxNewSynapseCount=3,
                            permanenceIncrement=.02,
                            permanenceDecrement=.02,
                            predictedSegmentDecrement=0.0,
                            seed=42,
                            maxSegmentsPerCell=2)

        prevActiveColumns1 = [0, 1, 2]
        prevActiveColumns2 = [3, 4, 5]
        prevActiveColumns3 = [6, 7, 8]
        activeColumns = [9]

        tm.compute(prevActiveColumns1)
        tm.compute(activeColumns)

        self.assertEqual(1, tm.connections.numSegments(9))
        oldestSegment = list(tm.connections.segmentsForCell(9))[0]
        tm.reset()
        tm.compute(prevActiveColumns2)
        tm.compute(activeColumns)

        self.assertEqual(2, tm.connections.numSegments(9))

        oldPresynaptic = \
          set(synapse.presynapticCell
              for synapse in tm.connections.synapsesForSegment(oldestSegment))

        tm.reset()
        tm.compute(prevActiveColumns3)
        tm.compute(activeColumns)
        self.assertEqual(2, tm.connections.numSegments(9))

        # Verify none of the segments are connected to the cells the old
        # segment was connected to.

        for segment in tm.connections.segmentsForCell(9):
            newPresynaptic = set(
                synapse.presynapticCell
                for synapse in tm.connections.synapsesForSegment(segment))
            self.assertEqual([], list(oldPresynaptic & newPresynaptic))
class JoinedInputsModel(LearningModel):
    """
    Joins all the words in the sentence in one SDR and tries to predict
    the sequence of actions.
    Structure:
       WordEncoder, ActionEncoder -> GeneralSP -> GeneralTM
    """

    def __init__(self, wordEncoder, actionEncoder, trainingSet,
            modulesParams=None):
        """
        @param wordEncoder
        @param actionEncoder
        @param dataSet: A module containing the trainingData, all of
            its categories and the inputIdx dict that maps each index
            in categories to an input name.
        """

        super(JoinedInputsModel, self).__init__(wordEncoder, actionEncoder,
            trainingSet, modulesParams)

        self.buckets = dict()
        self.iterationsTrained = 0

        self.initModules(trainingSet.categories, trainingSet.inputIdx)

        self.structure = {
            'wordInput': 'wordEnc',
            'wordEnc': 'generalSP',
            ###
            'actionInput': 'actionEnc',
            'actionEnc': 'generalSP',
            ###
            'generalSP': 'generalTM',
            'generalTM': None
        }
        self.modules = {
            'generalTM': self.generalTM,
            'generalSP': self.generalSP,
            'wordEnc': self.wordEncoder,
            'actionEnc': self.actionEncoder
        }

        self.layer = Layer(self.structure, self.modules, self.classifier)

    def initModules(self, categories, inputIdx):

        modulesNames = {'generalSP', 'generalTM'}

        nWords = len(categories[inputIdx['wordInput']])
        nActions = len(categories[inputIdx['actionInput']])


        inputDimensions = max(
            self.wordEncoder.getWidth(),
            self.actionEncoder.getWidth()
        )

        columnDimensions = (max((nWords + nActions),
            len(self.trainingData)) * 2, )

        defaultGeneralSPParams = {
            'inputDimensions': inputDimensions,
            'columnDimensions': columnDimensions,
            'seed': self.spSeed
        }

        defaultGeneralTMParams = {
            'columnDimensions': columnDimensions,
            'seed': self.tmSeed
        }

        if (self.modulesParams is not None) and\
                (set(self.modulesParams) == modulesNames):
            self.modulesParams['generalSP'].update(defaultGeneralSPParams)
            self.modulesParams['generalTM'].update(defaultGeneralTMParams)

            self.generalSP = SpatialPooler(**self.modulesParams['generalSP'])
            self.generalTM = TemporalMemory(**self.modulesParams['generalTM'])
            print("Using external Parameters!")

        else:
            self.generalSP = SpatialPooler(**defaultGeneralSPParams)
            self.generalTM = TemporalMemory(**defaultGeneralTMParams)
            print("External parameters invalid or not found, using"\
                " the default ones")

        self.classifier = CLAClassifierCond(
            steps=[1, 2],
            alpha=0.1,
            actValueAlpha=0.3,
            verbosity=0
        )

    def train(self, numIterations, trainingData=None, maxTime=-1, verbosity=0,
            learn=True):

        startTime = time.time()
        maxTimeReached = False

        if trainingData is None:
            trainingData = self.trainingData

        for iteration in xrange(numIterations):
            if verbosity > 0:
                print("Iteration "  + str(iteration))

            recordNum = 0

            for sentence, actionSeq in trainingData:
                self.inputSentence(sentence, verbosity, learn)
                recordNum += 1

                for action in actionSeq:
                    inputData = ('actionInput', action)
                    self.processInput(inputData, recordNum, verbosity, learn)
                    recordNum += 1

                self.reset()

                if (maxTime > 0):
                    elapsedMinutes = (time.time() - startTime) * (1.0 / 60.0)

                    if (elapsedMinutes > maxTime):
                        maxTimeReached = True
                        print("maxTime reached, training stoped at iteration "\
                            "{}!".format(self.iterationsTrained))
                        break

            if maxTimeReached:
                break

            self.iterationsTrained += 1

    def processInput(self, inputData, recordNum, verbosity=0, learn=False):

        inputName = inputData[0]
        actualValue = inputData[1]

        if verbosity > 1:
            print("===== " + inputName + ": " + str(actualValue) + " =====")

        encodedValue = numpy.zeros(
            self.generalSP.getInputDimensions(),
            dtype=numpy.uint8
        )

        if inputName == 'wordInput':
            for word in actualValue:
                encodedValue[self.wordEncoder.getBucketIndices(word)] = 1

            actualValue = ' '.join(actualValue)

        elif(inputName == 'actionInput'):
            aux = self.actionEncoder.encode(actualValue)
            encodedValue[numpy.where(aux > 1)] = 1

        if actualValue not in self.buckets:
            self.buckets[actualValue] = len(self.buckets)

        bucketIndex = self.buckets[actualValue]

        if verbosity > 1:
            print("Encoded Value: {0}\n"\
                "Bucket Index: {1}\n".format(encodedValue, bucketIndex))

        spOutput = numpy.zeros(self.generalSP.getColumnDimensions(),
                    dtype=numpy.uint8)
        self.generalSP.compute(encodedValue, learn, spOutput)

        tmInput = numpy.where(spOutput > 0)[0]
        self.generalTM.compute(set(tmInput), learn)

        retVal = self.classifier.compute(
                recordNum=recordNum,
                patternNZ=self.generalTM.activeCells,
                classification={
                    'bucketIdx': self.buckets[actualValue],
                    'actValue': actualValue
                },
                learn=learn,
                infer=True,
                conditionFunc=lambda x: x.endswith("-event")
            )

        bestPredictions = []

        for step in retVal:
            if step == 'actualValues':
                continue

            higherProbIndex = numpy.argmax(retVal[step])
            bestPredictions.append(
                retVal['actualValues'][higherProbIndex]
            )

        if verbosity > 2 :
            print("  |  CLAClassifier best predictions for step1: ")
            top = sorted(retVal[1].tolist(), reverse=True)[:3]

            for prob in top:
                probIndex = retVal[1].tolist().index(prob)
                print(str(retVal['actualValues'][probIndex]) +
                    " - " + str(prob))

            print("  |  CLAClassifier best predictions for step2: ")
            top = sorted(retVal[2].tolist(), reverse=True)[:3]

            for prob in top:
                probIndex = retVal[2].tolist().index(prob)
                print(str(retVal['actualValues'][probIndex]) +
                    " - " + str(prob))

            print("")
            print("---------------------------------------------------")
            print("")

        return bestPredictions

    def inputSentence(self, sentence, verbosity=0, learn=False):

        inputData = ('wordInput', sentence)
        bestPredictions = self.processInput(inputData, 0, verbosity, learn)

        if verbosity > 1:
            print('Best Predictions: ' + str(bestPredictions))

        return bestPredictions
def runHotgym():

  timeOfDayEncoder = DateEncoder(timeOfDay=(21,1))
  weekendEncoder = DateEncoder(weekend=21)
  scalarEncoder = RandomDistributedScalarEncoder(0.88)

  encodingWidth = timeOfDayEncoder.getWidth() \
    + weekendEncoder.getWidth() \
    + scalarEncoder.getWidth()

  sp = SpatialPooler(
    # How large the input encoding will be.
    inputDimensions=(encodingWidth),
    # How many mini-columns will be in the Spatial Pooler.
    columnDimensions=(2048),
    # What percent of the columns's receptive field is available for potential
    # synapses?
    potentialPct=0.85,
    # This means that the input space has no topology.
    globalInhibition=True,
    localAreaDensity=-1.0,
    # Roughly 2%, giving that there is only one inhibition area because we have
    # turned on globalInhibition (40 / 2048 = 0.0195)
    numActiveColumnsPerInhArea=40.0,
    # How quickly synapses grow and degrade.
    synPermInactiveDec=0.005,
    synPermActiveInc=0.04,
    synPermConnected=0.1,
    # boostStrength controls the strength of boosting. Boosting encourages
    # efficient usage of SP columns.
    boostStrength=3.0,
    # Random number generator seed.
    seed=1956,
    # Determines if inputs at the beginning and end of an input dimension should
    # be considered neighbors when mapping columns to inputs.
    wrapAround=False
  )

  tm = TemporalMemory(
    # Must be the same dimensions as the SP
    columnDimensions=(2048, ),
    # How many cells in each mini-column.
    cellsPerColumn=32,
    # A segment is active if it has >= activationThreshold connected synapses
    # that are active due to infActiveState
    activationThreshold=16,
    initialPermanence=0.21,
    connectedPermanence=0.5,
    # Minimum number of active synapses for a segment to be considered during
    # search for the best-matching segments.
    minThreshold=12,
    # The max number of synapses added to a segment during learning
    maxNewSynapseCount=20,
    permanenceIncrement=0.1,
    permanenceDecrement=0.1,
    predictedSegmentDecrement=0.0,
    maxSegmentsPerCell=128,
    maxSynapsesPerSegment=32,
    seed=1960
  )

  classifier = SDRClassifierFactory.create()

  with open (_INPUT_FILE_PATH) as fin:
    reader = csv.reader(fin)
    headers = reader.next()
    reader.next()
    reader.next()

    for count, record in enumerate(reader):
      # Convert data string into Python date object.
      dateString = datetime.datetime.strptime(record[0], "%m/%d/%y %H:%M")
      # Convert data value string into float.
      consumption = float(record[1])

      # To encode, we need to provide zero-filled numpy arrays for the encoders
      # to populate.
      timeOfDayBits = numpy.zeros(timeOfDayEncoder.getWidth())
      weekendBits = numpy.zeros(weekendEncoder.getWidth())
      consumptionBits = numpy.zeros(scalarEncoder.getWidth())

      # Now we call the encoders create bit representations for each value.
      timeOfDayEncoder.encodeIntoArray(dateString, timeOfDayBits)
      weekendEncoder.encodeIntoArray(dateString, weekendBits)
      scalarEncoder.encodeIntoArray(consumption, consumptionBits)

      # Concatenate all these encodings into one large encoding for Spatial
      # Pooling.
      encoding = numpy.concatenate(
        [timeOfDayBits, weekendBits, consumptionBits]
      )

      # Create an array to represent active columns, all initially zero. This
      # will be populated by the compute method below. It must have the same
      # dimensions as the Spatial Pooler.
      activeColumns = numpy.zeros(2048)

      # Execute Spatial Pooling algorithm over input space.
      sp.compute(encoding, True, activeColumns)
      activeColumnIndices = numpy.nonzero(activeColumns)[0]

      # Execute Temporal Memory algorithm over active mini-columns.
      tm.compute(activeColumnIndices, learn=True)

      activeCells = tm.getActiveCells()

      # Get the bucket info for this input value for classification.
      bucketIdx = scalarEncoder.getBucketIndices(consumption)[0]

      # Run classifier to translate active cells back to scalar value.
      classifierResult = classifier.compute(
        recordNum=count,
        patternNZ=activeCells,
        classification={
          "bucketIdx": bucketIdx,
          "actValue": consumption
        },
        learn=True,
        infer=True
      )

      # Print the best prediction for 1 step out.
      probability, value = sorted(
        zip(classifierResult[1], classifierResult["actualValues"]),
        reverse=True
      )[0]
      print("1-step: {:16} ({:4.4}%)".format(value, probability * 100))
Exemple #45
0
class FeedbackModel(LearningModel):
    """
     Structure:
       WordEncoder -> WordSP -> WordTM
       ActionEncoder -> ActionSP -> ActionTM
       WordTM, ActionTM -> GeneralSP -> GeneralTM

    """

    def __init__(self, wordEncoder, actionEncoder, trainingSet,
            modulesParams=None):
        """
        @param wordEncoder
        @param actionEncoder
        @param trainingSet: A module containing the trainingData, all of
            its categories and the inputIdx dict that maps each index
            in categories to an input name.
        """

        super(FeedbackModel, self).__init__(wordEncoder, actionEncoder,
            trainingSet, modulesParams)

        self.initModules(trainingSet.categories, trainingSet.inputIdx)

        self.structure = {
            'wordInput': 'wordEnc',
            'wordEnc': 'wordSP',
            'wordSP': 'wordTM',
            'wordTM': 'generalSP',
            ###
            'actionInput': 'actionEnc',
            'actionEnc': 'actionSP',
            'actionSP': 'actionTM',
            'actionTM': 'generalSP',
            ###
            'generalSP': 'generalTM',
            'generalTM': None
        }
        self.modules = {
            'generalTM': self.generalTM,
            #'generalSP': self.generalSP,
            'wordTM': self.wordTM,
            'wordSP': self.wordSP,
            'wordEnc': self.wordEncoder,
            'actionTM': self.actionTM,
            'actionSP': self.actionSP,
            'actionEnc': self.actionEncoder
        }

        #self.layer = Layer(self.structure, self.modules, self.classifier)

    def initModules(self, categories, inputIdx):

        modulesNames = {'wordSP', 'wordTM', 'actionSP', 'actionTM',
            'generalTM'}

        if (self.modulesParams is not None) and\
                (set(self.modulesParams) == modulesNames):
            self.modulesParams['wordSP'].update(self.defaultWordSPParams)
            self.modulesParams['wordTM'].update(self.defaultWordTMParams)
            self.modulesParams['actionSP'].update(self.defaultActionSPParams)
            self.modulesParams['actionTM'].update(self.defaultActionTMParams)

            self.wordSP = SpatialPooler(**self.modulesParams['wordSP'])
            self.wordTM = TemporalMemory(**self.modulesParams['wordTM'])
            self.actionSP = SpatialPooler(**self.modulesParams['actionSP'])
            self.actionTM = TemporalMemory(**self.modulesParams['actionTM'])

            defaultGeneralTMParams = {
                'columnDimensions': (2, max(self.wordTM.numberOfCells(),
                     self.actionTM.numberOfCells())),
                'seed': self.tmSeed
            }

            self.modulesParams['generalTM'].update(defaultGeneralTMParams)

            self.generalTM = TemporalMemory(**self.modulesParams['generalTM'])
            print("Using external Parameters!")

        else:
            self.wordSP = SpatialPooler(**self.defaultWordSPParams)
            self.wordTM = TemporalMemory(**self.defaultWordTMParams)
            self.actionSP = SpatialPooler(**self.defaultActionSPParams)
            self.actionTM = TemporalMemory(**self.defaultActionTMParams)
            print("External parameters invalid or not found, using"\
                " the default ones")

            defaultGeneralTMParams = {
                'columnDimensions': (2, max(self.wordTM.numberOfCells(),
                     self.actionTM.numberOfCells())),
                'seed': self.tmSeed
            }

            self.generalTM = TemporalMemory(**defaultGeneralTMParams)


        self.classifier = CLAClassifierCond(
            steps=[1, 2, 3],
            alpha=0.1,
            actValueAlpha=0.3,
            verbosity=0
        )

        self.startPointOverlap = CommonOverlap('==', 1,
            self.actionTM.columnDimensions, threshold=0.5)

    def processInput(self, sentence, actionSeq, wordSDR=None,
                     actionSDR=None, verbosity=0, learn=True):

        if wordSDR is None:
            wordSDR = numpy.zeros(self.wordSP.getColumnDimensions(),
                              dtype=numpy.uint8)
        if actionSDR is None:
            actionSDR = numpy.zeros(self.actionSP.getColumnDimensions(),
                              dtype=numpy.uint8)

        nCellsFromSentence = self.generalTM.columnDimensions[1]
        sentenceActiveCells = set()
        actionSeqActiveCells = set()
        recordNum = 0

        # Feed the words from the sentence to the region 1
        for word in sentence:
            encodedWord = self.wordEncoder.encode(word)
            self.wordSP.compute(encodedWord, learn, wordSDR)
            self.wordTM.compute(
                set(numpy.where(wordSDR > 0)[0]),
                learn
            )
            region1Predicting = (self.wordTM.predictiveCells != set())
            sentenceActiveCells.update(self.wordTM.getActiveCells())

            #print("{} - {}".format(word, ))
            retVal = self.classifier.compute(
                recordNum=recordNum,
                patternNZ=self.wordTM.getActiveCells(),
                classification={
                    'bucketIdx': self.wordEncoder.getBucketIndices(word)[0],
                    'actValue': word
                },
                learn=learn,
                infer=True,
                conditionFunc=lambda x: x.endswith("-event")
            )

            recordNum += 1

        bestPredictions = []

        for step in retVal:
            if step == 'actualValues':
                continue
            higherProbIndex = numpy.argmax(retVal[step])
            bestPredictions.append(
                retVal['actualValues'][higherProbIndex]
            )

        if region1Predicting:
            # Feed the sentence to the region 2
            self.generalTM.compute(sentenceActiveCells, learn)

            generalPrediction = set(self.generalTM.mapCellsToColumns(
                self.generalTM.predictiveCells
            ).keys())

            # Normalize predictions so cells stay in the actionTM
            # range.
            generalPrediction = set([i - nCellsFromSentence
                                     for i in generalPrediction
                                     if i >= nCellsFromSentence])

#            columnsPrediction = numpy.zeros(
#                self.actionSP.getNumColumns(),
#                dtype=numpy.uint8
#            )
#            columnsPrediction[self.actionTM.mapCellsToColumns(
#                generalPrediction).keys()] = 1
#            self.startPointOverlap.updateCounts(columnsPrediction)
#
#        if len(actionSeq) <= 0:
#
#            assert region1Predicting, "Region 1 is not predicting, consider "\
#                "training the model for a longer time"
#            predictedValues = []
#
#            firstColumns = numpy.where(numpy.bitwise_and(columnsPrediction > 0,
#                self.startPointOverlap.commonElements))
#
#            predictedEnc = numpy.zeros(self.actionEncoder.getWidth(),
#                                         dtype=numpy.uint8)
#            predictedEnc[
#                [self.actionSP._mapColumn(col) for col in firstColumns]] = 1
#            predictedValues.append(self.actionEncoder.decode(predictedEnc))
#
#            print(firstColumns)
#
#            self.actionTM.predictiveCells.update(generalPrediction)
#            self.actionTM.compute(firstColumns, learn)
#
#            predictedColumns = self.actionTM.mapCellsToColumns(
#                self.actionTM.predictiveCells).keys()[0]

        for action in actionSeq:
            encodedAction = self.actionEncoder.encode(action)
            # Use the predicted cells from region 2 to bias the
            # activity of cells in region 1.

            if region1Predicting:
                self.actionTM.predictiveCells.update(generalPrediction)

            self.actionSP.compute(encodedAction, learn, actionSDR)
            self.actionTM.compute(
                set(numpy.where(actionSDR > 0)[0]),
                learn
            )
            actionActiveCells = [i + nCellsFromSentence for i in
                                 self.actionTM.getActiveCells()]
            actionSeqActiveCells.update(actionActiveCells)
            self.classifier.compute(
                recordNum=recordNum,
                patternNZ=actionActiveCells,
                classification={
                    'bucketIdx': self.wordEncoder.getWidth() +
                        self.actionEncoder.getBucketIndices(action)[0],
                    'actValue': action
                },
                learn=learn,
                infer=True,
                conditionFunc=lambda x: x.endswith("-event")
            )

            recordNum += 1

        if region1Predicting:
            self.generalTM.compute(
                actionSeqActiveCells,
                True
            )

        if verbosity > 0:
            print('Best Predictions: ' + str(bestPredictions))

        if verbosity > 3:
            print("  |  CLAClassifier best predictions for step1: ")
            top = sorted(retVal[1].tolist(), reverse=True)[:3]

            for prob in top:
                probIndex = retVal[1].tolist().index(prob)
                print(str(retVal['actualValues'][probIndex]) +
                      " - " + str(prob))

            print("  |  CLAClassifier best predictions for step2: ")
            top = sorted(retVal[2].tolist(), reverse=True)[:3]

            for prob in top:
                probIndex = retVal[2].tolist().index(prob)
                print(str(retVal['actualValues'][probIndex]) +
                      " - " + str(prob))

            print("")
            print("---------------------------------------------------")
            print("")

        return bestPredictions

    def train(self, numIterations, trainingData=None,
              maxTime=-1, verbosity=0):
        """
        @param numIterations
        @param trainingData
        @param maxTime: (default: -1) Training stops if maxTime (in
            minutes) is exceeded. Note that this may interrupt an
            ongoing train ireration. -1 is no time restrictions.
        @param verbosity: (default: 0) How much verbose about the
            process. 0 doesn't print anything.
        """

        startTime = time.time()
        maxTimeReached = False
        recordNum = 0

        if trainingData is None:
            trainingData = self.trainingData

        wordSDR = numpy.zeros(self.wordSP.getColumnDimensions(),
                              dtype=numpy.uint8)
        actionSDR = numpy.zeros(self.actionSP.getColumnDimensions(),
                                dtype=numpy.uint8)
        #generalSDR = numpy.zeros(self.generalSP.getColumnDimensions(),
        #                         dtype=numpy.uint8)
        generalInput = numpy.zeros(self.generalTM.numberOfColumns(),
                                   dtype=numpy.uint8)

        for iteration in xrange(numIterations):
            print("Iteration " + str(iteration))

            for sentence, actionSeq in trainingData:
                self.processInput(sentence, actionSeq, wordSDR, actionSDR)
                self.reset()
                recordNum += 1

                if maxTime > 0:
                    elapsedMinutes = (time.time() - startTime) * (1.0 / 60.0)

                    if elapsedMinutes > maxTime:
                        maxTimeReached = True
                        print("maxTime reached, training stoped at iteration "\
                            "{}!".format(self.iterationsTrained))
                        break

            if maxTimeReached:
                break

            self.iterationsTrained += 1

    def inputSentence(self, sentence, verbosity=1, learn=False):

        return self.processInput(sentence, [], verbosity=verbosity, learn=learn)
Exemple #46
0
x[3, 30:40] = 1   # Input SDR representing "D", corresponding to columns 30-39
x[4, 40:50] = 1   # Input SDR representing "E", corresponding to columns 40-49


# Step 3: send this simple sequence to the temporal memory for learning
# We repeat the sequence 10 times
for i in range(10):

  # Send each letter in the sequence in order
  for j in range(5):
    activeColumns = set([i for i, j in zip(count(), x[j]) if j == 1])

    # The compute method performs one step of learning and/or inference. Note:
    # here we just perform learning but you can perform prediction/inference and
    # learning in the same step if you want (online learning).
    tm.compute(activeColumns, learn = True)

    # The following print statements can be ignored.
    # Useful for tracing internal states
    print("active cells " + str(tm.getActiveCells()))
    print("predictive cells " + str(tm.getPredictiveCells()))
    print("winner cells " + str(tm.getWinnerCells()))
    print("# of active segments " + str(tm.connections.numSegments()))

  # The reset command tells the TP that a sequence just ended and essentially
  # zeros out all the states. It is not strictly necessary but it's a bit
  # messier without resets, and the TP learns quicker with resets.
  tm.reset()


#######################################################################
Exemple #47
0
class FeedbackModel(LearningModel):
    """
     Structure:
       WordEncoder -> WordSP -> WordTM
       ActionEncoder -> ActionSP -> ActionTM
       WordTM, ActionTM -> GeneralSP -> GeneralTM

    """
    def __init__(self,
                 wordEncoder,
                 actionEncoder,
                 trainingSet,
                 modulesParams=None):
        """
        @param wordEncoder
        @param actionEncoder
        @param trainingSet: A module containing the trainingData, all of
            its categories and the inputIdx dict that maps each index
            in categories to an input name.
        """

        super(FeedbackModel, self).__init__(wordEncoder, actionEncoder,
                                            trainingSet, modulesParams)

        self.initModules(trainingSet.categories, trainingSet.inputIdx)

        self.structure = {
            'wordInput': 'wordEnc',
            'wordEnc': 'wordSP',
            'wordSP': 'wordTM',
            'wordTM': 'generalSP',
            ###
            'actionInput': 'actionEnc',
            'actionEnc': 'actionSP',
            'actionSP': 'actionTM',
            'actionTM': 'generalSP',
            ###
            'generalSP': 'generalTM',
            'generalTM': None
        }
        self.modules = {
            'generalTM': self.generalTM,
            #'generalSP': self.generalSP,
            'wordTM': self.wordTM,
            'wordSP': self.wordSP,
            'wordEnc': self.wordEncoder,
            'actionTM': self.actionTM,
            'actionSP': self.actionSP,
            'actionEnc': self.actionEncoder
        }

        #self.layer = Layer(self.structure, self.modules, self.classifier)

    def initModules(self, categories, inputIdx):

        modulesNames = {
            'wordSP', 'wordTM', 'actionSP', 'actionTM', 'generalTM'
        }

        if (self.modulesParams is not None) and\
                (set(self.modulesParams) == modulesNames):
            self.modulesParams['wordSP'].update(self.defaultWordSPParams)
            self.modulesParams['wordTM'].update(self.defaultWordTMParams)
            self.modulesParams['actionSP'].update(self.defaultActionSPParams)
            self.modulesParams['actionTM'].update(self.defaultActionTMParams)

            self.wordSP = SpatialPooler(**self.modulesParams['wordSP'])
            self.wordTM = TemporalMemory(**self.modulesParams['wordTM'])
            self.actionSP = SpatialPooler(**self.modulesParams['actionSP'])
            self.actionTM = TemporalMemory(**self.modulesParams['actionTM'])

            defaultGeneralTMParams = {
                'columnDimensions': (2,
                                     max(self.wordTM.numberOfCells(),
                                         self.actionTM.numberOfCells())),
                'seed':
                self.tmSeed
            }

            self.modulesParams['generalTM'].update(defaultGeneralTMParams)

            self.generalTM = TemporalMemory(**self.modulesParams['generalTM'])
            print("Using external Parameters!")

        else:
            self.wordSP = SpatialPooler(**self.defaultWordSPParams)
            self.wordTM = TemporalMemory(**self.defaultWordTMParams)
            self.actionSP = SpatialPooler(**self.defaultActionSPParams)
            self.actionTM = TemporalMemory(**self.defaultActionTMParams)
            print("External parameters invalid or not found, using"\
                " the default ones")

            defaultGeneralTMParams = {
                'columnDimensions': (2,
                                     max(self.wordTM.numberOfCells(),
                                         self.actionTM.numberOfCells())),
                'seed':
                self.tmSeed
            }

            self.generalTM = TemporalMemory(**defaultGeneralTMParams)

        self.classifier = CLAClassifierCond(steps=[1, 2, 3],
                                            alpha=0.1,
                                            actValueAlpha=0.3,
                                            verbosity=0)

        self.startPointOverlap = CommonOverlap('==',
                                               1,
                                               self.actionTM.columnDimensions,
                                               threshold=0.5)

    def processInput(self,
                     sentence,
                     actionSeq,
                     wordSDR=None,
                     actionSDR=None,
                     verbosity=0,
                     learn=True):

        if wordSDR is None:
            wordSDR = numpy.zeros(self.wordSP.getColumnDimensions(),
                                  dtype=numpy.uint8)
        if actionSDR is None:
            actionSDR = numpy.zeros(self.actionSP.getColumnDimensions(),
                                    dtype=numpy.uint8)

        nCellsFromSentence = self.generalTM.columnDimensions[1]
        sentenceActiveCells = set()
        actionSeqActiveCells = set()
        recordNum = 0

        # Feed the words from the sentence to the region 1
        for word in sentence:
            encodedWord = self.wordEncoder.encode(word)
            self.wordSP.compute(encodedWord, learn, wordSDR)
            self.wordTM.compute(set(numpy.where(wordSDR > 0)[0]), learn)
            region1Predicting = (self.wordTM.predictiveCells != set())
            sentenceActiveCells.update(self.wordTM.getActiveCells())

            #print("{} - {}".format(word, ))
            retVal = self.classifier.compute(
                recordNum=recordNum,
                patternNZ=self.wordTM.getActiveCells(),
                classification={
                    'bucketIdx': self.wordEncoder.getBucketIndices(word)[0],
                    'actValue': word
                },
                learn=learn,
                infer=True,
                conditionFunc=lambda x: x.endswith("-event"))

            recordNum += 1

        bestPredictions = []

        for step in retVal:
            if step == 'actualValues':
                continue
            higherProbIndex = numpy.argmax(retVal[step])
            bestPredictions.append(retVal['actualValues'][higherProbIndex])

        if region1Predicting:
            # Feed the sentence to the region 2
            self.generalTM.compute(sentenceActiveCells, learn)

            generalPrediction = set(
                self.generalTM.mapCellsToColumns(
                    self.generalTM.predictiveCells).keys())

            # Normalize predictions so cells stay in the actionTM
            # range.
            generalPrediction = set([
                i - nCellsFromSentence for i in generalPrediction
                if i >= nCellsFromSentence
            ])

#            columnsPrediction = numpy.zeros(
#                self.actionSP.getNumColumns(),
#                dtype=numpy.uint8
#            )
#            columnsPrediction[self.actionTM.mapCellsToColumns(
#                generalPrediction).keys()] = 1
#            self.startPointOverlap.updateCounts(columnsPrediction)
#
#        if len(actionSeq) <= 0:
#
#            assert region1Predicting, "Region 1 is not predicting, consider "\
#                "training the model for a longer time"
#            predictedValues = []
#
#            firstColumns = numpy.where(numpy.bitwise_and(columnsPrediction > 0,
#                self.startPointOverlap.commonElements))
#
#            predictedEnc = numpy.zeros(self.actionEncoder.getWidth(),
#                                         dtype=numpy.uint8)
#            predictedEnc[
#                [self.actionSP._mapColumn(col) for col in firstColumns]] = 1
#            predictedValues.append(self.actionEncoder.decode(predictedEnc))
#
#            print(firstColumns)
#
#            self.actionTM.predictiveCells.update(generalPrediction)
#            self.actionTM.compute(firstColumns, learn)
#
#            predictedColumns = self.actionTM.mapCellsToColumns(
#                self.actionTM.predictiveCells).keys()[0]

        for action in actionSeq:
            encodedAction = self.actionEncoder.encode(action)
            # Use the predicted cells from region 2 to bias the
            # activity of cells in region 1.

            if region1Predicting:
                self.actionTM.predictiveCells.update(generalPrediction)

            self.actionSP.compute(encodedAction, learn, actionSDR)
            self.actionTM.compute(set(numpy.where(actionSDR > 0)[0]), learn)
            actionActiveCells = [
                i + nCellsFromSentence for i in self.actionTM.getActiveCells()
            ]
            actionSeqActiveCells.update(actionActiveCells)
            self.classifier.compute(
                recordNum=recordNum,
                patternNZ=actionActiveCells,
                classification={
                    'bucketIdx':
                    self.wordEncoder.getWidth() +
                    self.actionEncoder.getBucketIndices(action)[0],
                    'actValue':
                    action
                },
                learn=learn,
                infer=True,
                conditionFunc=lambda x: x.endswith("-event"))

            recordNum += 1

        if region1Predicting:
            self.generalTM.compute(actionSeqActiveCells, True)

        if verbosity > 0:
            print('Best Predictions: ' + str(bestPredictions))

        if verbosity > 3:
            print("  |  CLAClassifier best predictions for step1: ")
            top = sorted(retVal[1].tolist(), reverse=True)[:3]

            for prob in top:
                probIndex = retVal[1].tolist().index(prob)
                print(
                    str(retVal['actualValues'][probIndex]) + " - " + str(prob))

            print("  |  CLAClassifier best predictions for step2: ")
            top = sorted(retVal[2].tolist(), reverse=True)[:3]

            for prob in top:
                probIndex = retVal[2].tolist().index(prob)
                print(
                    str(retVal['actualValues'][probIndex]) + " - " + str(prob))

            print("")
            print("---------------------------------------------------")
            print("")

        return bestPredictions

    def train(self, numIterations, trainingData=None, maxTime=-1, verbosity=0):
        """
        @param numIterations
        @param trainingData
        @param maxTime: (default: -1) Training stops if maxTime (in
            minutes) is exceeded. Note that this may interrupt an
            ongoing train ireration. -1 is no time restrictions.
        @param verbosity: (default: 0) How much verbose about the
            process. 0 doesn't print anything.
        """

        startTime = time.time()
        maxTimeReached = False
        recordNum = 0

        if trainingData is None:
            trainingData = self.trainingData

        wordSDR = numpy.zeros(self.wordSP.getColumnDimensions(),
                              dtype=numpy.uint8)
        actionSDR = numpy.zeros(self.actionSP.getColumnDimensions(),
                                dtype=numpy.uint8)
        #generalSDR = numpy.zeros(self.generalSP.getColumnDimensions(),
        #                         dtype=numpy.uint8)
        generalInput = numpy.zeros(self.generalTM.numberOfColumns(),
                                   dtype=numpy.uint8)

        for iteration in xrange(numIterations):
            print("Iteration " + str(iteration))

            for sentence, actionSeq in trainingData:
                self.processInput(sentence, actionSeq, wordSDR, actionSDR)
                self.reset()
                recordNum += 1

                if maxTime > 0:
                    elapsedMinutes = (time.time() - startTime) * (1.0 / 60.0)

                    if elapsedMinutes > maxTime:
                        maxTimeReached = True
                        print("maxTime reached, training stoped at iteration "\
                            "{}!".format(self.iterationsTrained))
                        break

            if maxTimeReached:
                break

            self.iterationsTrained += 1

    def inputSentence(self, sentence, verbosity=1, learn=False):

        return self.processInput(sentence, [],
                                 verbosity=verbosity,
                                 learn=learn)
Exemple #48
0
class Layer(object):
    """One combined layer of spatial and temporal pooling """

    # function called on init of layer
    def __init__(self, config):

        # Calculate the size of input and col space
        inputsize = np.array(config['inputDimensions']).prod()
        colsize = np.array(config['columnDimensions']).prod()

        # save colsize and data type
        self.colsize = colsize
        self.datatype = config['uintType']
        self.numIterations = config['numIterations']

        # setup the pooler and reference to active column holder
        self.sp = SpatialPooler(
            inputDimensions=config['inputDimensions'],
            columnDimensions=config['columnDimensions'],
            potentialRadius=int(config['potentialRadius'] * inputsize),
            numActiveColumnsPerInhArea=math.ceil(
                config['amountActiveCols'] * colsize),
            globalInhibition=config['inhibition']
        )

        # reference to active columns set that is output of the spatial pooler
        self.activeColumns = np.zeros(colsize, config['uintType'])

        # setup the temporal pooler
        self.tm = TemporalMemory(
            columnDimensions=config['columnDimensions'],
            cellsPerColumn=config['cellsPerColumn']
        )

    # learn the pools based upon the data
    def learn(self, data, colOut):
        """learn the spatical and temporal pooling on the dataset"""

        # run the spatial pooling
        for i in range(self.numIterations):
            self.sp.compute(
                data,
                True,
                self.activeColumns
            )

        # run the temporal pooling
        self.tm.compute(self.activeColumns, True)

        # get the active cells
        cells = self.tm.getActiveCells()

        if colOut is True:
            return bitmapSDR(
                self.tm.mapCellsToColumns(cells),
                self.colsize,
                self.datatype
            )
        else:
            return cells

    # predict the pools based upon the data
    def predict(self, data, colOut):
        """learn the spatical and temporal pooling on the dataset"""

        # run the spatial pooling
        self.sp.compute(
            data,
            False,
            self.activeColumns
        )

        # run the temporal pooling
        self.tm.compute(self.activeColumns, False)

        # get the active cells
        cells = self.tm.getActiveCells()

        if colOut is True:
            return bitmapSDR(
                self.tm.mapCellsToColumns(cells),
                self.colsize,
                self.datatype
            )
        else:
            return cells