Saturday, December 18, 2010

Practical AI: Hello World Bitworm Example with Numenta's Nupic (HTM for the masses)


Jeff Hawkins of Numenta and previously the creator of Palm Inc has shifted his focus from mobile computing to developing a sophisticated AI system. He has always been passionate about artificial intelligence. Jeff knew early on that the trends in AI research weren't very promising. He had concentrated his AI interest in human biology and neuroscience. Numenta has patented HTM (Hierarchical Temporal Memory) technology. According to Jeff Hawkins, you cannot mimic brain functions without including a hierarchical system of memory. The lower level has more input/output nodes than the level above it. According to Jeff, you must also take into account "temporal" memory. For example, the human brain has many parts of the brain that handle visual information. The brain may be able to detect a particular object but also factor in the time that the visual event occurred. If you are at the zoo, your brain predicts that you will see animals and animals in cages at the zoo. It is rare that you see a plane take off or land in the middle of your zoo visit. You would have had previous memories or seen pictures of the zoo in the past and parts of your brain activate other things associated the zoo. The context in time is a visit to the zoo. The memory of a zoo visit is probably in a different area of the brain than a trip to an airport. In the case of an airport, you expect to see planes landing and taking off. -- Repost from my previous blog entry.

Jeff's vision of HTM is implemented though Numenta's Nupic. Nupic is a HTM Python library and software suite that includes simple speech recognition demos, computer vision demos(picture object recognition), and other Nupic examples. Normally, you would have to pay hundreds for pattern recognition software of this quality. But all of these examples are functional and demonstrate the power of the HTM Nupic approach.

Bitworm Hello World Example

The Bitworm example provided with Nupic is a Hello World Example. But it is probably the most complex and thorough Hello World I have seen. It covers the basics but it also usable as a library or simple Nupic API. In the case of the Bitworm example, the goal is to track the movement of a bitworm through it's movement in 2D space and time. Think of the bitworm example in three dimensions. Dimension 1 is on the Y axis and is the height. In this case, the height is one. Dimension 2 is on the X axis. The X axis contains the length of the bitworm and movement along the X axis. And the third dimension is time. There are 20 time sequences trained for the bitworm examples. (OK, in reality you could think of the example in 2 dimensional space. The X and T axis are relevant).

There is one bitworm represented in the screen shot above. There are two bitworm lines from the top to the bottom of the screen. Line one is a representation of ONE bitworm and its position. In line two, the bitworm has moved in the X direction. Line two is a representation of the bitworm at TIME sequence two. There is ONE bitworm and 20 time sequences of that bitworm movement. The goal of the bitworm example is to train that movement and then predict the bitworm type based on a test set of bit worm examples.

I wrote a python example TK graphic program to render the bitworm's movement. The TK example is not provided with Nupic. The string of bits are created by the bitworm example, here is a representation of the training data set:

1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 [---- bitworm zero and time sequence 0
0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 [---- bitworm zero and time sequence 1
0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 [---- bitworm zero and time sequence 2
0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0
0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0
0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0

There are 420 lines of these bitworm bit vectors in the text file. Each line in the training set and the test set are representation bitworms.

The bitworm example is located at NUPIC_HOME\share\projects\bitworm

Summary to understand the bitworm example:
1. The bitworm python example does the following:
1a. The bitworm example creates the training data (File: training_data.txt)
1b. The bitworm python example creates the test data (File: test_data.txt)
1c. The bitworm example creates the bitworm categories (needed during the training process)
1d. The application trains the training test after the test and training data is created.
1e. The application validates that Nupic can learn the training data by verifying against the test data.

Think of training as training the Nupic AI software and test data as the way to check that the training worked.

2. training_data.txt and test_data.txt is a simple text file
2. Each line in the training_data.txt and test_data.txt database file consists of a bitworm (16 bits in the bitworm vector)
3. Each column or bit in the training and test file is a bit in the bitworm. There are 16 bits in the bitworm example.
4. Each line in the training and test data file is a bitworm and a representation of that bitworm at a particular time sequence.
5. There are twenty time sequences in a GROUP training set. Basically, line 1 of the training file represents a bitworm at time sequence 0. Line 2 of the training file represents a bitworm at time sequence 1, etc. At line twenty, that is the end of a time sequence group. At line twenty 22, a new bitworm example starts.
6. There are twenty EXAMPLE BITWORM time sequences.
7. There are 420 lines in the training and test data file, each line is bitworm at a particular moment in time.
9. There are zero bitworm vectors that delimit a time sequence

If you look at the file training_data.txt:

One bitworm is 16 bits:

1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 [---- bitworm zero and time sequence 0
Here is a formula to determine why there are 420 lines in the training and test file:

(1 bitworm * 20 time sequences) + (20 groups of time sequences)
+ (ZERO bitworm delimiter line * 20) = 420 lines in the file.

Example snippets from the Python Bitworm Example:

def generateBitwormData(additiveNoiseTraining = 0.0,
bitFlipProbabilityTraining = 0.0,
additiveNoiseTesting = 0.0,
bitFlipProbabilityTesting = 0.0,
numSequencesPerBitwormType = 10,
sequenceLength = 20,
inputSize = 16,
trainingMinLength = 9,
trainingMaxLength = 12,
testMinLength = 5,
testMaxLength = 8):

# Generate training data with worms of lengths between 5 and 8
trainingData = BitwormData()
trainingData['prefix'] = 'training_'
trainingData['minLength'] = trainingMinLength
trainingData['maxLength'] = trainingMaxLength
trainingData['sequenceLength'] = sequenceLength
trainingData['inputSize'] = inputSize
trainingData['numSequencesPerBitwormType'] = numSequencesPerBitwormType
trainingData['additiveNoise'] = additiveNoiseTraining
trainingData['bitFlipProability'] = bitFlipProbabilityTraining

Train and verify the bitworm example:

# Train the network
# TrainBasicNetwork: This function trains a basic network with the given data and category files and returns the trained network
bitNet = TrainBasicNetwork(bitNet,
dataFiles = [trainingFile],
categoryFiles = [trainingCategories])
print "Bit Net (TrainBasicNetwork-1): ", bitNet

# RunBasicNetwork: Runs the network using the given data files. The output of the classifier
# node for each input pattern is stored in resultsFile.
accuracy = RunBasicNetwork(bitNet,
dataFiles = [trainingFile],
categoryFiles = [trainingCategories],
resultsFile = trainingResults)
print "Bit Net (RunBasicNetwork-2): ", bitNet
print "Training set accuracy with HTM[a] = ", accuracy * 100.0

# RunBasicNetwork: Runs the network using the given data files. The output of the classifier
# node for each input pattern is stored in resultsFile.
# Run inference on test set to check generalization
accuracy2 = RunBasicNetwork(bitNet,
dataFiles = [testFile],
categoryFiles = [testCategories],
resultsFile = testResults)
print "Bit Net (RunBasicNetwork-3): ", bitNet
print "Test set accuracy with HTM[b] = ", accuracy2 * 100.0

Modifications to the Bitworm example and moving forward:

The bitworm example is a common type of example in the AI and pattern recognition world. You are given a bit sequence. Train the bit sequence and attempt to test the sequence against other sequences that have a similar structure. In the case of the bitworm example, a bit vector of 16 bits is trained. You could modify the example to train a 16x16=256 bit vector image.




Grinchy said...

As a java programmer, I'm trying to use this numenta system to find duplicate voters in the Voting List, for my elections integrity project.

I have the training data, I have a neural net and a genetic program that makes other neural nets. What I don't have is some simply numenta-style java code to identify trends as they stream past. There's so much data, but I have been able to successfully identify about 70% of duplicates (30% poor matches), and I want to do much better, like finding 90% of all duplicates while only mis-identifying 1 in 100.

Do you have some code that may help?

Unknown said...

Yea, I don't know, I am still new to Numenta's Nupic.

You might try the forums. They average about 2-3 posts a day. You may post and get a reply the next day.

"I have a neural net and a genetic program"

Were you using Numenta to do this or some other library?

Also, what does your input data include? Duplicate votes, does that mean you are looking at voter information like name, city, location?

It sounds like you are trying cluster or classify data (E.g. like spam detection programs).

So when you say trends, you might use Numenta or some other Data mining software to cluster or classify a particular trend.