Skip to content

Network API Requirements & Architecture

David Ray edited this page Feb 25, 2015 · 21 revisions

Network API Requirements & Architecture

This document describes essential goals and structural elements required for the Java version of the Network API for NuPIC (Numenta Platform for Intelligent Computing). It is offered as an open outline for discussion and "whiteboard" for illustrating the resolutions decided upon by the participating audience - as well as a final description of the product to be delivered.

Background

A "Network" in this context is a collection of wrapper elements (Node?) which contain discrete HTM components (i.e. SpatialPooler; TemporalMemory) and allow the assembly of these components in such a way where input can be submitted at one end, and output can be extracted at the other. It is a means of manipulating, monitoring and configuring the flow of information through each element as well as its persistence and reification. The term "API" signifies that this work is a developer level interface and intended for a more "knowledgeable" user base as a means of integration into a larger platform or application.

Scope & Purpose

As part of the effort to provide NuPIC functionality in the Java™ language, there is a clear need for a "Network" level interface to the NuPIC algorithmic components. The intention of the Network is to make it easier to fully describe an assembly of algorithmic components; specify their configuration details; execute a process flow and monitor its behavior and state. It should also provide a clear and easy means of integration into the end-user's application. Additionally, it should not exemplify any "personality" of its own, and should intuitively meet the developer's expectations and should transparently and easily be queried for the applicable parts of its internal state. Stated in itemized form (Excerpted from Python Architectural Document):

  1. Provide all essential functionality for using HTM Networks, but no more. Any additional functionality is to be provided by end-user libraries.
  2. Excellent performance - The Network Engine should add negligible overhead.
  3. Easy to understand and use. The API should be consistent and easy to learn; it should not use fancy or obscure language features.
  4. Clean architecture and transparent behavior.
  5. Easy to add support for new algorithms - (Modular architecture for algorithms; should isolate algorithm developers from needing to know much about Network Engine internals)

Proposed Architecture

(i) Object Model
  • Network

    As in the Python version, "[The] Network is the "root" object in the Network Engine. All other objects are contained within a Network object, either directly or indirectly." As in the Python version, the "Network" will also be a container of "Regions", but its serialization will be direct, and all to a single JSON file. The external API will also be a bit more simplified. There will simply be add methods as such implemented in Fluent style for convenience:

    Network n = Network.create(Parameters); // Returns a Network. Parameters, same as when creating SP or TM
    n.createRegion()               // Returns a Region
        .add(Sensor.create(url))   // Adds a Sensor node - described below. Returns the Region
        .add(Encoder.createMulti() // Adds a MultiEncoder, returning the Encoder (Multi)
            .add(Category)         // Adds an Encoder, returning the Encoder
            .add(Scalar)           // Adds an Encoder, returning the Encoder
        )                          // Returns the Region
        .add(SP)                   // Adds the SpatialPooler, returns the Region
        .add(TM)                   // Adds the TemporalMemory, returns the Region
        .add(Classifier)           // Adds the Classifier, returns the Region
        .add(Anomaly)              // Adds the Anomaly calculator, returns the Region
        .connect(Region)           // Connects input Region, returns the Region
        .connect(Region);          // Connects another input Region, returns the Region ";" marks termination

EDIT: The above "Parameters" argument to Network, should probably be on the create method of "Region" as in "n.createRegion(Parameters)", or maybe Parameters at the network level can establish defaults which are inherited and overridden at the "Region" level?

The above leaves out checks such as exceptions thrown due to Regions with added Sensors not being able to add input Regions underneath them (i.e. the "connect()" calls above would throw an Exception at runtime because a sensor has already been added indicating that the node is at the bottom) - but this is just a rough idea of how the Fluent assembly will be achieved. Also, some add() methods may have additional parameters.

  • Region
    These are the major building blocks, and arguments for the Network.add() methods and the Region.connect() methods. Execution order will be handled internally via the containment hierarchy implied by the user's call to the relative "Region.connect()" methods.
NOTE: All constructs such as Nodes (mentioned below) or anything supporting "linking" will be internal and hidden from the API user.
  • Node
    "Hidden" from the user and exists internally only, and is created to hold each algorithmic component separately with generic input and output handling - with the exception of "Sensors" (mentioned above)

    It is anticipated that Sensors will be special nodes that can be instantiated and configured to specify a DataSource of some kind (i.e. File, DB connection, URL). The implementation details are not specifically known at this time, and will work themselves out.


Persistence / Reification

As described above, the Network will be serializable via a call to Network.toJson() which will output a String which can be output to a JSON file or manipulated in memory by the user. At deserialization, the Network shall be fully operational and will resume execution starting from the state at which it was saved.


Running a Network

It is envisioned that a given Network will be able to be run in three modes:

  1. Manual Mode - Where Network.run() will be called repeatedly from an externally (user managed) loop. This way the user will have fine grained control over the operation at each iteration. (Pulls data via the Sensor(s))

  2. Automatic Mode - Where the Network will run until stop is called on it or until the Sensor nodes detect the termination of input data. (Pulls data via the Sensor(s))

  3. Reactive Mode - Where the user can call input() with data on a sensor(s) which will cause the chained execution of the rest of the network. Or data can be pushed in and "reacted" to whenever the Sensors push data through the Network. This will have a FRP push mode and will be executed using RxJava - Reactive Extensions for Java