def testCompute(self): """ Check that there are no errors in call to compute. """ inputs = SDR(100).randomize(.05) active = SDR(100) sp = SP(inputs.dimensions, active.dimensions, stimulusThreshold=1) sp.compute(inputs, True, active) assert (active.getSum() > 0)
class SPTrainer(): """Trainer for the spatial pooler. Takes fingerprints from an input file and feeds them to the spatial pooler. Captures resulting SDR and monitors convergence of the spatial pooler. Convergence is defined as the percentage of input fingerprints which are reliably mapped to the same output SDR each time the fingerprint is presented to the spatial pooler. Therefore, convergence is defined with two parameters: the fraction of input fingerprints which are reliably matched the fraction of presentations which must produce same SDR for the fingerprint to be considered reliable """ def __init__(self, fp_length): """ Parameters: ---------- fp_length : The length of a fingerprint. """ self.fp_length = fp_length self.num_columns = 2048 self.input_array = np.zeros(self.fp_length, dtype="int32") self.active_array = np.zeros(self.num_columns, dtype="int32") self.lemma_to_sdr = dict() self.sp = SP( (self.fp_length, 1), (self.num_columns, 1), potentialRadius=512, numActiveColumnsPerInhArea=int(0.02 * self.num_columns), globalInhibition=True, synPermActiveInc=0.0, # default 0.01 synPermInactiveDec=0.0, # default 0.01 spVerbosity=1, maxBoost=1.0, # down from 10 potentialPct=0.8 # up from .5 ) def run(self, lemma, fp): """Run the spatial pooler with the input fingerprint""" #clear the input_array to zero before creating a new input vector self.input_array[0:] = 0 self.input_array[list(fp)] = 1 #active_array[column]=1 if column is active after spatial pooling self.sp.compute(self.input_array, True, self.active_array) sdr = self.active_array.nonzero() if not self.lemma_to_sdr.has_key(lemma): self.lemma_to_sdr[lemma] = LemmaSDR(lemma, fp) self.lemma_to_sdr[lemma].set_sdr(sdr)
def testCompatibilityCppPyDirectCall2D(self): """Check SP implementations have same behavior with 2D input.""" pySp = PySpatialPooler(inputDimensions=[121, 1], columnDimensions=[30, 30]) cppSp = CPPSpatialPooler(inputDimensions=[121, 1], columnDimensions=[30, 30]) data = numpy.zeros([121, 1], dtype=uintType) for i in xrange(21): data[i][0] = 1 nCols = 900 d1 = numpy.zeros(nCols, dtype=uintType) d2 = numpy.zeros(nCols, dtype=uintType) pySp.compute(data, True, d1) # learn cppSp.compute(data, True, d2) d1 = d1.nonzero()[0].tolist() d2 = d2.nonzero()[0].tolist() self.assertListEqual(d1, d2, "SP outputs are not equal: \n%s \n%s" % (str(d1), str(d2)))
def testCompatibilityCppPyDirectCall1D(self): """Check SP implementations have same behavior with 1D input.""" pySp = PySpatialPooler(inputDimensions=[121], columnDimensions=[300]) cppSp = CPPSpatialPooler(inputDimensions=[121], columnDimensions=[300]) data = numpy.zeros([121], dtype=uintType) for i in range(21): data[i] = 1 nCols = 300 d1 = numpy.zeros(nCols, dtype=uintType) d2 = numpy.zeros(nCols, dtype=uintType) pySp.compute(data, True, d1) # learn cppSp.compute(data, True, d2) d1 = d1.nonzero()[0].tolist() d2 = d2.nonzero()[0].tolist() self.assertListEqual( d1, d2, "SP outputs are not equal: \n%s \n%s" % (str(d1), str(d2)))
def testComputeParametersValidation(self): sp = SpatialPooler(inputDimensions=[5], columnDimensions=[5]) inputGood = np.ones(5, dtype=uintDType) outGood = np.zeros(5, dtype=uintDType) inputBad = np.ones(5, dtype=realDType) outBad = np.zeros(5, dtype=realDType) # Validate good parameters sp.compute(inputGood, False, outGood) # Validate bad input with self.assertRaises(RuntimeError): sp.compute(inputBad, False, outGood) # Validate bad output with self.assertRaises(RuntimeError): sp.compute(inputGood, False, outBad)
class NumentaTMLowLevelDetector(AnomalyDetector): """The 'numentaTM' detector, but not using the CLAModel or network API """ def __init__(self, *args, **kwargs): super(NumentaTMLowLevelDetector, self).__init__(*args, **kwargs) self.valueEncoder = None self.encodedValue = None self.timestampEncoder = None self.encodedTimestamp = None self.sp = None self.spOutput = None self.tm = None self.anomalyLikelihood = None # Set this to False if you want to get results based on raw scores # without using AnomalyLikelihood. This will give worse results, but # useful for checking the efficacy of AnomalyLikelihood. You will need # to re-optimize the thresholds when running with this setting. self.useLikelihood = True def getAdditionalHeaders(self): """Returns a list of strings.""" return ["raw_score"] def initialize(self): # Initialize the RDSE with a resolution; calculated from the data min and # max, the resolution is specific to the data stream. rangePadding = abs(self.inputMax - self.inputMin) * 0.2 minVal = self.inputMin - rangePadding maxVal = (self.inputMax + rangePadding if self.inputMin != self.inputMax else self.inputMin + 1) numBuckets = 130.0 resolution = max(0.001, (maxVal - minVal) / numBuckets) self.valueEncoder = RandomDistributedScalarEncoder(resolution, seed=42) self.encodedValue = np.zeros(self.valueEncoder.getWidth(), dtype=np.uint32) # Initialize the timestamp encoder self.timestampEncoder = DateEncoder(timeOfDay=(21, 9.49, )) self.encodedTimestamp = np.zeros(self.timestampEncoder.getWidth(), dtype=np.uint32) inputWidth = (self.timestampEncoder.getWidth() + self.valueEncoder.getWidth()) self.sp = SpatialPooler(**{ "globalInhibition": True, "columnDimensions": [2048], "inputDimensions": [inputWidth], "potentialRadius": inputWidth, "numActiveColumnsPerInhArea": 40, "seed": 1956, "potentialPct": 0.8, "boostStrength": 0.0, "synPermActiveInc": 0.003, "synPermConnected": 0.2, "synPermInactiveDec": 0.0005, }) self.spOutput = np.zeros(2048, dtype=np.float32) self.tm = TemporalMemory(**{ "activationThreshold": 20, "cellsPerColumn": 32, "columnDimensions": (2048,), "initialPermanence": 0.24, "maxSegmentsPerCell": 128, "maxSynapsesPerSegment": 128, "minThreshold": 13, "maxNewSynapseCount": 31, "permanenceDecrement": 0.008, "permanenceIncrement": 0.04, "seed": 1960, }) if self.useLikelihood: learningPeriod = math.floor(self.probationaryPeriod / 2.0) self.anomalyLikelihood = anomaly_likelihood.AnomalyLikelihood( claLearningPeriod=learningPeriod, estimationSamples=self.probationaryPeriod - learningPeriod, reestimationPeriod=100 ) def handleRecord(self, inputData): """Returns a tuple (anomalyScore, rawScore).""" # Encode the input data record self.valueEncoder.encodeIntoArray( inputData["value"], self.encodedValue) self.timestampEncoder.encodeIntoArray( inputData["timestamp"], self.encodedTimestamp) # Run the encoded data through the spatial pooler self.sp.compute(np.concatenate((self.encodedTimestamp, self.encodedValue,)), True, self.spOutput) # At the current state, the set of the region's active columns and the set # of columns that have previously-predicted cells are used to calculate the # raw anomaly score. activeColumns = set(self.spOutput.nonzero()[0].tolist()) prevPredictedColumns = set(self.tm.columnForCell(cell) for cell in self.tm.getPredictiveCells()) rawScore = (len(activeColumns - prevPredictedColumns) / float(len(activeColumns))) self.tm.compute(activeColumns) if self.useLikelihood: # Compute the log-likelihood score anomalyScore = self.anomalyLikelihood.anomalyProbability( inputData["value"], rawScore, inputData["timestamp"]) logScore = self.anomalyLikelihood.computeLogLikelihood(anomalyScore) return (logScore, rawScore) return (rawScore, rawScore)
class Example(object): """A class to hold our code. TODO: Get rid of this class, it just makes it more difficult to read the code. """ def __init__(self, inputDimensions, columnDimensions): """ Parameters: ---------- _inputDimensions: The size of the input. (m,n) will give a size m x n _columnDimensions: The size of the 2 dimensional array of columns """ self.inputDimensions = inputDimensions self.columnDimensions = columnDimensions self.inputSize = np.array(inputDimensions).prod() self.columnNumber = np.array(columnDimensions).prod() self.inputArray = np.zeros(self.inputSize) self.activeArray = np.zeros(self.columnNumber) self.sp = SP(self.inputDimensions, self.columnDimensions, potentialRadius = self.inputSize, numActiveColumnsPerInhArea = int(0.02*self.columnNumber), globalInhibition = True, synPermActiveInc = 0.01) def createInput(self): """create a random input vector""" print "-" * 70 + "Creating a random input vector" + "-" * 70 #clear the inputArray to zero before creating a new input vector self.inputArray[0:] = 0 for i in range(self.inputSize): #randrange returns 0 or 1 self.inputArray[i] = randrange(2) def run(self): """Run the spatial pooler with the input vector""" print "-" * 80 + "Computing the SDR" + "-" * 80 #activeArray[column]=1 if column is active after spatial pooling self.sp.compute(self.inputArray, True, self.activeArray) print self.activeArray.nonzero() def addNoise(self, noiseLevel): """Flip the value of 10% of input bits (add noise) :param noiseLevel: The percentage of total input bits that should be flipped """ for _ in range(int(noiseLevel * self.inputSize)): # 0.1*self.inputSize represents 10% of the total input bits # random.random() returns a float between 0 and 1 randomPosition = int(random() * self.inputSize) # Flipping the bit at the randomly picked position if self.inputArray[randomPosition] == 1: self.inputArray[randomPosition] = 0 else: self.inputArray[randomPosition] = 1
def frequency(self, n=15, w=7, columnDimensions = 2048, numActiveColumnsPerInhArea = 40, stimulusThreshold = 0, spSeed = 1, spVerbosity = 0, numColors = 2, seed=42, minVal=0, maxVal=10, encoder = 'category', forced=True): """ Helper function that tests whether the SP predicts the most frequent record """ print "\nRunning SP overlap test..." print encoder, 'encoder,', 'Random seed:', seed, 'and', numColors, 'colors' #Setting up SP and creating training patterns # Instantiate Spatial Pooler spImpl = SpatialPooler( columnDimensions=(columnDimensions, 1), inputDimensions=(1, n), potentialRadius=n/2, numActiveColumnsPerInhArea=numActiveColumnsPerInhArea, spVerbosity=spVerbosity, stimulusThreshold=stimulusThreshold, potentialPct=0.5, seed=spSeed, ) rnd.seed(seed) numpy.random.seed(seed) colors = [] coincs = [] reUsedCoincs = [] spOutput = [] patterns = set([]) # Setting up the encodings if encoder=='scalar': enc = scalar.ScalarEncoder(name='car', w=w, n=n, minval=minVal, maxval=maxVal, periodic=False, forced=True) # forced: it's strongly recommended to use w>=21, in the example we force skip the check for readibility for y in xrange(numColors): temp = enc.encode(rnd.random()*maxVal) colors.append(numpy.array(temp, dtype=realDType)) else: for y in xrange(numColors): sdr = numpy.zeros(n, dtype=realDType) # Randomly setting w out of n bits to 1 sdr[rnd.sample(xrange(n), w)] = 1 colors.append(sdr) # Training the sp print 'Starting to train the sp on', numColors, 'patterns' startTime = time.time() for i in xrange(numColors): # TODO: See https://github.com/numenta/nupic/issues/2072 spInput = colors[i] onCells = numpy.zeros(columnDimensions) spImpl.compute(spInput, True, onCells) spOutput.append(onCells.tolist()) activeCoincIndices = set(onCells.nonzero()[0]) # Checking if any of the active cells have been previously active reUsed = activeCoincIndices.intersection(patterns) if len(reUsed) == 0: # The set of all coincidences that have won at least once coincs.append((i, activeCoincIndices, colors[i])) else: reUsedCoincs.append((i, activeCoincIndices, colors[i])) # Adding the active cells to the set of coincs that have been active at # least once patterns.update(activeCoincIndices) if (i + 1) % 100 == 0: print 'Record number:', i + 1 print "Elapsed time: %.2f seconds" % (time.time() - startTime) print len(reUsedCoincs), "re-used coinc(s)," # Check if results match expectations summ = [] for z in coincs: summ.append(sum([len(z[1].intersection(y[1])) for y in reUsedCoincs])) zeros = len([x for x in summ if x==0]) factor = max(summ)*len(summ)/sum(summ) if len(reUsed) < 10: self.assertLess(factor, 41, "\nComputed factor: %d\nExpected Less than %d" % ( factor, 41)) self.assertLess(zeros, 0.99*len(summ), "\nComputed zeros: %d\nExpected Less than %d" % ( zeros, 0.99*len(summ))) else: self.assertLess(factor, 8, "\nComputed factor: %d\nExpected Less than %d" % ( factor, 8)) self.assertLess(zeros, 12, "\nComputed zeros: %d\nExpected Less than %d" % ( zeros, 12))
class Example(object): """A class to hold our code. TODO: Get rid of this class, it just makes it more difficult to read the code. """ def __init__(self, inputDimensions, columnDimensions): """ Parameters: ---------- _inputDimensions: The size of the input. (m,n) will give a size m x n _columnDimensions: The size of the 2 dimensional array of columns """ self.inputDimensions = inputDimensions self.columnDimensions = columnDimensions self.inputSize = np.array(inputDimensions).prod() self.columnNumber = np.array(columnDimensions).prod() self.inputArray = np.zeros(self.inputSize) self.activeArray = np.zeros(self.columnNumber) self.sp = SP(self.inputDimensions, self.columnDimensions, potentialRadius=self.inputSize, numActiveColumnsPerInhArea=int(0.02 * self.columnNumber), globalInhibition=True, synPermActiveInc=0.01) def createInput(self): """create a random input vector""" print "-" * 70 + "Creating a random input vector" + "-" * 70 #clear the inputArray to zero before creating a new input vector self.inputArray[0:] = 0 for i in range(self.inputSize): #randrange returns 0 or 1 self.inputArray[i] = randrange(2) def run(self): """Run the spatial pooler with the input vector""" print "-" * 80 + "Computing the SDR" + "-" * 80 #activeArray[column]=1 if column is active after spatial pooling self.sp.compute(self.inputArray, True, self.activeArray) print self.activeArray.nonzero() def addNoise(self, noiseLevel): """Flip the value of 10% of input bits (add noise) :param noiseLevel: The percentage of total input bits that should be flipped """ for _ in range(int(noiseLevel * self.inputSize)): # 0.1*self.inputSize represents 10% of the total input bits # random.random() returns a float between 0 and 1 randomPosition = int(random() * self.inputSize) # Flipping the bit at the randomly picked position if self.inputArray[randomPosition] == 1: self.inputArray[randomPosition] = 0 else: self.inputArray[randomPosition] = 1
ax1.imshow(R1.reshape((8, 8)), cmap=plt.cm.gray) ax2.imshow(R3.reshape((8, 8)), cmap=plt.cm.gray) ax3.imshow(R3.reshape((8, 8)), cmap=plt.cm.gray) ax4.imshow(R4.reshape((8, 8)), cmap=plt.cm.gray) plt.pause(pauseInterval) # train N_train = x_train.shape[0] i = 0 for image in x_train[0:N_train]: image = image.astype(numpy.uint32) #SDR = numpy.zeros((16,16)) SDR = numpy.zeros(256) SDR = SDR.astype(numpy.uint32) sp.compute(image, True, SDR) if i % 500 == 0: print "training" visualizeSDR(image.reshape((8, 8)), SDR.reshape((16, 16))) i += 1 # now turn off sp learning and generate an sp SDR dataset #sp._learn = False #SDR_train = numpy.zeros((1347,256)) SDR_train = numpy.zeros((x_train.shape[0], 256)) i = 0 for image in x_train: image = image.astype(numpy.uint32) SDR = numpy.zeros(256) SDR = SDR.astype(numpy.uint32)
class DistalTimestamps1CellPerColumnDetector(AnomalyDetector): """The 'numenta' detector, with the following changes: - Use pure Temporal Memory, not the classic TP that uses backtracking. - Don't spatial pool the timestamp. Pass it in as distal input. - 1 cell per column. - Use w=41 in the scalar encoding, rather than w=21, to make up for the lost timestamp input to the spatial pooler. """ def __init__(self, *args, **kwargs): super(DistalTimestamps1CellPerColumnDetector, self).__init__(*args, **kwargs) self.valueEncoder = None self.encodedValue = None self.timestampEncoder = None self.encodedTimestamp = None self.activeExternalCells = [] self.prevActiveExternalCells = [] self.sp = None self.spOutput = None self.etm = None self.anomalyLikelihood = None def getAdditionalHeaders(self): """Returns a list of strings.""" return ["raw_score"] def initialize(self): rangePadding = abs(self.inputMax - self.inputMin) * 0.2 minVal = self.inputMin - rangePadding maxVal = (self.inputMax + rangePadding if self.inputMin != self.inputMax else self.inputMin + 1) numBuckets = 130.0 resolution = max(0.001, (maxVal - minVal) / numBuckets) self.valueEncoder = RandomDistributedScalarEncoder(resolution, w=41, seed=42) self.encodedValue = np.zeros(self.valueEncoder.getWidth(), dtype=np.uint32) self.timestampEncoder = DateEncoder(timeOfDay=( 21, 9.49, )) self.encodedTimestamp = np.zeros(self.timestampEncoder.getWidth(), dtype=np.uint32) inputWidth = self.valueEncoder.getWidth() self.sp = SpatialPooler( **{ "globalInhibition": True, "columnDimensions": [2048], "inputDimensions": [inputWidth], "potentialRadius": inputWidth, "numActiveColumnsPerInhArea": 40, "seed": 1956, "potentialPct": 0.8, "boostStrength": 0.0, "synPermActiveInc": 0.003, "synPermConnected": 0.2, "synPermInactiveDec": 0.0005, }) self.spOutput = np.zeros(2048, dtype=np.float32) self.etm = ExtendedTemporalMemory( **{ "activationThreshold": 13, "cellsPerColumn": 1, "columnDimensions": (2048, ), "basalInputDimensions": (self.timestampEncoder.getWidth(), ), "initialPermanence": 0.21, "maxSegmentsPerCell": 128, "maxSynapsesPerSegment": 32, "minThreshold": 10, "maxNewSynapseCount": 20, "permanenceDecrement": 0.1, "permanenceIncrement": 0.1, "seed": 1960, "checkInputs": False, }) learningPeriod = math.floor(self.probationaryPeriod / 2.0) self.anomalyLikelihood = anomaly_likelihood.AnomalyLikelihood( claLearningPeriod=learningPeriod, estimationSamples=self.probationaryPeriod - learningPeriod, reestimationPeriod=100) def handleRecord(self, inputData): """Returns a tuple (anomalyScore, rawScore).""" self.valueEncoder.encodeIntoArray(inputData["value"], self.encodedValue) self.timestampEncoder.encodeIntoArray(inputData["timestamp"], self.encodedTimestamp) self.prevActiveExternalCells = self.activeExternalCells self.activeExternalCells = self.encodedTimestamp.nonzero()[0] self.sp.compute(self.encodedValue, True, self.spOutput) activeColumns = self.spOutput.nonzero()[0] activeColumnsSet = set(activeColumns.tolist()) prevPredictedColumns = set( self.etm.columnForCell(cell) for cell in self.etm.getPredictiveCells()) rawScore = (len(activeColumnsSet - prevPredictedColumns) / float(len(activeColumns))) anomalyScore = self.anomalyLikelihood.anomalyProbability( inputData["value"], rawScore, inputData["timestamp"]) logScore = self.anomalyLikelihood.computeLogLikelihood(anomalyScore) self.etm.compute( activeColumns, activeCellsExternalBasal=self.activeExternalCells, reinforceCandidatesExternalBasal=self.prevActiveExternalCells, growthCandidatesExternalBasal=self.prevActiveExternalCells) return (logScore, rawScore)
from nupic.bindings.algorithms import SpatialPooler sp = SpatialPooler(inputDimensions=(15,), columnDimensions=(4,), potentialRadius=15, numActiveColumnsPerInhArea=1, globalInhibition=True, synPermActiveInc=0.03, potentialPct=1.0) for column in xrange(4): connected = np.zeros((15,), dtype="int") sp.getConnectedSynapses(column, connected) print connected output = np.zeros((4,), dtype="uint8") sp.compute(np.array(cat,dtype='uint8'),True,output) print output for _ in xrange(20): sp.compute(cat, True, output) from itertools import izip as zip, count from nupic.algorithms.temporal_memory import TemporalMemory as TM TM? # Utility routine for printing the input vector
def frequency(self, n=15, w=7, columnDimensions=2048, numActiveColumnsPerInhArea=40, stimulusThreshold=0, spSeed=1, spVerbosity=0, numColors=2, seed=42, minVal=0, maxVal=10, encoder='category', forced=True): """ Helper function that tests whether the SP predicts the most frequent record """ print("\nRunning SP overlap test...") print(encoder, 'encoder,', 'Random seed:', seed, 'and', numColors, 'colors') #Setting up SP and creating training patterns # Instantiate Spatial Pooler spImpl = SpatialPooler( columnDimensions=(columnDimensions, 1), inputDimensions=(1, n), potentialRadius=n // 2, numActiveColumnsPerInhArea=numActiveColumnsPerInhArea, spVerbosity=spVerbosity, stimulusThreshold=stimulusThreshold, potentialPct=0.5, seed=spSeed, globalInhibition=True, ) rnd.seed(seed) numpy.random.seed(seed) colors = [] coincs = [] reUsedCoincs = [] spOutput = [] patterns = set([]) # Setting up the encodings if encoder == 'scalar': enc = scalar.ScalarEncoder( name='car', w=w, n=n, minval=minVal, maxval=maxVal, periodic=False, forced=True ) # forced: it's strongly recommended to use w>=21, in the example we force skip the check for readibility for y in range(numColors): temp = enc.encode(rnd.random() * maxVal) colors.append(numpy.array(temp, dtype=numpy.uint32)) else: for y in range(numColors): sdr = numpy.zeros(n, dtype=numpy.uint32) # Randomly setting w out of n bits to 1 sdr[rnd.sample(range(n), w)] = 1 colors.append(sdr) # Training the sp print('Starting to train the sp on', numColors, 'patterns') startTime = time.time() for i in range(numColors): # TODO: See https://github.com/numenta/nupic/issues/2072 spInput = colors[i] onCells = numpy.zeros(columnDimensions, dtype=numpy.uint32) spImpl.compute(spInput, True, onCells) spOutput.append(onCells.tolist()) activeCoincIndices = set(onCells.nonzero()[0]) # Checking if any of the active cells have been previously active reUsed = activeCoincIndices.intersection(patterns) if len(reUsed) == 0: # The set of all coincidences that have won at least once coincs.append((i, activeCoincIndices, colors[i])) else: reUsedCoincs.append((i, activeCoincIndices, colors[i])) # Adding the active cells to the set of coincs that have been active at # least once patterns.update(activeCoincIndices) if (i + 1) % 100 == 0: print('Record number:', i + 1) print("Elapsed time: %.2f seconds" % (time.time() - startTime)) print(len(reUsedCoincs), "re-used coinc(s),") # Check if results match expectations summ = [] for z in coincs: summ.append( sum([len(z[1].intersection(y[1])) for y in reUsedCoincs])) zeros = len([x for x in summ if x == 0]) factor = max(summ) * len(summ) / sum(summ) if len(reUsed) < 10: self.assertLess( factor, 41, "\nComputed factor: %d\nExpected Less than %d" % (factor, 41)) self.assertLess( zeros, 0.99 * len(summ), "\nComputed zeros: %d\nExpected Less than %d" % (zeros, 0.99 * len(summ))) else: self.assertLess( factor, 8, "\nComputed factor: %d\nExpected Less than %d" % (factor, 8)) self.assertLess( zeros, 12, "\nComputed zeros: %d\nExpected Less than %d" % (zeros, 12))
class SpatialPoolerAPITest(unittest.TestCase): """Tests for SpatialPooler public API""" def setUp(self): self.sp = SpatialPooler(columnDimensions=[5], inputDimensions=[5]) def testCompute(self): # Check that there are no errors in call to compute inputVector = numpy.ones(5, dtype=uintType) activeArray = numpy.zeros(5, dtype=uintType) self.sp.compute(inputVector, True, activeArray) def testGetUpdatePeriod(self): inParam = 1234 self.sp.setUpdatePeriod(inParam) outParam = self.sp.getUpdatePeriod() self.assertEqual(inParam, outParam) def testGetPotentialRadius(self): inParam = 56 self.sp.setPotentialRadius(inParam) outParam = self.sp.getPotentialRadius() self.assertEqual(inParam, outParam) def testGetPotentialPct(self): inParam = 0.4 self.sp.setPotentialPct(inParam) outParam = self.sp.getPotentialPct() self.assertAlmostEqual(inParam, outParam) def testGetGlobalInhibition(self): inParam = True self.sp.setGlobalInhibition(inParam) outParam = self.sp.getGlobalInhibition() self.assertEqual(inParam, outParam) inParam = False self.sp.setGlobalInhibition(inParam) outParam = self.sp.getGlobalInhibition() self.assertEqual(inParam, outParam) def testGetNumActiveColumnsPerInhArea(self): inParam = 7 self.sp.setNumActiveColumnsPerInhArea(inParam) outParam = self.sp.getNumActiveColumnsPerInhArea() self.assertEqual(inParam, outParam) def testGetLocalAreaDensity(self): inParam = 0.4 self.sp.setLocalAreaDensity(inParam) outParam = self.sp.getLocalAreaDensity() self.assertAlmostEqual(inParam, outParam) def testGetStimulusThreshold(self): inParam = 89 self.sp.setStimulusThreshold(inParam) outParam = self.sp.getStimulusThreshold() self.assertEqual(inParam, outParam) def testGetInhibitionRadius(self): inParam = 4 self.sp.setInhibitionRadius(inParam) outParam = self.sp.getInhibitionRadius() self.assertEqual(inParam, outParam) def testGetDutyCyclePeriod(self): inParam = 2020 self.sp.setDutyCyclePeriod(inParam) outParam = self.sp.getDutyCyclePeriod() self.assertEqual(inParam, outParam) def testGetBoostStrength(self): inParam = 78 self.sp.setBoostStrength(inParam) outParam = self.sp.getBoostStrength() self.assertEqual(inParam, outParam) def testGetIterationNum(self): inParam = 999 self.sp.setIterationNum(inParam) outParam = self.sp.getIterationNum() self.assertEqual(inParam, outParam) def testGetIterationLearnNum(self): inParam = 666 self.sp.setIterationLearnNum(inParam) outParam = self.sp.getIterationLearnNum() self.assertEqual(inParam, outParam) def testGetSpVerbosity(self): inParam = 2 self.sp.setSpVerbosity(inParam) outParam = self.sp.getSpVerbosity() self.assertEqual(inParam, outParam) def testGetSynPermTrimThreshold(self): inParam = 0.7 self.sp.setSynPermTrimThreshold(inParam) outParam = self.sp.getSynPermTrimThreshold() self.assertAlmostEqual(inParam, outParam) def testGetSynPermActiveInc(self): inParam = 0.567 self.sp.setSynPermActiveInc(inParam) outParam = self.sp.getSynPermActiveInc() self.assertAlmostEqual(inParam, outParam) def testGetSynPermInactiveDec(self): inParam = 0.123 self.sp.setSynPermInactiveDec(inParam) outParam = self.sp.getSynPermInactiveDec() self.assertAlmostEqual(inParam, outParam) def testGetSynPermBelowStimulusInc(self): inParam = 0.0898 self.sp.setSynPermBelowStimulusInc(inParam) outParam = self.sp.getSynPermBelowStimulusInc() self.assertAlmostEqual(inParam, outParam) def testGetSynPermConnected(self): inParam = 0.514 self.sp.setSynPermConnected(inParam) outParam = self.sp.getSynPermConnected() self.assertAlmostEqual(inParam, outParam) def testGetMinPctOverlapDutyCycles(self): inParam = 0.11122 self.sp.setMinPctOverlapDutyCycles(inParam) outParam = self.sp.getMinPctOverlapDutyCycles() self.assertAlmostEqual(inParam, outParam) def testGetPermanence(self): numInputs = 5 numColumns = 5 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns], potentialRadius=1, potentialPct=1) inParam = numpy.array([0.06, 0.07, 0.08, 0.12, 0.13]).astype(realType) self.sp.setPermanence(0, inParam) outParam = numpy.zeros(numInputs).astype(realType) self.sp.getPermanence(0, outParam) self.assertListEqual(list(inParam), list(outParam)) def testGetBoostFactors(self): numInputs = 3 numColumns = 3 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns]) inParam = numpy.array([ 1, 1.2, 1.3, ]).astype(realType) self.sp.setBoostFactors(inParam) outParam = numpy.zeros(numInputs).astype(realType) self.sp.getBoostFactors(outParam) self.assertListEqual(list(inParam), list(outParam)) def testGetOverlapDutyCycles(self): numInputs = 3 numColumns = 3 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns]) inParam = numpy.array([0.9, 0.3, 0.1]).astype(realType) self.sp.setOverlapDutyCycles(inParam) outParam = numpy.zeros(numInputs).astype(realType) self.sp.getOverlapDutyCycles(outParam) self.assertListEqual(list(inParam), list(outParam)) def testGetActiveDutyCycles(self): numInputs = 3 numColumns = 3 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns]) inParam = numpy.array([ 0.9, 0.99, 0.999, ]).astype(realType) self.sp.setActiveDutyCycles(inParam) outParam = numpy.zeros(numInputs).astype(realType) self.sp.getActiveDutyCycles(outParam) self.assertListEqual(list(inParam), list(outParam)) def testGetMinOverlapDutyCycles(self): numInputs = 3 numColumns = 3 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns]) inParam = numpy.array([ 0.01, 0.02, 0.035, ]).astype(realType) self.sp.setMinOverlapDutyCycles(inParam) outParam = numpy.zeros(numInputs).astype(realType) self.sp.getMinOverlapDutyCycles(outParam) self.assertListEqual(list(inParam), list(outParam)) def testGetPotential(self): self.sp.initialize(columnDimensions=[3], inputDimensions=[3]) numInputs = 3 numColumns = 3 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns]) inParam1 = numpy.array([1, 0, 1]).astype(uintType) self.sp.setPotential(0, inParam1) inParam2 = numpy.array([1, 1, 0]).astype(uintType) self.sp.setPotential(1, inParam2) outParam1 = numpy.zeros(numInputs).astype(uintType) outParam2 = numpy.zeros(numInputs).astype(uintType) self.sp.getPotential(0, outParam1) self.sp.getPotential(1, outParam2) self.assertListEqual(list(inParam1), list(outParam1)) self.assertListEqual(list(inParam2), list(outParam2)) def testGetConnectedSynapses(self): numInputs = 5 numColumns = 5 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns], potentialRadius=1, potentialPct=1) inParam = numpy.array([0.06, 0.07, 0.08, 0.12, 0.13]).astype(realType) trueConnected = numpy.array([0, 0, 0, 1, 1]) self.sp.setSynPermConnected(0.1) self.sp.setPermanence(0, inParam) outParam = numpy.zeros(numInputs).astype(uintType) self.sp.getConnectedSynapses(0, outParam) self.assertListEqual(list(trueConnected), list(outParam)) def testGetConnectedCounts(self): numInputs = 5 numColumns = 5 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns], potentialRadius=1, potentialPct=1) inParam = numpy.array([0.06, 0.07, 0.08, 0.12, 0.11]).astype(realType) trueConnectedCount = 2 self.sp.setSynPermConnected(0.1) self.sp.setPermanence(0, inParam) outParam = numpy.zeros(numInputs).astype(uintType) self.sp.getConnectedCounts(outParam) self.assertEqual(trueConnectedCount, outParam[0]) def assertListAlmostEqual(self, alist, blist): self.assertEqual(len(alist), len(blist)) for (a, b) in zip(alist, blist): diff = abs(a - b) self.assertLess(diff, 1e-5)
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"]) rdseParams = RDSE_Parameters() rdseParams.size = 100 rdseParams.sparsity = .10 rdseParams.radius = 10 scalarEncoder = RDSE(rdseParams) # encodingWidth = (timeOfDayEncoder.getWidth() # + weekendEncoder.getWidth() # + scalarEncoder.getWidth()) encodingWidth = scalarEncoder.size sp = SpatialPooler( inputDimensions=(encodingWidth, ), columnDimensions=(spParams["columnCount"], ), potentialPct=spParams["potentialPct"], potentialRadius=encodingWidth, globalInhibition=spParams["globalInhibition"], localAreaDensity=spParams["localAreaDensity"], numActiveColumnsPerInhArea=spParams["numActiveColumnsPerInhArea"], synPermInactiveDec=spParams["synPermInactiveDec"], synPermActiveInc=spParams["synPermActiveInc"], synPermConnected=spParams["synPermConnected"], boostStrength=spParams["boostStrength"], seed=spParams["seed"], wrapAround=True) tm = TemporalMemory( columnDimensions=(tmParams["columnCount"], ), cellsPerColumn=tmParams["cellsPerColumn"], activationThreshold=tmParams["activationThreshold"], initialPermanence=tmParams["initialPerm"], connectedPermanence=spParams["synPermConnected"], minThreshold=tmParams["minThreshold"], maxNewSynapseCount=tmParams["newSynapseCount"], permanenceIncrement=tmParams["permanenceInc"], permanenceDecrement=tmParams["permanenceDec"], predictedSegmentDecrement=0.0, maxSegmentsPerCell=tmParams["maxSegmentsPerCell"], maxSynapsesPerSegment=tmParams["maxSynapsesPerSegment"], seed=tmParams["seed"]) results = [] with open(_INPUT_FILE_PATH, "r") as fin: reader = csv.reader(fin) headers = next(reader) next(reader) next(reader) 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.size) consumptionBits = SDR(scalarEncoder.size) # Now we call the encoders to create bit representations for each value. # timeOfDayEncoder.encodeIntoArray(dateString, timeOfDayBits) # weekendEncoder.encodeIntoArray(dateString, weekendBits) scalarEncoder.encode(consumption, consumptionBits) # Concatenate all these encodings into one large encoding for Spatial # Pooling. # encoding = numpy.concatenate( # [timeOfDayBits, weekendBits, consumptionBits] # ) encoding = 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"]) activeColumns = SDR(spParams["columnCount"]) encodingIn = numpy.uint32(encoding.dense) minicolumnsOut = numpy.uint32(activeColumns.dense) # Execute Spatial Pooling algorithm over input space. sp.compute(encodingIn, True, minicolumnsOut) activeColumnIndices = numpy.nonzero(minicolumnsOut)[0] # Execute Temporal Memory algorithm over active mini-columns. tm.compute(activeColumnIndices, learn=True) activeCells = tm.getActiveCells() print(len(activeCells)) results.append(activeCells) return results
class DistalTimestamps1CellPerColumnDetector(AnomalyDetector): """The 'numenta' detector, with the following changes: - Use pure Temporal Memory, not the classic TP that uses backtracking. - Don't spatial pool the timestamp. Pass it in as distal input. - 1 cell per column. - Use w=41 in the scalar encoding, rather than w=21, to make up for the lost timestamp input to the spatial pooler. """ def __init__(self, *args, **kwargs): super(DistalTimestamps1CellPerColumnDetector, self).__init__(*args, **kwargs) self.valueEncoder = None self.encodedValue = None self.timestampEncoder = None self.encodedTimestamp = None self.activeExternalCells = [] self.prevActiveExternalCells = [] self.sp = None self.spOutput = None self.etm = None self.anomalyLikelihood = None def getAdditionalHeaders(self): """Returns a list of strings.""" return ["raw_score"] def initialize(self): rangePadding = abs(self.inputMax - self.inputMin) * 0.2 minVal = self.inputMin - rangePadding maxVal = (self.inputMax + rangePadding if self.inputMin != self.inputMax else self.inputMin + 1) numBuckets = 130.0 resolution = max(0.001, (maxVal - minVal) / numBuckets) self.valueEncoder = RandomDistributedScalarEncoder(resolution, w=41, seed=42) self.encodedValue = np.zeros(self.valueEncoder.getWidth(), dtype=np.uint32) self.timestampEncoder = DateEncoder(timeOfDay=(21,9.49,)) self.encodedTimestamp = np.zeros(self.timestampEncoder.getWidth(), dtype=np.uint32) inputWidth = self.valueEncoder.getWidth() self.sp = SpatialPooler(**{ "globalInhibition": True, "columnDimensions": [2048], "inputDimensions": [inputWidth], "potentialRadius": inputWidth, "numActiveColumnsPerInhArea": 40, "seed": 1956, "potentialPct": 0.8, "boostStrength": 0.0, "synPermActiveInc": 0.003, "synPermConnected": 0.2, "synPermInactiveDec": 0.0005, }) self.spOutput = np.zeros(2048, dtype=np.float32) self.etm = ExtendedTemporalMemory(**{ "activationThreshold": 13, "cellsPerColumn": 1, "columnDimensions": (2048,), "basalInputDimensions": (self.timestampEncoder.getWidth(),), "initialPermanence": 0.21, "maxSegmentsPerCell": 128, "maxSynapsesPerSegment": 32, "minThreshold": 10, "maxNewSynapseCount": 20, "permanenceDecrement": 0.1, "permanenceIncrement": 0.1, "seed": 1960, "checkInputs": False, }) learningPeriod = math.floor(self.probationaryPeriod / 2.0) self.anomalyLikelihood = anomaly_likelihood.AnomalyLikelihood( claLearningPeriod=learningPeriod, estimationSamples=self.probationaryPeriod - learningPeriod, reestimationPeriod=100 ) def handleRecord(self, inputData): """Returns a tuple (anomalyScore, rawScore).""" self.valueEncoder.encodeIntoArray(inputData["value"], self.encodedValue) self.timestampEncoder.encodeIntoArray(inputData["timestamp"], self.encodedTimestamp) self.prevActiveExternalCells = self.activeExternalCells self.activeExternalCells = self.encodedTimestamp.nonzero()[0] self.sp.compute(self.encodedValue, True, self.spOutput) activeColumns = self.spOutput.nonzero()[0] activeColumnsSet = set(activeColumns.tolist()) prevPredictedColumns = set(self.etm.columnForCell(cell) for cell in self.etm.getPredictiveCells()) rawScore = (len(activeColumnsSet - prevPredictedColumns) / float(len(activeColumns))) anomalyScore = self.anomalyLikelihood.anomalyProbability( inputData["value"], rawScore, inputData["timestamp"]) logScore = self.anomalyLikelihood.computeLogLikelihood(anomalyScore) self.etm.compute(activeColumns, activeCellsExternalBasal=self.activeExternalCells, reinforceCandidatesExternalBasal=self.prevActiveExternalCells, growthCandidatesExternalBasal=self.prevActiveExternalCells) return (logScore, rawScore)
def generateBalancedSequenceSample(num_seqs=2, sample_size=100): ''' num_seqs = number of unique sequences to choose from sample_size = number of sequence id's to choose (i.e. the number of sample sequences) ''' seqs = [] for s in range(sample_size): seq_id = random.randint(0, num_seqs - 1) seqs.append(seq_id) return numpy.array(seqs) # define the SDR's for the 4 letters SDR_A = numpy.zeros(200) SDR_A = SDR_A.astype(numpy.uint32) sp.compute(encoded_A, False, SDR_A) SDR_A_activeColumns = numpy.where(SDR_A > 0)[0] SDR_A_activeColumns.sort() SDR_B = numpy.zeros(200) SDR_B = SDR_B.astype(numpy.uint32) sp.compute(encoded_B, False, SDR_B) SDR_B_activeColumns = numpy.where(SDR_B > 0)[0] SDR_B_activeColumns.sort() SDR_C = numpy.zeros(200) SDR_C = SDR_C.astype(numpy.uint32) sp.compute(encoded_C, False, SDR_C) SDR_C_activeColumns = numpy.where(SDR_C > 0)[0] SDR_C_activeColumns.sort()
class BaseNetwork(object): def __init__(self, inputMin=None, inputMax=None, runSanity=False): self.inputMin = inputMin self.inputMax = inputMax self.runSanity = runSanity self.encoder = None self.encoderOutput = None self.sp = None self.spOutput = None self.spOutputNZ = None self.tm = None self.anomalyScore = None if runSanity: self.sanity = None self.defaultEncoderResolution = 0.0001 self.numColumns = 2048 self.cellsPerColumn = 32 self.predictedActiveCells = None self.previouslyPredictiveCells = None def initialize(self): # Scalar Encoder resolution = self.getEncoderResolution() self.encoder = RandomDistributedScalarEncoder(resolution, seed=42) self.encoderOutput = np.zeros(self.encoder.getWidth(), dtype=np.uint32) # Spatial Pooler spInputWidth = self.encoder.getWidth() self.spParams = { "globalInhibition": True, "columnDimensions": [self.numColumns], "inputDimensions": [spInputWidth], "potentialRadius": spInputWidth, "numActiveColumnsPerInhArea": 40, "seed": 1956, "potentialPct": 0.8, "boostStrength": 0.0, "synPermActiveInc": 0.003, "synPermConnected": 0.2, "synPermInactiveDec": 0.0005, } self.sp = SpatialPooler(**self.spParams) self.spOutput = np.zeros(self.numColumns, dtype=np.uint32) # Temporal Memory self.tmParams = { "activationThreshold": 20, "cellsPerColumn": self.cellsPerColumn, "columnDimensions": (self.numColumns,), "initialPermanence": 0.24, "maxSegmentsPerCell": 128, "maxSynapsesPerSegment": 128, "minThreshold": 13, "maxNewSynapseCount": 31, "permanenceDecrement": 0.008, "permanenceIncrement": 0.04, "seed": 1960, } self.tm = TemporalMemory(**self.tmParams) # Sanity if self.runSanity: self.sanity = sanity.SPTMInstance(self.sp, self.tm) def handleRecord(self, scalarValue, label=None, skipEncoding=False, learningMode=True): """Process one record.""" if self.runSanity: self.sanity.waitForUserContinue() # Encode the input data record if it hasn't already been encoded. if not skipEncoding: self.encodeValue(scalarValue) # Run the encoded data through the spatial pooler self.sp.compute(self.encoderOutput, learningMode, self.spOutput) self.spOutputNZ = self.spOutput.nonzero()[0] # WARNING: this needs to happen here, before the TM runs. self.previouslyPredictiveCells = self.tm.getPredictiveCells() # Run SP output through temporal memory self.tm.compute(self.spOutputNZ) self.predictedActiveCells = _computePredictedActiveCells( self.tm.getActiveCells(), self.previouslyPredictiveCells) # Anomaly score self.anomalyScore = _computeAnomalyScore(self.spOutputNZ, self.previouslyPredictiveCells, self.cellsPerColumn) # Run Sanity if self.runSanity: self.sanity.appendTimestep(self.getEncoderOutputNZ(), self.getSpOutputNZ(), self.previouslyPredictiveCells, { 'value': scalarValue, 'label':label }) def encodeValue(self, scalarValue): self.encoder.encodeIntoArray(scalarValue, self.encoderOutput) def getEncoderResolution(self): """ Compute the Random Distributed Scalar Encoder (RDSE) resolution. It's calculated from the data min and max, specific to the data stream. """ if self.inputMin is None or self.inputMax is None: return self.defaultEncoderResolution else: rangePadding = abs(self.inputMax - self.inputMin) * 0.2 minVal = self.inputMin - rangePadding maxVal = (self.inputMax + rangePadding if self.inputMin != self.inputMax else self.inputMin + 1) numBuckets = 130.0 return max(self.defaultEncoderResolution, (maxVal - minVal) / numBuckets) def getEncoderOutputNZ(self): return self.encoderOutput.nonzero()[0] def getSpOutputNZ(self): return self.spOutputNZ def getTmPredictiveCellsNZ(self): return self.tm.getPredictiveCells() def getTmActiveCellsNZ(self): return self.tm.getActiveCells() def getTmPredictedActiveCellsNZ(self): return self.predictedActiveCells def getRawAnomalyScore(self): return self.anomalyScore
class SpatialPoolerAPITest(unittest.TestCase): """Tests for SpatialPooler public API""" def setUp(self): self.sp = SpatialPooler(columnDimensions=[5], inputDimensions=[5]) def testCompute(self): # Check that there are no errors in call to compute inputVector = numpy.ones(5) activeArray = numpy.zeros(5) self.sp.compute(inputVector, True, activeArray) def testGetUpdatePeriod(self): inParam = 1234 self.sp.setUpdatePeriod(inParam) outParam = self.sp.getUpdatePeriod() self.assertEqual(inParam, outParam) def testGetPotentialRadius(self): inParam = 56 self.sp.setPotentialRadius(inParam) outParam = self.sp.getPotentialRadius() self.assertEqual(inParam, outParam) def testGetPotentialPct(self): inParam = 0.4 self.sp.setPotentialPct(inParam) outParam = self.sp.getPotentialPct() self.assertAlmostEqual(inParam, outParam) def testGetGlobalInhibition(self): inParam = True self.sp.setGlobalInhibition(inParam) outParam = self.sp.getGlobalInhibition() self.assertEqual(inParam, outParam) inParam = False self.sp.setGlobalInhibition(inParam) outParam = self.sp.getGlobalInhibition() self.assertEqual(inParam, outParam) def testGetNumActiveColumnsPerInhArea(self): inParam = 7 self.sp.setNumActiveColumnsPerInhArea(inParam) outParam = self.sp.getNumActiveColumnsPerInhArea() self.assertEqual(inParam, outParam) def testGetLocalAreaDensity(self): inParam = 0.4 self.sp.setLocalAreaDensity(inParam) outParam = self.sp.getLocalAreaDensity() self.assertAlmostEqual(inParam, outParam) def testGetStimulusThreshold(self): inParam = 89 self.sp.setStimulusThreshold(inParam) outParam = self.sp.getStimulusThreshold() self.assertEqual(inParam, outParam) def testGetInhibitionRadius(self): inParam = 4 self.sp.setInhibitionRadius(inParam) outParam = self.sp.getInhibitionRadius() self.assertEqual(inParam, outParam) def testGetDutyCyclePeriod(self): inParam = 2020 self.sp.setDutyCyclePeriod(inParam) outParam = self.sp.getDutyCyclePeriod() self.assertEqual(inParam, outParam) def testGetBoostStrength(self): inParam = 78 self.sp.setBoostStrength(inParam) outParam = self.sp.getBoostStrength() self.assertEqual(inParam, outParam) def testGetIterationNum(self): inParam = 999 self.sp.setIterationNum(inParam) outParam = self.sp.getIterationNum() self.assertEqual(inParam, outParam) def testGetIterationLearnNum(self): inParam = 666 self.sp.setIterationLearnNum(inParam) outParam = self.sp.getIterationLearnNum() self.assertEqual(inParam, outParam) def testGetSpVerbosity(self): inParam = 2 self.sp.setSpVerbosity(inParam) outParam = self.sp.getSpVerbosity() self.assertEqual(inParam, outParam) def testGetSynPermTrimThreshold(self): inParam = 0.7 self.sp.setSynPermTrimThreshold(inParam) outParam = self.sp.getSynPermTrimThreshold() self.assertAlmostEqual(inParam, outParam) def testGetSynPermActiveInc(self): inParam = 0.567 self.sp.setSynPermActiveInc(inParam) outParam = self.sp.getSynPermActiveInc() self.assertAlmostEqual(inParam, outParam) def testGetSynPermInactiveDec(self): inParam = 0.123 self.sp.setSynPermInactiveDec(inParam) outParam = self.sp.getSynPermInactiveDec() self.assertAlmostEqual(inParam, outParam) def testGetSynPermBelowStimulusInc(self): inParam = 0.0898 self.sp.setSynPermBelowStimulusInc(inParam) outParam = self.sp.getSynPermBelowStimulusInc() self.assertAlmostEqual(inParam, outParam) def testGetSynPermConnected(self): inParam = 0.514 self.sp.setSynPermConnected(inParam) outParam = self.sp.getSynPermConnected() self.assertAlmostEqual(inParam, outParam) def testGetMinPctOverlapDutyCycles(self): inParam = 0.11122 self.sp.setMinPctOverlapDutyCycles(inParam) outParam = self.sp.getMinPctOverlapDutyCycles() self.assertAlmostEqual(inParam, outParam) def testGetPermanence(self): numInputs = 5 numColumns = 5 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns], potentialRadius=1, potentialPct=1) inParam = numpy.array( [0.06, 0.07, 0.08, 0.12, 0.13]).astype(realType) self.sp.setPermanence(0,inParam) outParam = numpy.zeros(numInputs).astype(realType) self.sp.getPermanence(0, outParam) self.assertListEqual(list(inParam),list(outParam)) def testGetBoostFactors(self): numInputs = 3 numColumns = 3 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns]) inParam = numpy.array([1, 1.2, 1.3, ]).astype(realType) self.sp.setBoostFactors(inParam) outParam = numpy.zeros(numInputs).astype(realType) self.sp.getBoostFactors(outParam) self.assertListEqual(list(inParam),list(outParam)) def testGetOverlapDutyCycles(self): numInputs = 3 numColumns = 3 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns]) inParam = numpy.array([0.9, 0.3, 0.1]).astype(realType) self.sp.setOverlapDutyCycles(inParam) outParam = numpy.zeros(numInputs).astype(realType) self.sp.getOverlapDutyCycles(outParam) self.assertListEqual(list(inParam),list(outParam)) def testGetActiveDutyCycles(self): numInputs = 3 numColumns = 3 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns]) inParam = numpy.array([0.9, 0.99, 0.999, ]).astype(realType) self.sp.setActiveDutyCycles(inParam) outParam = numpy.zeros(numInputs).astype(realType) self.sp.getActiveDutyCycles(outParam) self.assertListEqual(list(inParam),list(outParam)) def testGetMinOverlapDutyCycles(self): numInputs = 3 numColumns = 3 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns]) inParam = numpy.array([0.01, 0.02, 0.035, ]).astype(realType) self.sp.setMinOverlapDutyCycles(inParam) outParam = numpy.zeros(numInputs).astype(realType) self.sp.getMinOverlapDutyCycles(outParam) self.assertListEqual(list(inParam),list(outParam)) def testGetPotential(self): self.sp.initialize(columnDimensions=[3], inputDimensions=[3]) numInputs = 3 numColumns = 3 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns]) inParam1 = numpy.array([1, 0, 1]).astype(uintType) self.sp.setPotential(0, inParam1) inParam2 = numpy.array([1, 1, 0]).astype(uintType) self.sp.setPotential(1, inParam2) outParam1 = numpy.zeros(numInputs).astype(uintType) outParam2 = numpy.zeros(numInputs).astype(uintType) self.sp.getPotential(0, outParam1) self.sp.getPotential(1, outParam2) self.assertListEqual(list(inParam1),list(outParam1)) self.assertListEqual(list(inParam2),list(outParam2)) def testGetConnectedSynapses(self): numInputs = 5 numColumns = 5 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns], potentialRadius=1, potentialPct=1) inParam = numpy.array( [0.06, 0.07, 0.08, 0.12, 0.13]).astype(realType) trueConnected = numpy.array([0, 0, 0, 1, 1]) self.sp.setSynPermConnected(0.1) self.sp.setPermanence(0,inParam) outParam = numpy.zeros(numInputs).astype(uintType) self.sp.getConnectedSynapses(0, outParam) self.assertListEqual(list(trueConnected),list(outParam)) def testGetConnectedCounts(self): numInputs = 5 numColumns = 5 self.sp.initialize(columnDimensions=[numInputs], inputDimensions=[numColumns], potentialRadius=1, potentialPct=1) inParam = numpy.array( [0.06, 0.07, 0.08, 0.12, 0.11]).astype(realType) trueConnectedCount = 2 self.sp.setSynPermConnected(0.1) self.sp.setPermanence(0, inParam) outParam = numpy.zeros(numInputs).astype(uintType) self.sp.getConnectedCounts(outParam) self.assertEqual(trueConnectedCount, outParam[0]) def assertListAlmostEqual(self, alist, blist): self.assertEqual(len(alist), len(blist)) for (a,b) in zip(alist,blist): diff = abs(a - b) self.assertLess(diff,1e-5)
def go(): valueEncoder = RandomDistributedScalarEncoder(resolution=0.88, seed=42) timestampEncoder = DateEncoder(timeOfDay=( 21, 9.49, )) inputWidth = timestampEncoder.getWidth() + valueEncoder.getWidth() sp = SpatialPooler( **{ "globalInhibition": True, "columnDimensions": [2048], "inputDimensions": [inputWidth], "potentialRadius": inputWidth, "numActiveColumnsPerInhArea": 40, "seed": 1956, "potentialPct": 0.8, "boostStrength": 0.0, "synPermActiveInc": 0.003, "synPermConnected": 0.2, "synPermInactiveDec": 0.0005, }) tm = TemporalMemory( **{ "activationThreshold": 20, "cellsPerColumn": 32, "columnDimensions": (2048, ), "initialPermanence": 0.24, "maxSegmentsPerCell": 128, "maxSynapsesPerSegment": 128, "minThreshold": 13, "maxNewSynapseCount": 31, "permanenceDecrement": 0.008, "permanenceIncrement": 0.04, "seed": 1961, }) inputPath = os.path.join(os.path.dirname(__file__), "data/rec-center-hourly.csv") inputFile = open(inputPath, "rb") csvReader = csv.reader(inputFile) csvReader.next() csvReader.next() csvReader.next() encodedValue = np.zeros(valueEncoder.getWidth(), dtype=np.uint32) encodedTimestamp = np.zeros(timestampEncoder.getWidth(), dtype=np.uint32) spOutput = np.zeros(2048, dtype=np.float32) sanityInstance = sanity.SPTMInstance(sp, tm) for timestampStr, consumptionStr in csvReader: sanityInstance.waitForUserContinue() timestamp = datetime.datetime.strptime(timestampStr, "%m/%d/%y %H:%M") consumption = float(consumptionStr) timestampEncoder.encodeIntoArray(timestamp, encodedTimestamp) valueEncoder.encodeIntoArray(consumption, encodedValue) sensoryInput = np.concatenate(( encodedTimestamp, encodedValue, )) sp.compute(sensoryInput, True, spOutput) activeColumns = np.flatnonzero(spOutput) predictedCells = tm.getPredictiveCells() tm.compute(activeColumns) activeInputBits = np.flatnonzero(sensoryInput) displayText = { "timestamp": timestampStr, "consumption": consumptionStr } sanityInstance.appendTimestep(activeInputBits, activeColumns, predictedCells, displayText)
class Example(object): """A class to hold our code. TODO: Get rid of this class, it just makes it more difficult to read the code. """ def __init__(self, inputDimensions, columnDimensions): """ Parameters: ---------- _inputDimensions: The size of the input. (m,n) will give a size m x n _inputDimensions: 입력의 크기. (m, n) 이라면 m x n 이 된다. _columnDimensions: The size of the 2 dimensional array of columns _columnDimensions: 2차원 컬럼 배열의 크기 """ self.inputDimensions = inputDimensions self.columnDimensions = columnDimensions self.inputSize = np.array(inputDimensions).prod() self.columnNumber = np.array(columnDimensions).prod() self.inputArray = np.zeros(self.inputSize, dtype=uintType) self.activeArray = np.zeros(self.columnNumber, dtype=uintType) random.seed(1) self.sp = SP(self.inputDimensions, self.columnDimensions, potentialRadius = self.inputSize, numActiveColumnsPerInhArea = int(0.02*self.columnNumber), globalInhibition = True, seed = 1, synPermActiveInc = 0.01, synPermInactiveDec = 0.008) def createInput(self): """create a random input vector""" print "-" * 70 + "Creating a random input vector" + "-" * 70 #clear the inputArray to zero before creating a new input vector self.inputArray[0:] = 0 for i in range(self.inputSize): #randrange returns 0 or 1 #0이나 1로 랜덤하게 집어넣는다. self.inputArray[i] = random.randrange(2) def run(self): """Run the spatial pooler with the input vector input vector로 sparial pooler를 돌려보자""" print "-" * 80 + "Computing the SDR" + "-" * 80 #activeArray[column]=1 if column is active after spatial pooling #activeArray[column]=1 이면 spatial pooling 결과 활성화된 컬럼이다. self.sp.compute(self.inputArray, True, self.activeArray) print self.activeArray.nonzero() def addNoise(self, noiseLevel): """Flip the value of 10% of input bits (add noise) :param noiseLevel: The percentage of total input bits that should be flipped 10% 정도 input bits를 뒤집어서(flip) 노이즈를 추가하자 :param noiseLevel: 몇 퍼센트나 노이즈를 추가할 것인지? """ for _ in range(int(noiseLevel * self.inputSize)): # 0.1*self.inputSize represents 10% of the total input bits # random.random() returns a float between 0 and 1 # 0.1*self.inputSize 이면 전체 input bits의 10%다. # random.random() 은 0과 1사이의 실수를 반환하다. randomPosition = int(random.random() * self.inputSize) # Flipping the bit at the randomly picked position # 랜덤한 위치의 bit를 뒤집자... 1이면 0으로, 0이면 1로! if self.inputArray[randomPosition] == 1: self.inputArray[randomPosition] = 0 else: self.inputArray[randomPosition] = 1
def testComputeParametersValidation(self): sp = SpatialPooler(inputDimensions=[5], columnDimensions=[5]) inputGood = np.ones(5, dtype=uintDType) outGood = np.zeros(5, dtype=uintDType) inputBad = np.ones(5, dtype=realDType) inputBad2D = np.ones((5, 5), dtype=realDType) outBad = np.zeros(5, dtype=realDType) outBad2D = np.zeros((5, 5), dtype=realDType) # Validate good parameters sp.compute(inputGood, False, outGood) # Validate bad parameters with self.assertRaises(RuntimeError): sp.compute(inputBad, False, outBad) # Validate bad input with self.assertRaises(RuntimeError): sp.compute(inputBad, False, outGood) # Validate bad 2d input with self.assertRaises(RuntimeError): sp.compute(inputBad2D, False, outGood) # Validate bad output with self.assertRaises(RuntimeError): sp.compute(inputGood, False, outBad) # Validate bad 2d output with self.assertRaises(RuntimeError): sp.compute(inputGood, False, outBad2D)
class BaseNetwork(object): def __init__(self, inputMin=None, inputMax=None, runSanity=False): self.inputMin = inputMin self.inputMax = inputMax self.runSanity = runSanity self.encoder = None self.encoderOutput = None self.sp = None self.spOutput = None self.spOutputNZ = None self.tm = None self.anomalyScore = None if runSanity: self.sanity = None self.defaultEncoderResolution = 0.0001 self.numColumns = 2048 self.cellsPerColumn = 32 self.predictedActiveCells = None self.previouslyPredictiveCells = None def initialize(self): # Scalar Encoder resolution = self.getEncoderResolution() self.encoder = RandomDistributedScalarEncoder(resolution, seed=42) self.encoderOutput = np.zeros(self.encoder.getWidth(), dtype=np.uint32) # Spatial Pooler spInputWidth = self.encoder.getWidth() self.spParams = { "globalInhibition": True, "columnDimensions": [self.numColumns], "inputDimensions": [spInputWidth], "potentialRadius": spInputWidth, "numActiveColumnsPerInhArea": 40, "seed": 1956, "potentialPct": 0.8, "boostStrength": 5.0, "synPermActiveInc": 0.003, "synPermConnected": 0.2, "synPermInactiveDec": 0.0005, } self.sp = SpatialPooler(**self.spParams) self.spOutput = np.zeros(self.numColumns, dtype=np.uint32) # Temporal Memory self.tmParams = { "activationThreshold": 20, "cellsPerColumn": self.cellsPerColumn, "columnDimensions": (self.numColumns,), "initialPermanence": 0.24, "maxSegmentsPerCell": 128, "maxSynapsesPerSegment": 128, "minThreshold": 13, "maxNewSynapseCount": 31, "permanenceDecrement": 0.008, "permanenceIncrement": 0.04, "seed": 1960, } self.tm = TemporalMemory(**self.tmParams) # Sanity if self.runSanity: self.sanity = sanity.SPTMInstance(self.sp, self.tm) def handleRecord(self, scalarValue, label=None, skipEncoding=False, learningMode=True): """Process one record.""" if self.runSanity: self.sanity.waitForUserContinue() # Encode the input data record if it hasn't already been encoded. if not skipEncoding: self.encodeValue(scalarValue) # Run the encoded data through the spatial pooler self.sp.compute(self.encoderOutput, learningMode, self.spOutput) self.spOutputNZ = self.spOutput.nonzero()[0] # WARNING: this needs to happen here, before the TM runs. self.previouslyPredictiveCells = self.tm.getPredictiveCells() # Run SP output through temporal memory self.tm.compute(self.spOutputNZ) self.predictedActiveCells = _computePredictedActiveCells( self.tm.getActiveCells(), self.previouslyPredictiveCells) # Anomaly score self.anomalyScore = _computeAnomalyScore(self.spOutputNZ, self.previouslyPredictiveCells, self.cellsPerColumn) # Run Sanity if self.runSanity: self.sanity.appendTimestep(self.getEncoderOutputNZ(), self.getSpOutputNZ(), self.previouslyPredictiveCells, { 'value': scalarValue, 'label':label }) def encodeValue(self, scalarValue): self.encoder.encodeIntoArray(scalarValue, self.encoderOutput) def getEncoderResolution(self): """ Compute the Random Distributed Scalar Encoder (RDSE) resolution. It's calculated from the data min and max, specific to the data stream. """ if self.inputMin is None or self.inputMax is None: return self.defaultEncoderResolution else: rangePadding = abs(self.inputMax - self.inputMin) * 0.2 minVal = self.inputMin - rangePadding maxVal = (self.inputMax + rangePadding if self.inputMin != self.inputMax else self.inputMin + 1) numBuckets = 130.0 return max(self.defaultEncoderResolution, (maxVal - minVal) / numBuckets) def getEncoderOutputNZ(self): return self.encoderOutput.nonzero()[0] def getSpOutputNZ(self): return self.spOutputNZ def getTmPredictiveCellsNZ(self): return self.tm.getPredictiveCells() def getTmActiveCellsNZ(self): return self.tm.getActiveCells() def getTmPredictedActiveCellsNZ(self): return self.predictedActiveCells def getRawAnomalyScore(self): return self.anomalyScore
class SpatialPoolerAgent(Agent): """ agent that uses CAM (content-addresable memory; uses SpatialPooler to make abstractions and generalizations of inputs to learn actions. Can be trained in both supervised and unsupervised ways. Uses utility encoder with feedback = 1, to remember 1 step -> start={stateA, actionA} , score(start)==score after applying actionA""" def __init__(self, numFields): a=dict() t=[] # target super(SpatialPoolerAgent, self).__init__(a, t, listMemFields=["score", "visited"], name='SPlearner') self.me['x']=0 self.me['y']=0 self.me['steps']=0 self.enc = UtilEncoder(length=numFields, minval=0, maxval=100, scoreMin=0, scoreMax=100, scoreResolution=0.1) self.enc.setEvaluationFn(evalFn) # spatial pooler self.sp = SP( inputDimensions = [self.enc._offset], columnDimensions = [1024], potentialRadius = 15, potentialPct = 0.5, globalInhibition = True, localAreaDensity = -1.0, numActiveColumnsPerInhArea = 5, stimulusThreshold=0, synPermInactiveDec=0.01, synPermActiveInc = 0.1, synPermConnected = 0.20, minPctOverlapDutyCycle = 0.1, minPctActiveDutyCycle = 0.1, dutyCyclePeriod = 10, maxBoost = 10.0, seed = -1, spVerbosity = 2,) self.cls = Clas() # classifier def testSP(self): dataSize = 5 totalPatterns = 5 patterns=[] for i in xrange(0,totalPatterns): patterns.append(numpy.random.randint(0,2,dataSize).tolist()) # generate input patterns # SP learn patterns for _ in xrange(0,10): #learn-repeate for pattern in patterns: ret = numpy.zeros(1024) print "input=", pattern enc = self.enc.encode(pattern) print "encoded=",enc self.sp.compute(enc,True, ret) nz = numpy.nonzero(ret)[0].tolist() print len(nz) score = self.enc.getScoreIN(pattern) buckets = self.enc.getBucketIndices({'simpleUtility' : pattern,'utility' : score}) print self.enc.getScalarNames(), buckets print self.cls.compute(recordNum=1, patternNZ=nz, classification={'bucketIdx': buckets[0], 'actValue': score }, learn=True, infer=True) print "Test" for pattern in patterns: ret = numpy.zeros(1024) enc = self.enc.encode(pattern) self.sp.compute(enc,False, ret) nz = numpy.nonzero(ret)[0].tolist() score = self.enc.getScoreIN(pattern) buckets = self.enc.getBucketIndices({'simpleUtility' : pattern,'utility' : score}) print self.cls.compute(recordNum=1, patternNZ=nz, classification={'bucketIdx': buckets[0], 'actValue': None }, learn=False, infer=True)