![]() ![]() ![]()
|
2 Understanding HTM Development: Waves Example
This chapter explores the sequence of tasks involved in developing an HTM application. The chapter uses the Waves example to illustrate two aspects of each task:
The example in this chapter is slightly more complex than Bitworm. It uses the
RuntimeNetworkAPI directly instead of just using the helper functions in Bitworm.Topics
Development Overview
The process of creating an HTM application differs significantly from a traditional software engineering process. HTM Networks learn by building a statistical model based on a sequence of input data. The application developers task is not to specify an algorithm but to come up with a suitable representation of the data and to find the optimal parameter settings for the problem at hand. The quality of the final network depends on many factors, such as the network configuration (does the hierarchy have two levels or three?), node parameters (is
maxDistance0 or 0.2?), the training data (are there sufficient sequences?), and so on.The HTM development process is iterative at a very high level. You don't just write the program, find problems, rewrite and rerun. Instead, each task in the process might influence other tasks earlier or later in the process. During HTM Network design, you might need to refine the problem definition. During testing and analysis, you might find that the data representation is less than optimal.
Pay particular attention to the early stages of the process. Unless your data are represented in a way that's easy to understand for the HTM (and often for humans as well), the results will most likely not be satisfactory.
Figure 4 Numenta Development Process
This chapter walks through the development process using the Waves example as the context.
Defining the Problem
Finding a problem that's well suited to an HTM Network and formulating that problem in a fashion that yields good results are important parts of the HTM development cycle. Many developers redefine the problem as they see the results of running early prototypes of their HTM Network.
Problem Definition in the Waves Example
The Waves example generates data that represent temperature readings at fixed points in a moving stream. The example creates an HTM Network and trains the network with a set of input data. After training, the example submits new data to the HTM Network, and the network classifies those data.
This example assumes that 32 temperature monitors have been placed at fixed locations along the length of a stream. As time progresses, the monitors later in the stream see what the earlier monitors had seen.
This example assumes that the heat does not diffuse, and that hot and cold points move down the stream unaltered.
Figure 5 Waves Example
In the example, each hot spot is modeled as a Gaussian curve with positive amplitude; each cold spot is modeled as a Gaussian curve with negative amplitude. The state of the river is characterized as the combination of hot and cold spots.
The example uses these four state categories:
The warm and cold spots could be anywhere in the river. The goal is to have an HTM application that examines incoming data and recognizes whether the river is in one of the four categories.
The following illustration shows Category 0 (one warm spot).
Figure 6 River in Category 0 State (One Warm Spot)
`Note that the graph was generated as a by-product of calling
RunOnce.py. After theRunOnce.pyscript completes, you can find the graphs in a subdirectory calledvisuals. As you change the data generation parameters, you can examine the corresponding updated graphs.Input to the Temperature Monitors
The input vectors have both a spatial and a temporal element. Having both elements is critical for a problem well suited for an HTM Network.
- Spatial continuity - At each point in time, each monitor has a temperature reading. There is spatial continuity between monitor readings: At any point in time, neighboring monitors have a strong correlation while monitors far away from each other have no correlation.
- Temporal continuity - As time progresses, monitors later in the stream see what earlier monitors saw previously. In addition the reading at time T for each individual monitor is related to the reading at time T-1 and T+1 (there are no abrupt temperature changes). In contrast, readings far apart in time are not correlated.
Notes on Problem Definition
Take special care with problem definition. If problem definition was not thought out carefully, the HTM algorithms might be unable to work with your problem.
- Before you can start writing your code, you must determine the nature of the problem's spatial and temporal correlations, and you must consider how these correlations are structured hierarchically.
To be successful, your HTM Network must build a statistical model of the underlying causes in your problem domain.
- Think carefully about the hierarchy of the domain's spatial and temporal correlations. These correlations suggest the best topological structure of your HTM Network.
- After you've developed an initial topology, that is, a hierarchy with a number of levels and a number of nodes per levels that works well, you can start to write code and think about tweaking node parameters such as
requestedGroupCountormaxDistance. See Affecting Learning Node Behavior With Node Parameters in Advanced NuPIC Programming.- You might rethink your topology as you're working with parameter settings.
Representing Data
You must represent the data to match the sensor node, which receives input for the HTM Network. You need to prepare multiple datasets: training data, category data (if available), and testing data. Here are a few points to consider:
- Make sure the data match the
VectorFileSensorprecisely. TheVectorFileSensorexpects a file of vectors, either in.txtor.csvformat.
- The text file (
.txt) has one vector per line, separated by spaces.- The csv file (
.csv) has one vector per line, separated by commas.When you create a sensor, it expects a text file by default. To submit a csv file instead, set the
file_typethird argument, which defaults to text file, to 3, as follows:sensor.execute('loadFile', trainingFile, 3)If your data source does not produce vectors as output, manipulating the data so that they fit the available sensors is usually the best solution. Developers with source licenses might consider creating a custom sensor using the node plug-in API.
- For the training dataset, create an input file and, if category information is available, a category file. For each line in the data file, you need a corresponding line in the category file. When both files are fed to the HTM Network, it matches data and categories.
If no category information is available for a problem, the system groups data using the spatial and temporal information it can abstract from the data.
In the Waves example, a category file that represents the four river state categories is presented to the classifier node to allow that node to discriminate between the different river state categories.
- Training data must match a real temporal sequence in the world. For example, the images sample does not look at images statically but scans each image. In contrast, if you feed in images of a cat, a dog, and a cow, there is no correlation between those images.
- For the testing dataset, make sure the data are new to the system in interesting ways. For example, when training a vision system using photos of objects, include a photo of the same type of object but a different specific object (for example a teapot that's shaped slightly differently from the teapot you used for training). You might also present pictures of the object from different angles.
Testing data does not have to be temporally correlated; you can submit snapshots to the trained HTM Network for analysis.
For the Waves example, you can introduce a different random seed, which means each monitor gets different noise samples. You can introduce different amounts of thermal noise and experiment with how much noise the system can tolerate before it can no longer assign the data to categories.
Data in the Waves Example Programs
The
WavesData.pyscript generates data that are a sum of moving Gaussian curves plus a vertical offset. By default, each data time slice consists of 32 data points. There are four data categories; they differ in the numbers and signs of the curves. All curves have identical widths. Some curves have negative weight, some positive weight, and the number of curves ranges from 1 to 3. The centers of the curves are offset from each other by a little bit. The curves drift together at the same rate, which is 0.5 by default. The script saves the data in.txtformat for easy submission toVectorFileSensor.The goal is to have the HTM Network look at a set of data - representing the river in a certain state - and to determine whether the river is in one of the predefined four states. This categorization is trivial for a human to do, because it is easy to see how many humps are facing up and facing down, so it might also work well for the HTM system.
The Waves example data generator allows you to add two types of noise:
- Spatial noise - In each class, the center of each Gaussian curve is given a random horizontal offset. The generator chooses the offset based on the
spatialNoiseparameter. The offset is chosen uniformly in the range[-spatialNoise/2, spatialNoise/2].- Thermal noise - A small amount of noise is added to each data point. The amount is controlled by the
thermalNoiseparameter, and is chosen uniformly in the range[0,thermalNoise].The data generator also allows you to set the amplitudes of each Gaussian curve with an
amplitudesparameter. Changing this parameter affects the height and sign of each Gaussian curve. If you change thecentersparameter, the Gaussian curves have different locations. Other parameters affect data generation as well.Here's the code fragment from the
RunOnce.pyscript. The script creates one set of data for training the HTM Network and one set for testing. For each set, you specify the number of temperature monitors and the thermal noise (which differs between training and testing).print "\n====== GENERATING DATA ===========" trainData = WavesData() trainData['prefix']='train_' trainData['sensorDims'] = numTempMonitors trainData['thermalNoise'] = trainThermalNoise trainData['spatialNoise'] = trainSpatialNoise trainData.createData() testData = WavesData() testData['prefix']='test_' testData['randomSeed'] += 1 testData['numSeqPerCat'] = 4 testData['sensorDims'] = numTempMonitors testData['thermalNoise'] = testThermalNoise testData['spatialNoise'] = testSpatialNoise testData.createData()
RunOnce.pyincludes avisualize.Data()method that allows you to view the data for any parameter combinations you choose.Data Representation Questions
Assembling the data for training and testing the HTM requires organizing data correctly and ensuring that the data have the required spatial and temporal characteristics.
Consider the following questions when you prepare your data:
- How much data are appropriate? Too much data generally doesn't hurt, although it might slow down processing. Too little data might not be enough for learning. Experimentation is usually necessary but it's better to err on the side of having too much data.
- Is preprocessing required? You often have to preprocess source data before you can feed it to the HTM Network. In particular, the data need to be presented in temporal sequences. In the bitworm example, the bitworms are "walking" left to right and right to left over time. See The Bitworm Example for a discussion of that problem. In the Waves example, the hot and cold spots are moving down the stream.
- Do I need category data? If you submit category data, the classifier can use that information to group the data. If the model domain includes clearly defined categories, you can feed a category file to the HTM Network as part of training. This allows the classifier node to categorize the groups that the rest of the network has found. If the data don't allow easy categorization, the HTM Network performs grouping but cannot assign the output to predefined categories.
- Should I consider data generation? If source data are incomplete, or if you want to start developing your HTM Network prototype with a small, easily controlled set of data, data generation makes sense. You might use only generated data, as in the bitworm and waves examples, or modify existing data in different ways for a more complete training set.
If you already have a set of training data, you can generate a richer data set based on those data. Consider that humans learn to recognize objects at various distances, from different angles, and under different lighting conditions. Similarly, you can feed the HTM Network a comprehensive sample set for a vision problem by changing the lighting in the training images, blurring the images, and zooming in or out.
Designing and Creating the HTM Network Structure
Designing, configuring, and running the HTM Network are iterative steps. You usually start with a design that includes a sensor, a category sensor, and an effector and decide on the number of learning node levels. You then decide how many nodes you want at each level, and on any node parameters.
As part of analysis and testing, it might make sense to experiment with a different number of levels or to change other characteristics of the HTM Network.
Network Creation with the Network API and Helper Functions
You can use the
AddSensor(),AddLevel()andAddClassifierNode()helper functions to create most basic networks. The functions create an HTM Network with these elements:
If you call... Helper functions use these nodes by default...AddSensor()VectorFileSensorAddLevel()SpatialPoolerNode/TemporalPoolerNodepairsAddClassifier()Zeta1TopNode
Using the helper function makes sense if the HTM Network structure is simple.
Figure 7 Structure of Network Created with Helper Functions
The helper functions support the following network structure:
Network Creation with Node Constructors
When the default node type is not appropriate, for example, when you're using a non-default learning algorithm you can use node constructors. For example, if you want to use a non-default classifier node, you first create that node using a node constructor, then add the node to the network using
AddClassifierNode().knnNode = CreateNode('py.KNNClassifierNode') AddClassifierNode(myNet, numCategories = 4, nodeInstance = knnNode)The
Wavesexample does not use node constructors because the helper functions are appropriate for the desired structure.The
net_constructionfolder includes examples for many different types of HTM Network creation.Network Creation in the Waves Example
The Waves example creates the HTM Network structure as follows:
1. Create the network.
2. Add a sensor to the network, setting the vector length for the sensor to the number of temperature monitors.
3. Add each level and set appropriate parameter size, requested coincidences, and groups. The example adds levels using a loop.
for level,size in enumerate(levelSize): AddLevel(net, numNodes = size, requestedCoincidences = coincidences[level], requestedGroups = groups[level])4. Set parameters for experimentation. To have your HTM Network run well, you usually have to experiment with parameters.
net[levelSpatialName].maxDistance = maxDistance[level]
net[levelTemporalName].transitionMemory = transitionMemory[level]
The example uses the parameters most likely to affect your HTM Network. See Affecting Learning Node Behavior With Node Parameters in Advanced NuPIC Programming for a complete list.
When you add a level, you add two regions: one region of spatial pooler nodes and one region of temporal pooler nodes. Pairs of nodes are connected bySimpleLink.5. Finally, add a classifier node to the HTM Network.
Network Design Questions
When designing your HTM application, consider the following questions.
- What are the best values for node parameters? Some experimentation is usually necessary. See Affecting Learning Node Behavior With Node Parameters in Advanced NuPIC Programming for a description of each node parameter.
- What is the best way to arrange nodes (how many levels, how are nodes linked, etc.)?
- How many groups/coincidences do you expect for each node? You don't have direct control over the number of groups and coincidences, but HTM Network geometry affects those numbers. You might redesign parts of the HTM Network or manipulate the input data if the number of groups and coincidences is too small or too large.
- How much time is needed for training, and how can training time be optimized? Training time depends on a number of factors including HTM Network size, amount of data, training strategy, number of CPUs, speed of CPUs, and more.
There are no easy answers to these questions. In many cases, you need to experiment with the available options. For example, you might run your HTM with a different number of hierarchy levels, then compare the results. The Numenta website includes discussions of those topics.
Running the Network to Perform Learning and Inference
During training, an HTM Network performs learning and inference, one level at a time. The
RuntimeNetworkAPI and theRunBasicNetwork()helper function turn learning and inference on and off automatically.This section gives only a brief introduction to the topic.
- Inside a Learning Node: How Learning and Inference Happen in Advanced NuPIC Programming gives some additional information
- The white paper The HTM Learning Algorithms discusses HTMs in general in depth.
- The document Numenta Node Algorithms Guide discusses the learning algorithms.
When you construct your HTM Network using
AddLevel, the tool adds a region ofSpatialPoolerNodeinstances and a region ofTemporalPoolerNodeinstances, connected by single links. During learning, the learning algorithms work on that input on a per-level basis.Here's a simple view of this process:
1. First, the system performs learning at the lowest level (Level 1). Level 1 nodes are in learning mode, and all nodes above Level 1 are disabled.
2. Next, the system performs inference at the lowest level (Level 1) and learning at the next level (Level 2).
The Level 2
SpatialPoolerNodeandTemporalPoolerNodeare in learning mode. While Level 2 is being trained, Level 1 must be in inference mode, that is, its grouped data must be available to Level 2.3. The system performs inference at Level 2 and learning at the next level (Level 3).
4. The system continues performing first learning, then inference at each level until it reaches the classifier node. The classifier uses the data from the category sensor assign the data from the previous level to categories. If there is no category sensor, the classifier groups according to how the data are structured.
5. At the end of the run, each node is trained and in inference mode, ready to process more data.
Training in the Waves Example
The
Wavesexample allows you to perform training and testing in one of two ways:trainedNet = TrainBasicNetwork(net, dataFiles = ["train_sensor.txt"], categoryFiles = ["train_category.txt"]) trainedNet.save("trained_waves.xml")After the network has been trained, it is called with new data to test the HTM Network.
accuracy = RunBasicNetwork(trainedNet,RunBasicNetwork()returns the accuracy of the trained network. Accuracy is the percentage of input data that were classified correctly by the HTM Network. To receive accuracy information, you must supply both test data and category data (or accuracy isNone).dataFiles = ["train_sensor.txt"],
categoryFiles = ["train_category.txt"])
print "Accuracy of trained network on original training data is ", accuracy
Training Questions
Before you start training runs, asking the following questions can be useful:
- What are the most effective parameter settings? You might have to experiment with these settings, but you may also know approximately the right values based on the amount of noise in the data. See Affecting Learning Node Behavior With Node Parameters in Advanced NuPIC Programming for more information.
- What is the best sequence of training data to quickly train the HTM? If you want for the network to learn how to recognize things regardless of certain perturbations, for example, the noise or the position of the worm in the bitworm example, feed in sequences that demonstrate that perturbation.
- Can I reuse some trained nodes? For instance, the Pictures example trains one node, then make copies of that node for all other nodes at that level. See Training Your HTM Network: The Pictures Example.
- Can I speed up learning by supplying additional category information at certain levels?
- How many nodes per level, and how many levels give the best results? Consider starting with a one-level network and experiment with different parameter settings until the accuracy is optimal. Then train a two-level network using the same parameter settings.
Troubleshooting, Testing, and Analyzing Your HTM System
When you first attempt to run your HTM Network, you might have to do some troubleshooting if things don't work at all. Once the HTM Network runs satisfactorily on the training data set, you might wish to improve accuracy, speed, or both.
A number of tools and scripts allow you to view results and explore how the HTM Network arrived at the result.
- Use the
Visualizertool (nupic.analysis.visualizer) for a graphic display of the results that includes the group structure and other information. See Using HTM Network Visualizer.It is often useful to examine intermediate results or to experiment with different parameter settings to understand how your HTM application processed input data. Based on that information, you can change how you enter data, change nodes and their parameters, or modify other characteristics of your HTM Network. See Debugging Your HTM Application.
Testing and Analysis in the Waves Example
The Waves example generates visualizations of the coincidence matrix and group structure when it's invoked. The visualization code generates a file and is commented out by default. The code looks like this:
print "Visualizing trained network..."
vis = Visualizer(networkFilename="trained_waves.xml",
dataType='bar_graph')
vis.visualizeNetwork(openBrowser=False)
To test Waves and view results:
1. First, run the trained HTM network using the existing input data. View the results by looking at the visualizations that are generated.
2. Modify the
RunOnce.pyfile to change the input data or parameters. For example, try setting thetestThermalNoisevariable to a higher value. You can also change themaxDistanceorrequestedGroupCountparameters, which you can specify on a per-level basis inRunOnce.py.3. Run the HTM network with the new configuration and examine the visualizations.
You can also use NodeInspector to interactively look at results.
Using RunExperiment.py to Explore Results of Changes
The
RunExperiment.pyscript in theWaves/simplehtmdirectory illustrates how you can prepare different experiment runs to test the results of manipulating different aspects of the HIM's world. The available experiments include:
Testing and Analysis Questions
Tuning your HTM Network is the biggest part of the development process.
Remember that you might have to revisit data generation or submission, or even problem definition to arrive at a useful HTM Network design and implementation.
Summary and Guide to Documentation
The process from problem definition to HTM deployment is not linear. At each stage, you might need to return to an earlier stage for redefinition or refinement.
For example, when analyzing the data, you might discover the data gathering or data representation approach needs to change. When designing the HTM Network, you might find that the problem definition needs to be refined. Each stage is directly affected by other stages. You can deploy the HTM Network only when you're satisfied that it can generate satisfactory results for those new data; achieving good results for one set of data is not enough.
The following table summarizes design and implementation tasks and lists relevant documentation for each task. See How to Access NuPIC Built-in Help for information on getting help while working with the APIs.
Table 3: Tasks Overview and Documentation Task Documentation (Concepts) Documentation (Task-based)
Numenta website. Numenta website.Look at example code for examples of problem definition. Numenta website. Numenta website.Look at example code for examples of data representation (Pictures example) and data generation (all examples). Numenta website. Constructing an HTM Network. Python online help. The Numenta Node Algorithms Guide Running HTM Networks With Sessions in Advanced NuPIC Programming. Python online help.Numenta website.
|
Numenta www.Numenta.com |
![]() ![]() ![]()
|