예제 #1
0
    def testReadWrite(self):
        categories = ["ES", "GB", "US"]

        # forced: is not recommended, but is used here for readability. see
        # scalar.py
        original = CategoryEncoder(w=3, categoryList=categories, forced=True)
        output = original.encode("US")
        target = numpy.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
                             dtype=defaultDtype)
        self.assertTrue(numpy.array_equal(output, target))

        decoded = original.decode(output)

        proto1 = CategoryEncoderProto.new_message()
        original.write(proto1)

        # Write the proto to a temp file and read it back into a new proto
        with tempfile.TemporaryFile() as f:
            proto1.write(f)
            f.seek(0)
            proto2 = CategoryEncoderProto.read(f)

        encoder = CategoryEncoder.read(proto2)

        self.assertIsInstance(encoder, CategoryEncoder)
        self.assertEqual(encoder.verbosity, original.verbosity)
        self.assertEqual(encoder.width, original.width)
        self.assertEqual(encoder.description, original.description)
        self.assertEqual(encoder.name, original.name)
        self.assertDictEqual(encoder.categoryToIndex, original.categoryToIndex)
        self.assertDictEqual(encoder.indexToCategory, original.indexToCategory)
        self.assertTrue(numpy.array_equal(encoder.encode("US"), output))
        self.assertEqual(original.decode(encoder.encode("US")),
                         encoder.decode(original.encode("US")))
        self.assertEqual(decoded, encoder.decode(output))
예제 #2
0
파일: category_test.py 프로젝트: Afey/nupic
  def testReadWrite(self):
    categories = ["ES", "GB", "US"]

    # forced: is not recommended, but is used here for readability. see
    # scalar.py
    original = CategoryEncoder(w=3, categoryList=categories, forced=True)
    output = original.encode("US")
    target = numpy.array([0,0,0,0,0,0,0,0,0,1,1,1], dtype=defaultDtype)
    self.assertTrue(numpy.array_equal(output, target))

    decoded = original.decode(output)

    proto1 = CategoryEncoderProto.new_message()
    original.write(proto1)

    # Write the proto to a temp file and read it back into a new proto
    with tempfile.TemporaryFile() as f:
      proto1.write(f)
      f.seek(0)
      proto2 = CategoryEncoderProto.read(f)

    encoder = CategoryEncoder.read(proto2)

    self.assertIsInstance(encoder, CategoryEncoder)
    self.assertEqual(encoder.verbosity, original.verbosity)
    self.assertEqual(encoder.width, original.width)
    self.assertEqual(encoder.description, original.description)
    self.assertEqual(encoder.name, original.name)
    self.assertDictEqual(encoder.categoryToIndex, original.categoryToIndex)
    self.assertDictEqual(encoder.indexToCategory, original.indexToCategory)
    self.assertTrue(numpy.array_equal(encoder.encode("US"), output))
    self.assertEqual(original.decode(encoder.encode("US")),
                     encoder.decode(original.encode("US")))
    self.assertEqual(decoded, encoder.decode(output))
예제 #3
0
# now = datetime.datetime.strptime("2014-05-02 13:08:58", "%Y-%m-%d %H:%M:%S")
# print "striptime now =", now
# print "TimeTuple =", now.timetuple()
# print "type", type(now)
# print "now =", de.encode(now)
# nextMonth = datetime.datetime.strptime("2014-06-02 01:01:01", "%Y-%m-%d %H:%M:%S")
# print "next month =", de.encode(nextMonth)
# xmas = datetime.datetime.strptime("2014-12-25 13:08:58", "%Y-%m-%d %H:%M:%S")
# print "xmas =", de.encode(xmas)

# Cateogry Encoding
from nupic.encoders.category import CategoryEncoder

categories = ("cat", "dog", "monkey", "mai")
encoder = CategoryEncoder(w=5, categoryList=categories)
cat = encoder.encode("cat")
dog = encoder.encode("dog")
monkey = encoder.encode("monkey")
mai = encoder.encode("mai")

print "cat =", cat
print "dog =", dog
print "monkey =", monkey
print "mai =", mai
print
print "None =", encoder.encode(None)
print "Unknown =", encoder.encode("unknown")
print
print "Decode cat", encoder.decode(cat)
print "Decode dog", encoder.decode(dog)
print "Decode monkey", encoder.decode(monkey)
de = DateEncoder(season=5)

now = datetime.datetime.strptime("2014-05-02 13:08:58", "%Y-%m-%d %H:%M:%S")
print "now =       ", de.encode(now)
nextMonth = datetime.datetime.strptime("2014-06-02 13:08:58", "%Y-%m-%d %H:%M:%S")
print "next month =", de.encode(nextMonth)
xmas = datetime.datetime.strptime("2014-12-25 13:08:58", "%Y-%m-%d %H:%M:%S")
print "xmas =      ", de.encode(xmas)


from nupic.encoders.category import CategoryEncoder

categories = ("cat", "dog", "monkey", "slow loris")
encoder = CategoryEncoder(w=3, categoryList=categories, forced=True)
cat = encoder.encode("cat")
dog = encoder.encode("dog")
monkey = encoder.encode("monkey")
loris = encoder.encode("slow loris")
print "cat =       ", cat
print "dog =       ", dog
print "monkey =    ", monkey
print "slow loris =", loris

print encoder.decode(cat)
ss=cat+monkey+dog
print encoder.decode(ss)
ss

from nupic.bindings.algorithms import SpatialPooler 
예제 #5
0
    def testCategoryEncoder(self):
        categories = ["ES", "GB", "US"]

        # forced: is not recommended, but is used here for readability.
        # see scalar.py
        e = CategoryEncoder(w=3, categoryList=categories, forced=True)
        output = e.encode("US")
        expected = numpy.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
                               dtype=defaultDtype)
        self.assertTrue(numpy.array_equal(output, expected))

        # Test reverse lookup
        decoded = e.decode(output)
        (fieldsDict, fieldNames) = decoded
        self.assertEqual(len(fieldNames), 1)
        self.assertEqual(len(fieldsDict), 1)
        self.assertEqual(fieldNames[0], fieldsDict.keys()[0])
        (ranges, desc) = fieldsDict.values()[0]
        self.assertEqual(desc, "US")
        self.assertEqual(len(ranges), 1)
        self.assertTrue(numpy.array_equal(ranges[0], [3, 3]))

        # Test topdown compute
        for v in categories:
            output = e.encode(v)
            topDown = e.topDownCompute(output)
            self.assertEqual(topDown.value, v)
            self.assertEqual(topDown.scalar, e.getScalars(v)[0])

            bucketIndices = e.getBucketIndices(v)
            topDown = e.getBucketInfo(bucketIndices)[0]
            self.assertEqual(topDown.value, v)
            self.assertEqual(topDown.scalar, e.getScalars(v)[0])
            self.assertTrue(numpy.array_equal(topDown.encoding, output))
            self.assertEqual(topDown.value,
                             e.getBucketValues()[bucketIndices[0]])

        # ---------------------
        # unknown category
        output = e.encode("NA")
        expected = numpy.array([1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                               dtype=defaultDtype)
        self.assertTrue(numpy.array_equal(output, expected))

        # Test reverse lookup
        decoded = e.decode(output)
        (fieldsDict, fieldNames) = decoded
        self.assertEqual(len(fieldNames), 1)
        self.assertEqual(len(fieldsDict), 1)
        self.assertEqual(fieldNames[0], fieldsDict.keys()[0])
        (ranges, desc) = fieldsDict.values()[0]
        self.assertEqual(len(ranges), 1)
        self.assertTrue(numpy.array_equal(ranges[0], [0, 0]))

        # Test topdown compute
        topDown = e.topDownCompute(output)
        self.assertEqual(topDown.value, UNKNOWN)
        self.assertEqual(topDown.scalar, 0)

        # --------------------------------
        # ES
        output = e.encode("ES")
        expected = numpy.array([0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
                               dtype=defaultDtype)
        self.assertTrue(numpy.array_equal(output, expected))

        # MISSING VALUE
        outputForMissing = e.encode(SENTINEL_VALUE_FOR_MISSING_DATA)
        self.assertEqual(sum(outputForMissing), 0)

        # Test reverse lookup
        decoded = e.decode(output)
        (fieldsDict, fieldNames) = decoded
        self.assertEqual(len(fieldNames), 1)
        self.assertEqual(len(fieldsDict), 1)
        self.assertEqual(fieldNames[0], fieldsDict.keys()[0])
        (ranges, desc) = fieldsDict.values()[0]
        self.assertEqual(len(ranges), 1)
        self.assertTrue(numpy.array_equal(ranges[0], [1, 1]))

        # Test topdown compute
        topDown = e.topDownCompute(output)
        self.assertEqual(topDown.value, "ES")
        self.assertEqual(topDown.scalar, e.getScalars("ES")[0])

        # --------------------------------
        # Multiple categories
        output.fill(1)

        # Test reverse lookup
        decoded = e.decode(output)
        (fieldsDict, fieldNames) = decoded
        self.assertEqual(len(fieldNames), 1)
        self.assertEqual(len(fieldsDict), 1)
        self.assertEqual(fieldNames[0], fieldsDict.keys()[0])
        (ranges, desc) = fieldsDict.values()[0]
        self.assertEqual(len(ranges), 1)
        self.assertTrue(numpy.array_equal(ranges[0], [0, 3]))

        # -------------------------------------------------------------
        # Test with width = 1
        categories = ["cat1", "cat2", "cat3", "cat4", "cat5"]
        # forced: is not recommended, but is used here for readability.
        # see scalar.py
        e = CategoryEncoder(w=1, categoryList=categories, forced=True)
        for cat in categories:
            output = e.encode(cat)
            topDown = e.topDownCompute(output)
            self.assertEqual(topDown.value, cat)
            self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

        # -------------------------------------------------------------
        # Test with width = 9, removing some bits end the encoded output
        categories = ["cat%d" % (x) for x in range(1, 10)]
        # forced: is not recommended, but is used here for readability.
        # see scalar.py
        e = CategoryEncoder(w=9, categoryList=categories, forced=True)
        for cat in categories:
            output = e.encode(cat)
            topDown = e.topDownCompute(output)
            self.assertEqual(topDown.value, cat)
            self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

            # Get rid of 1 bit on the left
            outputNZs = output.nonzero()[0]
            output[outputNZs[0]] = 0
            topDown = e.topDownCompute(output)
            self.assertEqual(topDown.value, cat)
            self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

            # Get rid of 1 bit on the right
            output[outputNZs[0]] = 1
            output[outputNZs[-1]] = 0
            topDown = e.topDownCompute(output)
            self.assertEqual(topDown.value, cat)
            self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

            # Get rid of 4 bits on the left
            output.fill(0)
            output[outputNZs[-5:]] = 1
            topDown = e.topDownCompute(output)
            self.assertEqual(topDown.value, cat)
            self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

            # Get rid of 4 bits on the right
            output.fill(0)
            output[outputNZs[0:5]] = 1
            topDown = e.topDownCompute(output)
            self.assertEqual(topDown.value, cat)
            self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

        # OR together the output of 2 different categories, we should not get
        #  back the mean, but rather one or the other
        output1 = e.encode("cat1")
        output2 = e.encode("cat9")
        output = output1 + output2
        topDown = e.topDownCompute(output)
        self.assertTrue(topDown.scalar == e.getScalars("cat1")[0] \
                or topDown.scalar == e.getScalars("cat9")[0])
예제 #6
0
    def testCategoryEncoder(self):
        verbosity = 0

        print "Testing CategoryEncoder...",
        categories = ["ES", "GB", "US"]

        e = CategoryEncoder(w=3, categoryList=categories)
        output = e.encode("US")
        self.assertTrue(
            (output == numpy.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
                                   dtype=defaultDtype)).all())

        # Test reverse lookup
        decoded = e.decode(output)
        (fieldsDict, fieldNames) = decoded
        self.assertEqual(len(fieldsDict), 1)
        (ranges, desc) = fieldsDict.values()[0]
        self.assertTrue(
            len(ranges) == 1 and numpy.array_equal(ranges[0], [3, 3]))
        print "decodedToStr of", ranges, "=>", e.decodedToStr(decoded)

        # Test topdown compute
        for v in categories:
            output = e.encode(v)
            topDown = e.topDownCompute(output)
            self.assertEqual(topDown.value, v)
            self.assertEqual(topDown.scalar, e.getScalars(v)[0])

            bucketIndices = e.getBucketIndices(v)
            print "bucket index =>", bucketIndices[0]
            topDown = e.getBucketInfo(bucketIndices)[0]
            self.assertEqual(topDown.value, v)
            self.assertEqual(topDown.scalar, e.getScalars(v)[0])
            self.assertTrue((topDown.encoding == output).all())
            self.assertEqual(topDown.value,
                             e.getBucketValues()[bucketIndices[0]])

        # ---------------------
        # unknown category
        output = e.encode("NA")
        self.assertTrue(
            (output == numpy.array([1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                                   dtype=defaultDtype)).all())

        # Test reverse lookup
        decoded = e.decode(output)
        (fieldsDict, fieldNames) = decoded
        self.assertEqual(len(fieldsDict), 1)
        (ranges, desc) = fieldsDict.values()[0]
        self.assertTrue(
            len(ranges) == 1 and numpy.array_equal(ranges[0], [0, 0]))
        print "decodedToStr of", ranges, "=>", e.decodedToStr(decoded)

        # Test topdown compute
        topDown = e.topDownCompute(output)
        self.assertEqual(topDown.value, "<UNKNOWN>")
        self.assertEqual(topDown.scalar, 0)

        # --------------------------------
        # ES
        output = e.encode("ES")
        self.assertTrue(
            (output == numpy.array([0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
                                   dtype=defaultDtype)).all())

        # MISSING VALUE
        outputForMissing = e.encode(SENTINEL_VALUE_FOR_MISSING_DATA)
        self.assertEqual(sum(outputForMissing), 0)

        # Test reverse lookup
        decoded = e.decode(output)
        (fieldsDict, fieldNames) = decoded
        self.assertEqual(len(fieldsDict), 1)
        (ranges, desc) = fieldsDict.values()[0]
        self.assertTrue(
            len(ranges) == 1 and numpy.array_equal(ranges[0], [1, 1]))
        print "decodedToStr of", ranges, "=>", e.decodedToStr(decoded)

        # Test topdown compute
        topDown = e.topDownCompute(output)
        self.assertEqual(topDown.value, "ES")
        self.assertEqual(topDown.scalar, e.getScalars("ES")[0])

        # --------------------------------
        # Multiple categories
        output.fill(1)

        # Test reverse lookup
        decoded = e.decode(output)
        (fieldsDict, fieldNames) = decoded
        self.assertEqual(len(fieldsDict), 1)
        (ranges, desc) = fieldsDict.values()[0]
        self.assertTrue(
            len(ranges) == 1 and numpy.array_equal(ranges[0], [0, 3]))
        print "decodedToStr of", ranges, "=>", e.decodedToStr(decoded)

        # -------------------------------------------------------------
        # Test with width = 1
        categories = ["cat1", "cat2", "cat3", "cat4", "cat5"]
        e = CategoryEncoder(w=1, categoryList=categories)
        for cat in categories:
            output = e.encode(cat)
            topDown = e.topDownCompute(output)
            if verbosity >= 1:
                print cat, "->", output, output.nonzero()[0]
                print " scalarTopDown:", e.encoder.topDownCompute(output)
                print " topdown:", topDown
            self.assertEqual(topDown.value, cat)
            self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

        # -------------------------------------------------------------
        # Test with width = 9, removing some bits end the encoded output
        categories = ["cat%d" % (x) for x in range(1, 10)]
        e = CategoryEncoder(w=9, categoryList=categories)
        for cat in categories:
            output = e.encode(cat)
            topDown = e.topDownCompute(output)
            if verbosity >= 1:
                print cat, "->", output, output.nonzero()[0]
                print " scalarTopDown:", e.encoder.topDownCompute(output)
                print " topdown:", topDown
            self.assertEqual(topDown.value, cat)
            self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

            # Get rid of 1 bit on the left
            outputNZs = output.nonzero()[0]
            output[outputNZs[0]] = 0
            topDown = e.topDownCompute(output)
            if verbosity >= 1:
                print "missing 1 bit on left:", output, output.nonzero()[0]
                print " scalarTopDown:", e.encoder.topDownCompute(output)
                print " topdown:", topDown
            self.assertEqual(topDown.value, cat)
            self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

            # Get rid of 1 bit on the right
            output[outputNZs[0]] = 1
            output[outputNZs[-1]] = 0
            topDown = e.topDownCompute(output)
            if verbosity >= 1:
                print "missing 1 bit on right:", output, output.nonzero()[0]
                print " scalarTopDown:", e.encoder.topDownCompute(output)
                print " topdown:", topDown
            self.assertEqual(topDown.value, cat)
            self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

            # Get rid of 4 bits on the left
            output.fill(0)
            output[outputNZs[-5:]] = 1
            topDown = e.topDownCompute(output)
            if verbosity >= 1:
                print "missing 4 bits on left:", output, output.nonzero()[0]
                print " scalarTopDown:", e.encoder.topDownCompute(output)
                print " topdown:", topDown
            self.assertEqual(topDown.value, cat)
            self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

            # Get rid of 4 bits on the right
            output.fill(0)
            output[outputNZs[0:5]] = 1
            topDown = e.topDownCompute(output)
            if verbosity >= 1:
                print "missing 4 bits on right:", output, output.nonzero()[0]
                print " scalarTopDown:", e.encoder.topDownCompute(output)
                print " topdown:", topDown
            self.assertEqual(topDown.value, cat)
            self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

        # OR together the output of 2 different categories, we should not get
        #  back the mean, but rather one or the other
        output1 = e.encode("cat1")
        output2 = e.encode("cat9")
        output = output1 + output2
        topDown = e.topDownCompute(output)
        if verbosity >= 1:
            print "cat1 + cat9 ->", output, output.nonzero()[0]
            print " scalarTopDown:", e.encoder.topDownCompute(output)
            print " topdown:", topDown
        self.assertTrue(topDown.scalar == e.getScalars("cat1")[0] \
                or topDown.scalar == e.getScalars("cat9")[0])

        print "passed"
예제 #7
0
class SMSequences(object):

    """
  Class generates sensorimotor sequences
  """

    def __init__(
        self,
        sensoryInputElements,
        spatialConfig,
        sensoryInputElementsPool=list("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz0123456789"),
        minDisplacement=1,
        maxDisplacement=1,
        numActiveBitsSensoryInput=9,
        numActiveBitsMotorInput=9,
        seed=42,
        verbosity=False,
        useRandomEncoder=False,
    ):
        """
    @param sensoryInputElements       (list)
        Strings or numbers representing the sensory elements that exist in your
        world. Elements can be repeated if multiple of the same exist.

    @param spatialConfig              (numpy.array)
        Array of size: (1, len(sensoryInputElements), dimension). It has a
        coordinate for every element in sensoryInputElements.

    @param sensoryInputElementsPool   (list)
        List of strings representing a readable version of all possible sensory
        elements in this world. Elements don't need to be in any order and there
        should be no duplicates. By default this contains the set of
        alphanumeric characters.

    @param maxDisplacement            (int)
        Maximum `distance` for a motor command. Distance is defined by the
        largest difference along any coordinate dimension.

    @param minDisplacement            (int)
        Minimum `distance` for a motor command. Distance is defined by the
        largest difference along any coordinate dimension.

    @param numActiveBitsSensoryInput  (int)
        Number of active bits for each sensory input.

    @param numActiveBitsMotorInput    (int)
        Number of active bits for each dimension of the motor input.

    @param seed                       (int)
        Random seed for nupic.bindings.Random.

    @param verbosity                  (int)
        Verbosity

    @param useRandomEncoder           (boolean)
        if True, use the random encoder SDRCategoryEncoder. If False,
        use CategoryEncoder. CategoryEncoder encodes categories using contiguous
        non-overlapping bits for each category, which makes it easier to debug.
    """

        # ---------------------------------------------------------------------------------
        # Store creation parameters
        self.sensoryInputElements = sensoryInputElements
        self.sensoryInputElementsPool = sensoryInputElementsPool
        self.spatialConfig = spatialConfig.astype(int)
        self.spatialLength = len(spatialConfig)
        self.maxDisplacement = maxDisplacement
        self.minDisplacement = minDisplacement
        self.numActiveBitsSensoryInput = numActiveBitsSensoryInput
        self.numActiveBitsMotorInput = numActiveBitsMotorInput
        self.verbosity = verbosity
        self.seed = seed

        self.initialize(useRandomEncoder)

    def initialize(self, useRandomEncoder):
        """
    Initialize the various data structures.
    """
        self.setRandomSeed(self.seed)

        self.dim = numpy.shape(self.spatialConfig)[-1]

        self.spatialMap = dict(zip(map(tuple, list(self.spatialConfig)), self.sensoryInputElements))

        self.lengthMotorInput1D = (2 * self.maxDisplacement + 1) * self.numActiveBitsMotorInput

        uniqueSensoryElements = list(set(self.sensoryInputElementsPool))

        if useRandomEncoder:
            self.sensoryEncoder = SDRCategoryEncoder(
                n=1024, w=self.numActiveBitsSensoryInput, categoryList=uniqueSensoryElements, forced=True
            )
            self.lengthSensoryInput = self.sensoryEncoder.getWidth()

        else:
            self.lengthSensoryInput = (len(self.sensoryInputElementsPool) + 1) * self.numActiveBitsSensoryInput

            self.sensoryEncoder = CategoryEncoder(
                w=self.numActiveBitsSensoryInput, categoryList=uniqueSensoryElements, forced=True
            )

        motorEncoder1D = ScalarEncoder(
            n=self.lengthMotorInput1D,
            w=self.numActiveBitsMotorInput,
            minval=-self.maxDisplacement,
            maxval=self.maxDisplacement,
            clipInput=True,
            forced=True,
        )

        self.motorEncoder = VectorEncoder(length=self.dim, encoder=motorEncoder1D)

    def generateSensorimotorSequence(self, sequenceLength):
        """
    Generate sensorimotor sequences of length sequenceLength.

    @param sequenceLength (int)
        Length of the sensorimotor sequence.

    @return (tuple) Contains:
            sensorySequence       (list)
                Encoded sensory input for whole sequence.

            motorSequence         (list)
                Encoded motor input for whole sequence.

            sensorimotorSequence  (list)
                Encoder sensorimotor input for whole sequence. This is useful
                when you want to give external input to temporal memory.
    """
        motorSequence = []
        sensorySequence = []
        sensorimotorSequence = []
        currentEyeLoc = self.nupicRandomChoice(self.spatialConfig)

        for i in xrange(sequenceLength):

            currentSensoryInput = self.spatialMap[tuple(currentEyeLoc)]

            nextEyeLoc, currentEyeV = self.getNextEyeLocation(currentEyeLoc)

            if self.verbosity:
                print "sensory input = ", currentSensoryInput, "eye location = ", currentEyeLoc, " motor command = ", currentEyeV

            sensoryInput = self.encodeSensoryInput(currentSensoryInput)
            motorInput = self.encodeMotorInput(list(currentEyeV))
            sensorimotorInput = numpy.concatenate((sensoryInput, motorInput))

            sensorySequence.append(sensoryInput)
            motorSequence.append(motorInput)
            sensorimotorSequence.append(sensorimotorInput)

            currentEyeLoc = nextEyeLoc

        return (sensorySequence, motorSequence, sensorimotorSequence)

    def encodeSensorimotorSequence(self, eyeLocs):
        """
    Encode sensorimotor sequence given the eye movements. Sequence will have
    length len(eyeLocs) - 1 because only the differences of eye locations can be
    used to encoder motor commands.

    @param eyeLocs  (list)
        Numpy coordinates describing where the eye is looking.

    @return (tuple) Contains:
            sensorySequence       (list)
                Encoded sensory input for whole sequence.

            motorSequence         (list)
                Encoded motor input for whole sequence.

            sensorimotorSequence  (list)
                Encoder sensorimotor input for whole sequence. This is useful
                when you want to give external input to temporal memory.
    """
        sequenceLength = len(eyeLocs) - 1

        motorSequence = []
        sensorySequence = []
        sensorimotorSequence = []

        for i in xrange(sequenceLength):
            currentEyeLoc = eyeLocs[i]
            nextEyeLoc = eyeLocs[i + 1]

            currentSensoryInput = self.spatialMap[currentEyeLoc]

            currentEyeV = nextEyeLoc - currentEyeLoc

            if self.verbosity:
                print "sensory input = ", currentSensoryInput, "eye location = ", currentEyeLoc, " motor command = ", currentEyeV

            sensoryInput = self.encodeSensoryInput(currentSensoryInput)
            motorInput = self.encodeMotorInput(list(currentEyeV))
            sensorimotorInput = numpy.concatenate((sensoryInput, motorInput))

            sensorySequence.append(sensoryInput)
            motorSequence.append(motorInput)
            sensorimotorSequence.append(sensorimotorInput)

        return (sensorySequence, motorSequence, sensorimotorSequence)

    def getNextEyeLocation(self, currentEyeLoc):
        """
    Generate next eye location based on current eye location.

    @param currentEyeLoc (numpy.array)
        Current coordinate describing the eye location in the world.

    @return (tuple) Contains:
            nextEyeLoc  (numpy.array)
                Coordinate of the next eye location.

            eyeDiff     (numpy.array)
                Vector describing change from currentEyeLoc to nextEyeLoc.
    """
        possibleEyeLocs = []
        for loc in self.spatialConfig:
            shift = abs(max(loc - currentEyeLoc))
            if self.minDisplacement <= shift <= self.maxDisplacement:
                possibleEyeLocs.append(loc)

        nextEyeLoc = self.nupicRandomChoice(possibleEyeLocs)

        eyeDiff = nextEyeLoc - currentEyeLoc

        return nextEyeLoc, eyeDiff

    def setRandomSeed(self, seed):
        """
    Reset the nupic random generator. This is necessary to reset random seed to
    generate new sequences.

    @param seed       (int)
        Seed for nupic.bindings.Random.
    """
        self.seed = seed
        self._random = Random()
        self._random.setSeed(seed)

    def nupicRandomChoice(self, array):
        """
    Chooses a random element from an array using the nupic random number
    generator.

    @param array  (list or numpy.array)
        Array to choose random element from.

    @return       (element)
        Element chosen at random.
    """
        return array[self._random.getUInt32(len(array))]

    def encodeMotorInput(self, motorInput):
        """
    Encode motor command to bit vector.

    @param motorInput (1D numpy.array)
        Motor command to be encoded.

    @return           (1D numpy.array)
        Encoded motor command.
    """
        if not hasattr(motorInput, "__iter__"):
            motorInput = list([motorInput])

        return self.motorEncoder.encode(motorInput)

    def decodeMotorInput(self, motorInputPattern):
        """
    Decode motor command from bit vector.

    @param motorInputPattern (1D numpy.array)
        Encoded motor command.

    @return                  (1D numpy.array)
        Decoded motor command.

    """
        key = self.motorEncoder.decode(motorInputPattern)[0].keys()[0]
        motorCommand = self.motorEncoder.decode(motorInputPattern)[0][key][1][0]
        return motorCommand

    def encodeSensoryInput(self, sensoryInputElement):
        """
    Encode sensory input to bit vector

    @param sensoryElement (1D numpy.array)
        Sensory element to be encoded.

    @return               (1D numpy.array)
        Encoded sensory element.
    """
        return self.sensoryEncoder.encode(sensoryInputElement)

    def decodeSensoryInput(self, sensoryInputPattern):
        """
    Decode sensory input from bit vector.

    @param sensoryInputPattern  (1D numpy.array)
        Encoded sensory element.

    @return                     (1D numpy.array)
        Decoded sensory element.
    """
        return self.sensoryEncoder.decode(sensoryInputPattern)[0]["category"][1]

    def printSensoryCodingScheme(self):
        """
    Print sensory inputs along with their encoded versions.
    """
        print "\nsensory coding scheme: "
        for loc in self.spatialConfig:
            sensoryElement = self.spatialMap[tuple(loc)]
            print sensoryElement, "%s : " % loc,
            printSequence(self.encodeSensoryInput(sensoryElement))

    def printMotorCodingScheme(self):
        """
    Print motor commands (displacement vector) along with their encoded
    versions.
    """
        print "\nmotor coding scheme: "
        self.build(self.dim, [])

    def build(self, n, vec):
        """
    Recursive function to help print motor coding scheme.
    """
        for i in range(-self.maxDisplacement, self.maxDisplacement + 1):
            next = vec + [i]
            if n == 1:
                print "{:>5}\t".format(next), " = ",
                printSequence(self.encodeMotorInput(next))
            else:
                self.build(n - 1, next)
예제 #8
0
파일: category_test.py 프로젝트: Afey/nupic
  def testCategoryEncoder(self):
    categories = ["ES", "GB", "US"]

    # forced: is not recommended, but is used here for readability.
    # see scalar.py
    e = CategoryEncoder(w=3, categoryList=categories, forced=True)
    output = e.encode("US")
    expected = numpy.array([0,0,0,0,0,0,0,0,0,1,1,1], dtype=defaultDtype)
    self.assertTrue(numpy.array_equal(output, expected))

    # Test reverse lookup
    decoded = e.decode(output)
    (fieldsDict, fieldNames) = decoded
    self.assertEqual(len(fieldNames), 1)
    self.assertEqual(len(fieldsDict), 1)
    self.assertEqual(fieldNames[0], fieldsDict.keys()[0])
    (ranges, desc) = fieldsDict.values()[0]
    self.assertEqual(desc, "US")
    self.assertEqual(len(ranges), 1)
    self.assertTrue(numpy.array_equal(ranges[0], [3, 3]))

    # Test topdown compute
    for v in categories:
      output = e.encode(v)
      topDown = e.topDownCompute(output)
      self.assertEqual(topDown.value, v)
      self.assertEqual(topDown.scalar, e.getScalars(v)[0])

      bucketIndices = e.getBucketIndices(v)
      topDown = e.getBucketInfo(bucketIndices)[0]
      self.assertEqual(topDown.value, v)
      self.assertEqual(topDown.scalar, e.getScalars(v)[0])
      self.assertTrue(numpy.array_equal(topDown.encoding, output))
      self.assertEqual(topDown.value, e.getBucketValues()[bucketIndices[0]])



    # ---------------------
    # unknown category
    output = e.encode("NA")
    expected = numpy.array([1,1,1,0,0,0,0,0,0,0,0,0], dtype=defaultDtype)
    self.assertTrue(numpy.array_equal(output, expected))

    # Test reverse lookup
    decoded = e.decode(output)
    (fieldsDict, fieldNames) = decoded
    self.assertEqual(len(fieldNames), 1)
    self.assertEqual(len(fieldsDict), 1)
    self.assertEqual(fieldNames[0], fieldsDict.keys()[0])
    (ranges, desc) = fieldsDict.values()[0]
    self.assertEqual(len(ranges), 1)
    self.assertTrue(numpy.array_equal(ranges[0], [0, 0]))

    # Test topdown compute
    topDown = e.topDownCompute(output)
    self.assertEqual(topDown.value, UNKNOWN)
    self.assertEqual(topDown.scalar, 0)


    # --------------------------------
    # ES
    output = e.encode("ES")
    expected = numpy.array([0,0,0,1,1,1,0,0,0,0,0,0], dtype=defaultDtype)
    self.assertTrue(numpy.array_equal(output, expected))

    # MISSING VALUE
    outputForMissing = e.encode(SENTINEL_VALUE_FOR_MISSING_DATA)
    self.assertEqual(sum(outputForMissing), 0)

    # Test reverse lookup
    decoded = e.decode(output)
    (fieldsDict, fieldNames) = decoded
    self.assertEqual(len(fieldNames), 1)
    self.assertEqual(len(fieldsDict), 1)
    self.assertEqual(fieldNames[0], fieldsDict.keys()[0])
    (ranges, desc) = fieldsDict.values()[0]
    self.assertEqual(len(ranges), 1)
    self.assertTrue(numpy.array_equal(ranges[0], [1, 1]))

    # Test topdown compute
    topDown = e.topDownCompute(output)
    self.assertEqual(topDown.value, "ES")
    self.assertEqual(topDown.scalar, e.getScalars("ES")[0])


    # --------------------------------
    # Multiple categories
    output.fill(1)

    # Test reverse lookup
    decoded = e.decode(output)
    (fieldsDict, fieldNames) = decoded
    self.assertEqual(len(fieldNames), 1)
    self.assertEqual(len(fieldsDict), 1)
    self.assertEqual(fieldNames[0], fieldsDict.keys()[0])
    (ranges, desc) = fieldsDict.values()[0]
    self.assertEqual(len(ranges), 1)
    self.assertTrue(numpy.array_equal(ranges[0], [0, 3]))


    # -------------------------------------------------------------
    # Test with width = 1
    categories = ["cat1", "cat2", "cat3", "cat4", "cat5"]
      # forced: is not recommended, but is used here for readability.
      # see scalar.py
    e = CategoryEncoder(w=1, categoryList=categories, forced=True)
    for cat in categories:
      output = e.encode(cat)
      topDown = e.topDownCompute(output)
      self.assertEqual(topDown.value, cat)
      self.assertEqual(topDown.scalar, e.getScalars(cat)[0])


    # -------------------------------------------------------------
    # Test with width = 9, removing some bits end the encoded output
    categories = ["cat%d" % (x) for x in range(1, 10)]
     # forced: is not recommended, but is used here for readability.
     # see scalar.py
    e = CategoryEncoder(w=9, categoryList=categories, forced=True)
    for cat in categories:
      output = e.encode(cat)
      topDown = e.topDownCompute(output)
      self.assertEqual(topDown.value, cat)
      self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

      # Get rid of 1 bit on the left
      outputNZs = output.nonzero()[0]
      output[outputNZs[0]] = 0
      topDown = e.topDownCompute(output)
      self.assertEqual(topDown.value, cat)
      self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

      # Get rid of 1 bit on the right
      output[outputNZs[0]] = 1
      output[outputNZs[-1]] = 0
      topDown = e.topDownCompute(output)
      self.assertEqual(topDown.value, cat)
      self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

      # Get rid of 4 bits on the left
      output.fill(0)
      output[outputNZs[-5:]] = 1
      topDown = e.topDownCompute(output)
      self.assertEqual(topDown.value, cat)
      self.assertEqual(topDown.scalar, e.getScalars(cat)[0])

      # Get rid of 4 bits on the right
      output.fill(0)
      output[outputNZs[0:5]] = 1
      topDown = e.topDownCompute(output)
      self.assertEqual(topDown.value, cat)
      self.assertEqual(topDown.scalar, e.getScalars(cat)[0])


    # OR together the output of 2 different categories, we should not get
    #  back the mean, but rather one or the other
    output1 = e.encode("cat1")
    output2 = e.encode("cat9")
    output = output1 + output2
    topDown = e.topDownCompute(output)
    self.assertTrue(topDown.scalar == e.getScalars("cat1")[0] \
            or topDown.scalar == e.getScalars("cat9")[0])
예제 #9
0
  def testCategoryEncoder(self):
      verbosity = 0

      print "Testing CategoryEncoder...",
      categories = ["ES", "GB", "US"]

      e = CategoryEncoder(w=3, categoryList=categories)
      output = e.encode("US")
      assert (output == numpy.array([0,0,0,0,0,0,0,0,0,1,1,1], dtype=defaultDtype)).all()

      # Test reverse lookup
      decoded = e.decode(output)
      (fieldsDict, fieldNames) = decoded
      assert len(fieldsDict) == 1
      (ranges, desc) = fieldsDict.values()[0]
      assert len(ranges) == 1 and numpy.array_equal(ranges[0], [3,3])
      print "decodedToStr of", ranges, "=>", e.decodedToStr(decoded)

      # Test topdown compute
      for v in categories:
        output = e.encode(v)
        topDown = e.topDownCompute(output)
        assert topDown.value == v
        assert topDown.scalar == e.getScalars(v)[0]

        bucketIndices = e.getBucketIndices(v)
        print "bucket index =>", bucketIndices[0]
        topDown = e.getBucketInfo(bucketIndices)[0]
        assert topDown.value == v
        assert topDown.scalar == e.getScalars(v)[0]
        assert (topDown.encoding == output).all()
        assert topDown.value == e.getBucketValues()[bucketIndices[0]]



      # ---------------------
      # unknown category
      output = e.encode("NA")
      assert (output == numpy.array([1,1,1,0,0,0,0,0,0,0,0,0], dtype=defaultDtype)).all()

      # Test reverse lookup
      decoded = e.decode(output)
      (fieldsDict, fieldNames) = decoded
      assert len(fieldsDict) == 1
      (ranges, desc) = fieldsDict.values()[0]
      assert len(ranges) == 1 and numpy.array_equal(ranges[0], [0,0])
      print "decodedToStr of", ranges, "=>", e.decodedToStr(decoded)

      # Test topdown compute
      topDown = e.topDownCompute(output)
      assert topDown.value == "<UNKNOWN>"
      assert topDown.scalar == 0


      # --------------------------------
      # ES
      output = e.encode("ES")
      assert (output == numpy.array([0,0,0,1,1,1,0,0,0,0,0,0], dtype=defaultDtype)).all()

      # MISSING VALUE
      outputForMissing = e.encode(SENTINEL_VALUE_FOR_MISSING_DATA)
      assert sum(outputForMissing) == 0

      # Test reverse lookup
      decoded = e.decode(output)
      (fieldsDict, fieldNames) = decoded
      assert len(fieldsDict) == 1
      (ranges, desc) = fieldsDict.values()[0]
      assert len(ranges) == 1 and numpy.array_equal(ranges[0], [1,1])
      print "decodedToStr of", ranges, "=>", e.decodedToStr(decoded)

      # Test topdown compute
      topDown = e.topDownCompute(output)
      assert topDown.value == "ES"
      assert topDown.scalar == e.getScalars("ES")[0]


      # --------------------------------
      # Multiple categories
      output.fill(1)

      # Test reverse lookup
      decoded = e.decode(output)
      (fieldsDict, fieldNames) = decoded
      assert len(fieldsDict) == 1
      (ranges, desc) = fieldsDict.values()[0]
      assert len(ranges) == 1 and numpy.array_equal(ranges[0], [0,3])
      print "decodedToStr of", ranges, "=>", e.decodedToStr(decoded)



      # -------------------------------------------------------------
      # Test with width = 1
      categories = ["cat1", "cat2", "cat3", "cat4", "cat5"]
      e = CategoryEncoder(w=1, categoryList=categories)
      for cat in categories:
        output = e.encode(cat)
        topDown = e.topDownCompute(output)
        if verbosity >= 1:
          print cat, "->", output, output.nonzero()[0]
          print " scalarTopDown:", e.encoder.topDownCompute(output)
          print " topdown:", topDown
        assert topDown.value == cat
        assert topDown.scalar == e.getScalars(cat)[0]


      # -------------------------------------------------------------
      # Test with width = 9, removing some bits end the encoded output
      categories = ["cat%d" % (x) for x in range(1, 10)]
      e = CategoryEncoder(w=9, categoryList=categories)
      for cat in categories:
        output = e.encode(cat)
        topDown = e.topDownCompute(output)
        if verbosity >= 1:
          print cat, "->", output, output.nonzero()[0]
          print " scalarTopDown:", e.encoder.topDownCompute(output)
          print " topdown:", topDown
        assert topDown.value == cat
        assert topDown.scalar == e.getScalars(cat)[0]

        # Get rid of 1 bit on the left
        outputNZs = output.nonzero()[0]
        output[outputNZs[0]] = 0
        topDown = e.topDownCompute(output)
        if verbosity >= 1:
          print "missing 1 bit on left:", output, output.nonzero()[0]
          print " scalarTopDown:", e.encoder.topDownCompute(output)
          print " topdown:", topDown
        assert topDown.value == cat
        assert topDown.scalar == e.getScalars(cat)[0]

        # Get rid of 1 bit on the right
        output[outputNZs[0]] = 1
        output[outputNZs[-1]] = 0
        topDown = e.topDownCompute(output)
        if verbosity >= 1:
          print "missing 1 bit on right:", output, output.nonzero()[0]
          print " scalarTopDown:", e.encoder.topDownCompute(output)
          print " topdown:", topDown
        assert topDown.value == cat
        assert topDown.scalar == e.getScalars(cat)[0]

        # Get rid of 4 bits on the left
        output.fill(0)
        output[outputNZs[-5:]] = 1
        topDown = e.topDownCompute(output)
        if verbosity >= 1:
          print "missing 4 bits on left:", output, output.nonzero()[0]
          print " scalarTopDown:", e.encoder.topDownCompute(output)
          print " topdown:", topDown
        assert topDown.value == cat
        assert topDown.scalar == e.getScalars(cat)[0]

        # Get rid of 4 bits on the right
        output.fill(0)
        output[outputNZs[0:5]] = 1
        topDown = e.topDownCompute(output)
        if verbosity >= 1:
          print "missing 4 bits on right:", output, output.nonzero()[0]
          print " scalarTopDown:", e.encoder.topDownCompute(output)
          print " topdown:", topDown
        assert topDown.value == cat
        assert topDown.scalar == e.getScalars(cat)[0]


      # OR together the output of 2 different categories, we should not get
      #  back the mean, but rather one or the other
      output1 = e.encode("cat1")
      output2 = e.encode("cat9")
      output = output1 + output2
      topDown = e.topDownCompute(output)
      if verbosity >= 1:
        print "cat1 + cat9 ->", output, output.nonzero()[0]
        print " scalarTopDown:", e.encoder.topDownCompute(output)
        print " topdown:", topDown
      assert topDown.scalar == e.getScalars("cat1")[0] \
              or topDown.scalar == e.getScalars("cat9")[0]



      print "passed"
예제 #10
0
class RandomizedLetterEncoder(CustomEncoder):
    """
    Encoder for strings. It encodes each letter into binary and appends
    a random chain of bits at the end.
    """
    def __init__(self, width, nRandBits, actBitsPerLetter=1):
        """
        @param width: The size of the encoded list of bits output.
        @param nRandBits: The number of random bits that the output
            will have after the binary representation of the
            string. 0 for a pure string to binary conversion.
        @param actBitsPerLetter: The number of active bits per letter.
        """

        random.seed(SEED)

        if nRandBits > width:
            raise ValueError("nRandBits can't be greater than width.")
        if actBitsPerLetter < 1:
            raise ValueError("There must be at least 1 active bit per letter")

        self.width = width
        self.nRandBits = nRandBits
        self.actBitsPerLetter = actBitsPerLetter
        self.alreadyEncoded = dict()
        self.catEnc = CategoryEncoder(self.actBitsPerLetter,
                                      list(string.ascii_lowercase),
                                      forced=True)

    def getWidth(self):

        return self.width

    def encode(self, inputData, verbose=0):
        """
        @param inputData
        @param verbose=0
        """

        strBinaryLen = len(inputData) * self.catEnc.getWidth()

        if (strBinaryLen + self.nRandBits) > self.width:
            raise ValueError("The string is too long to be encoded with the"\
                "current parameters.")
        strBinary = []

        # Encode each char of the string
        for letter in inputData:
            strBinary.extend(list(self.catEnc.encode(letter)))

        if inputData not in self.alreadyEncoded:
            self.alreadyEncoded[inputData] = (
                [random.randrange(strBinaryLen, self.width) \
                        for _ in xrange(self.nRandBits)],
                (len(self.alreadyEncoded) + 1)
            )

        output = numpy.zeros((self.width, ), dtype=numpy.uint8)
        output[:strBinaryLen] = strBinary
        output[self.alreadyEncoded[inputData][0]] = 1
        return output
예제 #11
0
def wait():
    raw_input("Press Enter to continue...")


os.system("clear")
print "Executing Matt's HTM Experiments\n"
print "initializing categories"
inputCategoriesWindowWidth = 3
inputCategoriesRaw = ("cat", "dog", "penguin", "potato")
categoryEncoder = CategoryEncoder(w=inputCategoriesWindowWidth,
                                  categoryList=inputCategoriesRaw,
                                  forced=True,
                                  verbosity=0)
inputCategories = {}
for category in inputCategoriesRaw:
    inputCategories[category] = categoryEncoder.encode(category)
    print "   " + (category + ":").ljust(10), inputCategories[category]
print "   " + "UNKNOWN:".ljust(10), categoryEncoder.encode("UNKNOWN")
print "categories initialized\n"

print "initializing spatial pooler"
spatialPoolerInputWidth = (len(inputCategoriesRaw) +
                           1) * inputCategoriesWindowWidth
spatialPoolerColumnHeight = 8

spatialPooler = SpatialPooler(inputDimensions=spatialPoolerInputWidth,
                              columnDimensions=spatialPoolerColumnHeight,
                              potentialRadius=15,
                              numActiveColumnsPerInhArea=1,
                              globalInhibition=True,
                              synPermActiveInc=0.03,
예제 #12
0
de = DateEncoder(season=5)
file1 = open("time_file.txt", "r")
cpt = 0
for line in file1:
    if cpt == 0:
        line = line.replace("/", "-")
        line = line.replace("19-", "2019-")
        #print line,
        lines = '2019-06-03 00:00:16'
        now = datetime.datetime.strptime(lines, "%Y-%m-%d %H:%M:%S")
        print "now =       ", de.encode(now)
    cpt += 1

categories = ('info', 'error', 'warning')
encoder = CategoryEncoder(w=3, categoryList=categories, forced=True)
info = encoder.encode("info")
error = encoder.encode("error")
warning = encoder.encode("warning")
#print "info =       ", info
#print "error =       ", error
#print "warning =       ", warning
sp = SpatialPooler(inputDimensions=(len(info), ),
                   columnDimensions=(3, ),
                   potentialRadius=15,
                   numActiveColumnsPerInhArea=1,
                   globalInhibition=True,
                   synPermActiveInc=0.03,
                   potentialPct=1.0)
import numpy
for column in xrange(3):
    connected = numpy.zeros((len(info), ), dtype="int")
예제 #13
0
class SMSequences(object):
    """
  Class generates sensorimotor sequences
  """
    def __init__(self,
                 sensoryInputElements,
                 spatialConfig,
                 sensoryInputElementsPool=list(
                     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                     "abcdefghijklmnopqrstuvwxyz0123456789"),
                 minDisplacement=1,
                 maxDisplacement=1,
                 numActiveBitsSensoryInput=9,
                 numActiveBitsMotorInput=9,
                 seed=42,
                 verbosity=False,
                 useRandomEncoder=False):
        """
    @param sensoryInputElements       (list)
        Strings or numbers representing the sensory elements that exist in your
        world. Elements can be repeated if multiple of the same exist.

    @param spatialConfig              (numpy.array)
        Array of size: (1, len(sensoryInputElements), dimension). It has a
        coordinate for every element in sensoryInputElements.

    @param sensoryInputElementsPool   (list)
        List of strings representing a readable version of all possible sensory
        elements in this world. Elements don't need to be in any order and there
        should be no duplicates. By default this contains the set of
        alphanumeric characters.

    @param maxDisplacement            (int)
        Maximum `distance` for a motor command. Distance is defined by the
        largest difference along any coordinate dimension.

    @param minDisplacement            (int)
        Minimum `distance` for a motor command. Distance is defined by the
        largest difference along any coordinate dimension.

    @param numActiveBitsSensoryInput  (int)
        Number of active bits for each sensory input.

    @param numActiveBitsMotorInput    (int)
        Number of active bits for each dimension of the motor input.

    @param seed                       (int)
        Random seed for nupic.bindings.Random.

    @param verbosity                  (int)
        Verbosity

    @param useRandomEncoder           (boolean)
        if True, use the random encoder SDRCategoryEncoder. If False,
        use CategoryEncoder. CategoryEncoder encodes categories using contiguous
        non-overlapping bits for each category, which makes it easier to debug.
    """

        #---------------------------------------------------------------------------------
        # Store creation parameters
        self.sensoryInputElements = sensoryInputElements
        self.sensoryInputElementsPool = sensoryInputElementsPool
        self.spatialConfig = spatialConfig.astype(int)
        self.spatialLength = len(spatialConfig)
        self.maxDisplacement = maxDisplacement
        self.minDisplacement = minDisplacement
        self.numActiveBitsSensoryInput = numActiveBitsSensoryInput
        self.numActiveBitsMotorInput = numActiveBitsMotorInput
        self.verbosity = verbosity
        self.seed = seed

        self.initialize(useRandomEncoder)

    def initialize(self, useRandomEncoder):
        """
    Initialize the various data structures.
    """
        self.setRandomSeed(self.seed)

        self.dim = numpy.shape(self.spatialConfig)[-1]

        self.spatialMap = dict(
            zip(map(tuple, list(self.spatialConfig)),
                self.sensoryInputElements))

        self.lengthMotorInput1D = (2*self.maxDisplacement + 1) * \
                                                        self.numActiveBitsMotorInput

        uniqueSensoryElements = list(set(self.sensoryInputElementsPool))

        if useRandomEncoder:
            self.sensoryEncoder = SDRCategoryEncoder(
                n=1024,
                w=self.numActiveBitsSensoryInput,
                categoryList=uniqueSensoryElements,
                forced=True)
            self.lengthSensoryInput = self.sensoryEncoder.getWidth()

        else:
            self.lengthSensoryInput = (len(self.sensoryInputElementsPool)+1) * \
                                                self.numActiveBitsSensoryInput

            self.sensoryEncoder = CategoryEncoder(
                w=self.numActiveBitsSensoryInput,
                categoryList=uniqueSensoryElements,
                forced=True)

        motorEncoder1D = ScalarEncoder(n=self.lengthMotorInput1D,
                                       w=self.numActiveBitsMotorInput,
                                       minval=-self.maxDisplacement,
                                       maxval=self.maxDisplacement,
                                       clipInput=True,
                                       forced=True)

        self.motorEncoder = VectorEncoder(length=self.dim,
                                          encoder=motorEncoder1D)

    def generateSensorimotorSequence(self, sequenceLength):
        """
    Generate sensorimotor sequences of length sequenceLength.

    @param sequenceLength (int)
        Length of the sensorimotor sequence.

    @return (tuple) Contains:
            sensorySequence       (list)
                Encoded sensory input for whole sequence.

            motorSequence         (list)
                Encoded motor input for whole sequence.

            sensorimotorSequence  (list)
                Encoder sensorimotor input for whole sequence. This is useful
                when you want to give external input to temporal memory.
    """
        motorSequence = []
        sensorySequence = []
        sensorimotorSequence = []
        currentEyeLoc = self.nupicRandomChoice(self.spatialConfig)

        for i in xrange(sequenceLength):

            currentSensoryInput = self.spatialMap[tuple(currentEyeLoc)]

            nextEyeLoc, currentEyeV = self.getNextEyeLocation(currentEyeLoc)

            if self.verbosity:
                print "sensory input = ", currentSensoryInput, \
                  "eye location = ", currentEyeLoc, \
                  " motor command = ", currentEyeV

            sensoryInput = self.encodeSensoryInput(currentSensoryInput)
            motorInput = self.encodeMotorInput(list(currentEyeV))
            sensorimotorInput = numpy.concatenate((sensoryInput, motorInput))

            sensorySequence.append(sensoryInput)
            motorSequence.append(motorInput)
            sensorimotorSequence.append(sensorimotorInput)

            currentEyeLoc = nextEyeLoc

        return (sensorySequence, motorSequence, sensorimotorSequence)

    def encodeSensorimotorSequence(self, eyeLocs):
        """
    Encode sensorimotor sequence given the eye movements. Sequence will have
    length len(eyeLocs) - 1 because only the differences of eye locations can be
    used to encoder motor commands.

    @param eyeLocs  (list)
        Numpy coordinates describing where the eye is looking.

    @return (tuple) Contains:
            sensorySequence       (list)
                Encoded sensory input for whole sequence.

            motorSequence         (list)
                Encoded motor input for whole sequence.

            sensorimotorSequence  (list)
                Encoder sensorimotor input for whole sequence. This is useful
                when you want to give external input to temporal memory.
    """
        sequenceLength = len(eyeLocs) - 1

        motorSequence = []
        sensorySequence = []
        sensorimotorSequence = []

        for i in xrange(sequenceLength):
            currentEyeLoc = eyeLocs[i]
            nextEyeLoc = eyeLocs[i + 1]

            currentSensoryInput = self.spatialMap[currentEyeLoc]

            currentEyeV = nextEyeLoc - currentEyeLoc

            if self.verbosity:
                print "sensory input = ", currentSensoryInput, \
                    "eye location = ", currentEyeLoc, \
                    " motor command = ", currentEyeV

            sensoryInput = self.encodeSensoryInput(currentSensoryInput)
            motorInput = self.encodeMotorInput(list(currentEyeV))
            sensorimotorInput = numpy.concatenate((sensoryInput, motorInput))

            sensorySequence.append(sensoryInput)
            motorSequence.append(motorInput)
            sensorimotorSequence.append(sensorimotorInput)

        return (sensorySequence, motorSequence, sensorimotorSequence)

    def getNextEyeLocation(self, currentEyeLoc):
        """
    Generate next eye location based on current eye location.

    @param currentEyeLoc (numpy.array)
        Current coordinate describing the eye location in the world.

    @return (tuple) Contains:
            nextEyeLoc  (numpy.array)
                Coordinate of the next eye location.

            eyeDiff     (numpy.array)
                Vector describing change from currentEyeLoc to nextEyeLoc.
    """
        possibleEyeLocs = []
        for loc in self.spatialConfig:
            shift = abs(max(loc - currentEyeLoc))
            if self.minDisplacement <= shift <= self.maxDisplacement:
                possibleEyeLocs.append(loc)

        nextEyeLoc = self.nupicRandomChoice(possibleEyeLocs)

        eyeDiff = nextEyeLoc - currentEyeLoc

        return nextEyeLoc, eyeDiff

    def setRandomSeed(self, seed):
        """
    Reset the nupic random generator. This is necessary to reset random seed to
    generate new sequences.

    @param seed       (int)
        Seed for nupic.bindings.Random.
    """
        self.seed = seed
        self._random = Random()
        self._random.setSeed(seed)

    def nupicRandomChoice(self, array):
        """
    Chooses a random element from an array using the nupic random number
    generator.

    @param array  (list or numpy.array)
        Array to choose random element from.

    @return       (element)
        Element chosen at random.
    """
        return array[self._random.getUInt32(len(array))]

    def encodeMotorInput(self, motorInput):
        """
    Encode motor command to bit vector.

    @param motorInput (1D numpy.array)
        Motor command to be encoded.

    @return           (1D numpy.array)
        Encoded motor command.
    """
        if not hasattr(motorInput, "__iter__"):
            motorInput = list([motorInput])

        return self.motorEncoder.encode(motorInput)

    def decodeMotorInput(self, motorInputPattern):
        """
    Decode motor command from bit vector.

    @param motorInputPattern (1D numpy.array)
        Encoded motor command.

    @return                  (1D numpy.array)
        Decoded motor command.

    """
        key = self.motorEncoder.decode(motorInputPattern)[0].keys()[0]
        motorCommand = self.motorEncoder.decode(
            motorInputPattern)[0][key][1][0]
        return motorCommand

    def encodeSensoryInput(self, sensoryInputElement):
        """
    Encode sensory input to bit vector

    @param sensoryElement (1D numpy.array)
        Sensory element to be encoded.

    @return               (1D numpy.array)
        Encoded sensory element.
    """
        return self.sensoryEncoder.encode(sensoryInputElement)

    def decodeSensoryInput(self, sensoryInputPattern):
        """
    Decode sensory input from bit vector.

    @param sensoryInputPattern  (1D numpy.array)
        Encoded sensory element.

    @return                     (1D numpy.array)
        Decoded sensory element.
    """
        return self.sensoryEncoder.decode(
            sensoryInputPattern)[0]['category'][1]

    def printSensoryCodingScheme(self):
        """
    Print sensory inputs along with their encoded versions.
    """
        print "\nsensory coding scheme: "
        for loc in self.spatialConfig:
            sensoryElement = self.spatialMap[tuple(loc)]
            print sensoryElement, "%s : " % loc,
            printSequence(self.encodeSensoryInput(sensoryElement))

    def printMotorCodingScheme(self):
        """
    Print motor commands (displacement vector) along with their encoded
    versions.
    """
        print "\nmotor coding scheme: "
        self.build(self.dim, [])

    def build(self, n, vec):
        """
    Recursive function to help print motor coding scheme.
    """
        for i in range(-self.maxDisplacement, self.maxDisplacement + 1):
            next = vec + [i]
            if n == 1:
                print '{:>5}\t'.format(next), " = ",
                printSequence(self.encodeMotorInput(next))
            else:
                self.build(n - 1, next)
예제 #14
0
    #            print("Given: {}, predicted:\n{}".format(data, retVal['actualValues']))
    ##            print("Given: {}, predicted:\n{}".format(data, retVal))
    #            print("Best one: {}".format(
    #                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,
예제 #15
0
class RandomizedLetterEncoder(CustomEncoder):
    """
    Encoder for strings. It encodes each letter into binary and appends
    a random chain of bits at the end.
    """

    def __init__(self, width, nRandBits, actBitsPerLetter=1):
        """
        @param width: The size of the encoded list of bits output.
        @param nRandBits: The number of random bits that the output
            will have after the binary representation of the
            string. 0 for a pure string to binary conversion.
        @param actBitsPerLetter: The number of active bits per letter.
        """

        random.seed(SEED)

        if nRandBits > width:
            raise ValueError("nRandBits can't be greater than width.")
        if actBitsPerLetter < 1:
            raise ValueError("There must be at least 1 active bit per letter")

        self.width = width
        self.nRandBits = nRandBits
        self.actBitsPerLetter = actBitsPerLetter
        self.alreadyEncoded = dict()
        self.catEnc = CategoryEncoder(self.actBitsPerLetter,
                                      list(string.ascii_lowercase),
                                      forced=True)

    def getWidth(self):

        return self.width

    def encode(self, inputData, verbose=0):
        """
        @param inputData
        @param verbose=0
        """

        strBinaryLen = len(inputData) * self.catEnc.getWidth()

        if (strBinaryLen + self.nRandBits) > self.width:
            raise ValueError("The string is too long to be encoded with the"\
                "current parameters.")
        strBinary = []

        # Encode each char of the string 
        for letter in inputData:
            strBinary.extend(list(self.catEnc.encode(letter)))

        if inputData not in self.alreadyEncoded:
            self.alreadyEncoded[inputData] = (
                [random.randrange(strBinaryLen, self.width) \
                        for _ in xrange(self.nRandBits)],
                (len(self.alreadyEncoded) + 1)
            )

        output = numpy.zeros((self.width,), dtype=numpy.uint8)
        output[:strBinaryLen] = strBinary
        output[self.alreadyEncoded[inputData][0]] = 1
        return output