예제 #1
0
    def basicTest(self):
        """Basic test (creation, pickling, basic run of learning and inference)"""
        # Create TM object
        tm = BacktrackingTMCPP(numberOfCols=10,
                               cellsPerColumn=3,
                               initialPerm=.2,
                               connectedPerm=0.8,
                               minThreshold=2,
                               newSynapseCount=5,
                               permanenceInc=.1,
                               permanenceDec=.05,
                               permanenceMax=1,
                               globalDecay=.05,
                               activationThreshold=4,
                               doPooling=False,
                               segUpdateValidDuration=5,
                               seed=SEED,
                               verbosity=VERBOSITY)
        tm.retrieveLearningStates = True

        # Save and reload
        tm.makeCells4Ephemeral = False
        pickle.dump(tm, open("test_tm_cpp.pkl", "wb"))
        tm2 = pickle.load(open("test_tm_cpp.pkl"))

        self.assertTrue(fdrutils.tmDiff2(tm, tm2, VERBOSITY,
                                         checkStates=False))

        # Learn
        for i in xrange(5):
            x = numpy.zeros(tm.numberOfCols, dtype='uint32')
            _RGEN.initializeUInt32Array(x, 2)
            tm.learn(x)

        # Save and reload after learning
        tm.reset()
        tm.makeCells4Ephemeral = False
        pickle.dump(tm, open("test_tm_cpp.pkl", "wb"))
        tm2 = pickle.load(open("test_tm_cpp.pkl"))
        self.assertTrue(fdrutils.tmDiff2(tm, tm2, VERBOSITY))

        ## Infer
        patterns = numpy.zeros((4, tm.numberOfCols), dtype='uint32')
        for i in xrange(4):
            _RGEN.initializeUInt32Array(patterns[i], 2)

        for i in xrange(10):
            x = numpy.zeros(tm.numberOfCols, dtype='uint32')
            _RGEN.initializeUInt32Array(x, 2)
            tm.infer(x)
            if i > 0:
                tm._checkPrediction(patterns)
예제 #2
0
    def assertTMsEqual(self, tm1, tm2):
        """Asserts that two TM instances are the same.

    This is temporarily disabled since it does not work with the C++
    implementation of the TM.
    """
        self.assertEqual(tm1, tm2, tm1.diff(tm2))
        self.assertTrue(fdrutilities.tmDiff2(tm1, tm2, 1, False))
예제 #3
0
  def assertTMsEqual(self, tm1, tm2):
    """Asserts that two TM instances are the same.

    This is temporarily disabled since it does not work with the C++
    implementation of the TM.
    """
    self.assertEqual(tm1, tm2, tm1.diff(tm2))
    self.assertTrue(fdrutilities.tmDiff2(tm1, tm2, 1, False))
예제 #4
0
    def test_cpp_py_tms(self):

        # Create cpp tm
        tm = BacktrackingTMCPP(numberOfCols=10,
                               cellsPerColumn=1,
                               verbosity=VERBOSITY)
        tm.cells4.setCellSegmentOrder(True)

        # Create Python tm from same characteristics
        tmPy = BacktrackingTM(numberOfCols=tm.numberOfCols,
                              cellsPerColumn=tm.cellsPerColumn,
                              initialPerm=tm.initialPerm,
                              connectedPerm=tm.connectedPerm,
                              minThreshold=tm.minThreshold,
                              newSynapseCount=tm.newSynapseCount,
                              permanenceInc=tm.permanenceInc,
                              permanenceDec=tm.permanenceDec,
                              permanenceMax=tm.permanenceMax,
                              globalDecay=tm.globalDecay,
                              activationThreshold=tm.activationThreshold,
                              doPooling=tm.doPooling,
                              segUpdateValidDuration=tm.segUpdateValidDuration,
                              pamLength=tm.pamLength,
                              maxAge=tm.maxAge,
                              maxSeqLength=tm.maxSeqLength,
                              maxSegmentsPerCell=tm.maxSegmentsPerCell,
                              maxSynapsesPerSegment=tm.maxSynapsesPerSegment,
                              seed=tm.seed,
                              verbosity=tm.verbosity)

        # Check if both tm's are equal
        self.assertTrue(fdrutils.tmDiff2(tm, tmPy, VERBOSITY, False))

        # Build up sequences
        numPatterns = 1
        numRepetitions = 1
        activity = 1

        sequence = fdrutils.generateCoincMatrix(nCoinc=numPatterns,
                                                length=tm.numberOfCols,
                                                activity=activity)
        # print(sequence)

        sequence_row = sequence.getRow(0)

        y1 = tm.learn(sequence_row)
        y2 = tmPy.learn(sequence_row)

        num_segments_cpp = tm.getNumSegments()
        num_segments_py = tmPy.getNumSegments()

        # fails since num_segments_cpp = 0 and num_segments_py = 1
        self.assertTrue(num_segments_cpp=num_segments_py)

        # Check if both tm's are equal
        # self.assertTrue(fdrutils.tmDiff2(tm, tmPy, VERBOSITY, False))

        return
예제 #5
0
  def basicTest(self):
    """Basic test (creation, pickling, basic run of learning and inference)"""
    # Create TM object
    tm = BacktrackingTMCPP(numberOfCols=10, cellsPerColumn=3,
                           initialPerm=.2, connectedPerm= 0.8,
                           minThreshold=2, newSynapseCount=5,
                           permanenceInc=.1, permanenceDec= .05,
                           permanenceMax=1, globalDecay=.05,
                           activationThreshold=4, doPooling=False,
                           segUpdateValidDuration=5, seed=SEED,
                           verbosity=VERBOSITY)
    tm.retrieveLearningStates = True

    # Save and reload
    tm.makeCells4Ephemeral = False
    pickle.dump(tm, open("test_tm_cpp.pkl", "wb"))
    tm2 = pickle.load(open("test_tm_cpp.pkl"))

    self.assertTrue(fdrutils.tmDiff2(tm, tm2, VERBOSITY, checkStates=False))

    # Learn
    for i in xrange(5):
      x = numpy.zeros(tm.numberOfCols, dtype='uint32')
      _RGEN.initializeUInt32Array(x, 2)
      tm.learn(x)

    # Save and reload after learning
    tm.reset()
    tm.makeCells4Ephemeral = False
    pickle.dump(tm, open("test_tm_cpp.pkl", "wb"))
    tm2 = pickle.load(open("test_tm_cpp.pkl"))
    self.assertTrue(fdrutils.tmDiff2(tm, tm2, VERBOSITY))

    ## Infer
    patterns = numpy.zeros((4, tm.numberOfCols), dtype='uint32')
    for i in xrange(4):
      _RGEN.initializeUInt32Array(patterns[i], 2)

    for i in xrange(10):
      x = numpy.zeros(tm.numberOfCols, dtype='uint32')
      _RGEN.initializeUInt32Array(x, 2)
      tm.infer(x)
      if i > 0:
        tm.checkPrediction2(patterns)
예제 #6
0
def assertNoTMDiffs(tms):
  """
  Check for diffs among the TM instances in the passed in tms dict and
  raise an assert if any are detected

  Parameters:
  ---------------------------------------------------------------------
  tms:                  dict of TM instances
  """

  if len(tms) == 1:
    return
  if len(tms) > 2:
    raise "Not implemented for more than 2 TMs"

  same = fdrutils.tmDiff2(tms.values(), verbosity=VERBOSITY)
  assert(same)
  return
예제 #7
0
def assertNoTMDiffs(tms):
    """
  Check for diffs among the TM instances in the passed in tms dict and
  raise an assert if any are detected

  Parameters:
  ---------------------------------------------------------------------
  tms:                  dict of TM instances
  """

    if len(tms) == 1:
        return
    if len(tms) > 2:
        raise "Not implemented for more than 2 TMs"

    same = fdrutils.tmDiff2(*tms.values(), verbosity=VERBOSITY)
    assert (same)
    return
예제 #8
0
    def basicTest2(self,
                   tm,
                   numPatterns=100,
                   numRepetitions=3,
                   activity=15,
                   testTrimming=False,
                   testRebuild=False):
        """Basic test (basic run of learning and inference)"""
        # Create PY TM object that mirrors the one sent in.
        tmPy = BacktrackingTM(numberOfCols=tm.numberOfCols,
                              cellsPerColumn=tm.cellsPerColumn,
                              initialPerm=tm.initialPerm,
                              connectedPerm=tm.connectedPerm,
                              minThreshold=tm.minThreshold,
                              newSynapseCount=tm.newSynapseCount,
                              permanenceInc=tm.permanenceInc,
                              permanenceDec=tm.permanenceDec,
                              permanenceMax=tm.permanenceMax,
                              globalDecay=tm.globalDecay,
                              activationThreshold=tm.activationThreshold,
                              doPooling=tm.doPooling,
                              segUpdateValidDuration=tm.segUpdateValidDuration,
                              pamLength=tm.pamLength,
                              maxAge=tm.maxAge,
                              maxSeqLength=tm.maxSeqLength,
                              maxSegmentsPerCell=tm.maxSegmentsPerCell,
                              maxSynapsesPerSegment=tm.maxSynapsesPerSegment,
                              seed=tm.seed,
                              verbosity=tm.verbosity)

        # Ensure we are copying over learning states for TMDiff
        tm.retrieveLearningStates = True

        verbosity = VERBOSITY

        # Learn

        # Build up sequences
        sequence = fdrutils.generateCoincMatrix(nCoinc=numPatterns,
                                                length=tm.numberOfCols,
                                                activity=activity)
        for r in xrange(numRepetitions):
            for i in xrange(sequence.nRows()):

                #if i > 11:
                #  setVerbosity(6, tm, tmPy)

                if i % 10 == 0:
                    tm.reset()
                    tmPy.reset()

                if verbosity >= 2:
                    print "\n\n    ===================================\nPattern:",
                    print i, "Round:", r, "input:", sequence.getRow(i)

                y1 = tm.learn(sequence.getRow(i))
                y2 = tmPy.learn(sequence.getRow(i))

                # Ensure everything continues to work well even if we continuously
                # rebuild outSynapses structure
                if testRebuild:
                    tm.cells4.rebuildOutSynapses()

                if testTrimming:
                    tm.trimSegments()
                    tmPy.trimSegments()

                if verbosity > 2:
                    print "\n   ------  CPP states  ------ ",
                    tm.printStates()
                    print "\n   ------  PY states  ------ ",
                    tmPy.printStates()
                    if verbosity > 6:
                        print "C++ cells: "
                        tm.printCells()
                        print "PY cells: "
                        tmPy.printCells()

                if verbosity >= 3:
                    print "Num segments in PY and C++", tmPy.getNumSegments(), \
                        tm.getNumSegments()

                # Check if the two TM's are identical or not. This check is slow so
                # we do it every other iteration. Make it every iteration for debugging
                # as needed.
                self.assertTrue(fdrutils.tmDiff2(tm, tmPy, verbosity, False))

                # Check that outputs are identical
                self.assertLess(abs((y1 - y2).sum()), 3)

        print "Learning completed"

        self.assertTrue(fdrutils.tmDiff2(tm, tmPy, verbosity))

        # TODO: Need to check - currently failing this
        #checkCell0(tmPy)

        # Remove unconnected synapses and check TM's again

        # Test rebuild out synapses
        print "Rebuilding outSynapses"
        tm.cells4.rebuildOutSynapses()
        self.assertTrue(fdrutils.tmDiff2(tm, tmPy, VERBOSITY))

        print "Trimming segments"
        tm.trimSegments()
        tmPy.trimSegments()
        self.assertTrue(fdrutils.tmDiff2(tm, tmPy, VERBOSITY))

        # Save and reload after learning
        print "Pickling and unpickling"
        tm.makeCells4Ephemeral = False
        pickle.dump(tm, open("test_tm_cpp.pkl", "wb"))
        tm2 = pickle.load(open("test_tm_cpp.pkl"))
        self.assertTrue(fdrutils.tmDiff2(tm, tm2, VERBOSITY,
                                         checkStates=False))

        # Infer
        print "Testing inference"

        # Setup for inference
        tm.reset()
        tmPy.reset()
        setVerbosity(INFERENCE_VERBOSITY, tm, tmPy)

        patterns = numpy.zeros((40, tm.numberOfCols), dtype='uint32')
        for i in xrange(4):
            _RGEN.initializeUInt32Array(patterns[i], 2)

        for i, x in enumerate(patterns):

            x = numpy.zeros(tm.numberOfCols, dtype='uint32')
            _RGEN.initializeUInt32Array(x, 2)
            y = tm.infer(x)
            yPy = tmPy.infer(x)

            self.assertTrue(
                fdrutils.tmDiff2(tm, tmPy, VERBOSITY, checkLearn=False))
            if abs((y - yPy).sum()) > 0:
                print "C++ output", y
                print "Py output", yPy
                assert False

            if i > 0:
                tm._checkPrediction(patterns)
                tmPy._checkPrediction(patterns)

        print "Inference completed"
        print "===================================="

        return tm, tmPy
예제 #9
0
 def testIdenticalTms(self):
   self.assertTrue(fdrutils.tmDiff2(self.cppTm, self.pyTm))
예제 #10
0
  def _testSegmentLearningSequence(self, tms,
                                   trainingSequences,
                                   testSequences,
                                   doResets = True):

    """Train the given TM once on the entire training set. on the Test a single
    set of sequences once and check that individual predictions reflect the true
    relative frequencies. Return a success code. Success code is 1 for pass, 0
    for fail."""

    # If no test sequence is specified, use the first training sequence
    if testSequences == None:
      testSequences = trainingSequences

    cppTM, pyTM = tms[0], tms[1]

    if cppTM is not None:
      assert fdrutils.tmDiff2(cppTM, pyTM, g_options.verbosity) == True

    #--------------------------------------------------------------------------
    # Learn
    if g_options.verbosity > 0:
      print "============= Training ================="
      print "TM parameters:"
      print "CPP"
      if cppTM is not None:
        print cppTM.printParameters()
      print "\nPY"
      print pyTM.printParameters()

    for sequenceNum, trainingSequence in enumerate(trainingSequences):

      if g_options.verbosity > 1:
        print "============= New sequence ================="

      if doResets:
        if cppTM is not None:
          cppTM.reset()
        pyTM.reset()

      for t, x in enumerate(trainingSequence):

        if g_options.verbosity > 1:
          print "Time step", t, "sequence number", sequenceNum
          print "Input: ", pyTM.printInput(x)
          print "NNZ:", x.nonzero()

        x = numpy.array(x).astype('float32')
        if cppTM is not None:
          cppTM.learn(x)
        pyTM.learn(x)

        if cppTM is not None:
          assert fdrutils.tmDiff2(cppTM, pyTM, g_options.verbosity,
                                  relaxSegmentTests = False) == True

        if g_options.verbosity > 2:
          if cppTM is not None:
            print "CPP"
            cppTM.printStates(printPrevious = (g_options.verbosity > 4))
          print "\nPY"
          pyTM.printStates(printPrevious = (g_options.verbosity > 4))
          print

      if g_options.verbosity > 4:
        print "Sequence finished. Complete state after sequence"
        if cppTM is not None:
          print "CPP"
          cppTM.printCells()
        print "\nPY"
        pyTM.printCells()
        print

    if g_options.verbosity > 2:
      print "Calling trim segments"

    if cppTM is not None:
      nSegsRemovedCPP, nSynsRemovedCPP = cppTM.trimSegments()
    nSegsRemoved, nSynsRemoved = pyTM.trimSegments()
    if cppTM is not None:
      assert nSegsRemovedCPP == nSegsRemoved
      assert nSynsRemovedCPP == nSynsRemoved

    if cppTM is not None:
      assert fdrutils.tmDiff2(cppTM, pyTM, g_options.verbosity) == True

    print "Training completed. Stats:"
    info = pyTM.getSegmentInfo()
    print "  nSegments:", info[0]
    print "  nSynapses:", info[1]
    if g_options.verbosity > 3:
      print "Complete state:"
      if cppTM is not None:
        print "CPP"
        cppTM.printCells()
      print "\nPY"
      pyTM.printCells()

    #---------------------------------------------------------------------------
    # Infer
    if g_options.verbosity > 1:
      print "============= Inference ================="

    if cppTM is not None:
      cppTM.collectStats = True
    pyTM.collectStats = True

    nPredictions = 0
    cppNumCorrect, pyNumCorrect = 0, 0

    for sequenceNum, testSequence in enumerate(testSequences):

      if g_options.verbosity > 1:
        print "============= New sequence ================="

      slen = len(testSequence)

      if doResets:
        if cppTM is not None:
          cppTM.reset()
        pyTM.reset()

      for t, x in enumerate(testSequence):

        if g_options.verbosity >= 2:
          print "Time step", t, '\nInput:'
          pyTM.printInput(x)

        if cppTM is not None:
          cppTM.infer(x)
        pyTM.infer(x)

        if cppTM is not None:
          assert fdrutils.tmDiff2(cppTM, pyTM, g_options.verbosity) == True

        if g_options.verbosity > 2:
          if cppTM is not None:
            print "CPP"
            cppTM.printStates(printPrevious = (g_options.verbosity > 4),
                           printLearnState = False)
          print "\nPY"
          pyTM.printStates(printPrevious = (g_options.verbosity > 4),
                         printLearnState = False)

        if cppTM is not None:
          cppScores = cppTM.getStats()
        pyScores = pyTM.getStats()

        if g_options.verbosity >= 2:
          if cppTM is not None:
            print "CPP"
            print cppScores
          print "\nPY"
          print pyScores

        if t < slen-1 and t > pyTM.burnIn:
          nPredictions += 1
          if cppTM is not None:
            if cppScores['curPredictionScore2'] > 0.3:
              cppNumCorrect += 1
          if pyScores['curPredictionScore2'] > 0.3:
            pyNumCorrect += 1

    # Check that every inference was correct, excluding the very last inference
    if cppTM is not None:
      cppScores = cppTM.getStats()
    pyScores = pyTM.getStats()

    passTest = False
    if cppTM is not None:
      if cppNumCorrect == nPredictions and pyNumCorrect == nPredictions:
        passTest = True
    else:
      if pyNumCorrect == nPredictions:
        passTest = True

    if not passTest:
      print "CPP correct predictions:", cppNumCorrect
      print "PY correct predictions:", pyNumCorrect
      print "Total predictions:", nPredictions

    return passTest
 def testIdenticalTms(self):
     self.assertTrue(fdrutils.tmDiff2(self.cppTm, self.pyTm))
예제 #12
0
    def _testSegmentLearningSequence(self,
                                     tms,
                                     trainingSequences,
                                     testSequences,
                                     doResets=True):
        """Train the given TM once on the entire training set. on the Test a single
    set of sequences once and check that individual predictions reflect the true
    relative frequencies. Return a success code. Success code is 1 for pass, 0
    for fail."""

        # If no test sequence is specified, use the first training sequence
        if testSequences == None:
            testSequences = trainingSequences

        cppTM, pyTM = tms[0], tms[1]

        if cppTM is not None:
            assert fdrutils.tmDiff2(cppTM, pyTM, g_options.verbosity) == True

        #--------------------------------------------------------------------------
        # Learn
        if g_options.verbosity > 0:
            print("============= Training =================")
            print("TM parameters:")
            print("CPP")
            if cppTM is not None:
                print(cppTM.printParameters())
            print("\nPY")
            print(pyTM.printParameters())

        for sequenceNum, trainingSequence in enumerate(trainingSequences):

            if g_options.verbosity > 1:
                print("============= New sequence =================")

            if doResets:
                if cppTM is not None:
                    cppTM.reset()
                pyTM.reset()

            for t, x in enumerate(trainingSequence):

                if g_options.verbosity > 1:
                    print("Time step", t, "sequence number", sequenceNum)
                    print("Input: ", pyTM.printInput(x))
                    print("NNZ:", x.nonzero())

                x = numpy.array(x).astype('float32')
                if cppTM is not None:
                    cppTM.learn(x)
                pyTM.learn(x)

                if cppTM is not None:
                    assert fdrutils.tmDiff2(cppTM,
                                            pyTM,
                                            g_options.verbosity,
                                            relaxSegmentTests=False) == True

                if g_options.verbosity > 2:
                    if cppTM is not None:
                        print("CPP")
                        cppTM.printStates(
                            printPrevious=(g_options.verbosity > 4))
                    print("\nPY")
                    pyTM.printStates(printPrevious=(g_options.verbosity > 4))
                    print()

            if g_options.verbosity > 4:
                print("Sequence finished. Complete state after sequence")
                if cppTM is not None:
                    print("CPP")
                    cppTM.printCells()
                print("\nPY")
                pyTM.printCells()
                print()

        if g_options.verbosity > 2:
            print("Calling trim segments")

        if cppTM is not None:
            nSegsRemovedCPP, nSynsRemovedCPP = cppTM.trimSegments()
        nSegsRemoved, nSynsRemoved = pyTM.trimSegments()
        if cppTM is not None:
            assert nSegsRemovedCPP == nSegsRemoved
            assert nSynsRemovedCPP == nSynsRemoved

        if cppTM is not None:
            assert fdrutils.tmDiff2(cppTM, pyTM, g_options.verbosity) == True

        print("Training completed. Stats:")
        info = pyTM.getSegmentInfo()
        print("  nSegments:", info[0])
        print("  nSynapses:", info[1])
        if g_options.verbosity > 3:
            print("Complete state:")
            if cppTM is not None:
                print("CPP")
                cppTM.printCells()
            print("\nPY")
            pyTM.printCells()

        #---------------------------------------------------------------------------
        # Infer
        if g_options.verbosity > 1:
            print("============= Inference =================")

        if cppTM is not None:
            cppTM.collectStats = True
        pyTM.collectStats = True

        nPredictions = 0
        cppNumCorrect, pyNumCorrect = 0, 0

        for sequenceNum, testSequence in enumerate(testSequences):

            if g_options.verbosity > 1:
                print("============= New sequence =================")

            slen = len(testSequence)

            if doResets:
                if cppTM is not None:
                    cppTM.reset()
                pyTM.reset()

            for t, x in enumerate(testSequence):

                if g_options.verbosity >= 2:
                    print("Time step", t, '\nInput:')
                    pyTM.printInput(x)

                if cppTM is not None:
                    cppTM.infer(x)
                pyTM.infer(x)

                if cppTM is not None:
                    assert fdrutils.tmDiff2(cppTM, pyTM,
                                            g_options.verbosity) == True

                if g_options.verbosity > 2:
                    if cppTM is not None:
                        print("CPP")
                        cppTM.printStates(
                            printPrevious=(g_options.verbosity > 4),
                            printLearnState=False)
                    print("\nPY")
                    pyTM.printStates(printPrevious=(g_options.verbosity > 4),
                                     printLearnState=False)

                if cppTM is not None:
                    cppScores = cppTM.getStats()
                pyScores = pyTM.getStats()

                if g_options.verbosity >= 2:
                    if cppTM is not None:
                        print("CPP")
                        print(cppScores)
                    print("\nPY")
                    print(pyScores)

                if t < slen - 1 and t > pyTM.burnIn:
                    nPredictions += 1
                    if cppTM is not None:
                        if cppScores['curPredictionScore2'] > 0.3:
                            cppNumCorrect += 1
                    if pyScores['curPredictionScore2'] > 0.3:
                        pyNumCorrect += 1

        # Check that every inference was correct, excluding the very last inference
        if cppTM is not None:
            cppScores = cppTM.getStats()
        pyScores = pyTM.getStats()

        passTest = False
        if cppTM is not None:
            if cppNumCorrect == nPredictions and pyNumCorrect == nPredictions:
                passTest = True
        else:
            if pyNumCorrect == nPredictions:
                passTest = True

        if not passTest:
            print("CPP correct predictions:", cppNumCorrect)
            print("PY correct predictions:", pyNumCorrect)
            print("Total predictions:", nPredictions)

        return passTest
예제 #13
0
  def basicTest2(self, tm, numPatterns=100, numRepetitions=3, activity=15,
                 testTrimming=False, testRebuild=False):
    """Basic test (basic run of learning and inference)"""
    # Create PY TM object that mirrors the one sent in.
    tmPy = BacktrackingTM(numberOfCols=tm.numberOfCols,
                          cellsPerColumn=tm.cellsPerColumn,
                          initialPerm=tm.initialPerm,
                          connectedPerm=tm.connectedPerm,
                          minThreshold=tm.minThreshold,
                          newSynapseCount=tm.newSynapseCount,
                          permanenceInc=tm.permanenceInc,
                          permanenceDec=tm.permanenceDec,
                          permanenceMax=tm.permanenceMax,
                          globalDecay=tm.globalDecay,
                          activationThreshold=tm.activationThreshold,
                          doPooling=tm.doPooling,
                          segUpdateValidDuration=tm.segUpdateValidDuration,
                          pamLength=tm.pamLength, maxAge=tm.maxAge,
                          maxSeqLength=tm.maxSeqLength,
                          maxSegmentsPerCell=tm.maxSegmentsPerCell,
                          maxSynapsesPerSegment=tm.maxSynapsesPerSegment,
                          seed=tm.seed, verbosity=tm.verbosity)

    # Ensure we are copying over learning states for TMDiff
    tm.retrieveLearningStates = True

    verbosity = VERBOSITY

    # Learn

    # Build up sequences
    sequence = fdrutils.generateCoincMatrix(nCoinc=numPatterns,
                                            length=tm.numberOfCols,
                                            activity=activity)
    for r in xrange(numRepetitions):
      for i in xrange(sequence.nRows()):

        #if i > 11:
        #  setVerbosity(6, tm, tmPy)

        if i % 10 == 0:
          tm.reset()
          tmPy.reset()

        if verbosity >= 2:
          print "\n\n    ===================================\nPattern:",
          print i, "Round:", r, "input:", sequence.getRow(i)

        y1 = tm.learn(sequence.getRow(i))
        y2 = tmPy.learn(sequence.getRow(i))

        # Ensure everything continues to work well even if we continuously
        # rebuild outSynapses structure
        if testRebuild:
          tm.cells4.rebuildOutSynapses()

        if testTrimming:
          tm.trimSegments()
          tmPy.trimSegments()

        if verbosity > 2:
          print "\n   ------  CPP states  ------ ",
          tm.printStates()
          print "\n   ------  PY states  ------ ",
          tmPy.printStates()
          if verbosity > 6:
            print "C++ cells: "
            tm.printCells()
            print "PY cells: "
            tmPy.printCells()

        if verbosity >= 3:
          print "Num segments in PY and C++", tmPy.getNumSegments(), \
              tm.getNumSegments()

        # Check if the two TM's are identical or not. This check is slow so
        # we do it every other iteration. Make it every iteration for debugging
        # as needed.
        self.assertTrue(fdrutils.tmDiff2(tm, tmPy, verbosity, False))

        # Check that outputs are identical
        self.assertLess(abs((y1 - y2).sum()), 3)

    print "Learning completed"

    self.assertTrue(fdrutils.tmDiff2(tm, tmPy, verbosity))

    # TODO: Need to check - currently failing this
    #checkCell0(tmPy)

    # Remove unconnected synapses and check TM's again

    # Test rebuild out synapses
    print "Rebuilding outSynapses"
    tm.cells4.rebuildOutSynapses()
    self.assertTrue(fdrutils.tmDiff2(tm, tmPy, VERBOSITY))

    print "Trimming segments"
    tm.trimSegments()
    tmPy.trimSegments()
    self.assertTrue(fdrutils.tmDiff2(tm, tmPy, VERBOSITY))

    # Save and reload after learning
    print "Pickling and unpickling"
    tm.makeCells4Ephemeral = False
    pickle.dump(tm, open("test_tm_cpp.pkl", "wb"))
    tm2 = pickle.load(open("test_tm_cpp.pkl"))
    self.assertTrue(fdrutils.tmDiff2(tm, tm2, VERBOSITY, checkStates=False))

    # Infer
    print "Testing inference"

    # Setup for inference
    tm.reset()
    tmPy.reset()
    setVerbosity(INFERENCE_VERBOSITY, tm, tmPy)

    patterns = numpy.zeros((40, tm.numberOfCols), dtype='uint32')
    for i in xrange(4):
      _RGEN.initializeUInt32Array(patterns[i], 2)

    for i, x in enumerate(patterns):

      x = numpy.zeros(tm.numberOfCols, dtype='uint32')
      _RGEN.initializeUInt32Array(x, 2)
      y = tm.infer(x)
      yPy = tmPy.infer(x)

      self.assertTrue(fdrutils.tmDiff2(tm, tmPy, VERBOSITY, checkLearn=False))
      if abs((y - yPy).sum()) > 0:
        print "C++ output", y
        print "Py output", yPy
        assert False

      if i > 0:
        tm.checkPrediction2(patterns)
        tmPy.checkPrediction2(patterns)

    print "Inference completed"
    print "===================================="

    return tm, tmPy