def _allocateSpatialFDR(self, rfInput): """Allocate the spatial pooler instance.""" if self._sfdr: return # Retrieve the necessary extra arguments that were handled automatically autoArgs = dict((name, getattr(self, name)) for name in self._spatialArgNames) autoArgs.pop('coincidencesShape') autoArgs.pop('inputShape') autoArgs.pop('inputBorder') autoArgs.pop('coincInputRadius') autoArgs.pop('cloneMap') autoArgs.pop('numCloneMasters') coincidencesShape = (self.columnCount, 1) inputShape = (1, self.inputWidth) inputBorder = inputShape[1]/2 if inputBorder*2 >= inputShape[1]: inputBorder -= 1 coincInputRadius = inputShape[1]/2 cloneMap, numCloneMasters = fdru.makeCloneMap( columnsShape=coincidencesShape, outputCloningWidth=coincidencesShape[1], outputCloningHeight=coincidencesShape[0] ) self._sfdr = FDRCSpatial2.FDRCSpatial2( # These parameters are standard defaults for SPRegion # They can be overridden by explicit calls to # getParameter cloneMap=cloneMap, numCloneMasters=numCloneMasters, coincidencesShape=coincidencesShape, inputShape=inputShape, inputBorder=inputBorder, coincInputRadius = coincInputRadius, **autoArgs) self._sfdr.setStoreDenseOutput(self.storeDenseOutput)
def testSPFile(): """ Run test on the data file - the file has records previously encoded. """ spSize = 2048 spSet = 40 poolPct = 0.5 pattern = [50, 1000] doLearn = True PLOT_PRECISION = 100.0 distribMatrix = np.zeros((PLOT_PRECISION + 1, PLOT_PRECISION + 1)) inputs = [] #file = open('~/Desktop/ExperimentResults/sampleArtificial.csv', 'rb') #elemSize = 400 #numSet = 42 #file = open('~/Desktop/ExperimentResults/sampleDataBasilOneField.csv', 'rb') #elemSize = 499 #numSet = 7 outdir = '~/Desktop/ExperimentResults/Basil100x21' inputFile = outdir + '.csv' file = open(inputFile, 'rb') elemSize = 100 numSet = 21 reader = csv.reader(file) for row in reader: input = np.array(map(float, row), dtype=realDType) if len(input.nonzero()[0]) != numSet: continue inputs.append(input.copy()) file.close() # Setup a SP sp = FDRCSpatial2.FDRCSpatial2(coincidencesShape=(spSize, 1), inputShape=(1, elemSize), inputBorder=(elemSize - 1) / 2, coincInputRadius=elemSize / 2, numActivePerInhArea=spSet, spVerbosity=0, stimulusThreshold=0, synPermConnected=0.10, seed=1, coincInputPoolPct=poolPct, globalInhibition=True) cleanPlot = False doLearn = False print 'Finished reading file, inputs/outputs to process =', len(inputs) size = len(inputs) for iter in xrange(100): print 'Iteration', iter # Learn if iter != 0: for learnRecs in xrange(pattern[0]): ind = np.random.random_integers(0, size - 1, 1)[0] sp.compute(inputs[ind], learn=True, infer=False) # Test for _ in xrange(pattern[1]): rand1 = np.random.random_integers(0, size - 1, 1)[0] rand2 = np.random.random_integers(0, size - 1, 1)[0] output1 = sp.compute(inputs[rand1], learn=False, infer=True).copy() output2 = sp.compute(inputs[rand2], learn=False, infer=True).copy() outDist = (abs(output1 - output2) > 0.1) intOutDist = int(outDist.sum() / 2 + 0.1) inDist = (abs(inputs[rand1] - inputs[rand2]) > 0.1) intInDist = int(inDist.sum() / 2 + 0.1) if intInDist != numSet or intOutDist != spSet: print rand1, rand2, '-', intInDist, intOutDist x = int(PLOT_PRECISION * intOutDist / spSet) y = int(PLOT_PRECISION * intInDist / numSet) if distribMatrix[x, y] < 0.1: distribMatrix[x, y] = 3 else: if distribMatrix[x, y] < 10: distribMatrix[x, y] += 1 if True: plt.imshow(distribMatrix, origin='lower', interpolation="nearest") plt.ylabel('SP (%d/%d) distance in pct' % (spSize, spSet)) plt.xlabel('Input (%d/%d) distance in pct' % (elemSize, numSet)) title = 'SP distribution' title += ', iter = %d' % iter title += ', Pct =%f' % poolPct plt.suptitle(title, fontsize=12) #plt.savefig(os.path.join('~/Desktop/ExperimentResults/videosArtData', '%s' % iter)) plt.savefig(os.path.join(outdir, '%s' % iter)) plt.clf() distribMatrix = np.zeros((PLOT_PRECISION + 1, PLOT_PRECISION + 1))
def testSPNew(): """ New version of the test""" elemSize = 400 numSet = 42 addNear = True numRecords = 1000 wantPlot = False poolPct = 0.5 itr = 5 pattern = [60, 1000] doLearn = True start = 1 learnIter = 0 noLearnIter = 0 numLearns = 0 numTests = 0 numIter = 1 numGroups = 1000 PLOT_PRECISION = 100.0 distribMatrix = np.zeros((PLOT_PRECISION + 1, PLOT_PRECISION + 1)) inputs = generateRandomInput(numGroups, elemSize, numSet) # Setup a SP sp = FDRCSpatial2.FDRCSpatial2(coincidencesShape=(2048, 1), inputShape=(1, elemSize), inputBorder=elemSize / 2 - 1, coincInputRadius=elemSize / 2, numActivePerInhArea=40, spVerbosity=0, stimulusThreshold=0, synPermConnected=0.12, seed=1, coincInputPoolPct=poolPct, globalInhibition=True) cleanPlot = False for i in xrange(numRecords): input1 = getRandomWithMods(inputs, 4) if i % 2 == 0: input2 = getRandomWithMods(inputs, 4) else: input2 = input1.copy() input2 = modifyBits(input2, 21) inDist = (abs(input1 - input2) > 0.1) intInDist = int(inDist.sum() / 2 + 0.1) #print intInDist if start == 0: doLearn = True learnIter += 1 if learnIter == pattern[start]: numLearns += 1 start = 1 noLearnIter = 0 elif start == 1: doLearn = False noLearnIter += 1 if noLearnIter == pattern[start]: numTests += 1 start = 0 learnIter = 0 cleanPlot = True output1 = sp.compute(input1, learn=doLearn, infer=False).copy() output2 = sp.compute(input2, learn=doLearn, infer=False).copy() time.sleep(0.001) outDist = (abs(output1 - output2) > 0.1) intOutDist = int(outDist.sum() / 2 + 0.1) if not doLearn and intOutDist < 2 and intInDist > 10: """ sp.spVerbosity = 10 sp.compute(input1, learn=doLearn, infer=False) sp.compute(input2, learn=doLearn, infer=False) sp.spVerbosity = 0 print 'Elements has very small SP distance: %d' % intOutDist print output1.nonzero() print output2.nonzero() print sp._firingBoostFactors[output1.nonzero()[0]] print sp._synPermBoostFactors[output1.nonzero()[0]] print 'Input elements distance is %d' % intInDist print input1.nonzero() print input2.nonzero() sys.stdin.readline() """ if not doLearn: x = int(PLOT_PRECISION * intOutDist / 40.0) y = int(PLOT_PRECISION * intInDist / 42.0) if distribMatrix[x, y] < 0.1: distribMatrix[x, y] = 3 else: if distribMatrix[x, y] < 10: distribMatrix[x, y] += 1 #print i # If we don't want a plot, just continue if wantPlot and cleanPlot: plt.imshow(distribMatrix, origin='lower', interpolation="nearest") plt.ylabel('SP (2048/40) distance in %') plt.xlabel('Input (400/42) distance in %') title = 'SP distribution' #if doLearn: # title += ', leaning ON' #else: # title += ', learning OFF' title += ', learn sets = %d' % numLearns title += ', test sets = %d' % numTests title += ', iter = %d' % numIter title += ', groups = %d' % numGroups title += ', Pct =%f' % poolPct plt.suptitle(title, fontsize=12) #plt.show() plt.savefig( os.path.join('~/Desktop/ExperimentResults/videosNew', '%s' % i)) plt.clf() distribMatrix = np.zeros((PLOT_PRECISION + 1, PLOT_PRECISION + 1)) cleanPlot = False
def testSP(): """ Run a SP test """ elemSize = 400 numSet = 42 addNear = True numRecords = 2 wantPlot = True poolPct = 0.5 itr = 1 doLearn = True while numRecords < 3: # Setup a SP sp = FDRCSpatial2.FDRCSpatial2(coincidencesShape=(2048, 1), inputShape=(1, elemSize), inputBorder=elemSize / 2 - 1, coincInputRadius=elemSize / 2, numActivePerInhArea=40, spVerbosity=0, stimulusThreshold=0, seed=1, coincInputPoolPct=poolPct, globalInhibition=True) # Generate inputs using rand() inputs = generateRandomInput(numRecords, elemSize, numSet) if addNear: # Append similar entries (distance of 1) appendInputWithNSimilarValues(inputs, 42) inputSize = len(inputs) print 'Num random records = %d, inputs to process %d' % (numRecords, inputSize) # Run a number of iterations, with learning on or off, # retrieve results from the last iteration only outputs = np.zeros((inputSize, 2048)) numIter = 1 if doLearn: numIter = itr for iter in xrange(numIter): for i in xrange(inputSize): time.sleep(0.001) if iter == numIter - 1: outputs[i] = sp.compute(inputs[i], learn=doLearn, infer=False) #print outputs[i].sum(), outputs[i] else: sp.compute(inputs[i], learn=doLearn, infer=False) # Build a plot from the generated input and output and display it distribMatrix = generatePlot(outputs, inputs) # If we don't want a plot, just continue if wantPlot: plt.imshow(distribMatrix, origin='lower', interpolation="nearest") plt.ylabel('SP (2048/40) distance in %') plt.xlabel('Input (400/42) distance in %') title = 'SP distribution' if doLearn: title += ', leaning ON' else: title += ', learning OFF' title += ', inputs = %d' % len(inputs) title += ', iterations = %d' % numIter title += ', poolPct =%f' % poolPct plt.suptitle(title, fontsize=12) plt.show() #plt.savefig(os.path.join('~/Desktop/ExperimentResults/videos5', '%s' % numRecords)) #plt.clf() numRecords += 1 return
def testInhibition(self): """ Test if the firing number of coincidences after inhibition equals spatial poolernumActivePerInhArea. """ # Miscellaneous variables: # n, w: n, w of encoders # inputLen: Length of binary input # synPermConnected: Spatial pooler synPermConnected # synPermActiveInc: Spatial pooler synPermActiveInc # connectPct: Initial connect percentage of permanences # coincidencesShape: Number of spatial pooler coincidences # numActivePerInhArea: Spatial pooler numActivePerInhArea # stimulusThreshold: Spatial pooler stimulusThreshold # spSeed: Spatial pooler for initial permanences # stimulusThresholdInh: Parameter for inhibition, default value 0.00001 # kDutyCycleFactor: kDutyCycleFactor for dutyCycleTieBreaker in # Inhibition # spVerbosity: Verbosity to print other sp initial parameters # testIter: Testing iterations n = 100 w = 15 inputLen = 300 coincidencesShape = 2048 numActivePerInhArea = 40 stimulusThreshold = 0 spSeed = 1956 stimulusThresholdInh = 0.00001 kDutyCycleFactor = 0.01 spVerbosity = 0 testIter = 100 spTest = FDRCSpatial2.FDRCSpatial2( coincidencesShape=(coincidencesShape, 1), inputShape=(1, inputLen), inputBorder=inputLen / 2 - 1, coincInputRadius=inputLen / 2, numActivePerInhArea=numActivePerInhArea, spVerbosity=spVerbosity, stimulusThreshold=stimulusThreshold, seed=spSeed) initialPermanence = spTest._initialPermanence() spTest._masterPotentialM, spTest._masterPermanenceM = ( spTest._makeMasterCoincidences(spTest.numCloneMasters, spTest._coincRFShape, spTest.coincInputPoolPct, initialPermanence, spTest.random)) spTest._updateInhibitionObj() boostFactors = numpy.ones(coincidencesShape) for i in range(testIter): spTest._iterNum = i # random binary input input_ = numpy.zeros((1, inputLen)) nonzero = numpy.random.random(inputLen) input_[0][numpy.where(nonzero < float(w) / float(n))] = 1 # overlap step spTest._computeOverlapsFP( input_, stimulusThreshold=spTest.stimulusThreshold) spTest._overlaps *= boostFactors onCellIndices = numpy.where(spTest._overlaps > 0) spTest._onCells.fill(0) spTest._onCells[onCellIndices] = 1 denseOn = spTest._onCells # update _dutyCycleBeforeInh spTest.dutyCyclePeriod = min(i + 1, 1000) spTest._dutyCycleBeforeInh = ( (spTest.dutyCyclePeriod - 1) * spTest._dutyCycleBeforeInh + denseOn) / spTest.dutyCyclePeriod dutyCycleTieBreaker = spTest._dutyCycleAfterInh.copy() dutyCycleTieBreaker *= kDutyCycleFactor # inhibition step numOn = spTest._inhibitionObj.compute( spTest._overlaps + dutyCycleTieBreaker, spTest._onCellIndices, stimulusThresholdInh, # stimulusThresholdInh max(spTest._overlaps) / 1000, # addToWinners ) # update _dutyCycleAfterInh spTest._onCells.fill(0) onCellIndices = spTest._onCellIndices[0:numOn] spTest._onCells[onCellIndices] = 1 denseOn = spTest._onCells spTest._dutyCycleAfterInh = ( ((spTest.dutyCyclePeriod - 1) * spTest._dutyCycleAfterInh + denseOn) / spTest.dutyCyclePeriod) # learning step spTest._adaptSynapses(onCellIndices, [], input_) # update boostFactor spTest._updateBoostFactors() boostFactors = spTest._firingBoostFactors # update dutyCycle and boost if ((spTest._iterNum + 1) % 50) == 0: spTest._updateInhibitionObj() spTest._updateMinDutyCycles(spTest._dutyCycleBeforeInh, spTest.minPctDutyCycleBeforeInh, spTest._minDutyCycleBeforeInh) spTest._updateMinDutyCycles(spTest._dutyCycleAfterInh, spTest.minPctDutyCycleAfterInh, spTest._minDutyCycleAfterInh) # test numOn and spTest.numActivePerInhArea self.assertEqual( numOn, spTest.numActivePerInhArea, "Error at input %s, actual numOn are: %i, " "numActivePerInhAre is: %s" % (i, numOn, numActivePerInhArea))
def frequency(self, n=15, w=7, coincidencesShape=2048, numActivePerInhArea=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 = FDRCSpatial2.FDRCSpatial2( coincidencesShape=(coincidencesShape, 1), inputShape=(1, n), inputBorder=(n - 2) / 2, coincInputRadius=n / 2, numActivePerInhArea=numActivePerInhArea, spVerbosity=spVerbosity, stimulusThreshold=stimulusThreshold, coincInputPoolPct=0.5, seed=spSeed, spReconstructionParam='dutycycle', ) 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): spInput = colors[i] onCells = spImpl.compute(spInput, learn=True, infer=False) 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, 30, "\nComputed factor: %d\nExpected Less than %d" % (factor, 30)) 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))
def _runLearnInference(self, n=30, w=15, coincidencesShape=2048, numActivePerInhArea=40, spSeed=1951, spVerbosity=0, numTrainingRecords=100, seed=42): # Instantiate two identical spatial pooler. One will be used only for # learning. The other will be trained with identical records, but with # random inference calls thrown in spLearnOnly = FDRCSpatial2.FDRCSpatial2( coincidencesShape=(coincidencesShape, 1), inputShape=(1, n), inputBorder=n / 2 - 1, coincInputRadius=n / 2, numActivePerInhArea=numActivePerInhArea, spVerbosity=spVerbosity, seed=spSeed, synPermInactiveDec=0.01, synPermActiveInc=0.2, ) spLearnInfer = FDRCSpatial2.FDRCSpatial2( coincidencesShape=(coincidencesShape, 1), inputShape=(1, n), inputBorder=n / 2 - 1, coincInputRadius=n / 2, numActivePerInhArea=numActivePerInhArea, spVerbosity=spVerbosity, seed=spSeed, synPermInactiveDec=0.01, synPermActiveInc=0.2, ) random.seed(seed) np.random.seed(seed) # Build up training set with numTrainingRecords patterns inputs = [] # holds post-encoded input patterns for i in xrange(numTrainingRecords): inputVector = np.zeros(n, dtype=realDType) inputVector[random.sample(xrange(n), w)] = 1 inputs.append(inputVector) # Train each SP with identical inputs startTime = time.time() random.seed(seed) np.random.seed(seed) for i in xrange(numTrainingRecords): if spVerbosity > 0: print "Input #%d" % i encodedInput = inputs[i] spLearnOnly.compute(encodedInput, learn=True, infer=False) random.seed(seed) np.random.seed(seed) for i in xrange(numTrainingRecords): if spVerbosity > 0: print "Input #%d" % i encodedInput = inputs[i] spLearnInfer.compute(encodedInput, learn=True, infer=False) print "\nElapsed time: %.2f seconds\n" % (time.time() - startTime) # Test that both SP"s are identical by checking learning stats # A more in depth test would check all the coincidences, duty cycles, etc. # ala tpDiff # Edit: spDiff has been written as an in depth tester of the spatial pooler learnOnlyStats = spLearnOnly.getLearningStats() learnInferStats = spLearnInfer.getLearningStats() success = True # Check that the two spatial poolers are equivalent after the same training. success = success and spDiff(spLearnInfer, spLearnOnly) self.assertTrue(success) # Make sure that the pickled and loaded SPs are equivalent. spPickle = pickle.dumps(spLearnOnly, protocol=0) spLearnOnlyLoaded = pickle.loads(spPickle) success = success and spDiff(spLearnOnly, spLearnOnlyLoaded) self.assertTrue(success) for k in learnOnlyStats.keys(): if learnOnlyStats[k] != learnInferStats[k]: success = False print "Stat", k, "is different:", learnOnlyStats[ k], learnInferStats[k] self.assertTrue(success) if success: print "Test succeeded"