def testProximalLearning_InitiallyDisconnected(self): """ If the initialProximalPermanence is below the connectedPermanence, new synapses should not be marked as connected. """ pooler = ColumnPooler( inputWidth=2048 * 8, lateralInputWidth=512, numActiveColumnsPerInhArea=12, initialProximalPermanence=0.45, connectedPermanence=0.50, maxNewProximalSynapseCount=10, maxNewDistalSynapseCount=10, ) feedforwardInput = set(range(10)) pooler.compute(feedforwardInput, learn=True) activeCells = pooler.getActiveCells() self.assertEqual(len(activeCells), 12) for cell in activeCells: self.assertEqual(pooler.numberOfSynapses([cell]), 10, "Should connect to every active input bit.") self.assertEqual(pooler.numberOfConnectedSynapses([cell]), 0, "The synapses shouldn't have a high enough permanence" " to be connected.")
def testConstructor(self): """Create a simple instance and test the constructor.""" pooler = ColumnPooler( inputWidth=2048*8, columnDimensions=[2048, 1], maxSynapsesPerSegment=2048*8 ) self.assertEqual(pooler.numberOfCells(), 2048, "Incorrect number of cells") self.assertEqual(pooler.numberOfInputs(), 16384, "Incorrect number of inputs") self.assertEqual( pooler.numberOfSynapses(range(2048)), 0, "Should be no synapses on initialization" ) self.assertEqual( pooler.numberOfConnectedSynapses(range(2048)), 0, "Should be no connected synapses on initialization" )
def testProximalLearning_SubsequentGrowth(self): """ When all of the active input bits are synapsed, don't grow new synapses. When some of them are not synapsed, grow new synapses to them. """ pooler = ColumnPooler( inputWidth=2048 * 8, lateralInputWidth=512, numActiveColumnsPerInhArea=12, synPermProximalInc=0.0, synPermProximalDec=0.0, initialProximalPermanence=0.60, connectedPermanence=0.50, maxNewProximalSynapseCount=10, maxNewDistalSynapseCount=10, ) # Grow synapses. pooler.compute(set(range(10)), learn=True) for cell in pooler.getActiveCells(): self.assertEqual(pooler.numberOfSynapses([cell]), 10, "Should connect to every active input bit.") # Given the same input, no new synapses should form. pooler.compute(set(range(10)), learn=True) for cell in pooler.getActiveCells(): self.assertEqual(pooler.numberOfSynapses([cell]), 10, "No new synapses should form.") # Given a superset of the input, some new synapses should form. pooler.compute(set(range(20)), learn=True) for cell in pooler.getActiveCells(): self.assertEqual(pooler.numberOfSynapses([cell]), 20, "Should connect to the new active input bits.") self.assertEqual(pooler.numberOfConnectedSynapses([cell]), 20, "Each synapse should be marked as connected.")
def testProximalLearning_PunishExisting(self): """ When a cell has a synapse to an inactive input bit, decrease its permanence by 'synPermProximalDec'. """ pooler = ColumnPooler( inputWidth=2048 * 8, lateralInputWidth=512, numActiveColumnsPerInhArea=12, synPermProximalInc=0.0, synPermProximalDec=0.1, initialProximalPermanence=0.55, connectedPermanence=0.50, maxNewProximalSynapseCount=10, maxNewDistalSynapseCount=10, ) # Grow some synapses. pooler.compute(set(range(0, 10)), learn=True) # Punish some of them. pooler.compute(set(range(0, 5)), learn=True) activeCells = pooler.getActiveCells() self.assertEqual(len(activeCells), 12) for cell in activeCells: self.assertEqual(pooler.numberOfSynapses([cell]), 10, "Should connect to every active input bit.") self.assertEqual(pooler.numberOfConnectedSynapses([cell]), 5, "Each punished synapse should no longer be marked as" " connected.") (presynapticCells, permanences) = pooler.proximalPermanences.rowNonZeros(cell) d = dict(zip(presynapticCells, permanences)) for presynapticCell in xrange(0, 5): perm = d[presynapticCell] self.assertAlmostEqual( perm, 0.55, msg="Should have permanence of 'initialProximalPermanence'") for presynapticCell in xrange(5, 10): perm = d[presynapticCell] self.assertAlmostEqual( perm, 0.45, msg=("Should have permanence of 'initialProximalPermanence'" " - 'synPermProximalDec'."))
def testProximalLearning_Growth_ManyActiveInputBits(self): """ When the number of available active input bits is > maxNewSynapseCount, each cell should grow 'maxNewSynapseCount' synapses. """ pooler = ColumnPooler( inputWidth=2048 * 8, lateralInputWidth=512, numActiveColumnsPerInhArea=12, initialProximalPermanence=0.60, connectedPermanence=0.50, maxNewProximalSynapseCount=10, maxNewDistalSynapseCount=10, ) feedforwardInput = set(range(11)) pooler.compute(feedforwardInput, learn=True) activeCells = pooler.getActiveCells() self.assertEqual(len(activeCells), 12) for cell in activeCells: self.assertEqual(pooler.numberOfSynapses([cell]), 10, "Should connect to every active input bit.") self.assertEqual(pooler.numberOfConnectedSynapses([cell]), 10, "Each synapse should be marked as connected.") (presynapticCells, permanences) = pooler.proximalPermanences.rowNonZeros(cell) self.assertTrue(set(presynapticCells).issubset(feedforwardInput), "Should connect to a subset of the active input bits.") for perm in permanences: self.assertAlmostEqual(perm, 0.60, msg="Should use 'initialProximalPermanence'.")
def testInitialProximalLearning(self): """Tests the first few steps of proximal learning. """ pooler = ColumnPooler( inputWidth=2048 * 8, columnDimensions=[2048, 1], maxSynapsesPerSegment=2048 * 8 ) activatedCells = numpy.zeros(pooler.numberOfCells()) # Get initial activity pooler.compute(feedforwardInput=set(range(0,40)), learn=True) activatedCells[pooler.getActiveCells()] = 1 self.assertEqual(activatedCells.sum(), 40, "Incorrect number of active cells") sum1 = sum(pooler.getActiveCells()) # Ensure we've added correct number synapses on the active cells self.assertEqual( pooler.numberOfSynapses(pooler.getActiveCells()), 800, "Incorrect number of nonzero permanences on active cells" ) # Ensure they are all connected self.assertEqual( pooler.numberOfConnectedSynapses(pooler.getActiveCells()), 800, "Incorrect number of connected synapses on active cells" ) # If we call compute with different feedforward input we should # get the same set of active cells pooler.compute(feedforwardInput=set(range(100,140)), learn=True) self.assertEqual(sum1, sum(pooler.getActiveCells()), "Activity is not consistent for same input") # Ensure we've added correct number of new synapses on the active cells self.assertEqual( pooler.numberOfSynapses(pooler.getActiveCells()), 1600, "Incorrect number of nonzero permanences on active cells" ) # Ensure they are all connected self.assertEqual( pooler.numberOfConnectedSynapses(pooler.getActiveCells()), 1600, "Incorrect number of connected synapses on active cells" ) # If we call compute with no input we should still # get the same set of active cells pooler.compute(feedforwardInput=set(), learn=True) self.assertEqual(sum1, sum(pooler.getActiveCells()), "Activity is not consistent for same input") # Ensure we do actually add the number of synapses we want # In "learn new object mode", if we call compute with the same feedforward # input after reset we should not get the same set of active cells pooler.reset() pooler.compute(feedforwardInput=set(range(0,40)), learn=True) self.assertNotEqual(sum1, sum(pooler.getActiveCells()), "Activity should not be consistent for same input after reset") self.assertEqual(len(pooler.getActiveCells()), 40, "Incorrect number of active cells after reset")
def testLearnProximal(self): """Test _learnProximal method""" pooler = ColumnPooler( inputWidth=2048 * 8, columnDimensions=[2048, 1], maxSynapsesPerSegment=2048 * 8 ) proximalPermanences = pooler.proximalPermanences proximalConnections = pooler.proximalConnections pooler._learnProximal( activeInputs=set(range(20)), activeCells=set(range(10)), maxNewSynapseCount=7, proximalPermanences=proximalPermanences, proximalConnections=proximalConnections, initialPermanence=0.2, synPermProximalInc=0.2, synPermProximalDec=0.1, connectedPermanence=0.3 ) # There should be exactly 7 * 10 new connections, each with permanence 0.2 self.assertEqual(proximalPermanences.nNonZeros(), 70, "Incorrect number of synapses") self.assertAlmostEqual(proximalPermanences.sum(), 0.2*70, msg="Incorrect permanence total", places=4) # Ensure the correct indices are there and there are no extra ones for cell in range(10): nz,_ = proximalPermanences.rowNonZeros(cell) for i in nz: self.assertTrue(i in range(20), "Incorrect input index") self.assertEqual(pooler.numberOfSynapses(range(10,2048)), 0, "Extra synapses exist") # Do another learning step to ensure increments and decrements are handled pooler._learnProximal( activeInputs=set(range(5,15)), activeCells=set(range(10)), maxNewSynapseCount=5, proximalPermanences=proximalPermanences, proximalConnections=proximalConnections, initialPermanence=0.2, synPermProximalInc=0.2, synPermProximalDec=0.1, connectedPermanence=0.3 ) # Should be no synapses on cells that were never active self.assertEqual(pooler.numberOfSynapses(range(10,2048)), 0, "Extra synapses exist") # Should be 12 synapses on cells that were active # Number of connected cells can vary, depending on how many from range # 10-14 were selected in the first learning step for cell in range(10): self.assertEqual(pooler.numberOfSynapses([cell]), 12, "Incorrect number of synapses on active cell") self.assertGreater(pooler.numberOfConnectedSynapses([cell]), 0, "Must be at least one connected synapse on cell.") cellNonZeroIndices, cellPerms = proximalPermanences.rowNonZeros(cell) self.assertAlmostEqual(min(cellPerms), 0.1, 3, "Must be at least one decremented permanence.")