Beispiel #1
0
class Brain(object):
    def __init__(self):
        self.tm = MonitoredSensorimotorTemporalMemory(**TM_PARAMS)
        self.sp = SpatialPooler(**SP_PARAMS)

    def consume_motion(self, sensor_input, motor_input, human_readable_sensor_value):
        # Rather than connecting the sensor input directly to columns, spatial pool over the input.
        # One example where this becomes necessary: when you combine different granularities of vision.
        # When a shape moves out of low-granularity vision to high-granularity vision, it needs to expect a vague mix
        # of white and black pixels, without being surprised by any particular pixel.
        sp_output = numpy.zeros((COLUMN_COUNT,), dtype="int")
        self.sp.compute(inputVector=sensor_input,
                        learn=True,
                        activeArray=sp_output)
        active_sensor_columns = set(numpy.where(sp_output > 0)[0])

        motor_pattern_no_collisions = set(map(lambda x: x + COLUMN_COUNT, motor_input))
        sensorimotor_pattern = active_sensor_columns.union(motor_pattern_no_collisions)

        self.tm.compute(active_sensor_columns,
                        activeExternalCells=sensorimotor_pattern,
                        formInternalConnections=False,
                        learn=True,
                        sequenceLabel=str(human_readable_sensor_value))
        print self.tm.mmPrettyPrintMetrics(self.tm.mmGetDefaultMetrics())

        return {"sp_output": list(get_indices_of_1(sp_output))}


        def get_predictions_for_action(self, message):
            raise Exception("Not implemented")
Beispiel #2
0
    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)))
Beispiel #3
0
class Example():
    """
    """
    def __init__(self, inputShape, columnDimensions):
        self.inputShape       = inputShape
        self.columnDimensions = columnDimensions
        self.inputSize        = np.array(inputShape).prod()
        self.columnNumber     = np.array(columnDimensions).prod()
        self.inputArray       = np.zeros(self.inputSize)
        self.activeArray      = np.zeros(self.columnNumber)

        self.sp = SP(self.inputShape,
                self.columnDimensions,
                potentialRadius = self.inputSize,
                numActiveColumnsPerInhArea = int(0.02*self.columnNumber),
                globalInhibition = True,
                synPermActiveInc = 0.01
                )

    def run(self):
        self.sp.compute(self.inputArray, True, self.activeArray)
Beispiel #4
0
def runSaveTest():
  inputSize = 600
  outputSize = 2048

  sp = SP(
    inputDimensions=(inputSize,),
    columnDimensions=(outputSize,),
    potentialRadius=16,
    potentialPct=0.85,
    globalInhibition=True,
    localAreaDensity=-1.0,
    numActiveColumnsPerInhArea=40.0,
    stimulusThreshold=1,
    synPermInactiveDec=0.008,
    synPermActiveInc=0.05,
    synPermConnected=0.10,
    minPctOverlapDutyCycle=0.001,
    minPctActiveDutyCycle=0.001,
    dutyCyclePeriod=1000,
    maxBoost=2.0,
    seed=-1,
    spVerbosity=0,
    wrapAround=True
  )
  # Totally nukes any SP History data that exists in Redis.
  spHistory.nuke()
  # Create a facade around the SP that saves history as it runs.
  sp = spHistory.create(sp)
  # If the SP Facade is "active" that means it has a life spatial pooler. If it
  # is not active, it cannot compute, only playback the history.
  assert sp.isActive()
  for _ in range(0, 10):
    encoding = np.zeros(shape=(inputSize,))
    for j, _ in enumerate(encoding):
      if random() < 0.1:
        encoding[j] = 1
    # For each compute cycle, save the SP state to Redis for playback later.
    sp.compute(encoding, learn=True, save=True)
  # This SP's history can be retrieved with an id.
  return sp.getId()
def run():
  sp = SpatialPooler(
    inputDimensions=[10, 15],
    columnDimensions=[5, 10],
    potentialRadius=2,
    potentialPct=0.5,
    synPermInactiveDec=0.1,
    synPermActiveInc=0.1,
    synPermConnected=0.1,
    localAreaDensity=0.1,
    numActiveColumnsPerInhArea=-1,
    globalInhibition=True
  )
  inputArray = numpy.zeros(sp.getNumInputs())
  activeArray = numpy.zeros(sp.getNumColumns())

  Patcher().patchSP(sp)

  for i in range(100):
    generateInput(inputArray)
    sp.compute(inputArray, True, activeArray)
    print "Ran iteration:\t{0}".format(i)
  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)))
Beispiel #7
0
               color=cmap(float(epoch) / epochs))

    activeColumnsPreviousEpoch = copy.copy(activeColumnsCurrentEpoch)
    connectedCountsPreviousEpoch = copy.copy(connectedCounts)

    # train SP here,
    # Learn is turned off at the first epoch to gather stats of untrained SP
    learn = False if epoch == 0 else True

    # randomize the presentation order of input vectors
    sdrOrders = np.random.permutation(np.arange(numInputVector))
    for i in range(numInputVector):
      outputColumns = np.zeros(sp.getColumnDimensions(), dtype=uintType)
      inputVector = copy.deepcopy(inputVectors[sdrOrders[i]][:])
      # addNoiseToVector(inputVector, 0.05, inputVectorType)
      sp.compute(inputVector, learn, outputColumns)

      activeColumnsCurrentEpoch[sdrOrders[i]][:] = np.reshape(outputColumns,
                                                              (1, columnNumber))

    sp.getConnectedCounts(connectedCounts)

    entropyTrace.append(calculateEntropy(activeColumnsCurrentEpoch))

    if epoch >= 1:
      activeColumnsDiff = activeColumnsCurrentEpoch > activeColumnsPreviousEpoch
      numBitDiffTrace.append(np.mean(np.sum(activeColumnsDiff, 1)))

      numConnectedSynapsesTrace.append(np.sum(connectedCounts))

      numNewSynapses = connectedCounts - connectedCountsPreviousEpoch
Beispiel #8
0
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 = SpatialPooler(
         columnDimensions=(spSize, 1),
         inputDimensions=(1, elemSize),
         potentialRadius=elemSize/2,
         numActiveColumnsPerInhArea=spSet,
         spVerbosity=0,
         stimulusThreshold=0,
         synPermConnected=0.10,
         seed=1,
         potentialPct=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]):

        # TODO: See https://github.com/numenta/nupic/issues/2072
        ind = np.random.random_integers(0, size-1, 1)[0]
        sp.compute(inputs[ind], learn=True, activeArray=outputs[ind]) 

    # 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]
    
      sp.compute(inputs[rand1], learn=False, activeArray=output1)
      sp.compute(inputs[rand2], learn=False, activeArray=output2)
    
      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))
Beispiel #9
0
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 = SpatialPooler(
           columnDimensions=(2048, 1),
           inputDimensions=(1, elemSize),
           potentialRadius=elemSize/2,
           numActiveColumnsPerInhArea=40,
           spVerbosity=0,
           stimulusThreshold=0,
           seed=1,
           potentialPct=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:
          # TODO: See https://github.com/numenta/nupic/issues/2072
          sp.compute(inputs[i], learn=doLearn, activeArray=outputs[i])
          #print outputs[i].sum(), outputs[i]
        else:
          # TODO: See https://github.com/numenta/nupic/issues/2072
          output = np.zeros(2048)
          sp.compute(inputs[i], learn=doLearn, activeArray=output)
      
    # 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
Beispiel #10
0
  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, learn=True, activeArray=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))
Beispiel #11
0
  def _runLearnInference(self,
                         n=30,
                         w=15,
                         columnDimensions=2048,
                         numActiveColumnsPerInhArea=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 = SpatialPooler(
        columnDimensions=(columnDimensions, 1),
        inputDimensions=(1, n),
        potentialRadius=n/2,
        numActiveColumnsPerInhArea=numActiveColumnsPerInhArea,
        spVerbosity=spVerbosity,
        seed=spSeed,
        synPermInactiveDec=0.01,
        synPermActiveInc=0.2,
        synPermConnected=0.11,)

    spLearnInfer = SpatialPooler(
        columnDimensions=(columnDimensions, 1),
        inputDimensions=(1, n),
        potentialRadius=n/2,
        numActiveColumnsPerInhArea=numActiveColumnsPerInhArea,
        spVerbosity=spVerbosity,
        seed=spSeed,
        synPermInactiveDec=0.01,
        synPermActiveInc=0.2,
        synPermConnected=0.11,)

    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
      # TODO: See https://github.com/numenta/nupic/issues/2072
      encodedInput = inputs[i]
      decodedOutput = np.zeros(columnDimensions)
      spLearnOnly.compute(encodedInput, learn=True, activeArray=decodedOutput)

    random.seed(seed)
    np.random.seed(seed)
    for i in xrange(numTrainingRecords):
      if spVerbosity > 0:
        print "Input #%d" % i
      # TODO: See https://github.com/numenta/nupic/issues/2072
      encodedInput = inputs[i]
      decodedOutput = np.zeros(columnDimensions)
      spLearnInfer.compute(encodedInput, learn=True, activeArray=decodedOutput)

    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"
Beispiel #12
0
class HTMNetwork(object):
    """
    Attribute:
    shape: tuple -- set size of the encoder's output, for matrix_encoder,
            it has two int elements.
    """
    def __init__(
            self,
            shape=(32, 32),  # tuple -- two element
            inputDimensions=(1024, ),  # tuple two element or int
            columnDimensions=1024,  # int, tuple is not allowed
            globalInhibition=1,
            sp_seed=1960,
            potentialPct=0.8,
            synPermConnected=0.10,
            synPermActiveInc=0.05,
            synPermInactiveDec=0.0008,
            maxBoost=2.0,
            potentialRadius=16,
            numActiveColumnsPerInhArea=40.0,
            localAreaDensity=-1.0,
            stimulusThreshold=0,
            numberOfCols=1024,  # int
            cellsPerColumn=16,  # 32 is the official setting
            tp_seed=1960,
            newSynapseCount=20,
            maxSynapsesPerSegment=32,
            maxSegmentsPerCell=128,
            initialPerm=0.21,
            permanenceInc=0.1,
            permanenceDec=0.0,  # 0.1 is the official setting
            globalDecay=0,
            maxAge=0,
            minThreshold=12,
            activationThreshold=12,
            pamLength=1,
            connectedPerm=0.5,
            burnIn=2,
            visible=1):

        # size insurance
        if type(inputDimensions) == int:
            self._assert_fun(shape, (inputDimensions, ))
        else:
            self._assert_fun(shape, inputDimensions)
        self._assert_fun((columnDimensions, ), (numberOfCols, ))

        self.shape = shape

        # the params of the sp
        self.input_dimensions = inputDimensions
        self.column_dimensions = columnDimensions
        self.potential_radius = potentialRadius
        self.numActive_columns_perInhArea = numActiveColumnsPerInhArea
        self.global_inhibition = globalInhibition
        self.syn_perm_active_inc = synPermActiveInc
        self.potential_pct = potentialPct
        self.synPermInactiveDec = synPermInactiveDec
        self.synPermConnected = synPermConnected
        self.sp_seed = sp_seed
        self.localAreaDensity = localAreaDensity
        self.stimulusThreshold = stimulusThreshold
        self.maxBoost = maxBoost

        # the params of the tp
        self.number_of_cols = numberOfCols
        self.cells_per_column = cellsPerColumn
        self.initial_perm = initialPerm
        self.connected_perm = connectedPerm
        self.min_threshold = minThreshold
        self.new_synapse_count = newSynapseCount
        self.permanence_inc = permanenceInc
        self.permanence_dec = permanenceDec
        self.activation_threshold = activationThreshold
        self.global_decay = globalDecay
        self.burn_in = burnIn
        self.pam_length = pamLength
        self.maxAge = maxAge
        self.maxSynapsesPerSegment = maxSynapsesPerSegment
        self.maxSegmentsPerCell = maxSegmentsPerCell
        self.tp_seed = tp_seed

        self.visible = visible
        self.label = ""

        # network
        self.enc = None
        self.sp = None
        self.tp = None

        self._create_network()

    def set_label(self, label):
        """
        :param label: str -- the tag of the network
        """
        self.label = label

    def get_label(self):
        return self.label

    def _assert_fun(self, param1, param2):
        """
        :param param1, param2: tuple -- contain int type elements.
        make sure two params have a same size.
        """
        product_elements1 = 1
        product_elements2 = 1

        for e in param1:
            product_elements1 = product_elements1 * e
        for i in param2:
            product_elements2 = product_elements2 * i
        assert product_elements1 == product_elements2

    def _check_type(self):
        pass

    def view(self):
        pass

    def _create_network(self, mean=128):
        """
        :param mean: int, the mean of the frame pix value, will be used in BASE_ENCODE.
        """
        # some rulers of creating network
        # the product of the shape's two dimensions is equal to inputDimensions
        # columnDimensions equal to numberOfCols
        self.enc = MatrixEncoder(shape=self.shape, mean=mean)
        self.sp = SpatialPooler(
            inputDimensions=self.shape[0] * self.shape[1],
            columnDimensions=self.column_dimensions,
            potentialRadius=self.potential_radius,
            numActiveColumnsPerInhArea=self.numActive_columns_perInhArea,
            globalInhibition=self.global_inhibition,
            synPermActiveInc=self.syn_perm_active_inc,
            potentialPct=self.potential_pct,
            synPermInactiveDec=self.synPermInactiveDec,
            synPermConnected=self.synPermConnected,
            seed=self.sp_seed,
            localAreaDensity=self.localAreaDensity,
            stimulusThreshold=self.stimulusThreshold,
            maxBoost=self.maxBoost)
        self.tp = TP(numberOfCols=self.column_dimensions,
                     cellsPerColumn=self.cells_per_column,
                     initialPerm=self.initial_perm,
                     connectedPerm=self.connected_perm,
                     minThreshold=self.min_threshold,
                     newSynapseCount=self.new_synapse_count,
                     permanenceInc=self.permanence_inc,
                     permanenceDec=self.permanence_dec,
                     activationThreshold=self.activation_threshold,
                     globalDecay=self.global_decay,
                     burnIn=self.burn_in,
                     pamLength=self.pam_length,
                     maxSynapsesPerSegment=self.maxSynapsesPerSegment,
                     maxSegmentsPerCell=self.maxSegmentsPerCell,
                     seed=self.tp_seed,
                     maxAge=self.maxAge)

    def _compute(self, a_frame, output, sp_enable_learn, tp_enable_learn):
        """
        the essential proceeding of the network compute,
        the training and prediction is the iteration of it.
        :param a_frame: Array, a frame of the video.
        :param output: np.darray, be used to save the output of the sp.
        """
        matrix = self.enc.encodeIntoArray(a_frame,
                                          encoder_model=matrix_encoder.K_MEANS)

        # TODO(kawawa): show the output encoder and sp.
        # image = (np.int16(matrix)-1)*(-255)
        # cv2.imshow("kkk", np.uint8(image))
        # cv2.waitKey(10)
        self.sp.compute(inputVector=matrix,
                        learn=sp_enable_learn,
                        activeArray=output)
        # a = output
        self.tp.compute(bottomUpInput=output,
                        enableLearn=tp_enable_learn,
                        computeInfOutput=None)

    def train(self, frames_matrix, sp_enable_learn=True, tp_enable_learn=True):
        """
        tran the network by a series of frames
        :param frames_matrix: a array of the frames
        :param sp_enable_learn, tp_enable_learn: set the learning model
        """
        output = np.zeros(self.column_dimensions, dtype=int)

        for i in range(len(frames_matrix)):
            self._compute(frames_matrix[i], output, sp_enable_learn,
                          tp_enable_learn)

    def _formatRow(self, x):
        """make a print format"""
        s = ''
        for c in range(len(x)):
            if c > 0 and c % 10 == 0:
                s += ' '
            s += str(x[c])
        s += ' '
        return s

    def predict_detect(self,
                       frames_matrix,
                       sp_enable_learn=False,
                       tp_enable_learn=False):
        """
        get frames, predict the next frame, compare the predicted one with the next input.
        and give a corresponding mark of them.
        :param frames_matrix: a array of the frames
        :param sp_enable_learn, tp_enable_learn: set the learning model
        :return: float -- the corresponding rank of prediction frames and input frames
        """
        output = np.zeros(self.column_dimensions, dtype=int)
        score_list = []

        self._compute(frames_matrix[0], output, sp_enable_learn,
                      tp_enable_learn)
        pre_prediction = self.tp.getPredictedState()

        # view the prediction state
        if self.visible > 1:
            self.tp.printStates(printPrevious=False, printLearnState=False)
            self._formatRow(pre_prediction.max(axis=1).nonzero())

        for i in range(len(frames_matrix))[1:]:
            self._compute(frames_matrix[i], output, sp_enable_learn,
                          tp_enable_learn)
            score = self._give_a_mark(sp_output=output,
                                      tp_prediction=pre_prediction)
            score_list.append(score)
            pre_prediction = self.tp.getPredictedState()

            # view the prediction state
            if self.visible > 1:
                self.tp.printStates(printPrevious=False, printLearnState=False)
                self._formatRow(pre_prediction.max(axis=1).nonzero())

        return sum(score_list)

    def getPredictedState(self):
        return self.tp.getPredictedState

    def get_sp_active_cells_index(self, sp_cells_state):
        """
        :return index of active cells/columns in format:
        (array([0, 2, 4], dtype=int64),)
        """
        return sp_cells_state.nonzero()

    def get_tp_active_cells_index(self, tp_cells_state):
        """
        eg:
        the tp_cells _state = [[1, 0],
                               [0, 0],
                               [0, 1]
                               [0, 0]
                               [1, 0]] is a np.ndarray
        :return: index of active columns in format:
        (array([0, 2, 4], dtype=int64),)
        """
        return tp_cells_state.max(axis=1).nonzero()

    def get_tp_active_columns(self, sp_cells_state):
        """
        eg:
        the tp_cells _state = [[1, 0],
                               [0, 0],
                               [0, 1]
                               [0, 0]
                               [1, 0]] is a np.ndarray
        :return: active columns coder [1, 0, 1, 0, 1]
        """
        return sp_cells_state.max(axis=1)

    def _corresponding(self, sp_active_column, tp_active_column):
        """
        compute number of bits where two binary array have the same '1' value.
        sp_active_column and tp_active_column have size 1-d binary array.
        """
        sum = sp_active_column + tp_active_column
        corresponding_elements = sum / 2
        return corresponding_elements.sum()

    def _give_a_mark(self, sp_output, tp_prediction):
        """
        for two frames: next input and the prediction at this time.
        (num of same 1 value bit) /  (num of 1 value bit in sp_output)
        :return: a int between 0-1, 1 means have good prediction
        """
        tp_active_columns = self.get_tp_active_columns(tp_prediction)
        corresponding_num = self._corresponding(sp_output, tp_active_columns)

        return float(corresponding_num) / float(sum(sp_output))
Beispiel #13
0
# -------
# A column connects to a subset of the input vector (specified
# by both the potentialRadius and potentialPct). The overlap score
# for a column is the number of connections to the input that become
# active when presented with a vector. When learning is 'on' in the SP,
# the active connections are reinforced, whereas those inactive are
# depressed (according to parameters synPermActiveInc and synPermInactiveDec.
# In order for the SP to create a sparse representation of the input, it
# will select a small percentage (usually 2%) of its most active columns,
# ie. columns with the largest overlap score.
# In this first part, we will create a histogram showing the overlap scores
# of the Spatial Pooler (SP) after feeding it with a random binary
# input. As well, the histogram will show the scores of those columns
# that are chosen to build the sparse representation of the input.

sp.compute(inputArray, False, activeCols)
overlaps = sp.getOverlaps()
activeColsScores = []
for i in activeCols.nonzero():
  activeColsScores.append(overlaps[i])

print ""
print "---------------------------------"
print "Figure 1 shows an histogram of the overlap scores"
print "from all the columns in the spatial pooler, as well as the"
print "overlap scores of those columns that were selected to build a"
print "sparse representation of the input (shown in green)."
print "The SP chooses 2% of the columns with the largest overlap score"
print "to make such sparse representation."
print "---------------------------------"
print ""
Beispiel #14
0
# In[18]:

for column in xrange(4):
    connected = np.zeros((24,), dtype="int")
    sp.getConnectedSynapses(column, connected)
    print connected


# In[19]:

output = np.zeros((4,), dtype="int")
for _ in xrange(20):
    print 'iteration #' + str(_)
    for note in encoded_list:
        sp.compute(note, learn=True, activeArray=output)

print 'FINISHED SPATIAL POOLING'

# In[20]:

for column in xrange(4):
    connected = np.zeros((24,), dtype="int")
    sp.getConnectedSynapses(column, connected)
    print connected


print 'STARTING TEMPORAL POOLING'

# In[21]:
Beispiel #15
0
    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, learn=True, activeArray=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))
Beispiel #16
0
class SpatialPoolerEncoder(Encoder):
  """
  w=inputDimensions
  """

  def __init__(self,
               w,
               minval=0,
               maxval=0,
               periodic=False,
               n=0,
               radius=DEFAULT_RADIUS,
               resolution=DEFAULT_RESOLUTION,
               name=None,
               verbosity=0,
               clipInput=False,
               forced=False):
    """
    w -- number of bits to set in output
    """

    assert isinstance(w, numbers.Integral)
    self.encoders = None
    self.verbosity = verbosity
    self.w = w
    #if (w % 2 == 0):
    #  raise Exception("Width must be an odd number (%f)" % w)

    self.n=n
    self._initEncoder(w, n)

    self.type_skip=True

    # Our name
    if name is not None:
      self.name = name
    else:
      self.name = "[%s:%s]" % (self.minval, self.maxval)
    if self.verbosity >= 2:
      print "SP encoder initialized",self.name


  def _initEncoder(self, w,n):
    self._SpatialPooler=SpatialPooler( [w],[n] , 403,0.8,1,-1.0,40.0,0)


  def getDescription(self):
    return [(self.name, 0)]
  def getWidth(self):
    return self.n
  def getDecoderOutputFieldTypes(self):
    """ [Encoder class virtual method override]
    """
    #return (FieldMetaType.float, )
    return (FieldMetaType.string, )

  def getScalars(self, inpt):
    return None

  def encodeIntoArray(self, input, output, learn=True):
    """ See method description in base.py """

    __IsValid=False
    if input is not None:
      input=eval(input)

      if type(input)==list or type_skip:
        __IsValid=True
      if __IsValid==False:

        if input == None:
          return None

        if self.verbosity >= 2:
            print "Example:"
            print 'input="[0,0,0,1,0]"'
        raise TypeError(
            "Expected a string input but got input of type %s" % type(input))
    else:
      return None

    if type(input)==list:
      inputVector = numpy.array( input )

      output[:self.n] = 0
      self._SpatialPooler.compute(inputVector=inputVector, learn=1, activeArray=output[:self.n] )
    else:
      #input as numpy array
      output[:self.n] = 0
      self._SpatialPooler.compute(inputVector=input, learn=1, activeArray=output[:self.n] )


    if self.verbosity >= 2:
      print
      print "input:", input
      print "n:", self.n, "w:", self.w
      print "output:",
      self.pprint(output)
      print "input desc:", self.decodedToStr(self.decode(output))


  def dump(self):
    ToImplement()
    print "ScalarEncoder:"
    print "  min: %f" % self.minval
    print "  max: %f" % self.maxval
    print "  w:   %d" % self.w
    print "  n:   %d" % self.n
    print "  resolution: %f" % self.resolution
    print "  radius:     %f" % self.radius
    print "  periodic: %s" % self.periodic
    print "  nInternal: %d" % self.nInternal
    print "  rangeInternal: %f" % self.rangeInternal
    print "  padding: %d" % self.padding


  @classmethod
  def read(cls, proto):
    ToImplement()
    if proto.n is not None:
      radius = DEFAULT_RADIUS
      resolution = DEFAULT_RESOLUTION
    else:
      radius = proto.radius
      resolution = proto.resolution

    return cls(w=proto.w,
               minval=proto.minval,
               maxval=proto.maxval,
               periodic=proto.periodic,
               n=proto.n,
               name=proto.name,
               verbosity=proto.verbosity,
               clipInput=proto.clipInput,
               forced=True)

  def write(self, proto):
    ToImplement()
    proto.w = self.w
    proto.minval = self.minval
    proto.maxval = self.maxval
    proto.periodic = self.periodic
    # Radius and resolution can be recalculated based on n
    proto.n = self.n
    proto.name = self.name
    proto.verbosity = self.verbosity
    proto.clipInput = self.clipInput
Beispiel #17
0
class SpatialPoolerEncoder(Encoder):
    """
  w=inputDimensions
  """
    def __init__(self,
                 w,
                 minval=0,
                 maxval=0,
                 periodic=False,
                 n=0,
                 radius=DEFAULT_RADIUS,
                 resolution=DEFAULT_RESOLUTION,
                 name=None,
                 verbosity=0,
                 clipInput=False,
                 forced=False):
        """
    w -- number of bits to set in output
    """

        assert isinstance(w, numbers.Integral)
        self.encoders = None
        self.verbosity = verbosity
        self.w = w
        #if (w % 2 == 0):
        #  raise Exception("Width must be an odd number (%f)" % w)

        self.n = n
        self._initEncoder(w, n)

        self.type_skip = True

        # Our name
        if name is not None:
            self.name = name
        else:
            self.name = "[%s:%s]" % (self.minval, self.maxval)
        if self.verbosity >= 2:
            print "SP encoder initialized", self.name

    def _initEncoder(self, w, n):
        self._SpatialPooler = SpatialPooler([w], [n], 403, 0.8, 1, -1.0, 40.0,
                                            0)

    def getDescription(self):
        return [(self.name, 0)]

    def getWidth(self):
        return self.n

    def getDecoderOutputFieldTypes(self):
        """ [Encoder class virtual method override]
    """
        #return (FieldMetaType.float, )
        return (FieldMetaType.string, )

    def getScalars(self, inpt):
        return None

    def encodeIntoArray(self, input, output, learn=True):
        """ See method description in base.py """

        __IsValid = False
        if input is not None:
            input = eval(input)

            if type(input) == list or type_skip:
                __IsValid = True
            if __IsValid == False:

                if input == None:
                    return None

                if self.verbosity >= 2:
                    print "Example:"
                    print 'input="[0,0,0,1,0]"'
                raise TypeError(
                    "Expected a string input but got input of type %s" %
                    type(input))
        else:
            return None

        if type(input) == list:
            inputVector = numpy.array(input)

            output[:self.n] = 0
            self._SpatialPooler.compute(inputVector=inputVector,
                                        learn=1,
                                        activeArray=output[:self.n])
        else:
            #input as numpy array
            output[:self.n] = 0
            self._SpatialPooler.compute(inputVector=input,
                                        learn=1,
                                        activeArray=output[:self.n])

        if self.verbosity >= 2:
            print
            print "input:", input
            print "n:", self.n, "w:", self.w
            print "output:",
            self.pprint(output)
            print "input desc:", self.decodedToStr(self.decode(output))

    def dump(self):
        ToImplement()
        print "ScalarEncoder:"
        print "  min: %f" % self.minval
        print "  max: %f" % self.maxval
        print "  w:   %d" % self.w
        print "  n:   %d" % self.n
        print "  resolution: %f" % self.resolution
        print "  radius:     %f" % self.radius
        print "  periodic: %s" % self.periodic
        print "  nInternal: %d" % self.nInternal
        print "  rangeInternal: %f" % self.rangeInternal
        print "  padding: %d" % self.padding

    @classmethod
    def read(cls, proto):
        ToImplement()
        if proto.n is not None:
            radius = DEFAULT_RADIUS
            resolution = DEFAULT_RESOLUTION
        else:
            radius = proto.radius
            resolution = proto.resolution

        return cls(w=proto.w,
                   minval=proto.minval,
                   maxval=proto.maxval,
                   periodic=proto.periodic,
                   n=proto.n,
                   name=proto.name,
                   verbosity=proto.verbosity,
                   clipInput=proto.clipInput,
                   forced=True)

    def write(self, proto):
        ToImplement()
        proto.w = self.w
        proto.minval = self.minval
        proto.maxval = self.maxval
        proto.periodic = self.periodic
        # Radius and resolution can be recalculated based on n
        proto.n = self.n
        proto.name = self.name
        proto.verbosity = self.verbosity
        proto.clipInput = self.clipInput
Beispiel #18
0
    #                retVal['actualValues'][numpy.argmax(retVal[1])]
    #            ))

    #        tm.reset()
    #        recordNum = 0

    for dataList in trainingData2:

        print("----------dataList = {}----------".format(dataList[0]))
        for data in dataList[0]:
            spIn.fill(0)
            spIn[:sp.getInputDimensions()[1]] = numpy.resize(
                encoder1.encode(data),
                sp.getInputDimensions()[1])

            sp.compute(spIn, True, spOut)

            tmIn = set(numpy.where(spOut > 0)[0])
            tm.compute(tmIn, True)

            retVal = cla.compute(
                recordNum,
                tm.activeCells,
                {
                    'bucketIdx': encoder1.getBucketIndices(data)[0],
                    'actValue': data
                },
                True,
                True,
                lambda x: x.endswith('x') or x.endswith('y') or x.endswith('z')\
                    or x.endswith('a')
Beispiel #19
0
class AudioStream:

  def __init__(self):
    """
    Instantiate temporal pooler, encoder, audio sampler, filter, & freq plot
    """
    self.vis = Visualizations()
    
    """
    The number of columns in the input and therefore the TP
     2**9 = 512
     Trial and error pulled that out
     numCols should be tested during benchmarking
    """
    self.numCols = 2**8
    sparsity = 0.10
    self.numInput = int(self.numCols * sparsity)

    """
    Create a bit map encoder
    
    From the encoder's __init__ method:
     1st arg: the total bits in input
     2nd arg: the number of bits used to encode each input bit
    """
    self.e = BitmapArrayEncoder(self.numCols, 1)

    """
    Sampling details
     rate: The sampling rate in Hz of my soundcard
     buffersize: The size of the array to which we will save audio segments (2^12 = 4096 is very good)
     secToRecord: The length of each sampling
     buffersToRecord: how many multiples of buffers are we recording?
    """
    rate=44100
    secToRecord=.1
    self.buffersize=2**12
    self.buffersToRecord=int(rate*secToRecord/self.buffersize)
    if not self.buffersToRecord: 
      self.buffersToRecord=1

    """
    Filters in Hertz
     highHertz: lower limit of the bandpass filter, in Hertz
     lowHertz: upper limit of the bandpass filter, in Hertz
       max lowHertz = (buffersize / 2 - 1) * rate / buffersize
    """
    highHertz = 500
    lowHertz = 10000

    """
    Convert filters from Hertz to bins
     highpass: convert the highHertz into a bin for the FFT
     lowpass: convert the lowHertz into a bin for the FFt
     NOTES:
      highpass is at least the 1st bin since most mics only pick up >=20Hz
      lowpass is no higher than buffersize/2 - 1 (highest array index)
      passband needs to be wider than size of numInput - not checking for that
    """
    self.highpass = max(int(highHertz * self.buffersize / rate),1)
    self.lowpass = min(int(lowHertz * self.buffersize / rate), self.buffersize/2 - 1)

    """
    The call to create the temporal pooler region
    """
    self.sp = SP(inputDimensions=[self.numCols],columnDimensions=[self.numCols],
		   potentialRadius=4,potentialPct=0.5,
		   globalInhibition=True,localAreaDensity=-1.0,
		   numActiveColumnsPerInhArea=10.0,stimulusThreshold=0,
		   synPermInactiveDec=0.01,synPermActiveInc=0.1,
		   synPermConnected=0.10,minPctOverlapDutyCycle=0.001,
		   minPctActiveDutyCycle=0.001,dutyCyclePeriod=500,
		   maxBoost=10.0,seed=-1,spVerbosity=0)
  
    self.tp = TP(numberOfCols=self.numCols, cellsPerColumn=4,
      initialPerm=0.5, connectedPerm=0.5,
      minThreshold=10, newSynapseCount=10,
      permanenceInc=0.1, permanenceDec=0.07,
      activationThreshold=8,
      globalDecay=0.02, burnIn=2,
      checkSynapseConsistency=False,
      pamLength=100)    
    
    """
    Creating the audio stream from our mic
    """
    p = pyaudio.PyAudio()
    self.inStream = p.open(format=pyaudio.paInt32,channels=1,rate=rate,input=True,frames_per_buffer=self.buffersize)

    """
    Setting up the array that will handle the timeseries of audio data from our input
    """
    self.audio = numpy.empty((self.buffersToRecord*self.buffersize),dtype="uint32")

    """
    Print out the inputs
    """
    print "Number of columns:\t" + str(self.numCols)
    print "Max size of input:\t" + str(self.numInput)
    print "Sampling rate (Hz):\t" + str(rate)
    print "Passband filter (Hz):\t" + str(highHertz) + " - " + str(lowHertz)
    print "Passband filter (bin):\t" + str(self.highpass) + " - " + str(self.lowpass)
    print "Bin difference:\t\t" + str(self.lowpass - self.highpass)
    print "Buffersize:\t\t" + str(self.buffersize)

    """
    Setup the plot
     Use the bandpass filter frequency range as the x-axis
     Rescale the y-axis
    """
    plt.ion()
    bin = range(self.highpass,self.lowpass)
    xs = numpy.arange(len(bin))*rate/self.buffersize + highHertz
    self.freqPlot = plt.plot(xs,xs)[0]
    plt.ylim(0, 10**12)
    
    while True:
      self.processAudio()
  
  
  def processAudio (self): 
    """
    Sample audio, encode, send it to the TP
    
    Pulls the audio from the mic
    Conditions that audio as an SDR
    Computes a prediction via the TP
    Update the visualizations
    """
    
    """
    Cycle through the multiples of the buffers we're sampling
    Sample audio to store for each frame in buffersize
     Mic voltage-level timeseries is saved as 32-bit binary
    Convert that 32-bit binary into integers, and save to array for the FFT
    """
    for i in range(self.buffersToRecord):
      audioString = self.inStream.read(self.buffersize)
      self.audio[i*self.buffersize:(i + 1)*self.buffersize] = numpy.fromstring(audioString,dtype = "uint32")
    
    """
    Get int array of strength for each bin of frequencies via fast fourier transform
    Get the indices of the strongest frequencies (the top 'numInput')
    Scale the indices so that the frequencies fit to within numCols
    Pick out the unique indices (we've reduced the mapping, so we likely have multiples)
    Encode those indices into an SDR via the BitmapArrayEncoder
    Cast the SDR as a float for the TP
    """
    ys = self.fft(self.audio, self.highpass, self.lowpass)
    fs = numpy.sort(ys.argsort()[-self.numInput:])
    rfs = fs.astype(numpy.float32) / (self.lowpass - self.highpass) * self.numCols
    ufs = numpy.unique(rfs)
    actualInt = self.e.encode(ufs)
    actual = actualInt.astype(numpy.float32)
    
    """
    Pass the SDR to the TP
    Collect the prediction SDR from the TP
    Pass the prediction & actual SDRS to the anomaly calculator & array comparer
    Update the frequency plot
    """
    pooled = numpy.zeros(self.numCols)
    self.sp.compute(actual, learn = True, activeArray = pooled)
    self.tp.compute(pooled, enableLearn = True, computeInfOutput = True)
    predictedInt = self.tp.getPredictedState().max(axis=1)
    compare = self.vis.compareArray(actualInt, predictedInt)
    anomaly = self.vis.calcAnomaly(actualInt, predictedInt)
    print "." . join(compare)
    print self.vis.hashtagAnomaly(anomaly)
    self.freqPlot.set_ydata(ys)
    plt.show(block = False)
    plt.draw()
  
  
  def fft(self, audio, highpass, lowpass):
    """
    Fast fourier transform conditioning

    Output:
    'output' contains the strength of each frequency in the audio signal
    frequencies are marked by its position in 'output':
    frequency = index * rate / buffesize
    output.size = buffersize/2 
    Method:
    Use numpy's FFT (numpy.fft.fft)
    Find the magnitude of the complex numbers returned (abs value)
    Split the FFT array in half, because we have mirror frequencies
     (they're the complex conjugates)
    Use just the first half to apply the bandpass filter

    Great info here: http://stackoverflow.com/questions/4364823/how-to-get-frequency-from-fft-result
    """
    left,right = numpy.split(numpy.abs(numpy.fft.fft(audio)),2)
    output = left[highpass:lowpass]
    return output 
    def _runLearnInference(self,
                           n=30,
                           w=15,
                           columnDimensions=2048,
                           numActiveColumnsPerInhArea=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 = SpatialPooler(
            columnDimensions=(columnDimensions, 1),
            inputDimensions=(1, n),
            potentialRadius=n / 2,
            numActiveColumnsPerInhArea=numActiveColumnsPerInhArea,
            spVerbosity=spVerbosity,
            seed=spSeed,
            synPermInactiveDec=0.01,
            synPermActiveInc=0.2,
            synPermConnected=0.11,
        )

        spLearnInfer = SpatialPooler(
            columnDimensions=(columnDimensions, 1),
            inputDimensions=(1, n),
            potentialRadius=n / 2,
            numActiveColumnsPerInhArea=numActiveColumnsPerInhArea,
            spVerbosity=spVerbosity,
            seed=spSeed,
            synPermInactiveDec=0.01,
            synPermActiveInc=0.2,
            synPermConnected=0.11,
        )

        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
            # TODO: See https://github.com/numenta/nupic/issues/2072
            encodedInput = inputs[i]
            decodedOutput = np.zeros(columnDimensions)
            spLearnOnly.compute(encodedInput,
                                learn=True,
                                activeArray=decodedOutput)

        random.seed(seed)
        np.random.seed(seed)
        for i in xrange(numTrainingRecords):
            if spVerbosity > 0:
                print "Input #%d" % i
            # TODO: See https://github.com/numenta/nupic/issues/2072
            encodedInput = inputs[i]
            decodedOutput = np.zeros(columnDimensions)
            spLearnInfer.compute(encodedInput,
                                 learn=True,
                                 activeArray=decodedOutput)

        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"
Beispiel #21
0
class Region(Node):
  """
  A class only to group properties related to regions.
  """

  #region Constructor

  def __init__(self, name):
    """
    Initializes a new instance of this class.
    """

    Node.__init__(self, name, NodeType.region)

    #region Instance fields

    self.columns = []
    """List of columns that compose this region"""

    self._inputMap = []
    """An array representing the input map for this region."""

    #region Spatial Parameters

    self.enableSpatialLearning = True
    """Switch for spatial learning"""

    self.potentialRadius = 0
    """This parameter determines the extent of the input that each column can potentially be connected to. This can be thought of as the input bits that are visible to each column, or a 'receptiveField' of the field of vision. A large enough value will result in 'global coverage', meaning that each column can potentially be connected to every input bit. This parameter defines a square (or hyper square) area: a column will have a max square potential pool with sides of length 2 * potentialRadius + 1."""

    self.potentialPct = 0.5
    """The percent of the inputs, within a column's potential radius, that a column can be connected to. If set to 1, the column will be connected to every input within its potential radius. This parameter is used to give each column a unique potential pool when a large potentialRadius causes overlap between the columns. At initialization time we choose ((2*potentialRadius + 1)^(# inputDimensions) * potentialPct) input bits to comprise the column's potential pool."""

    self.globalInhibition = False
    """If true, then during inhibition phase the winning columns are selected as the most active columns from the region as a whole. Otherwise, the winning columns are selected with respect to their local neighborhoods. Using global inhibition boosts performance x60."""

    self.localAreaDensity = -1.0
    """The desired density of active columns within a local inhibition area (the size of which is set by the internally calculated inhibitionRadius, which is in turn determined from the average size of the connected potential pools of all columns). The inhibition logic will insure that at most N columns remain ON within a local inhibition area, where N = localAreaDensity * (total number of columns in inhibition area)."""

    self.numActiveColumnsPerInhArea = int(0.02 * (self.width * self.height))
    """An alternate way to control the density of the active columns. If numActiveColumnsPerInhArea is specified then localAreaDensity must be less than 0, and vice versa. When using numActiveColumnsPerInhArea, the inhibition logic will insure that at most 'numActiveColumnsPerInhArea' columns remain ON within a local inhibition area (the size of which is set by the internally calculated inhibitionRadius, which is in turn determined from the average size of the connected receptive fields of all columns). When using this method, as columns learn and grow their effective receptive fields, the inhibitionRadius will grow, and hence the net density of the active columns will *decrease*. This is in contrast to the localAreaDensity method, which keeps the density of active columns the same regardless of the size of their receptive fields."""

    self.stimulusThreshold = 0
    """This is a number specifying the minimum number of synapses that must be on in order for a columns to turn ON. The purpose of this is to prevent noise input from activating columns. Specified as a percent of a fully grown synapse."""

    self.proximalSynConnectedPerm = 0.10
    """The default connected threshold. Any synapse whose permanence value is above the connected threshold is a "connected synapse", meaning it can contribute to the cell's firing."""

    self.proximalSynPermIncrement = 0.1
    """The amount by which an active synapse is incremented in each round. Specified as a percent of a fully grown synapse."""

    self.proximalSynPermDecrement = 0.01
    """The amount by which an inactive synapse is decremented in each round. Specified as a percent of a fully grown synapse."""

    self.minPctOverlapDutyCycle = 0.001
    """A number between 0 and 1.0, used to set a floor on how often a column should have at least stimulusThreshold active inputs. Periodically, each column looks at the overlap duty cycle of all other columns within its inhibition radius and sets its own internal minimal acceptable duty cycle to:
      minPctDutyCycleBeforeInh * max(other columns' duty cycles).
    On each iteration, any column whose overlap duty cycle falls below this computed value will get all of its permanence values boosted up by synPermActiveInc. Raising all permanences in response to a sub-par duty cycle before inhibition allows a cell to search for new inputs when either its previously learned inputs are no longer ever active, or when the vast majority of them have been "hijacked" by other columns."""

    self.minPctActiveDutyCycle = 0.001
    """A number between 0 and 1.0, used to set a floor on how often a column should be activate. Periodically, each column looks at the activity duty cycle of all other columns within its inhibition radius and sets its own internal minimal acceptable duty cycle to:
      minPctDutyCycleAfterInh * max(other columns' duty cycles).
    On each iteration, any column whose duty cycle after inhibition falls below this computed value will get its internal boost factor increased."""

    self.dutyCyclePeriod = 1000
    """The period used to calculate duty cycles. Higher values make it take longer to respond to changes in boost or synPerConnectedCell. Shorter values make it more unstable and likely to oscillate."""

    self.maxBoost = 10.0
    """The maximum overlap boost factor. Each column's overlap gets multiplied by a boost factor before it gets considered for inhibition. The actual boost factor for a column is number between 1.0 and maxBoost. A boost factor of 1.0 is used if the duty cycle is >= minOverlapDutyCycle, maxBoost is used if the duty cycle is 0, and any duty cycle in between is linearly extrapolated from these 2 endpoints."""

    self.spSeed = -1
    """Seed for generate random values"""

    #endregion

    #region Temporal Parameters

    self.enableTemporalLearning = True
    """Switch for temporal learning"""

    self.numCellsPerColumn = 10
    """Number of cells per column. More cells, more contextual information"""

    self.distalSynInitialPerm = 0.11
    """The initial permanence of an distal synapse."""

    self.distalSynConnectedPerm = 0.50
    """The default connected threshold. Any synapse whose permanence value is above the connected threshold is a "connected synapse", meaning it can contribute to the cell's firing."""

    self.distalSynPermIncrement = 0.10
    """The amount by which an active synapse is incremented in each round. Specified as a percent of a fully grown synapse."""

    self.distalSynPermDecrement = 0.10
    """The amount by which an inactive synapse is decremented in each round. Specified as a percent of a fully grown synapse."""

    self.minThreshold = 8
    """If the number of synapses active on a segment is at least this threshold, it is selected as the best matching cell in a bursing column."""

    self.activationThreshold = 12
    """If the number of active connected synapses on a segment is at least this threshold, the segment is said to be active."""

    self.maxNumNewSynapses = 15
    """The maximum number of synapses added to a segment during learning."""

    self.tpSeed = 42
    """Seed for generate random values"""

    #endregion

    self.spatialPooler = None
    """Spatial Pooler instance"""

    self.temporalPooler = None
    """Temporal Pooler instance"""

    #endregion

    #region Statistics properties

    self.statsPrecisionRate = 0.

    #endregion

  #endregion

  #region Methods

  def getColumn(self, x, y):
    """
    Return the column located at given position
    """

    column = self.columns[(y * self.width) + x]

    return column

  def getInputSize(self):
    """
    Return the sum of sizes of all feeder nodes.
    """

    sumSizes = 0
    for feeder in Global.project.network.getFeederNodes(self):
      sumSizes += feeder.width * feeder.height

    return sumSizes

  def initialize(self):
    """
    Initialize this node.
    """

    # Check if this region has nodes that feed it
    numFeeders = len(Global.project.network.getFeederNodes(self))
    if numFeeders == 0:
      QtGui.QMessageBox.warning(None, "Warning", "Region '" + self.name + "' does not have any child!")
      return

    # Initialize this node and the nodes that feed it
    Node.initialize(self)

    # Create the input map
    # An input map is a set of input elements (cells or sensor bits) that should are grouped
    # For example, if we have 2 nodes that feed this region (#1 and #2) with dimensions 6 and 12 respectively,
    # a input map would be something like:
    #   111111222222222222
    self._inputMap = []
    elemIdx = 0
    for feeder in Global.project.network.getFeederNodes(self):

      # Arrange input from feeder into input map of this region
      if feeder.type == NodeType.region:
        for column in feeder.columns:
          inputElem = column.cells[0]
          self._inputMap.append(inputElem)
      else:
        for bit in feeder.bits:
          inputElem = bit
          self._inputMap.append(inputElem)
      elemIdx += 1

    # Initialize elements
    self.columns = []
    colIdx = 0
    for x in range(self.width):
      for y in range(self.height):
        column = Column()
        column.x = x
        column.y = y
        for z in range(self.numCellsPerColumn):
          cell = Cell()
          cell.index = (colIdx * self.numCellsPerColumn) + z
          cell.z = z
          column.cells.append(cell)
        self.columns.append(column)
        colIdx += 1

    # Create Spatial Pooler instance with appropriate parameters
    self.spatialPooler = SpatialPooler(
      inputDimensions = (self.getInputSize(), 1),
      columnDimensions = (self.width, self.height),
      potentialRadius = self.potentialRadius,
      potentialPct = self.potentialPct,
      globalInhibition = self.globalInhibition,
      localAreaDensity = self.localAreaDensity,
      numActiveColumnsPerInhArea = self.numActiveColumnsPerInhArea,
      stimulusThreshold = self.stimulusThreshold,
      synPermInactiveDec = self.proximalSynPermDecrement,
      synPermActiveInc = self.proximalSynPermIncrement,
      synPermConnected = self.proximalSynConnectedPerm,
      minPctOverlapDutyCycle = self.minPctOverlapDutyCycle,
      minPctActiveDutyCycle = self.minPctActiveDutyCycle,
      dutyCyclePeriod = self.dutyCyclePeriod,
      maxBoost = self.maxBoost,
      seed = self.spSeed,
      spVerbosity = False)

    # Create Temporal Pooler instance with appropriate parameters
    self.temporalPooler = TemporalPooler(
      columnDimensions = (self.width, self.height),
      cellsPerColumn = self.numCellsPerColumn,
      initialPermanence = self.distalSynInitialPerm,
      connectedPermanence = self.distalSynConnectedPerm,
      minThreshold = self.minThreshold,
      maxNewSynapseCount = self.maxNumNewSynapses,
      permanenceIncrement = self.distalSynPermIncrement,
      permanenceDecrement = self.distalSynPermDecrement,
      activationThreshold = self.activationThreshold,
      seed = self.tpSeed)

    return True

  def nextStep(self):
    """
    Perfoms actions related to time step progression.
    """

    Node.nextStep(self)
    for column in self.columns:
      column.nextStep()

    # Get input from sensors or lower regions and put into a single input map.
    input = self.getInput()

    # Send input to Spatial Pooler and get processed output (i.e. the active columns)
    # First initialize the vector for representing the current record
    columnDimensions = (self.width, self.height)
    columnNumber = numpy.array(columnDimensions).prod()
    activeColumns = numpy.zeros(columnNumber)
    self.spatialPooler.compute(input, self.enableSpatialLearning, activeColumns)

    # Send active columns to Temporal Pooler and get processed output (i.e. the predicting cells)
    # First convert active columns from float array to integer set
    activeColumnsSet = set()
    for colIdx in range(len(activeColumns)):
      if activeColumns[colIdx] == 1:
        activeColumnsSet.add(colIdx)
    self.temporalPooler.compute(activeColumnsSet, self.enableTemporalLearning)

    # Update elements regarding spatial pooler
    self.updateSpatialElements(activeColumns)

    # Update elements regarding temporal pooler
    self.updateTemporalElements()

    # Get the predicted values
    self.getPredictions()

    #TODO: self._output = self.temporalPooler.getPredictedState()

  def getPredictions(self):
    """
    Get the predicted values after an iteration.
    """

    for feeder in Global.project.network.getFeederNodes(self):
      feeder.getPredictions()

  def calculateStatistics(self):
    """
    Calculate statistics after an iteration.
    """

    # The region's prediction precision is the average between the nodes that feed it
    precisionRate = 0.
    numFeeders = 0
    for feeder in Global.project.network.getFeederNodes(self):
      precisionRate += feeder.statsPrecisionRate
      numFeeders += 1
    self.statsPrecisionRate = precisionRate / numFeeders

    for column in self.columns:
      column.calculateStatistics()

  def getInput(self):
    """
    Get input from sensors or lower regions and put into a single input map.
    """

    # Initialize the vector for representing the current input map
    inputList = []
    for inputElem in self._inputMap:
      if inputElem.isActive.atCurrStep():
        inputList.append(1)
      else:
        inputList.append(0)
    input = numpy.array(inputList)

    return input

  def updateSpatialElements(self, activeColumns):
    """
    Update elements regarding spatial pooler
    """

    # Update proximal segments and synapses according to active columns
    for colIdx in range(len(self.columns)):
      column = self.columns[colIdx]

      # Update proximal segment
      segment = column.segment
      if activeColumns[colIdx] == 1:
        segment.isActive.setForCurrStep(True)
      else:
        segment.isActive.setForCurrStep(False)

      # Check if proximal segment is predicted by check if the column has any predicted cell
      for cell in column.cells:
        if cell.index in self.temporalPooler.predictiveCells:
          segment.isPredicted.setForCurrStep(True)

      # Update proximal synapses
      if segment.isActive.atCurrStep() or segment.isPredicted.atCurrStep():
        permanencesSynapses = []
        self.spatialPooler.getPermanence(colIdx, permanencesSynapses)
        connectedSynapses = []
        self.spatialPooler.getConnectedSynapses(colIdx, connectedSynapses)
        for synIdx in range(len(permanencesSynapses)):
          # Get the proximal synapse given its position in the input map
          # Create a new one if it doesn't exist
          synapse = segment.getSynapse(synIdx)

          # Update proximal synapse
          if permanencesSynapses[synIdx] > 0.:
            if synapse == None:
              # Create a new synapse to a input element
              # An input element is a column if feeder is a region
              # or then a bit if feeder is a sensor
              synapse = Synapse()
              synapse.inputElem = self._inputMap[synIdx]
              synapse.indexSP = synIdx
              segment.synapses.append(synapse)

            # Update state
            synapse.isRemoved.setForCurrStep(False)
            synapse.permanence.setForCurrStep(permanencesSynapses[synIdx])
            if connectedSynapses[synIdx] == 1:
              synapse.isConnected.setForCurrStep(True)
            else:
              synapse.isConnected.setForCurrStep(False)
          else:
            if synapse != None:
              synapse.isRemoved.setForCurrStep(True)

  def updateTemporalElements(self):
    """
    Update elements regarding temporal pooler
    """

    # Update cells, distal segments and synapses according to active columns
    for colIdx in range(len(self.columns)):
      column = self.columns[colIdx]

      # Mark proximal segment and its connected synapses as predicted
      if column.segment.isPredicted.atCurrStep():
        for synapse in column.segment.synapses:
          if synapse.isConnected.atCurrStep():
            synapse.isPredicted.setForCurrStep(True)
            synapse.inputElem.isPredicted.setForCurrStep(True)

      # Mark proximal segment and its connected synapses that were predicted but are not active now
      if column.segment.isPredicted.atPreviousStep():
        if not column.segment.isActive.atCurrStep():
          column.segment.isFalselyPredicted.setForCurrStep(True)
        for synapse in column.segment.synapses:
          if (synapse.isPredicted.atPreviousStep() and not synapse.isConnected.atCurrStep()) or (synapse.isConnected.atCurrStep() and synapse.inputElem.isFalselyPredicted.atCurrStep()):
            synapse.isFalselyPredicted.setForCurrStep(True)

      for cell in column.cells:
        cellIdx = cell.index

        # Update cell's states
        if cellIdx in self.temporalPooler.winnerCells:
          cell.isLearning.setForCurrStep(True)
        if cellIdx in self.temporalPooler.activeCells:
          cell.isActive.setForCurrStep(True)
        if cellIdx in self.temporalPooler.predictiveCells:
          cell.isPredicted.setForCurrStep(True)
        if cell.isPredicted.atPreviousStep() and not cell.isActive.atCurrStep():
          cell.isFalselyPredicted.setForCurrStep(True)

        # Get the indexes of the distal segments of this cell
        segmentsForCell = self.temporalPooler.connections.segmentsForCell(cellIdx)

        # Add the segments that appeared after last iteration
        for segIdx in segmentsForCell:
          # Check if segment already exists in the cell
          segFound = False
          for segment in cell.segments:
            if segment.indexTP == segIdx:
              segFound = True
              break

          # If segment is new, add it to cell
          if not segFound:
            segment = Segment(SegmentType.distal)
            segment.indexTP = segIdx
            cell.segments.append(segment)

        # Update distal segments
        for segment in cell.segments:
          segIdx = segment.indexTP

          # If segment not found in segments indexes returned in last iteration mark it as removed
          if segIdx in segmentsForCell:

            # Update segment's state
            if segIdx in self.temporalPooler.activeSegments:
              segment.isActive.setForCurrStep(True)
            else:
              segment.isActive.setForCurrStep(False)

            # Get the indexes of the synapses of this segment
            synapsesForSegment = self.temporalPooler.connections.synapsesForSegment(segIdx)

            # Add the synapses that appeared after last iteration
            for synIdx in synapsesForSegment:
              # Check if synapse already exists in the segment
              synFound = False
              for synapse in segment.synapses:
                if synapse.indexTP == synIdx:
                  synFound = True
                  break

              # If synapse is new, add it to segment
              if not synFound:
                synapse = Synapse()
                synapse.indexTP = synIdx
                segment.synapses.append(synapse)

            # Update synapses
            for synapse in segment.synapses:
              synIdx = synapse.indexTP

              # If synapse not found in synapses indexes returned in last iteration mark it as removed
              if synIdx in synapsesForSegment:

                # Update synapse's state
                (_, sourceCellAbsIdx, permanence) = self.temporalPooler.connections.dataForSynapse(synIdx)
                synapse.permanence.setForCurrStep(permanence)
                if permanence >= self.distalSynConnectedPerm:
                  synapse.isConnected.setForCurrStep(True)
                else:
                  synapse.isConnected.setForCurrStep(False)

                # Get cell given cell's index
                sourceColIdx = sourceCellAbsIdx / self.numCellsPerColumn
                sourceCellRelIdx = sourceCellAbsIdx % self.numCellsPerColumn
                sourceCell = self.columns[sourceColIdx].cells[sourceCellRelIdx]
                synapse.inputElem = sourceCell
              else:
                synapse.isRemoved.setForCurrStep(True)
          else:
            segment.isRemoved.setForCurrStep(True)
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 testGetMaxBoost(self):
    inParam = 78
    self.sp.setMaxBoost(inParam)
    outParam = self.sp.getMaxBoost()
    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 testGetMinPctActiveDutyCycles(self):
    inParam = 0.444333
    self.sp.setMinPctActiveDutyCycles(inParam)
    outParam = self.sp.getMinPctActiveDutyCycles()
    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 testGetMinActiveDutyCycles(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.setMinActiveDutyCycles(inParam)
    outParam = numpy.zeros(numInputs).astype(realType)
    self.sp.getMinActiveDutyCycles(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)
Beispiel #23
0
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 = SpatialPooler(
         columnDimensions=(spSize, 1),
         inputDimensions=(1, elemSize),
         potentialRadius=elemSize/2,
         numActiveColumnsPerInhArea=spSet,
         spVerbosity=0,
         stimulusThreshold=0,
         synPermConnected=0.10,
         seed=1,
         potentialPct=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]):

        # TODO: See https://github.com/numenta/nupic/issues/2072
        ind = np.random.random_integers(0, size-1, 1)[0]
        sp.compute(inputs[ind], learn=True, activeArray=outputs[ind]) 

    # 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]
    
      sp.compute(inputs[rand1], learn=False, activeArray=output1)
      sp.compute(inputs[rand2], learn=False, activeArray=output2)
    
      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))
Beispiel #24
0
                                     dtype="int")
    spatialPooler.getConnectedSynapses(column=col,
                                       connectedSynapses=currentlyConnected)
    print "   ", currentlyConnected
print "spatial pooler initialized\n"

spatialPoolerTest = False
if spatialPoolerTest:
    print "iterating some test data"
    for category in [
            "cat", "dog", "cat", "cat", "dog", "cat", "potato", "potato",
            "cat", "penguin"
    ]:
        iterationOutput = numpy.zeros(shape=8, dtype="int")
        spatialPooler.compute(inputCategories[category],
                              learn=True,
                              activeArray=iterationOutput)
        print(category + ":").ljust(10), iterationOutput
    print "end iterating some test data\n"

print "initializing temporal pooler"
temporalPooler = TP(
    numberOfCols=15,
    cellsPerColumn=4,
    initialPerm=0.5,
    connectedPerm=0.5,
    minThreshold=10,
    newSynapseCount=10,
    permanenceInc=0.1,
    permanenceDec=0.0,
    activationThreshold=3,
Beispiel #25
0
class Example():
  
  """A class to hold our code. Going object oriented"""

  
  def __init__(self, inputShape, columnDimensions):
    """
     Parameters:
     ----------
     _inputShape	:	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.inputShape = inputShape
    self.columnDimensions = columnDimensions
    self.inputSize = np.array(inputShape).prod()
    self.columnNumber = np.array(columnDimensions).prod()
    self.inputArray = np.zeros(self.inputSize)
    self.activeArray = np.zeros(self.columnNumber)

    self.sp = SP(self.inputShape, 
		 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)
      
      PARAMETERS
      ----------
      noiseLevel : The percentage of total input bits that should be flipped """
    
    for i 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
for i in range(10000):
    t.append(enc.encode(i))

print("Encoding is done")

sp = SpatialPooler(inputDimensions=(10000,),
                   columnDimensions=(20,),
                   potentialRadius=15,
                   numActiveColumnsPerInhArea=1,
                   globalInhibition=True,
                   synPermActiveInc=0.03,
                   potentialPct=1.0)
output = numpy.zeros((20,),dtype="int")
for _ in range(10):
    for i in xrange(10000):
        sp.compute(t[i], learn=True, activeArray=output)

print("Spatial pooler strengthened")

from nupic.research.TP import TP

tp = TP(numberOfCols=10000, cellsPerColumn=20,
        initialPerm=0.5, connectedPerm=0.5,
        minThreshold=10, newSynapseCount=10,
        permanenceInc=0.1, permanenceDec=0.0,
        activationThreshold=8,
        globalDecay=0, burnIn=1,
        checkSynapseConsistency=False,
        pamLength=10)

pub = rospy.Publisher("prediction_stream", Float64, queue_size=10)	
Beispiel #27
0
# -------
# A column connects to a subset of the input vector (specified
# by both the potentialRadius and potentialPct). The overlap score
# for a column is the number of connections to the input that become
# active when presented with a vector. When learning is 'on' in the SP,
# the active connections are reinforced, whereas those inactive are
# depressed (according to parameters synPermActiveInc and synPermInactiveDec.
# In order for the SP to create a sparse representation of the input, it
# will select a small percentage (usually 2%) of its most active columns,
# ie. columns with the largest overlap score.
# In this first part, we will create a histogram showing the overlap scores
# of the Spatial Pooler (SP) after feeding it with a random binary
# input. As well, the histogram will show the scores of those columns
# that are chosen to build the sparse representation of the input.

sp.compute(inputArray, False, activeCols)
overlaps = sp.getOverlaps()
activeColsScores = []
for i in activeCols.nonzero():
  activeColsScores.append(overlaps[i])

print ""
print "---------------------------------"
print "Figure 1 shows an histogram of the overlap scores"
print "from all the columns in the spatial pooler, as well as the"
print "overlap scores of those columns that were selected to build a"
print "sparse representation of the input (shown in green)."
print "The SP chooses 2% of the columns with the largest overlap score"
print "to make such sparse representation."
print "---------------------------------"
print ""
Beispiel #28
0
class Region(Node):
  """
  A class only to group properties related to regions.
  """

  #region Constructor

  def __init__(self, name):
    """
    Initializes a new instance of this class.
    """

    Node.__init__(self, name, NodeType.region)

    #region Instance fields

    self.columns = []
    """List of columns that compose this region"""

    self._inputMap = []
    """An array representing the input map for this region."""

    #region Spatial Parameters

    self.enableSpatialLearning = True
    """Switch for spatial learning"""

    self.potentialRadius = 0
    """This parameter determines the extent of the input that each column can potentially be connected to. This can be thought of as the input bits that are visible to each column, or a 'receptiveField' of the field of vision. A large enough value will result in 'global coverage', meaning that each column can potentially be connected to every input bit. This parameter defines a square (or hyper square) area: a column will have a max square potential pool with sides of length 2 * potentialRadius + 1."""

    self.potentialPct = 0.5
    """The percent of the inputs, within a column's potential radius, that a column can be connected to. If set to 1, the column will be connected to every input within its potential radius. This parameter is used to give each column a unique potential pool when a large potentialRadius causes overlap between the columns. At initialization time we choose ((2*potentialRadius + 1)^(# inputDimensions) * potentialPct) input bits to comprise the column's potential pool."""

    self.globalInhibition = False
    """If true, then during inhibition phase the winning columns are selected as the most active columns from the region as a whole. Otherwise, the winning columns are selected with respect to their local neighborhoods. Using global inhibition boosts performance x60."""

    self.localAreaDensity = -1.0
    """The desired density of active columns within a local inhibition area (the size of which is set by the internally calculated inhibitionRadius, which is in turn determined from the average size of the connected potential pools of all columns). The inhibition logic will insure that at most N columns remain ON within a local inhibition area, where N = localAreaDensity * (total number of columns in inhibition area)."""

    self.numActiveColumnsPerInhArea = int(0.02 * (self.width * self.height))
    """An alternate way to control the density of the active columns. If numActiveColumnsPerInhArea is specified then localAreaDensity must be less than 0, and vice versa. When using numActiveColumnsPerInhArea, the inhibition logic will insure that at most 'numActiveColumnsPerInhArea' columns remain ON within a local inhibition area (the size of which is set by the internally calculated inhibitionRadius, which is in turn determined from the average size of the connected receptive fields of all columns). When using this method, as columns learn and grow their effective receptive fields, the inhibitionRadius will grow, and hence the net density of the active columns will *decrease*. This is in contrast to the localAreaDensity method, which keeps the density of active columns the same regardless of the size of their receptive fields."""

    self.stimulusThreshold = 0
    """This is a number specifying the minimum number of synapses that must be on in order for a columns to turn ON. The purpose of this is to prevent noise input from activating columns. Specified as a percent of a fully grown synapse."""

    self.proximalSynConnectedPerm = 0.10
    """The default connected threshold. Any synapse whose permanence value is above the connected threshold is a "connected synapse", meaning it can contribute to the cell's firing."""

    self.proximalSynPermIncrement = 0.1
    """The amount by which an active synapse is incremented in each round. Specified as a percent of a fully grown synapse."""

    self.proximalSynPermDecrement = 0.01
    """The amount by which an inactive synapse is decremented in each round. Specified as a percent of a fully grown synapse."""

    self.minPctOverlapDutyCycle = 0.001
    """A number between 0 and 1.0, used to set a floor on how often a column should have at least stimulusThreshold active inputs. Periodically, each column looks at the overlap duty cycle of all other columns within its inhibition radius and sets its own internal minimal acceptable duty cycle to:
      minPctDutyCycleBeforeInh * max(other columns' duty cycles).
    On each iteration, any column whose overlap duty cycle falls below this computed value will get all of its permanence values boosted up by synPermActiveInc. Raising all permanences in response to a sub-par duty cycle before inhibition allows a cell to search for new inputs when either its previously learned inputs are no longer ever active, or when the vast majority of them have been "hijacked" by other columns."""

    self.minPctActiveDutyCycle = 0.001
    """A number between 0 and 1.0, used to set a floor on how often a column should be activate. Periodically, each column looks at the activity duty cycle of all other columns within its inhibition radius and sets its own internal minimal acceptable duty cycle to:
      minPctDutyCycleAfterInh * max(other columns' duty cycles).
    On each iteration, any column whose duty cycle after inhibition falls below this computed value will get its internal boost factor increased."""

    self.dutyCyclePeriod = 1000
    """The period used to calculate duty cycles. Higher values make it take longer to respond to changes in boost or synPerConnectedCell. Shorter values make it more unstable and likely to oscillate."""

    self.maxBoost = 10.0
    """The maximum overlap boost factor. Each column's overlap gets multiplied by a boost factor before it gets considered for inhibition. The actual boost factor for a column is number between 1.0 and maxBoost. A boost factor of 1.0 is used if the duty cycle is >= minOverlapDutyCycle, maxBoost is used if the duty cycle is 0, and any duty cycle in between is linearly extrapolated from these 2 endpoints."""

    self.spSeed = -1
    """Seed for generate random values"""

    #endregion

    #region Temporal Parameters

    self.enableTemporalLearning = True
    """Switch for temporal learning"""

    self.numCellsPerColumn = 10
    """Number of cells per column. More cells, more contextual information"""

    self.distalSynInitialPerm = 0.11
    """The initial permanence of an distal synapse."""

    self.distalSynConnectedPerm = 0.50
    """The default connected threshold. Any synapse whose permanence value is above the connected threshold is a "connected synapse", meaning it can contribute to the cell's firing."""

    self.distalSynPermIncrement = 0.10
    """The amount by which an active synapse is incremented in each round. Specified as a percent of a fully grown synapse."""

    self.distalSynPermDecrement = 0.10
    """The amount by which an inactive synapse is decremented in each round. Specified as a percent of a fully grown synapse."""

    self.minThreshold = 8
    """If the number of synapses active on a segment is at least this threshold, it is selected as the best matching cell in a bursing column."""

    self.activationThreshold = 12
    """If the number of active connected synapses on a segment is at least this threshold, the segment is said to be active."""

    self.maxNumNewSynapses = 15
    """The maximum number of synapses added to a segment during learning."""

    self.tpSeed = 42
    """Seed for generate random values"""

    #endregion

    self.spatialPooler = None
    """Spatial Pooler instance"""

    self.temporalPooler = None
    """Temporal Pooler instance"""

    #endregion

    #region Statistics properties

    self.statsPrecisionRate = 0.

    #endregion

  #endregion

  #region Methods

  def getColumn(self, x, y):
    """
    Return the column located at given position
    """

    column = self.columns[(y * self.width) + x]

    return column

  def getInputSize(self):
    """
    Return the sum of sizes of all feeder nodes.
    """

    sumSizes = 0
    for feeder in Global.project.network.getFeederNodes(self):
      sumSizes += feeder.width * feeder.height

    return sumSizes

  def initialize(self):
    """
    Initialize this node.
    """

    # Check if this region has nodes that feed it
    numFeeders = len(Global.project.network.getFeederNodes(self))
    if numFeeders == 0:
      QtGui.QMessageBox.warning(None, "Warning", "Region '" + self.name + "' does not have any child!")
      return

    # Initialize this node and the nodes that feed it
    Node.initialize(self)

    # Create the input map
    # An input map is a set of input elements (cells or sensor bits) that should are grouped
    # For example, if we have 2 nodes that feed this region (#1 and #2) with dimensions 6 and 12 respectively,
    # a input map would be something like:
    #   111111222222222222
    self._inputMap = []
    elemIdx = 0
    for feeder in Global.project.network.getFeederNodes(self):

      # Arrange input from feeder into input map of this region
      if feeder.type == NodeType.region:
        for column in feeder.columns:
          inputElem = column.cells[0]
          self._inputMap.append(inputElem)
      else:
        for bit in feeder.bits:
          inputElem = bit
          self._inputMap.append(inputElem)
      elemIdx += 1

    # Initialize elements
    self.columns = []
    colIdx = 0
    for x in range(self.width):
      for y in range(self.height):
        column = Column()
        column.x = x
        column.y = y
        for z in range(self.numCellsPerColumn):
          cell = Cell()
          cell.index = (colIdx * self.numCellsPerColumn) + z
          cell.z = z
          column.cells.append(cell)
        self.columns.append(column)
        colIdx += 1

    # Create Spatial Pooler instance with appropriate parameters
    self.spatialPooler = SpatialPooler(
      inputDimensions = (self.getInputSize(), 1),
      columnDimensions = (self.width, self.height),
      potentialRadius = self.potentialRadius,
      potentialPct = self.potentialPct,
      globalInhibition = self.globalInhibition,
      localAreaDensity = self.localAreaDensity,
      numActiveColumnsPerInhArea = self.numActiveColumnsPerInhArea,
      stimulusThreshold = self.stimulusThreshold,
      synPermInactiveDec = self.proximalSynPermDecrement,
      synPermActiveInc = self.proximalSynPermIncrement,
      synPermConnected = self.proximalSynConnectedPerm,
      minPctOverlapDutyCycle = self.minPctOverlapDutyCycle,
      minPctActiveDutyCycle = self.minPctActiveDutyCycle,
      dutyCyclePeriod = self.dutyCyclePeriod,
      maxBoost = self.maxBoost,
      seed = self.spSeed,
      spVerbosity = False)

    # Create Temporal Pooler instance with appropriate parameters
    self.temporalPooler = TemporalPooler(
      columnDimensions = (self.width, self.height),
      cellsPerColumn = self.numCellsPerColumn,
      initialPermanence = self.distalSynInitialPerm,
      connectedPermanence = self.distalSynConnectedPerm,
      minThreshold = self.minThreshold,
      maxNewSynapseCount = self.maxNumNewSynapses,
      permanenceIncrement = self.distalSynPermIncrement,
      permanenceDecrement = self.distalSynPermDecrement,
      activationThreshold = self.activationThreshold,
      seed = self.tpSeed)

    return True

  def nextStep(self):
    """
    Perfoms actions related to time step progression.
    """

    Node.nextStep(self)
    for column in self.columns:
      column.nextStep()

    # Get input from sensors or lower regions and put into a single input map.
    input = self.getInput()

    # Send input to Spatial Pooler and get processed output (i.e. the active columns)
    # First initialize the vector for representing the current record
    columnDimensions = (self.width, self.height)
    columnNumber = numpy.array(columnDimensions).prod()
    activeColumns = numpy.zeros(columnNumber)
    self.spatialPooler.compute(input, self.enableSpatialLearning, activeColumns)

    # Send active columns to Temporal Pooler and get processed output (i.e. the predicting cells)
    # First convert active columns from float array to integer set
    activeColumnsSet = set()
    for colIdx in range(len(activeColumns)):
      if activeColumns[colIdx] == 1:
        activeColumnsSet.add(colIdx)
    self.temporalPooler.compute(activeColumnsSet, self.enableTemporalLearning)

    # Update elements regarding spatial pooler
    self.updateSpatialElements(activeColumns)

    # Update elements regarding temporal pooler
    self.updateTemporalElements()

    # Get the predicted values
    self.getPredictions()

    #TODO: self._output = self.temporalPooler.getPredictedState()

  def getPredictions(self):
    """
    Get the predicted values after an iteration.
    """

    for feeder in Global.project.network.getFeederNodes(self):
      feeder.getPredictions()

  def calculateStatistics(self):
    """
    Calculate statistics after an iteration.
    """

    # The region's prediction precision is the average between the nodes that feed it
    precisionRate = 0.
    numFeeders = 0
    for feeder in Global.project.network.getFeederNodes(self):
      precisionRate += feeder.statsPrecisionRate
      numFeeders += 1
    self.statsPrecisionRate = precisionRate / numFeeders

    for column in self.columns:
      column.calculateStatistics()

  def getInput(self):
    """
    Get input from sensors or lower regions and put into a single input map.
    """

    # Initialize the vector for representing the current input map
    inputList = []
    for inputElem in self._inputMap:
      if inputElem.isActive.atCurrStep():
        inputList.append(1)
      else:
        inputList.append(0)
    input = numpy.array(inputList)

    return input

  def updateSpatialElements(self, activeColumns):
    """
    Update elements regarding spatial pooler
    """

    # Update proximal segments and synapses according to active columns
    for colIdx in range(len(self.columns)):
      column = self.columns[colIdx]

      # Update proximal segment
      segment = column.segment
      if activeColumns[colIdx] == 1:
        segment.isActive.setForCurrStep(True)
      else:
        segment.isActive.setForCurrStep(False)

      # Check if proximal segment is predicted by check if the column has any predicted cell
      for cell in column.cells:
        if cell.index in self.temporalPooler.predictiveCells:
          segment.isPredicted.setForCurrStep(True)

      # Update proximal synapses
      if segment.isActive.atCurrStep() or segment.isPredicted.atCurrStep():
        permanencesSynapses = []
        self.spatialPooler.getPermanence(colIdx, permanencesSynapses)
        connectedSynapses = []
        self.spatialPooler.getConnectedSynapses(colIdx, connectedSynapses)
        for synIdx in range(len(permanencesSynapses)):
          # Get the proximal synapse given its position in the input map
          # Create a new one if it doesn't exist
          synapse = segment.getSynapse(synIdx)

          # Update proximal synapse
          if permanencesSynapses[synIdx] > 0.:
            if synapse == None:
              # Create a new synapse to a input element
              # An input element is a column if feeder is a region
              # or then a bit if feeder is a sensor
              synapse = Synapse()
              synapse.inputElem = self._inputMap[synIdx]
              synapse.indexSP = synIdx
              segment.synapses.append(synapse)

            # Update state
            synapse.isRemoved.setForCurrStep(False)
            synapse.permanence.setForCurrStep(permanencesSynapses[synIdx])
            if connectedSynapses[synIdx] == 1:
              synapse.isConnected.setForCurrStep(True)
            else:
              synapse.isConnected.setForCurrStep(False)
          else:
            if synapse != None:
              synapse.isRemoved.setForCurrStep(True)

  def updateTemporalElements(self):
    """
    Update elements regarding temporal pooler
    """

    # Update cells, distal segments and synapses according to active columns
    for colIdx in range(len(self.columns)):
      column = self.columns[colIdx]

      # Mark proximal segment and its connected synapses as predicted
      if column.segment.isPredicted.atCurrStep():
        for synapse in column.segment.synapses:
          if synapse.isConnected.atCurrStep():
            synapse.isPredicted.setForCurrStep(True)
            synapse.inputElem.isPredicted.setForCurrStep(True)

      # Mark proximal segment and its connected synapses that were predicted but are not active now
      if column.segment.isPredicted.atPreviousStep():
        if not column.segment.isActive.atCurrStep():
          column.segment.isFalselyPredicted.setForCurrStep(True)
        for synapse in column.segment.synapses:
          if (synapse.isPredicted.atPreviousStep() and not synapse.isConnected.atCurrStep()) or (synapse.isConnected.atCurrStep() and synapse.inputElem.isFalselyPredicted.atCurrStep()):
            synapse.isFalselyPredicted.setForCurrStep(True)

      for cell in column.cells:
        cellIdx = cell.index

        # Update cell's states
        if cellIdx in self.temporalPooler.winnerCells:
          cell.isLearning.setForCurrStep(True)
        if cellIdx in self.temporalPooler.activeCells:
          cell.isActive.setForCurrStep(True)
        if cellIdx in self.temporalPooler.predictiveCells:
          cell.isPredicted.setForCurrStep(True)
        if cell.isPredicted.atPreviousStep() and not cell.isActive.atCurrStep():
          cell.isFalselyPredicted.setForCurrStep(True)

        # Get the indexes of the distal segments of this cell
        segmentsForCell = self.temporalPooler.connections.segmentsForCell(cellIdx)

        # Add the segments that appeared after last iteration
        for segIdx in segmentsForCell:
          # Check if segment already exists in the cell
          segFound = False
          for segment in cell.segments:
            if segment.indexTP == segIdx:
              segFound = True
              break

          # If segment is new, add it to cell
          if not segFound:
            segment = Segment(SegmentType.distal)
            segment.indexTP = segIdx
            cell.segments.append(segment)

        # Update distal segments
        for segment in cell.segments:
          segIdx = segment.indexTP

          # If segment not found in segments indexes returned in last iteration mark it as removed
          if segIdx in segmentsForCell:

            # Update segment's state
            if segIdx in self.temporalPooler.activeSegments:
              segment.isActive.setForCurrStep(True)
            else:
              segment.isActive.setForCurrStep(False)

            # Get the indexes of the synapses of this segment
            synapsesForSegment = self.temporalPooler.connections.synapsesForSegment(segIdx)

            # Add the synapses that appeared after last iteration
            for synIdx in synapsesForSegment:
              # Check if synapse already exists in the segment
              synFound = False
              for synapse in segment.synapses:
                if synapse.indexTP == synIdx:
                  synFound = True
                  break

              # If synapse is new, add it to segment
              if not synFound:
                synapse = Synapse()
                synapse.indexTP = synIdx
                segment.synapses.append(synapse)

            # Update synapses
            for synapse in segment.synapses:
              synIdx = synapse.indexTP

              # If synapse not found in synapses indexes returned in last iteration mark it as removed
              if synIdx in synapsesForSegment:

                # Update synapse's state
                synapseData = self.temporalPooler.connections.dataForSynapse(synIdx)
                synapse.permanence.setForCurrStep(synapseData.permanence)
                if synapseData.permanence >= self.distalSynConnectedPerm:
                  synapse.isConnected.setForCurrStep(True)
                else:
                  synapse.isConnected.setForCurrStep(False)

                # Get cell given cell's index
                sourceColIdx = synapseData.presynapticCell / self.numCellsPerColumn
                sourceCellRelIdx = synapseData.presynapticCell % self.numCellsPerColumn
                sourceCell = self.columns[sourceColIdx].cells[sourceCellRelIdx]
                synapse.inputElem = sourceCell
              else:
                synapse.isRemoved.setForCurrStep(True)
          else:
            segment.isRemoved.setForCurrStep(True)
Beispiel #29
0
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
Beispiel #30
0
class JoinedInputsModel(LearningModel):
    """
    Joins all the words in the sentence in one SDR and tries to predict
    the sequence of actions.
    Structure:
       WordEncoder, ActionEncoder -> GeneralSP -> GeneralTM
    """

    def __init__(self, wordEncoder, actionEncoder, trainingSet,
            modulesParams=None):
        """
        @param wordEncoder
        @param actionEncoder
        @param dataSet: A module containing the trainingData, all of
            its categories and the inputIdx dict that maps each index
            in categories to an input name.
        """

        super(JoinedInputsModel, self).__init__(wordEncoder, actionEncoder,
            trainingSet, modulesParams)

        self.buckets = dict()
        self.iterationsTrained = 0

        self.initModules(trainingSet.categories, trainingSet.inputIdx)

        self.structure = {
            'wordInput': 'wordEnc',
            'wordEnc': 'generalSP',
            ###
            'actionInput': 'actionEnc',
            'actionEnc': 'generalSP',
            ###
            'generalSP': 'generalTM',
            'generalTM': None
        }
        self.modules = {
            'generalTM': self.generalTM,
            'generalSP': self.generalSP,
            'wordEnc': self.wordEncoder,
            'actionEnc': self.actionEncoder
        }

        self.layer = Layer(self.structure, self.modules, self.classifier)

    def initModules(self, categories, inputIdx):

        modulesNames = {'generalSP', 'generalTM'}

        nWords = len(categories[inputIdx['wordInput']])
        nActions = len(categories[inputIdx['actionInput']])


        inputDimensions = max(
            self.wordEncoder.getWidth(),
            self.actionEncoder.getWidth()
        )

        columnDimensions = (max((nWords + nActions),
            len(self.trainingData)) * 2, )

        defaultGeneralSPParams = {
            'inputDimensions': inputDimensions,
            'columnDimensions': columnDimensions,
            'seed': self.spSeed
        }

        defaultGeneralTMParams = {
            'columnDimensions': columnDimensions,
            'seed': self.tmSeed
        }

        if (self.modulesParams is not None) and\
                (set(self.modulesParams) == modulesNames):
            self.modulesParams['generalSP'].update(defaultGeneralSPParams)
            self.modulesParams['generalTM'].update(defaultGeneralTMParams)

            self.generalSP = SpatialPooler(**self.modulesParams['generalSP'])
            self.generalTM = TemporalMemory(**self.modulesParams['generalTM'])
            print("Using external Parameters!")

        else:
            self.generalSP = SpatialPooler(**defaultGeneralSPParams)
            self.generalTM = TemporalMemory(**defaultGeneralTMParams)
            print("External parameters invalid or not found, using"\
                " the default ones")

        self.classifier = CLAClassifierCond(
            steps=[1, 2],
            alpha=0.1,
            actValueAlpha=0.3,
            verbosity=0
        )

    def train(self, numIterations, trainingData=None, maxTime=-1, verbosity=0,
            learn=True):

        startTime = time.time()
        maxTimeReached = False

        if trainingData is None:
            trainingData = self.trainingData

        for iteration in xrange(numIterations):
            if verbosity > 0:
                print("Iteration "  + str(iteration))

            recordNum = 0

            for sentence, actionSeq in trainingData:
                self.inputSentence(sentence, verbosity, learn)
                recordNum += 1

                for action in actionSeq:
                    inputData = ('actionInput', action)
                    self.processInput(inputData, recordNum, verbosity, learn)
                    recordNum += 1

                self.reset()

                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 processInput(self, inputData, recordNum, verbosity=0, learn=False):

        inputName = inputData[0]
        actualValue = inputData[1]

        if verbosity > 1:
            print("===== " + inputName + ": " + str(actualValue) + " =====")

        encodedValue = numpy.zeros(
            self.generalSP.getInputDimensions(),
            dtype=numpy.uint8
        )

        if inputName == 'wordInput':
            for word in actualValue:
                encodedValue[self.wordEncoder.getBucketIndices(word)] = 1

            actualValue = ' '.join(actualValue)

        elif(inputName == 'actionInput'):
            aux = self.actionEncoder.encode(actualValue)
            encodedValue[numpy.where(aux > 1)] = 1

        if actualValue not in self.buckets:
            self.buckets[actualValue] = len(self.buckets)

        bucketIndex = self.buckets[actualValue]

        if verbosity > 1:
            print("Encoded Value: {0}\n"\
                "Bucket Index: {1}\n".format(encodedValue, bucketIndex))

        spOutput = numpy.zeros(self.generalSP.getColumnDimensions(),
                    dtype=numpy.uint8)
        self.generalSP.compute(encodedValue, learn, spOutput)

        tmInput = numpy.where(spOutput > 0)[0]
        self.generalTM.compute(set(tmInput), learn)

        retVal = self.classifier.compute(
                recordNum=recordNum,
                patternNZ=self.generalTM.activeCells,
                classification={
                    'bucketIdx': self.buckets[actualValue],
                    'actValue': actualValue
                },
                learn=learn,
                infer=True,
                conditionFunc=lambda x: x.endswith("-event")
            )

        bestPredictions = []

        for step in retVal:
            if step == 'actualValues':
                continue

            higherProbIndex = numpy.argmax(retVal[step])
            bestPredictions.append(
                retVal['actualValues'][higherProbIndex]
            )

        if verbosity > 2 :
            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 inputSentence(self, sentence, verbosity=0, learn=False):

        inputData = ('wordInput', sentence)
        bestPredictions = self.processInput(inputData, 0, verbosity, learn)

        if verbosity > 1:
            print('Best Predictions: ' + str(bestPredictions))

        return bestPredictions
Beispiel #31
0
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 = SpatialPooler(
         columnDimensions=(2048, 1),
         inputDimensions=(1, elemSize),
         potentialRadius=elemSize/2,
         numActiveColumnsPerInhArea=40,
         spVerbosity=0,
         stimulusThreshold=0,
         synPermConnected=0.12,
         seed=1,
         potentialPct=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

    # TODO: See https://github.com/numenta/nupic/issues/2072
    sp.compute(input1, learn=doLearn, activeArray=output1)
    sp.compute(input2, learn=doLearn, activeArray=output2)
    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
      # TODO: See https://github.com/numenta/nupic/issues/2072
      sp.compute(input1, learn=doLearn, activeArray=output1)
      sp.compute(input2, learn=doLearn, activeArray=output2)
      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
Beispiel #32
0
        currentlyConnected = numpy.zeros(shape=flatInputLength, dtype="uint8")
        spatialPooler.getConnectedSynapses(
            column=col, connectedSynapses=currentlyConnected)
        print "   ", currentlyConnected
    print "spatial pooler initialized\n"

genericTest = False
if genericTest:
    print "generic test"
    for i in xrange(0, 10):
        input = exputils.getRandom2dBoolMatrix(inputWidth, inputHeight)
        flatInput = input.flatten()
        #print "flatInput = ", flatInput
        iterationOutput = numpy.zeros(shape=flatInputLength, dtype="uint8")
        spatialPooler.compute(inputVector=flatInput,
                              learn=True,
                              activeArray=iterationOutput)
        print "Iteration " + str(i) + ":", iterationOutput

print "Initializing temporal pooler"
temporalPooler = TP(
    numberOfCols=flatInputLength,
    cellsPerColumn=104,  # c++ version max = 104
    initialPerm=0.5,
    connectedPerm=0.5,
    minThreshold=10,
    newSynapseCount=10,
    permanenceInc=0.1,
    permanenceDec=0.0,
    activationThreshold=1,
    globalDecay=0,
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))
Beispiel #34
0
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
Beispiel #35
0
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)
Beispiel #36
0
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 = SpatialPooler(
           columnDimensions=(2048, 1),
           inputDimensions=(1, elemSize),
           potentialRadius=elemSize/2,
           numActiveColumnsPerInhArea=40,
           spVerbosity=0,
           stimulusThreshold=0,
           seed=1,
           potentialPct=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:
          # TODO: See https://github.com/numenta/nupic/issues/2072
          sp.compute(inputs[i], learn=doLearn, activeArray=outputs[i])
          #print outputs[i].sum(), outputs[i]
        else:
          # TODO: See https://github.com/numenta/nupic/issues/2072
          output = np.zeros(2048)
          sp.compute(inputs[i], learn=doLearn, activeArray=output)
      
    # 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
Beispiel #37
0
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 testGetMaxBoost(self):
        inParam = 78
        self.sp.setMaxBoost(inParam)
        outParam = self.sp.getMaxBoost()
        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 testGetMinPctActiveDutyCycles(self):
        inParam = 0.444333
        self.sp.setMinPctActiveDutyCycles(inParam)
        outParam = self.sp.getMinPctActiveDutyCycles()
        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 testGetMinActiveDutyCycles(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.setMinActiveDutyCycles(inParam)
        outParam = numpy.zeros(numInputs).astype(realType)
        self.sp.getMinActiveDutyCycles(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)
Beispiel #38
0
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 = SpatialPooler(
         columnDimensions=(2048, 1),
         inputDimensions=(1, elemSize),
         potentialRadius=elemSize/2,
         numActiveColumnsPerInhArea=40,
         spVerbosity=0,
         stimulusThreshold=0,
         synPermConnected=0.12,
         seed=1,
         potentialPct=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

    # TODO: See https://github.com/numenta/nupic/issues/2072
    sp.compute(input1, learn=doLearn, activeArray=output1)
    sp.compute(input2, learn=doLearn, activeArray=output2)
    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
      # TODO: See https://github.com/numenta/nupic/issues/2072
      sp.compute(input1, learn=doLearn, activeArray=output1)
      sp.compute(input2, learn=doLearn, activeArray=output2)
      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
Beispiel #39
0
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)
Beispiel #40
0
                     color=cmap(float(epoch) / epochs))

        activeColumnsPreviousEpoch = copy.copy(activeColumnsCurrentEpoch)
        connectedCountsPreviousEpoch = copy.copy(connectedCounts)

        # train SP here,
        # Learn is turned off at the first epoch to gather stats of untrained SP
        learn = False if epoch == 0 else True

        # randomize the presentation order of input vectors
        sdrOrders = np.random.permutation(np.arange(numInputVector))
        for i in range(numInputVector):
            outputColumns = np.zeros(sp.getColumnDimensions(), dtype=uintType)
            inputVector = copy.deepcopy(inputVectors[sdrOrders[i]][:])
            # addNoiseToVector(inputVector, 0.05, inputVectorType)
            sp.compute(inputVector, learn, outputColumns)

            activeColumnsCurrentEpoch[sdrOrders[i]][:] = np.reshape(
                outputColumns, (1, columnNumber))

        sp.getConnectedCounts(connectedCounts)

        entropyTrace.append(calculateEntropy(activeColumnsCurrentEpoch))

        if epoch >= 1:
            activeColumnsDiff = activeColumnsCurrentEpoch > activeColumnsPreviousEpoch
            numBitDiffTrace.append(np.mean(np.sum(activeColumnsDiff, 1)))

            numConnectedSynapsesTrace.append(np.sum(connectedCounts))

            numNewSynapses = connectedCounts - connectedCountsPreviousEpoch