def testCompute(self): tm = ExtendedTemporalMemory(columnDimensions=[4], cellsPerColumn=10, learnOnOneCell=False, initialPermanence=0.2, connectedPermanence=0.7, activationThreshold=1) seg1 = tm.connections.createSegment(0) seg2 = tm.connections.createSegment(20) seg3 = tm.connections.createSegment(25) try: tm.connections.createSynapse(seg1, 15, 0.9) tm.connections.createSynapse(seg2, 35, 0.9) tm.connections.createSynapse(seg2, 45, 0.9) # external cell tm.connections.createSynapse(seg3, 35, 0.9) tm.connections.createSynapse(seg3, 50, 0.9) # external cell except IndexError: self.fail("IndexError raised unexpectedly for distal segments") aSeg1 = tm.apicalConnections.createSegment(1) aSeg2 = tm.apicalConnections.createSegment(25) try: tm.apicalConnections.createSynapse(aSeg1, 3, 0.9) tm.apicalConnections.createSynapse(aSeg2, 1, 0.9) except IndexError: self.fail("IndexError raised unexpectedly for apical segments") activeColumns = set([1, 3]) activeExternalCells = set([5, 10, 15]) activeApicalCells = set([1, 2, 3, 4]) tm.compute(activeColumns, activeExternalCells=activeExternalCells, activeApicalCells=activeApicalCells, learn=False) activeColumns = set([0, 2]) tm.compute(activeColumns, activeExternalCells=set(), activeApicalCells=set()) self.assertEqual(tm.activeCells, set([0, 20, 25]))
def testCompute(self): tm = ExtendedTemporalMemory( columnDimensions=[4], cellsPerColumn=10, learnOnOneCell=False, initialPermanence=0.2, connectedPermanence=0.7, activationThreshold=1, ) seg1 = tm.connections.createSegment(0) seg2 = tm.connections.createSegment(20) seg3 = tm.connections.createSegment(25) try: tm.connections.createSynapse(seg1, 15, 0.9) tm.connections.createSynapse(seg2, 35, 0.9) tm.connections.createSynapse(seg2, 45, 0.9) # external cell tm.connections.createSynapse(seg3, 35, 0.9) tm.connections.createSynapse(seg3, 50, 0.9) # external cell except IndexError: self.fail("IndexError raised unexpectedly for distal segments") aSeg1 = tm.apicalConnections.createSegment(1) aSeg2 = tm.apicalConnections.createSegment(25) try: tm.apicalConnections.createSynapse(aSeg1, 3, 0.9) tm.apicalConnections.createSynapse(aSeg2, 1, 0.9) except IndexError: self.fail("IndexError raised unexpectedly for apical segments") activeColumns = set([1, 3]) activeExternalCells = set([5, 10, 15]) activeApicalCells = set([1, 2, 3, 4]) tm.compute( activeColumns, activeExternalCells=activeExternalCells, activeApicalCells=activeApicalCells, learn=False ) activeColumns = set([0, 2]) tm.compute(activeColumns, activeExternalCells=set(), activeApicalCells=set()) self.assertEqual(tm.activeCells, set([0, 20, 25]))
def testWriteRead(self): tm1 = ExtendedTemporalMemory( 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 = ExtendedTemporalMemory.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)
def testWriteRead(self): tm1 = ExtendedTemporalMemory(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 = ExtendedTemporalMemory.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)
def testLearning(self): tm = ExtendedTemporalMemory( columnDimensions=[4], cellsPerColumn=10, learnOnOneCell=False, initialPermanence=0.5, connectedPermanence=0.6, activationThreshold=1, minThreshold=1, maxNewSynapseCount=2, permanenceDecrement=0.05, permanenceIncrement=0.2, ) seg1 = tm.connections.createSegment(0) seg2 = tm.connections.createSegment(10) seg3 = tm.connections.createSegment(20) seg4 = tm.connections.createSegment(30) try: tm.connections.createSynapse(seg1, 10, 0.9) tm.connections.createSynapse(seg2, 20, 0.9) tm.connections.createSynapse(seg3, 30, 0.9) tm.connections.createSynapse(seg3, 41, 0.9) tm.connections.createSynapse(seg3, 25, 0.9) tm.connections.createSynapse(seg4, 0, 0.9) except IndexError: self.fail("IndexError raised unexpectedly for distal segments") aSeg1 = tm.apicalConnections.createSegment(0) aSeg2 = tm.apicalConnections.createSegment(20) try: tm.apicalConnections.createSynapse(aSeg1, 42, 0.8) tm.apicalConnections.createSynapse(aSeg2, 43, 0.8) except IndexError: self.fail("IndexError raised unexpectedly for apical segments") activeColumns = set([1, 3]) activeExternalCells = set([1]) # will be re-indexed to 41 activeApicalCells = set([2, 3]) # will be re-indexed to 42, 43 tm.compute( activeColumns, activeExternalCells=activeExternalCells, activeApicalCells=activeApicalCells, learn=False ) activeColumns = set([0, 2]) tm.compute(activeColumns, activeExternalCells=None, activeApicalCells=None, learn=True) self.assertEqual(tm.activeCells, set([0, 20])) # distal learning synapse = list(tm.connections.synapsesForSegment(seg1))[0] self.assertEqual(tm.connections.dataForSynapse(synapse).permanence, 1.0) synapse = list(tm.connections.synapsesForSegment(seg2))[0] self.assertEqual(tm.connections.dataForSynapse(synapse).permanence, 0.9) synapse = list(tm.connections.synapsesForSegment(seg3))[0] self.assertEqual(tm.connections.dataForSynapse(synapse).permanence, 1.0) synapse = list(tm.connections.synapsesForSegment(seg3))[1] self.assertEqual(tm.connections.dataForSynapse(synapse).permanence, 1.0) synapse = list(tm.connections.synapsesForSegment(seg3))[2] self.assertEqual(tm.connections.dataForSynapse(synapse).permanence, 0.85) synapse = list(tm.connections.synapsesForSegment(seg4))[0] self.assertEqual(tm.connections.dataForSynapse(synapse).permanence, 0.9) # apical learning synapse = list(tm.apicalConnections.synapsesForSegment(aSeg1))[0] self.assertEqual(tm.apicalConnections.dataForSynapse(synapse).permanence, 1.0) synapse = list(tm.apicalConnections.synapsesForSegment(aSeg2))[0] self.assertEqual(tm.apicalConnections.dataForSynapse(synapse).permanence, 1.0)
class NIK(object): """Class implementing NIK""" def __init__( self, minDx=-2.0, maxDx=2.0, minDy=-2.0, maxDy=2.0, minTheta1=0.0, maxTheta1=85.0, minTheta2=0.0, maxTheta2=360.0, ): self.dxEncoder = ScalarEncoder(5, minDx, maxDx, n=75, forced=True) self.dyEncoder = ScalarEncoder(5, minDy, maxDy, n=75, forced=True) self.externalSize = self.dxEncoder.getWidth()**2 self.externalOnBits = self.dxEncoder.w**2 self.theta1Encoder = ScalarEncoder(5, minTheta1, maxTheta1, n=75, forced=True) self.theta2Encoder = ScalarEncoder(5, minTheta2, maxTheta2, n=75, forced=True) self.bottomUpInputSize = self.theta1Encoder.getWidth( ) * self.theta2Encoder.getWidth() self.bottomUpOnBits = self.theta1Encoder.w * self.theta2Encoder.w self.minDx = 100.0 self.maxDx = -100.0 self.minTheta1 = minTheta1 self.minTheta2 = minTheta2 self.maxTheta1 = maxTheta1 self.maxTheta2 = maxTheta2 self.trainingIterations = 0 self.testIterations = 0 self.maxPredictionError = 0 self.totalPredictionError = 0 self.numMissedPredictions = 0 self.tm = TM(columnDimensions=(self.bottomUpInputSize, ), basalInputDimensions=(self.externalSize, ), cellsPerColumn=1, initialPermanence=0.4, connectedPermanence=0.5, minThreshold=self.externalOnBits, maxNewSynapseCount=40, permanenceIncrement=0.1, permanenceDecrement=0.00, activationThreshold=int( 0.75 * (self.externalOnBits + self.bottomUpOnBits)), predictedSegmentDecrement=0.00, checkInputs=False) print >> sys.stderr, "TM parameters:" print >> sys.stderr, " num columns=", self.tm.getColumnDimensions() print >> sys.stderr, " activation threshold=", self.tm.getActivationThreshold( ) print >> sys.stderr, " min threshold=", self.tm.getMinThreshold() print >> sys.stderr, " basal input dimensions=", self.tm.getBasalInputDimensions( ) print >> sys.stderr print >> sys.stderr def compute(self, xt1, yt1, xt, yt, theta1t1, theta2t1, theta1, theta2, learn): """ The main function to call. If learn is False, it will print a prediction: (theta1, theta2) """ dx = xt - xt1 dy = yt - yt1 self.minDx = min(self.minDx, dx) self.maxDx = max(self.maxDx, dx) print >> sys.stderr, "Learn: ", learn print >> sys.stderr, "Training iterations: ", self.trainingIterations print >> sys.stderr, "Test iterations: ", self.testIterations print >> sys.stderr, "Xt's: ", xt1, yt1, xt, yt, "Delta's: ", dx, dy print >> sys.stderr, "Theta t-1: ", theta1t1, theta2t1, "t:", theta1, theta2 bottomUpSDR = self.encodeThetas(theta1, theta2) self.decodeThetas(bottomUpSDR) # Encode the inputs appropriately and train the HTM externalSDR = self.encodeDeltas(dx, dy) if learn: # During learning we provide the current pose angle as bottom up input bottomUpSDR = self.encodeThetas(theta1, theta2) self.trainTM(bottomUpSDR, externalSDR) self.trainingIterations += 1 else: # During inference we provide the previous pose angle as bottom up input # If we don't get a prediction, we keep trying random shifts until we get # something. predictedCells = [] newt1 = theta1t1 newt2 = theta2t1 newdx = dx newdy = dy angleRange = 10 numAttempts = 1 while len(predictedCells) == 0 and numAttempts < 3: print >> sys.stderr, "Attempt:", numAttempts, print >> sys.stderr, "Trying to predict using thetas:", newt1, newt2, print >> sys.stderr, "and deltas:", newdx, newdy externalSDR = self.encodeDeltas(newdx, newdy) bottomUpSDR = self.encodeThetas(newt1, newt2) predictedCells = self.inferTM(bottomUpSDR, externalSDR) predictedValues = self.decodeThetas(predictedCells) print >> sys.stderr, "Predicted values", predictedValues newt1 = theta1t1 + random.randrange(-angleRange, angleRange) newt2 = theta2t1 + random.randrange(-angleRange, angleRange) newdx = dx + (random.random() / 2.0 - 0.25) newdy = dy + (random.random() / 2.0 - 0.25) # Ensure we are in bounds otherwise we get an exception newt1 = min(self.maxTheta1, max(self.minTheta1, newt1)) newt2 = min(self.maxTheta2, max(self.minTheta2, newt2)) newdx = min(2.0, max(-2.0, newdx)) newdy = min(2.0, max(-2.0, newdy)) numAttempts += 1 if numAttempts % 10 == 0: angleRange += 2 print predictedValues # Accumulate errors for our metrics if len(predictedCells) == 0: self.numMissedPredictions += 1 self.testIterations += 1 error = abs(predictedValues[0] - theta1) + abs(predictedValues[1] - theta2) self.totalPredictionError += error if self.maxPredictionError < error: self.maxPredictionError = error print >> sys.stderr, "Error: ", error print >> sys.stderr def reset(self): self.tm.reset() def encodeDeltas(self, dx, dy): """Return the SDR for dx,dy""" dxe = self.dxEncoder.encode(dx) dye = self.dyEncoder.encode(dy) ex = numpy.outer(dxe, dye) return ex.flatten().nonzero()[0] def encodeThetas(self, theta1, theta2): """Return the SDR for theta1 and theta2""" # print >> sys.stderr, "encoded theta1 value = ", theta1 # print >> sys.stderr, "encoded theta2 value = ", theta2 t1e = self.theta1Encoder.encode(theta1) t2e = self.theta2Encoder.encode(theta2) # print >> sys.stderr, "encoded theta1 = ", t1e.nonzero()[0] # print >> sys.stderr, "encoded theta2 = ", t2e.nonzero()[0] ex = numpy.outer(t2e, t1e) return ex.flatten().nonzero()[0] def decodeThetas(self, predictedCells): """ Given the set of predicted cells, return the predicted theta1 and theta2 """ a = numpy.zeros(self.bottomUpInputSize) a[predictedCells] = 1 a = a.reshape( (self.theta1Encoder.getWidth(), self.theta1Encoder.getWidth())) theta1PredictedBits = a.mean(axis=0).nonzero()[0] theta2PredictedBits = a.mean(axis=1).nonzero()[0] # To decode it we need to create a flattened array again and pass it # to encoder. # TODO: We use encoder's topDownCompute method - not sure if that is best. t1 = numpy.zeros(self.theta1Encoder.getWidth()) t1[theta1PredictedBits] = 1 t1Prediction = self.theta1Encoder.topDownCompute(t1)[0].value t2 = numpy.zeros(self.theta2Encoder.getWidth()) t2[theta2PredictedBits] = 1 t2Prediction = self.theta2Encoder.topDownCompute(t2)[0].value # print >> sys.stderr, "predicted cells = ", predictedCells # print >> sys.stderr, "decoded theta1 bits = ", theta1PredictedBits # print >> sys.stderr, "decoded theta2 bits = ", theta2PredictedBits # print >> sys.stderr, "decoded theta1 value = ", t1Prediction # print >> sys.stderr, "decoded theta2 value = ", t2Prediction return t1Prediction, t2Prediction def printStats(self): print >> sys.stderr, "min/max dx=", self.minDx, self.maxDx print >> sys.stderr, "Total number of segments=", numSegments(self.tm) if self.testIterations > 0: print >> sys.stderr, "Maximum prediction error: ", self.maxPredictionError print >> sys.stderr, "Mean prediction error: ", self.totalPredictionError / self.testIterations print >> sys.stderr, "Num missed predictions: ", self.numMissedPredictions def trainTM(self, bottomUp, externalInput): # print >> sys.stderr, "Bottom up: ", bottomUp # print >> sys.stderr, "ExternalInput: ",externalInput self.tm.depolarizeCells(externalInput, learn=True) self.tm.activateCells(bottomUp, reinforceCandidatesExternalBasal=externalInput, growthCandidatesExternalBasal=externalInput, learn=True) # print >> sys.stderr, ("new active cells " + str(self.tm.getActiveCells())) print >> sys.stderr, "Total number of segments=", numSegments(self.tm) def inferTM(self, bottomUp, externalInput): """ Run inference and return the set of predicted cells """ self.reset() # print >> sys.stderr, "Bottom up: ", bottomUp # print >> sys.stderr, "ExternalInput: ",externalInput self.tm.compute(bottomUp, activeCellsExternalBasal=externalInput, learn=False) # print >> sys.stderr, ("new active cells " + str(self.tm.getActiveCells())) # print >> sys.stderr, ("new predictive cells " + str(self.tm.getPredictiveCells())) return self.tm.getPredictiveCells() def save(self, filename="temp.pkl"): """ Save TM in the filename specified above """ output = open(filename, 'wb') cPickle.dump(self.tm, output, protocol=cPickle.HIGHEST_PROTOCOL) def load(self, filename="temp.pkl"): """ Save TM in the filename specified above """ inputFile = open(filename, 'rb') self.tm = cPickle.load(inputFile)
def testLearning(self): tm = ExtendedTemporalMemory(columnDimensions=[4], cellsPerColumn=10, learnOnOneCell=False, initialPermanence=0.5, connectedPermanence=0.6, activationThreshold=1, minThreshold=1, maxNewSynapseCount=2, permanenceDecrement=0.05, permanenceIncrement=0.2) seg1 = tm.connections.createSegment(0) seg2 = tm.connections.createSegment(10) seg3 = tm.connections.createSegment(20) seg4 = tm.connections.createSegment(30) try: tm.connections.createSynapse(seg1, 10, 0.9) tm.connections.createSynapse(seg2, 20, 0.9) tm.connections.createSynapse(seg3, 30, 0.9) tm.connections.createSynapse(seg3, 41, 0.9) tm.connections.createSynapse(seg3, 25, 0.9) tm.connections.createSynapse(seg4, 0, 0.9) except IndexError: self.fail("IndexError raised unexpectedly for distal segments") aSeg1 = tm.apicalConnections.createSegment(0) aSeg2 = tm.apicalConnections.createSegment(20) try: tm.apicalConnections.createSynapse(aSeg1, 42, 0.8) tm.apicalConnections.createSynapse(aSeg2, 43, 0.8) except IndexError: self.fail("IndexError raised unexpectedly for apical segments") activeColumns = set([1, 3]) activeExternalCells = set([1]) # will be re-indexed to 41 activeApicalCells = set([2, 3]) # will be re-indexed to 42, 43 tm.compute(activeColumns, activeExternalCells=activeExternalCells, activeApicalCells=activeApicalCells, learn=False) activeColumns = set([0, 2]) tm.compute(activeColumns, activeExternalCells=None, activeApicalCells=None, learn=True) self.assertEqual(tm.activeCells, set([0, 20])) # distal learning synapse = list(tm.connections.synapsesForSegment(seg1))[0] self.assertEqual( tm.connections.dataForSynapse(synapse).permanence, 1.0) synapse = list(tm.connections.synapsesForSegment(seg2))[0] self.assertEqual( tm.connections.dataForSynapse(synapse).permanence, 0.9) synapse = list(tm.connections.synapsesForSegment(seg3))[0] self.assertEqual( tm.connections.dataForSynapse(synapse).permanence, 1.0) synapse = list(tm.connections.synapsesForSegment(seg3))[1] self.assertEqual( tm.connections.dataForSynapse(synapse).permanence, 1.0) synapse = list(tm.connections.synapsesForSegment(seg3))[2] self.assertEqual( tm.connections.dataForSynapse(synapse).permanence, 0.85) synapse = list(tm.connections.synapsesForSegment(seg4))[0] self.assertEqual( tm.connections.dataForSynapse(synapse).permanence, 0.9) # apical learning synapse = list(tm.apicalConnections.synapsesForSegment(aSeg1))[0] self.assertEqual( tm.apicalConnections.dataForSynapse(synapse).permanence, 1.0) synapse = list(tm.apicalConnections.synapsesForSegment(aSeg2))[0] self.assertEqual( tm.apicalConnections.dataForSynapse(synapse).permanence, 1.0)