def testDefaultParameters(self): """ Test multi column object classification """ random.seed(36) exp = l2_l4_inference.L4L2Experiment( "testClassification", numCorticalColumns=1, inputSize=1024, numInputBits=20, externalInputSize=512, numExternalInputBits=10, numLearningPoints=3, ) net = exp.network L4Params = { "columnCount": 1024, "cellsPerColumn": 16, "learn": True, "learnOnOneCell": False, "initialPermanence": 0.51, "connectedPermanence": 0.6, "permanenceIncrement": 0.1, "permanenceDecrement": 0.02, "minThreshold": 8, "basalPredictedSegmentDecrement": 0.0, "activationThreshold": 8, "sampleSize": 15, } L2Params = { "inputWidth": 1024 * 16, "cellCount": 4096, "sdrSize": 40, "synPermProximalInc": 0.1, "synPermProximalDec": 0.001, "initialProximalPermanence": 0.6, "minThresholdProximal": 5, "sampleSizeProximal": 10, "connectedPermanenceProximal": 0.5, "synPermDistalInc": 0.1, "synPermDistalDec": 0.001, "initialDistalPermanence": 0.41, "activationThresholdDistal": 13, "sampleSizeDistal": 20, "connectedPermanenceDistal": 0.5, "distalSegmentInhibitionFactor": 0.999, "learningMode": True, } L4Column = net.regions["L4Column_0"].getSelf() L2Column = net.regions["L2Column_0"].getSelf() # check the default parameters are correct in L4 for param, value in L4Params.iteritems(): self.assertEqual(L4Column.getParameter(param), value) # check the default parameters are correct in L2 for param, value in L2Params.iteritems(): self.assertEqual(L2Column.getParameter(param), value)
def testSimpleExperiment(self): """Simple test of the basic interface for L4L2Experiment.""" # Set up experiment exp = l2_l4_inference.L4L2Experiment( name="sample", numCorticalColumns=2, numInputBits=20, numExternalInputBits=20 ) # Set up feature and location SDRs for two locations, A and B, for each # cortical column, 0 and 1. locA0 = list(xrange(0, 20)) featA0 = list(xrange(0, 20)) locA1 = list(xrange(20, 40)) featA1 = list(xrange(20, 40)) locB0 = list(xrange(40, 60)) featB0 = list(xrange(40, 60)) locB1 = list(xrange(60, 80)) featB1 = list(xrange(60, 80)) # Learn each location for each column with several repetitions objectsToLearn = {"obj1": [ {0: (locA0, featA0), 1: (locA1, featA1)}, {0: (locB0, featB0), 1: (locB1, featB1)}, {0: (locA0, featA0), 1: (locA1, featA1)}, {0: (locB0, featB0), 1: (locB1, featB1)}, {0: (locA0, featA0), 1: (locA1, featA1)}, {0: (locB0, featB0), 1: (locB1, featB1)}, ]} exp.learnObjects(objectsToLearn, reset=True) # Do the inference phase sensationsToInfer = [ {0: (locA0, featA0), 1: (locA1, featA1)}, {0: (locB0, featB0), 1: ([], [])}, {0: ([], []), 1: (locA1, featA1)}, {0: (locA0, featA0), 1: (locA1, featA1)}, ] exp.infer(sensationsToInfer, objectName="obj1", reset=False) # Check the results stats = exp.getInferenceStats() self.assertEqual(len(stats), 1) self.assertEqual(stats[0]["numSteps"], 4) self.assertEqual(stats[0]["object"], "obj1") self.assertSequenceEqual(stats[0]["Overlap L2 with object C0"], [40, 40, 40, 40]) self.assertSequenceEqual(stats[0]["Overlap L2 with object C1"], [40, 40, 40, 40]) self.assertEqual(len(exp.getL2Representations()[0]),40) self.assertEqual(len(exp.getL2Representations()[1]),40) self.assertEqual(len(exp.getL4Representations()[0]),20) self.assertEqual(len(exp.getL4Representations()[1]),20)
def testObjectClassificationUnit(self): """ Unit Test for multi column object classification """ random.seed(36) objectL2SDR = { "Can": [set(_randomSDR(4096, 40)) for _ in xrange(5)], "Mug": [set(_randomSDR(4096, 40)) for _ in xrange(5)], "Box": [set(_randomSDR(4096, 40)) for _ in xrange(5)] } with patch.object(l2_l4_inference.L4L2Experiment, "getL2Representations")\ as mock_getL2Representations: exp = l2_l4_inference.L4L2Experiment( "testClassificationUnit", numCorticalColumns=5 ) # Replace objects L2 representations to mock learning exp.objectL2Representations = objectL2SDR # test exact match mock_getL2Representations.return_value = objectL2SDR["Can"] results = exp.getCurrentClassification() self.assertDictEqual(results, {"Box": 0, "Mug": 0, "Can": 1}) # test no match mock_getL2Representations.return_value = [ set(_randomSDR(4096, 40)) for _ in xrange(5)] results = exp.getCurrentClassification() self.assertDictEqual(results, {"Box": 0, "Mug": 0, "Can": 0}) # test no touch mock_getL2Representations.return_value = [(), (), (), (), ()] results = exp.getCurrentClassification() self.assertDictEqual(results, {"Box": 0, "Mug": 0, "Can": 0}) # test partial match (Mug/Can) mock_getL2Representations.return_value = [ objectL2SDR["Can"][0], objectL2SDR["Can"][1], objectL2SDR["Mug"][2], objectL2SDR["Mug"][3], () ] results = exp.getCurrentClassification() self.assertDictEqual(results, {"Box": 0, "Mug": 0.5, "Can": 0.5})
def testObjectClassification(self): """ Test multi column object classification """ random.seed(36) exp = l2_l4_inference.L4L2Experiment( "testClassification", numCorticalColumns=5, inputSize=1024, numInputBits=20, externalInputSize=1024, numLearningPoints=3, ) # Location and feature pool features = [_randomSDR(1024, 20) for _ in xrange(4)] locations = [_randomSDR(1024, 20) for _ in xrange(15)] # Learn 3 different objects (Can, Mug, Box) objectsToLearn = dict() # Soda can (cylinder) grasp from top. # Same feature at different locations, not all columns have input objectsToLearn["Can"] = [ { 0: (locations[0], features[0]), # NW - round 1: (locations[1], features[0]), # N - round 2: (locations[2], features[0]), # NE - round 3: (locations[3], features[0]), # SE - round 4: ([], []), # Little Finger has no input }, { 0: (locations[1], features[0]), # N - round 1: (locations[2], features[0]), # NE - round 2: (locations[3], features[0]), # SE - round 3: (locations[4], features[0]), # S - round 4: ([], []), # Little Finger has no input }, { 0: (locations[2], features[0]), # NE - round 1: (locations[3], features[0]), # SE - round 2: (locations[4], features[0]), # S - round 3: (locations[0], features[0]), # NW - round 4: ([], []), # Little Finger has no input }, ] # Coffee mug grasp from top # Same as cylinder with extra feature (handle) objectsToLearn["Mug"] = [ { 0: (locations[0], features[0]), # NW - round 1: (locations[1], features[1]), # N - handle 2: (locations[2], features[0]), # NE - round 3: (locations[3], features[0]), # SE - round 4: (locations[4], features[0]), # S - round }, { 0: (locations[3], features[0]), # SE - round 1: (locations[0], features[0]), # NW - round 2: (locations[1], features[1]), # N - handle 3: (locations[2], features[0]), # NE - round 4: (locations[4], features[0]), # S - round }, { 0: (locations[4], features[0]), # S - round 1: (locations[3], features[0]), # SE - round 2: (locations[0], features[0]), # NW - round 3: (locations[1], features[1]), # N - handle 4: (locations[2], features[0]), # NE - round }, ] # Box grasp from top # Symetrical features at different locations. objectsToLearn["Box"] = [ { # Top/Front of the box 0: (locations[5], features[2]), # W1 - flat 1: (locations[6], features[3]), # N1 - corner 2: (locations[7], features[3]), # N2 - corner 3: (locations[8], features[2]), # E1 - flat 4: (locations[9], features[2]), # E2 - flat }, { # Top/Side of the box 0: (locations[5], features[2]), # W1 - flat 1: (locations[8], features[2]), # E1 - flat 2: (locations[9], features[2]), # E2 - flat 3: (locations[10], features[2]), # E3 - flat 4: (locations[11], features[2]), # E4 - flat }, { # Top/Back of the box 0: (locations[9], features[2]), # E2 - flat 1: (locations[12], features[3]), # S1 - corner 2: (locations[13], features[3]), # S2 - corner 3: (locations[14], features[2]), # W3 - flat 4: (locations[5], features[2]), # W1 - flat }, ] exp.learnObjects(objectsToLearn) # Try to infer "Mug" using first learned grasp sensations = [objectsToLearn["Mug"][0]] exp.sendReset() exp.infer(sensations, reset=False) results = exp.getCurrentClassification() self.assertEquals(results["Mug"], 1) self.assertEquals(results["Box"], 0) self.assertEquals(results["Can"], 0) # Try to infer "Cylinder" using first learned grasp sensations = [objectsToLearn["Can"][0]] exp.sendReset() exp.infer(sensations, reset=False) results = exp.getCurrentClassification() self.assertEquals(results["Mug"], 0) self.assertEquals(results["Box"], 0) self.assertEquals(results["Can"], 1) # Try to infer "Box" using first learned grasp sensations = [objectsToLearn["Box"][0]] exp.sendReset() exp.infer(sensations, reset=False) results = exp.getCurrentClassification() self.assertEquals(results["Mug"], 0) self.assertEquals(results["Box"], 1) self.assertEquals(results["Can"], 0) # Try to infer half "Box" half "Mug" to confuse sensations = [{ 0: objectsToLearn["Box"][0][0], 1: objectsToLearn["Box"][0][1], 2: objectsToLearn["Mug"][0][0], 3: objectsToLearn["Mug"][0][1], 4: ([], []), }] exp.sendReset() exp.infer(sensations, reset=False) results = exp.getCurrentClassification() self.assertEquals(results["Mug"], 0.5) self.assertEquals(results["Box"], 0.5) self.assertEquals(results["Can"], 0)
def testConsistency(self): """ Test that L2 and L4 representations are consistent across different instantiations with the same seed. """ random.seed(23) # Location and feature pool features = [_randomSDR(1024, 20) for _ in xrange(4)] locations = [_randomSDR(1024, 20) for _ in xrange(15)] # Learn 3 different objects (Can, Mug, Box) objectsToLearn = dict() # Soda can (cylinder) grasp from top. # Same feature at different locations, not all columns have input objectsToLearn["Can"] = [ { 0: (locations[0], features[0]), # NW - round 1: (locations[1], features[0]), # N - round 2: (locations[2], features[0]), # NE - round 3: (locations[3], features[0]), # SE - round 4: ([], []), # Little Finger has no input }, { 0: (locations[1], features[0]), # N - round 1: (locations[2], features[0]), # NE - round 2: (locations[3], features[0]), # SE - round 3: (locations[4], features[0]), # S - round 4: ([], []), # Little Finger has no input }, { 0: (locations[2], features[0]), # NE - round 1: (locations[3], features[0]), # SE - round 2: (locations[4], features[0]), # S - round 3: (locations[0], features[0]), # NW - round 4: ([], []), # Little Finger has no input }, ] # Coffee mug grasp from top # Same as cylinder with extra feature (handle) objectsToLearn["Mug"] = [ { 0: (locations[0], features[0]), # NW - round 1: (locations[1], features[1]), # N - handle 2: (locations[2], features[0]), # NE - round 3: (locations[3], features[0]), # SE - round 4: (locations[4], features[0]), # S - round }, { 0: (locations[3], features[0]), # SE - round 1: (locations[0], features[0]), # NW - round 2: (locations[1], features[1]), # N - handle 3: (locations[2], features[0]), # NE - round 4: (locations[4], features[0]), # S - round }, { 0: (locations[4], features[0]), # S - round 1: (locations[3], features[0]), # SE - round 2: (locations[0], features[0]), # NW - round 3: (locations[1], features[1]), # N - handle 4: (locations[2], features[0]), # NE - round }, ] # Box grasp from top # Symetrical features at different locations. objectsToLearn["Box"] = [ { # Top/Front of the box 0: (locations[5], features[2]), # W1 - flat 1: (locations[6], features[3]), # N1 - corner 2: (locations[7], features[3]), # N2 - corner 3: (locations[8], features[2]), # E1 - flat 4: (locations[9], features[2]), # E2 - flat }, { # Top/Side of the box 0: (locations[5], features[2]), # W1 - flat 1: (locations[8], features[2]), # E1 - flat 2: (locations[9], features[2]), # E2 - flat 3: (locations[10], features[2]), # E3 - flat 4: (locations[11], features[2]), # E4 - flat }, { # Top/Back of the box 0: (locations[9], features[2]), # E2 - flat 1: (locations[12], features[3]), # S1 - corner 2: (locations[13], features[3]), # S2 - corner 3: (locations[14], features[2]), # W3 - flat 4: (locations[5], features[2]), # W1 - flat }, ] # Create 10 experiment instances, train them on all objects and run # inference on one object numExps = 10 exps = [] for i in range(numExps): exps.append( l2_l4_inference.L4L2Experiment( "testClassification", numCorticalColumns=5, inputSize=1024, numInputBits=20, externalInputSize=1024, numLearningPoints=3, seed=23, )) exps[i].learnObjects(objectsToLearn) # Try to infer "Mug" using first learned grasp sensations = [objectsToLearn["Mug"][0]] exps[i].sendReset() exps[i].infer(sensations * 2, reset=False) # Ensure L2 and L4 representations are consistent across all experiment # instantiations, across all columns, and across 2 different repeats for i in range(2): for c in range(5): L20 = set(exps[0].getL2Representations()[c]) for e in range(1, numExps): self.assertSequenceEqual( L20, set(exps[e].getL2Representations()[c])) L40 = set(exps[0].getL4Representations()[c]) for e in range(numExps): self.assertSequenceEqual( L40, set(exps[e].getL4Representations()[c]))
def testCapacity(self): """This test mimmicks the capacity test parameters with smaller numbers. See `projects/l2_pooling/capacity_test.py`. """ l2Params = { "inputWidth": 50 * 4, "cellCount": 100, "sdrSize": 10, "synPermProximalInc": 0.1, "synPermProximalDec": 0.001, "initialProximalPermanence": 0.6, "minThresholdProximal": 1, "sampleSizeProximal": 5, "connectedPermanenceProximal": 0.5, "synPermDistalInc": 0.1, "synPermDistalDec": 0.001, "initialDistalPermanence": 0.41, "activationThresholdDistal": 3, "sampleSizeDistal": 5, "connectedPermanenceDistal": 0.5, "distalSegmentInhibitionFactor": 1.5, "learningMode": True, } l4Params = { "columnCount": 50, "cellsPerColumn": 4, "formInternalBasalConnections": True, "learn": True, "learnOnOneCell": False, "initialPermanence": 0.51, "connectedPermanence": 0.6, "permanenceIncrement": 0.1, "permanenceDecrement": 0.02, "minThreshold": 3, "predictedSegmentDecrement": 0.002, "activationThreshold": 3, "maxNewSynapseCount": 20, "implementation": "etm_cpp", } l4ColumnCount = 50 numCorticalColumns = 2 exp = l2_l4_inference.L4L2Experiment( "testCapacity", numInputBits=100, L2Overrides=l2Params, L4Overrides=l4Params, inputSize=l4ColumnCount, externalInputSize=l4ColumnCount, numLearningPoints=4, numCorticalColumns=numCorticalColumns) # Set up feature and location SDRs for two locations, A and B, for each # cortical column, 0 and 1. locA0 = list(xrange(0, 5)) featA0 = list(xrange(0, 5)) locA1 = list(xrange(5, 10)) featA1 = list(xrange(5, 10)) locB0 = list(xrange(10, 15)) featB0 = list(xrange(10, 15)) locB1 = list(xrange(15, 20)) featB1 = list(xrange(15, 20)) # Learn each location for each column with several repetitions objectsToLearn = { "obj1": [ { 0: (locA0, featA0), 1: (locA1, featA1) }, { 0: (locB0, featB0), 1: (locB1, featB1) }, { 0: (locA0, featA0), 1: (locA1, featA1) }, { 0: (locB0, featB0), 1: (locB1, featB1) }, { 0: (locA0, featA0), 1: (locA1, featA1) }, { 0: (locB0, featB0), 1: (locB1, featB1) }, ] } exp.learnObjects(objectsToLearn, reset=True) # Do the inference phase sensationsToInfer = [ { 0: (locA0, featA0), 1: (locA1, featA1) }, { 0: (locB0, featB0), 1: ([], []) }, { 0: ([], []), 1: (locA1, featA1) }, { 0: (locA0, featA0), 1: (locA1, featA1) }, ] exp.infer(sensationsToInfer, objectName="obj1", reset=False) # Check the results stats = exp.getInferenceStats() self.assertEqual(len(stats), 1) self.assertEqual(stats[0]["numSteps"], 4) self.assertEqual(stats[0]["object"], "obj1") self.assertSequenceEqual(stats[0]["Overlap L2 with object C0"], [10, 10, 10, 10]) self.assertSequenceEqual(stats[0]["Overlap L2 with object C1"], [10, 10, 10, 10])
def testDelayedLateralandApicalInputs(self): """Test whether lateral and apical inputs are synchronized across columns""" # Set up experiment exp = l2_l4_inference.L4L2Experiment( name="sample", numCorticalColumns=2, ) objects = createObjectMachine( machineType="simple", numInputBits=20, sensorInputSize=1024, externalInputSize=1024, numCorticalColumns=2, ) objects.addObject([(1, 1), (2, 2)]) objects.addObject([(1, 1), (3, 2)]) exp.learnObjects(objects.provideObjectsToLearn()) exp._sendReset() sensationC0 = [(1, 1), (1, 1), (1, 1)] sensationC1 = [(3, 2), (3, 2), (3, 2)] lateralInputs = [] apicalInputs = [] activeCells = [] for step in range(3): inferConfig = { "noiseLevel": None, "numSteps": 1, "pairs": {0: [sensationC0[step]], 1: [sensationC1[step]]} } exp.infer(objects.provideObjectToInfer(inferConfig), objectName=1, reset=False) lateralInputs.append( {0: copy.copy( exp.network.regions['L2Column_0'].getInputData("lateralInput")), 1: copy.copy( exp.network.regions['L2Column_1'].getInputData("lateralInput"))} ) activeCells.append( {0: copy.copy( exp.network.regions['L2Column_0'].getOutputData("feedForwardOutput")), 1: copy.copy( exp.network.regions['L2Column_1'].getOutputData("feedForwardOutput"))} ) apicalInputs.append(( {0: copy.copy( exp.network.regions['L4Column_0'].getInputData("apicalInput")), 1: copy.copy( exp.network.regions['L4Column_1'].getInputData("apicalInput"))} )) # no lateral inputs on first iteration self.assertEqual(numpy.sum(numpy.abs(lateralInputs[0][0])), 0) self.assertEqual(numpy.sum(numpy.abs(lateralInputs[0][1])), 0) # no apical inputs to L4 on first iteration self.assertEqual(numpy.sum(numpy.abs(apicalInputs[0][0])), 0) self.assertEqual(numpy.sum(numpy.abs(apicalInputs[0][1])), 0) # lateral inputs of C0 at time t+1 = active cells of C1 at time t for step in range(2): self.assertEqual( numpy.sum(numpy.abs(lateralInputs[step+1][0]-activeCells[step][1])), 0) self.assertEqual( numpy.sum(numpy.abs(lateralInputs[step+1][1]-activeCells[step][0])), 0) # apical inputs of L4_0 at time t+1 = active cells of L2_0 at time t for step in range(2): self.assertEqual( numpy.sum(numpy.abs(apicalInputs[step + 1][0] - activeCells[step][0])), 0) self.assertEqual( numpy.sum(numpy.abs(apicalInputs[step + 1][1] - activeCells[step][1])), 0)