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 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 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)
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)
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 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 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 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 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)
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))
# 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() ####################################################################### # # Step 3: send the same sequence of vectors and look at predictions made by # temporal memory for j in range(5): print "\n\n--------", "ABCDE"[j], "-----------"
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)
# 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() ####################################################################### # # Step 3: send the same sequence of vectors and look at predictions made by # temporal memory for j in range(5):
#numpy.savetxt("Vec%d.txt" % i, Vec) Vec = [] for x in range(xRange): for y in range(yRange): V = EncodeVector(random.randint(-100, 100), random.randint(-100, 100)) u, v = DecodeVector(V) #print "(%d, %d) = v(%d, %d)" % (x, y, u, v) #plt.quiver(x, y, u, v, pivot='mid', scale=10, units='dots', width=1) Vec = numpy.append(Vec, V) activeColumns = set([j for j, k in zip(count(), Vec) if k == 1]) tm.compute(activeColumns, learn = False) activeColumnsIndeces = [tm.columnForCell(i) for i in tm.getActiveCells()] predictedColumnIndeces = [tm.columnForCell(i) for i in tm.getPredictiveCells()] actColState = [1 if i in activeColumnsIndeces else 0 for i in range(tm.numberOfColumns())] predColState = [1 if i in predictedColumnIndeces else 0 for i in range(tm.numberOfColumns())] z = 0 for x in range(xRange): for y in range(yRange): AV = actColState[z: z + UnitEncoder.getWidth() * 2] PV = predColState[z: z + UnitEncoder.getWidth() * 2] PV = numpy.asarray( PV ) u, v = DecodeVector( PV ) if u != -999 and v != -999: print "(%d, %d) = v(%d, %d)" % (x, y, u, v) plt.quiver(x, y, u, v, pivot='mid', scale=10, units='dots', width=1)
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)
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
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)
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