Example #1
0
    def testPathsNotInvalidatedByOtherDestroys(self):
        """ Creates segments and synapses, then destroys segments and synapses on
        either side of them and verifies that existing Segment and Synapse
        instances still point to the same segment / synapse as before.
    """
        connections = Connections(1024)
        segment1 = connections.createSegment(11)
        connections.createSegment(12)
        segment3 = connections.createSegment(13)
        connections.createSegment(14)
        segment5 = connections.createSegment(15)

        synapse1 = connections.createSynapse(segment3, 201, .85)
        synapse2 = connections.createSynapse(segment3, 202, .85)
        synapse3 = connections.createSynapse(segment3, 203, .85)
        synapse4 = connections.createSynapse(segment3, 204, .85)
        synapse5 = connections.createSynapse(segment3, 205, .85)

        self.assertEqual(203, synapse3.presynapticCell)
        connections.destroySynapse(synapse1)
        self.assertEqual(203, synapse3.presynapticCell)
        connections.destroySynapse(synapse5)
        self.assertEqual(203, synapse3.presynapticCell)

        connections.destroySegment(segment1)
        self.assertEqual([synapse2, synapse3, synapse4],
                         list(connections.synapsesForSegment(segment3)))
        connections.destroySegment(segment5)
        self.assertEqual([synapse2, synapse3, synapse4],
                         list(connections.synapsesForSegment(segment3)))
        self.assertEqual(203, synapse3.presynapticCell)
Example #2
0
    def __init__(self,
                 columnDimensions=(2048, ),
                 cellsPerColumn=32,
                 activationThreshold=13,
                 initialPermanence=0.21,
                 connectedPermanence=0.50,
                 minThreshold=10,
                 maxNewSynapseCount=20,
                 permanenceIncrement=0.10,
                 permanenceDecrement=0.10,
                 seed=42):
        """
    Translate parameters and initialize member variables
    specific to TemporalMemory
    """
        numberOfCols = 1
        for n in columnDimensions:
            numberOfCols *= n

        super(TemporalMemoryShim,
              self).__init__(numberOfCols=numberOfCols,
                             cellsPerColumn=cellsPerColumn,
                             initialPerm=initialPermanence,
                             connectedPerm=connectedPermanence,
                             minThreshold=minThreshold,
                             newSynapseCount=maxNewSynapseCount,
                             permanenceInc=permanenceIncrement,
                             permanenceDec=permanenceDecrement,
                             permanenceMax=1.0,
                             globalDecay=0,
                             activationThreshold=activationThreshold,
                             seed=seed)

        self.connections = Connections(numberOfCols * cellsPerColumn)
        self.predictiveCells = set()
Example #3
0
    def __init__(self,
                 columnDimensions=(2048, ),
                 cellsPerColumn=32,
                 activationThreshold=13,
                 initialPermanence=0.21,
                 connectedPermanence=0.50,
                 minThreshold=10,
                 maxNewSynapseCount=20,
                 permanenceIncrement=0.10,
                 permanenceDecrement=0.10,
                 predictedSegmentDecrement=0.0,
                 seed=42):
        """
    @param columnDimensions          (list)  Dimensions of the column space
    @param cellsPerColumn            (int)   Number of cells per column
    @param activationThreshold       (int)   If the number of active connected synapses on a segment is at least this threshold, the segment is said to be active.
    @param initialPermanence         (float) Initial permanence of a new synapse.
    @param connectedPermanence       (float) If the permanence value for a synapse is greater than this value, it is said to be connected.
    @param minThreshold              (int)   If the number of synapses active on a segment is at least this threshold, it is selected as the best matching cell in a bursting column.
    @param maxNewSynapseCount        (int)   The maximum number of synapses added to a segment during learning.
    @param permanenceIncrement       (float) Amount by which permanences of synapses are incremented during learning.
    @param permanenceDecrement       (float) Amount by which permanences of synapses are decremented during learning.
    @param predictedSegmentDecrement (float) Amount by which active permanences of synapses of previously predicted but inactive segments are decremented.
    @param seed                      (int)   Seed for the random number generator.
    """
        # Error checking
        if not len(columnDimensions):
            raise ValueError(
                "Number of column dimensions must be greater than 0")

        if not cellsPerColumn > 0:
            raise ValueError(
                "Number of cells per column must be greater than 0")

        # TODO: Validate all parameters (and add validation tests)

        # Save member variables
        self.columnDimensions = columnDimensions
        self.cellsPerColumn = cellsPerColumn
        self.activationThreshold = activationThreshold
        self.initialPermanence = initialPermanence
        self.connectedPermanence = connectedPermanence
        self.minThreshold = minThreshold
        self.maxNewSynapseCount = maxNewSynapseCount
        self.permanenceIncrement = permanenceIncrement
        self.permanenceDecrement = permanenceDecrement
        self.predictedSegmentDecrement = predictedSegmentDecrement
        # Initialize member variables
        self.connections = Connections(self.numberOfCells())
        self._random = Random(seed)

        self.activeCells = set()
        self.predictiveCells = set()
        self.activeSegments = set()
        self.winnerCells = set()
        self.matchingSegments = set()
        self.matchingCells = set()
Example #4
0
    def connectionsFactory(*args, **kwargs):
        """ Create a Connections instance.  TemporalMemory subclasses may override
    this method to choose a different Connections implementation, or to augment
    the instance otherwise returned by the default Connections implementation.

    See Connections for constructor signature and usage

    @return: Connections instance
    """
        return Connections(*args, **kwargs)
Example #5
0
    def testComputeActivity(self):
        """ Creates a sample set of connections, and makes sure that computing the
        activity for a collection of cells with no activity returns the right
        activity data.
    """
        connections = Connections(1024)

        # Cell with 1 segment.
        # Segment with:
        # - 1 connected synapse: active
        # - 2 matching synapses
        segment1a = connections.createSegment(10)
        connections.createSynapse(segment1a, 150, .85)
        connections.createSynapse(segment1a, 151, .15)

        # Cell with 2 segment.
        # Segment with:
        # - 2 connected synapse: 2 active
        # - 3 matching synapses: 3 active
        segment2a = connections.createSegment(20)
        connections.createSynapse(segment2a, 80, .85)
        connections.createSynapse(segment2a, 81, .85)
        synapse = connections.createSynapse(segment2a, 82, .85)
        connections.updateSynapsePermanence(synapse, .15)

        # Segment with:
        # - 2 connected synapses: 1 active, 1 inactive
        # - 3 matching synapses: 2 active, 1 inactive
        # - 1 non-matching synapse: 1 active
        segment2b = connections.createSegment(20)
        connections.createSynapse(segment2b, 50, .85)
        connections.createSynapse(segment2b, 51, .85)
        connections.createSynapse(segment2b, 52, .15)
        connections.createSynapse(segment2b, 53, .05)

        # Cell with one segment.
        # Segment with:
        # - 1 non-matching synapse: 1 active
        segment3a = connections.createSegment(30)
        connections.createSynapse(segment3a, 53, .05)

        inputVec = [50, 52, 53, 80, 81, 82, 150, 151]
        active, matching = connections.computeActivity(inputVec, .5, 2, .1, 1)

        self.assertEqual(1, len(active))
        self.assertEqual(segment2a, active[0].segment)
        self.assertEqual(2, active[0].overlap)

        self.assertEqual(3, len(matching))
        self.assertEqual(segment1a, matching[0].segment)
        self.assertEqual(2, matching[0].overlap)
        self.assertEqual(segment2a, matching[1].segment)
        self.assertEqual(3, matching[1].overlap)
        self.assertEqual(segment2b, matching[2].segment)
        self.assertEqual(2, matching[2].overlap)
Example #6
0
    def testCreateSegment(self):
        connections = Connections(1024)

        segment1 = connections.createSegment(10)
        self.assertEqual(segment1.cell, 10)

        segment2 = connections.createSegment(10)
        self.assertEqual(segment2.cell, 10)

        self.assertEqual([segment1, segment2],
                         list(connections.segmentsForCell(10)))
Example #7
0
    def testUpdateSynapsePermanence(self):
        """ Creates a synapse and updates its permanence, and makes sure that its
        data was correctly updated.
    """
        connections = Connections(1024)
        segment = connections.createSegment(10)
        synapse = connections.createSynapse(segment, 50, .34)

        connections.updateSynapsePermanence(synapse, .21)

        synapseData = connections.dataForSynapse(synapse)
        self.assertAlmostEqual(synapseData.permanence, .21)
Example #8
0
    def testReachSegmentLimitMultipleTimes(self):
        """ Hit the maxSynapsesPerSegment threshold multiple times. Make sure it
        works more than once.
    """
        connections = Connections(1024, 2, 2)

        segment = connections.createSegment(10)
        connections.createSynapse(segment, 201, .85)
        self.assertEqual(1, connections.numSynapses())
        connections.createSynapse(segment, 202, .9)
        self.assertEqual(2, connections.numSynapses())
        connections.createSynapse(segment, 203, .8)
        self.assertEqual(2, connections.numSynapses())
        synapse = connections.createSynapse(segment, 204, .8)
        self.assertEqual(2, connections.numSynapses())
Example #9
0
    def testCreateSegmentReuse(self):
        connections = Connections(1024, 2)

        segment1 = connections.createSegment(42)
        connections.createSynapse(segment1, 1, .5)
        connections.createSynapse(segment1, 2, .5)

        # Let some time pass.
        connections.startNewIteration()
        connections.startNewIteration()
        connections.startNewIteration()

        # Create a segment with 3 synapse.
        segment2 = connections.createSegment(42)
        connections.createSynapse(segment2, 1, .5)
        connections.createSynapse(segment2, 2, .5)
        connections.createSynapse(segment2, 3, .5)
        connections.startNewIteration()

        # Give the first segment some activity.
        connections.recordSegmentActivity(segment1)

        # Create a new segment with 1 synapse.
        segment3 = connections.createSegment(42)
        connections.createSynapse(segment3, 1, .5)

        segments = connections.segmentsForCell(42)
        self.assertEqual(2, len(segments))

        # Verify first segment is still there with the same synapses.
        self.assertEqual(
            set([1, 2]),
            set(synapse.presynapticCell
                for synapse in connections.synapsesForSegment(segments[0])))

        # Verify second segment has been replaced.
        self.assertEqual(
            set([1]),
            set(synapse.presynapticCell
                for synapse in connections.synapsesForSegment(segments[1])))

        # Verify the flatIdxs were properly reused.
        self.assertLess(segment1.flatIdx, 2)
        self.assertLess(segment3.flatIdx, 2)
        self.assertTrue(
            segment1 is connections.segmentForFlatIdx(segment1.flatIdx))
        self.assertTrue(
            segment3 is connections.segmentForFlatIdx(segment3.flatIdx))
Example #10
0
    def testCreateSegmentReuse(self):
        connections = Connections(1024, 2)

        segment1 = connections.createSegment(42)
        connections.createSynapse(segment1, 1, .5)
        connections.createSynapse(segment1, 2, .5)

        connections.computeActivity([], .5, 2, .1, 1)
        connections.computeActivity([], .5, 2, .1, 1)
        connections.computeActivity([], .5, 2, .1, 1)

        segment2 = connections.createSegment(42)
        activeSegs, _ = connections.computeActivity([1, 2], .5, 2, .1, 1)
        self.assertEqual(1, len(activeSegs))
        self.assertEqual(segment1, activeSegs[0].segment)

        segment3 = connections.createSegment(42)
        self.assertEqual(segment2.idx, segment3.idx)
    def __init__(self, learnOnOneCell=True, **kwargs):
        """
    @param learnOnOneCell (boolean) If True, the winner cell for each column will be fixed between resets.
    """

        super(ExtendedTemporalMemory, self).__init__(**kwargs)

        self.activeExternalCells = set()
        self.learnOnOneCell = learnOnOneCell
        self.chosenCellForColumn = dict()

        self.unpredictedActiveColumns = set()
        self.predictedActiveCells = set()

        self.activeApicalCells = set()
        self.apicalConnections = Connections(self.numberOfCells())
        self.activeApicalSegments = set()
        self.matchingApicalSegments = set()
Example #12
0
    def testCreateSegmentReuse(self):
        connections = Connections(1024, 2)

        segment1 = connections.createSegment(42)
        connections.createSynapse(segment1, 1, .5)
        connections.createSynapse(segment1, 2, .5)

        # Let some time pass.
        connections.startNewIteration()
        connections.startNewIteration()
        connections.startNewIteration()

        segment2 = connections.createSegment(42)
        connections.startNewIteration()

        connections.recordSegmentActivity(segment1)

        segment3 = connections.createSegment(42)

        self.assertEqual(segment2.idx, segment3.idx)
Example #13
0
    def testDestroySegmentsThenReachLimit(self):
        """ Destroy some segments then verify that the maxSegmentsPerCell is still
        correctly applied.
    """
        connections = Connections(1024, 2, 2)

        segment1 = connections.createSegment(11)
        segment2 = connections.createSegment(11)

        self.assertEqual(2, connections.numSegments())
        connections.destroySegment(segment1)
        connections.destroySegment(segment2)
        self.assertEqual(0, connections.numSegments())

        connections.createSegment(11)
        self.assertEqual(1, connections.numSegments())
        connections.createSegment(11)
        self.assertEqual(2, connections.numSegments())
        segment3 = connections.createSegment(11)
        self.assertLess(segment3.idx, 2)
        self.assertEqual(2, connections.numSegments())
Example #14
0
    def testSynapseReuse(self):
        """ Creates a synapse over the synapses per segment limit, and verifies
        that the lowest permanence synapse is removed to make room for the new
        synapse.
    """
        connections = Connections(1024, 1024, 2)
        segment = connections.createSegment(10)

        synapse1 = connections.createSynapse(segment, 50, .34)
        synapse2 = connections.createSynapse(segment, 51, .34)

        synapses = connections.synapsesForSegment(segment)
        self.assertEqual(synapses, [synapse1, synapse2])

        #Add an additional synapse to force it over the limit of num synapses
        #per segment.
        synapse3 = connections.createSynapse(segment, 52, .52)
        self.assertEqual(0, synapse3.idx)

        #ensure lower permanence synapse was removed
        synapses = connections.synapsesForSegment(segment)
        self.assertEqual(synapses, [synapse3, synapse2])
Example #15
0
    def testReuseSegmentWithDestroyedSynapses(self):
        """ Destroy a segment that has a destroyed synapse and a non-destroyed
        synapse. Create a new segment in the same place. Make sure its synapse
        count is correct.
    """
        connections = Connections(1024)

        segment = connections.createSegment(11)

        synapse1 = connections.createSynapse(segment, 201, .85)
        connections.createSynapse(segment, 202, .85)

        connections.destroySynapse(synapse1)

        self.assertEqual(1, connections.numSynapses(segment))

        connections.destroySegment(segment)

        reincarnated = connections.createSegment(11)

        self.assertEqual(0, connections.numSynapses(reincarnated))
        self.assertEqual(0, len(connections.synapsesForSegment(reincarnated)))
Example #16
0
    def testDestroySynapsesThenReachLimit(self):
        """ Destroy some synapses then verify that the maxSynapsesPerSegment is
        still correctly applied.
    """
        connections = Connections(1024, 2, 2)

        segment = connections.createSegment(10)

        synapse1 = connections.createSynapse(segment, 201, .85)
        synapse2 = connections.createSynapse(segment, 202, .85)

        self.assertEqual(2, connections.numSynapses())
        connections.destroySynapse(synapse1)
        connections.destroySynapse(synapse2)
        self.assertEqual(0, connections.numSynapses())

        connections.createSynapse(segment, 201, .85)
        self.assertEqual(1, connections.numSynapses())
        connections.createSynapse(segment, 202, .90)
        self.assertEqual(2, connections.numSynapses())
        synapse3 = connections.createSynapse(segment, 203, .8)
        self.assertEqual(2, connections.numSynapses())
Example #17
0
    def testDestroySynapse(self):
        """ Creates a segment, creates a number of synapses on it, destroys a
        synapse, and makes sure it got destroyed.
    """
        connections = Connections(1024)

        segment = connections.createSegment(20)
        synapse1 = connections.createSynapse(segment, 80, .85)
        synapse2 = connections.createSynapse(segment, 81, .85)
        synapse3 = connections.createSynapse(segment, 82, .15)

        self.assertEqual(3, connections.numSynapses())

        connections.destroySynapse(synapse2)

        self.assertEqual(2, connections.numSynapses())
        self.assertEqual(connections.synapsesForSegment(segment),
                         [synapse1, synapse3])
        active, matching = connections.computeActivity([80, 81, 82], .5, 2,
                                                       0.0, 1)
        self.assertEqual(0, len(active))
        self.assertEqual(1, len(matching))
        self.assertEqual(2, matching[0].overlap)
Example #18
0
    def testSynapseReuse(self):
        """ Creates a synapse over the synapses per segment limit, and verifies
        that the lowest permanence synapse is removed to make room for the new
        synapse.
    """
        connections = Connections(1024, 1024, 2)
        segment = connections.createSegment(10)

        synapse1 = connections.createSynapse(segment, 50, .34)
        synapse2 = connections.createSynapse(segment, 51, .48)

        synapses = connections.synapsesForSegment(segment)
        self.assertEqual(set([synapse1, synapse2]), synapses)

        # Add an additional synapse to force it over the limit of num synapses
        # per segment.
        connections.createSynapse(segment, 52, .52)

        # Ensure lower permanence synapse was removed.
        self.assertEqual(
            set([51, 52]),
            set(synapse.presynapticCell
                for synapse in connections.synapsesForSegment(segment)))
Example #19
0
    def testDestroySynapse(self):
        """ Creates a segment, creates a number of synapses on it, destroys a
        synapse, and makes sure it got destroyed.
    """
        connections = Connections(1024)

        segment = connections.createSegment(20)
        synapse1 = connections.createSynapse(segment, 80, .85)
        synapse2 = connections.createSynapse(segment, 81, .85)
        synapse3 = connections.createSynapse(segment, 82, .15)

        self.assertEqual(3, connections.numSynapses())

        connections.destroySynapse(synapse2)

        self.assertEqual(2, connections.numSynapses())
        self.assertEqual(set([synapse1, synapse3]),
                         connections.synapsesForSegment(segment))
        (numActiveConnected,
         numActivePotential) = connections.computeActivity([80, 81, 82], .5)

        self.assertEqual(1, numActiveConnected[segment.flatIdx])
        self.assertEqual(2, numActivePotential[segment.flatIdx])
Example #20
0
    def testDestroySegmentWithDestroyedSynapses(self):
        """ Destroy a segment that has a destroyed synapse and a non-destroyed
        synapse. Make sure nothing gets double-destroyed.
    """
        connections = Connections(1024)

        segment1 = connections.createSegment(11)
        segment2 = connections.createSegment(12)

        connections.createSynapse(segment1, 101, .85)
        synapse2a = connections.createSynapse(segment2, 201, .85)
        connections.createSynapse(segment2, 202, .85)

        self.assertEqual(3, connections.numSynapses())

        connections.destroySynapse(synapse2a)

        self.assertEqual(2, connections.numSegments())
        self.assertEqual(2, connections.numSynapses())

        connections.destroySegment(segment2)

        self.assertEqual(1, connections.numSegments())
        self.assertEqual(1, connections.numSynapses())
Example #21
0
    def __init__(self,
                 columnDimensions=(2048, ),
                 cellsPerColumn=32,
                 activationThreshold=13,
                 initialPermanence=0.21,
                 connectedPermanence=0.50,
                 minThreshold=10,
                 maxNewSynapseCount=20,
                 permanenceIncrement=0.10,
                 permanenceDecrement=0.10,
                 predictedSegmentDecrement=0.0,
                 maxSegmentsPerCell=255,
                 maxSynapsesPerSegment=255,
                 seed=42,
                 **kwargs):
        """
    @param columnDimensions          (list)  Dimensions of the column space
    @param cellsPerColumn            (int)   Number of cells per column
    @param activationThreshold       (int)   If the number of active connected
                                             synapses on a segment is at least
                                             this threshold, the segment is said
                                             to be active.
    @param initialPermanence         (float) Initial permanence of a new synapse
    @param connectedPermanence       (float) If the permanence value for a
                                             synapse is greater than this value,
                                             it is said to be connected.
    @param minThreshold              (int)   If the number of synapses active on
                                             a segment is at least this
                                             threshold, it is selected as the
                                             best matching cell in a bursting
                                             column
    @param maxNewSynapseCount        (int)   The maximum number of synapses
                                             added to a segment during learning
    @param permanenceIncrement       (float) Amount by which permanences of
                                             synapses are incremented during
                                             learning.
    @param permanenceDecrement       (float) Amount by which permanences of
                                             synapses are decremented during
                                             learning.
    @param predictedSegmentDecrement (float) Amount by which active permanences
                                             of synapses of previously predicted
                                             but inactive segments are
                                             decremented.
    @param seed                      (int)   Seed for the random number
                                             generator
    Notes:

    predictedSegmentDecrement: A good value is just a bit larger than
    (the column-level sparsity * permanenceIncrement). So, if column-level
    sparsity is 2% and permanenceIncrement is 0.01, this parameter should be
    something like 4% * 0.01 = 0.0004).
    """
        # Error checking
        if not len(columnDimensions):
            raise ValueError(
                "Number of column dimensions must be greater than 0")

        if cellsPerColumn <= 0:
            raise ValueError(
                "Number of cells per column must be greater than 0")

        if minThreshold > activationThreshold:
            raise ValueError(
                "The min threshold can't be greater than the activation threshold"
            )

        # TODO: Validate all parameters (and add validation tests)

        # Save member variables
        self.columnDimensions = columnDimensions
        self.cellsPerColumn = cellsPerColumn
        self.activationThreshold = activationThreshold
        self.initialPermanence = initialPermanence
        self.connectedPermanence = connectedPermanence
        self.minThreshold = minThreshold
        self.maxNewSynapseCount = maxNewSynapseCount
        self.permanenceIncrement = permanenceIncrement
        self.permanenceDecrement = permanenceDecrement
        self.predictedSegmentDecrement = predictedSegmentDecrement
        # Initialize member variables
        self.connections = Connections(
            self.numberOfCells(),
            maxSegmentsPerCell=maxSegmentsPerCell,
            maxSynapsesPerSegment=maxSynapsesPerSegment)
        self._random = Random(seed)

        self.activeCells = []
        self.winnerCells = []
        self.activeSegments = []
        self.matchingSegments = []
Example #22
0
 def setUp(self):
     self.connections = Connections(2048 * 32)