Table of ContentsPreviousNextIndex

Put your logo here!


3 Constructing an HTM Network

This chapter explains how you can use the Numenta Python APIs to create an untrained HTM Network.

Topics

HTM Programming Steps Overview

This section briefly discusses the complete development process to help you understand the relationship between your HTM Network's structure (encapsulated by a Network instance) and the RuntimeNetwork that is used during training and inference.

For most basic HTM Networks, you actually don't need to create nodes and links explicitly but can instead using the helper functions to create the structure. Many of the examples, including Bitworm and Waves, use helper functions to add sensors, levels, and classifiers to the network and linking happens automatically.

Figure 8 HTM Development Process Overview

Creating the HTM Network with Helper Functions

The helper module allows users to create, run, and experiment with basic HTM Networks The module is useful for creating and experimenting with initial prototypes. You can also look at the code for the helper module (helpers.py) as example code because it uses the explicit network and node creation functions to define the helper functions.

You cannot create image recognition networks with the helper functions. See the Vision Framework for those tasks.

Network Structure Supported by Helper Functions

A basic network is strictly defined to have the hierarchical structure shown in Figure 7. Each level feeds into the next and each level can have a different number of nodes. There can be 0 or more levels, but there is always a single classifier node at the top. There can be overlapping connections between levels.

Nodes Supported by Helper Functions

The helper functions support the following nodes:

Creating the HTM Network Components Explicitly

The rest of this chapter explains how you can create an untrained network (the Network object and all associated objects). In some cases, the examples use helper functions, but in many cases they don't. Here's an overview of the steps:

Table 4: Overview of Network Creation Tasks
Step
Task
Discussed in
1
Create the empty HTM Network
2
Create and configure nodes, add them to the HTM Network
OR
Create a template nodes, then create regions, add them to the HTM Network
4
Link network elements

Understanding HTM Network Components

HTM Networks are data-driven learning systems.

The untrained network has no inherent capability and cannot be used to perform inference. The untrained network is like a scaffold that describes the flow of data and other aspects of analysis at runtime. This scaffold information includes, for example, the number of nodes and levels, characteristics of the nodes, and how the nodes' inputs and outputs are connected.

Figure 10 shows a sample HTM Network. While the sample network shown below is small and highly symmetrical, an HTM Network can actually have an arbitrary number of levels and connections, and it does not need to be symmetrical.

Figure 9 Sample HTM Network

Nodes

A node - sensor, effector, or learning node - is the basic unit of a Numenta HTM Network. Each node is implemented as a Python or C++ plugin to NuPIC. Numenta nodes are usually created and manipulated using classes in the NuPIC Python API, as discussed in Constructing an HTM Network.

Node Categories

Basic node categories are:

Node Attributes

Each node has a number of attributes.

Attribute
Description
See
NodeHelp
Displays information about each node, for example:
   from nupic.network import * 
   nodeHelp(`SpatialPoolerNode') 
Inputs and outputs
Vectors of floating-point numbers in the nodes that are currently implemented.
Sensors have no inputs but at least one output.
Learning nodes have at least one input and output each.
Effectors have no outputs but at least one input.
Links
Connect nodes. A node can receive input from and send output to nodes to which it is linked. The helper functions link nodes automatically.
Parameters
Affect node behavior at runtime.
Scheduling (phase) information
determines the order in which the nodes are processed. The NRE processes each phase in sequence. You specify phase information when using node constructors or regions.
Internal state
Most of the internal state is saved when the HTM Network is saved after training. Some node data, such as the current input and output vectors, are transient and are not saved.
 

Regions

A region is an array of nodes that have precisely the same parameters, including the same phase. If you use the helper functions to create your HTM Network, they internally create a region for each set of nodes. You can also create regions explicitly. Many larger HTM Networks include regions. See Creating Regions.

Figure 10 1-D Region of Four Nodes (Top) and 2-D Region of 2x3 Nodes (Bottom).

Links

Links determine the flow of information in the HTM Network. You can link individual nodes, or link arrays of nodes at once using link types. See Link Types.

Creating the Network and Node Objects

You use the Network class to create the initial untrained HTM Network. The untrained network describes the network structure, similar to the way a database schema describes the structure of a database. Creating the HTM Network with Helper Functions explains how to create most basic networks. This section discusses a network using node objects, which offers more flexibility. The process consists of these steps, discussed with code fragments below:

1. Import the nupic.network Python package

2. Create an Empty Network

3. Create and Configure the Nodes

4. Add the Nodes to the Network Object

After you've completed these steps, you can link the different nodes, as discussed in Linking the Elements of the Network.

1 Import the nupic.network Python package

The nupic.network package contains all the classes you need for creating your network. It usually makes sense to import all classes in the package as well as the helpers package, as follows:

from nupic.network import * 
from nupic.network.helpers import *  

Here are some of the classes and functions from nupic.network:

Network
Container class. You can create an instance of Network, and then add the network elements (nodes or regions).
CreateNode 
Used to create nodes explicitly using the node class and its methods. See NuPIC Node Types for an overview of node types. See Affecting Learning Node Behavior With Node Parameters in Advanced NuPIC Programming for an introduction to node parameters.
Region 
Use to create arrays of nodes based on a template. See Creating Regions.

For information about any of the classes, you can use pydoc, as discussed in Getting Help for Nodes and Helper Functions.

2 Create an Empty Network

After you've imported the appropriate classes, you can create an empty network to serve as container for network elements and links. For example:

myNet = Network() 
3 Create and Configure the Nodes

The CreateNode() function allows you to create and configure a node with one call.

For each node, you can specify a node type and all node parameters. Some parameters are required, as indicated in the online help. If you make a mistake, CreateNode() warns you immediately by throwing a Python exception.

The following code fragment creates a node using CreateNode() and specifies its parameters.

CreateNode("SpatialPoolerNode",  
   phase=1,  
   bottomUpOut=200,  
   maxDistance=0.05 ),  
4 Add the Nodes to the Network Object

After you've created the node(s), you can add them to the network as follows:

myNet.add ("<unique_element_name>", myNode) 

Here,

For example:

myNet.add ("Level1Node", myNode) 
You must remember the name you assign in this call and use it later when linking nodes or regions.

Network.add() adds an element reference to the network. Modifications to the original affect the element inside the HTM Network. If you prefer to add a copy, use addElement().

Creating Regions

Creating a region involves a few simple steps.

1. Create a Node that Serves as the Template.

Use CreateNode() to create a node template. To create an HTM Network that uses the Numenta learning algorithm, create a SpatialPoolerNode first and set all parameters as part of node creation.

   myTemplateNode = CreateNode(nodeType = "SpatialPoolerNode", ...) 

2. Create a Region Using the Template and Specifying the Dimensions.

You create a 1-D region that consists of four nodes as follows:

   myRegion = Region (4, myTemplateNode) 
 

You create a 2-D region of six nodes arranged in a grid with two rows and three columns (see Figure 10) as follows:

   myRegion = Region ([2,3], myTemplateNode)

3. Add the Region to the Network.

Adding a region to an HTM Network is identical to adding a node to a network.

   myNet.add("<unique_region_name>", myRegion) 

After you've completed these steps, you can link the region to other regions or to nodes, as discussed in Linking the Elements of the Network. If you want to create an HTM Network that uses the Numenta learning algorithm, you can next create a TemporalPoolerNode template node, create a region, and link the spatial pooler and temporal pooler regions.

The LogoExampleRegions example in the net_construction example set illustrates creating regions.

Node Names in Regions

All the node names for a 1-D region are <region_name>[<num>]

where <num> is a number between 0 and the number of nodes in the region, minus 1.

All the node names for a 2-D region are <region_name>[num,num]

where the two numbers are the indices into the region. Note that there is no space between the two numbers.

You can use node names when setting up more advanced links, or when analyzing individual nodes in a trained network.

Region Example

Figure 11, Regions represented by the Pictures Example, shows an example of regions.

Figure 11 Regions represented by the Pictures Example

Linking the Elements of the Network

After you've added nodes to a Network, you must link the nodes (unless you use the helper functions, which link nodes automatically). In the simplest case, you can link the nodes as follows:

myNet.link(<source_node>, <dest_node>) 

That call assumes a single link, and assumes a single source output and a single destination output.

Each node can have multiple named outputs and named inputs. You can therefore perform linking with the following arguments:

   myNet.link ("<source_node_name>",  
            "<dest_node_name>",  
            linkType= <link_type>,  
            sourceOutputName= <source_output>,  
            destinationInputName= <dest_input>,  
            sourceDims= <dims>)  
   myNet.link ("<source_node_name>",  
            "<dest_node_name>",  
            linkType= <link_type>,  
            sourceOutputName= <source_output>,  
            destinationInputName= <dest_input>,  
            sourceDims= <dims>,  
            overlap= <overlap>) 

The rest of this section discusses the different link types you can use, both with and without overlap.

Link Types

Three link types are defined:

   myNet.link ("<source_region_name", "<dest_region_name>", linkType = <link>) 

For example, if the sensor output is an array of 64 elements, and the region consists of four nodes, the first 16 data values go to the first node, the next 16 data values go to the second node, and so on.

To link a sensor with a 1-D region, use code like the following:

   myNet.link ("sensor",  
               "level1",  
               linkType="SensorLink",  
               sourceOutputName= "dataOut",  
               destinationInputName="bottomUpIn",  
               sourceDims=[18]) 
 

To link a sensor with a 2-D region, use code like the following:

   myNet.link ("sensor",                "level1",                linkType="SensorLink",                sourceOutputName= "dataOut",                destinationInputName="bottomUpIn",                sourceDims=[18])

sourceDims is a list, e.g. [32, 32] if the sensor outputs 1024 elements that should be treated as a 32x32 array.

Overlapping Connections

To specify overlaps, use the SimpleLink link type or the FanIn link type with an overlap argument.

For example, you can link nodes at two levels using a specified overlap, as follows:

link ("level1", "level2", linkType="FanIn", sourceOutputName="bottomUpOut", 
destinationInputName="bottomUpIn, overlap=[1]) 

Figure 12 FanIn Example with Overlap

The system calculates the fan-in using the source element (or region) dimension, destination element (or region) dimension, and overlap. The overlap, which is a list to allow for multi-dimensional HTM Networks, specifies the number of source nodes shared by any two adjacent destination nodes.

You can use link with SensorLink link type and an overlap argument to divide a single sensor output array equally across the nodes of the destination region, for example:

link ("sensor", "level1", linkType="SensorLink", sourceOutputName= "dataOut", 
destinationInputName="bottomUpIn", sourceDims=[18], overlap=[2]) 

Figure 13 FanIn Example with SensorLink

In this example, the sensor output array has 18 array elements, which are divided across four nodes. Each node receives the output of six array elements, with adjacent nodes getting the input from two shared elements each.


Numenta
www.Numenta.com
Table of ContentsPreviousNextIndex