HTM.java Network API: “Tip of the Day” (11-21-2015)

Greetings Earthlings (and Otherwise Affiliated),

Did you know that you could insert any generic or custom function into an HTM.java network?

That’s right…

Within the NAPI’s known fluent style “add” methods such as:

Network network = Network.create("Network API Demo", p)
    .add(Network.createRegion("Region 1")
        .add(Network.createLayer("Layer 2/3", p)
            .alterParameter(KEY.AUTO_CLASSIFY, Boolean.TRUE)
            .add(Anomaly.create())
            .add(new TemporalMemory())
            .add(new SpatialPooler())
            .add(Sensor.create(FileSensor::create, SensorParams.create(
                Keys::path, "", ResourceLocator.path("rec-center-hourly.csv"))))));

…where there are the usual statements:

add(new SpatialPooler())

add(new TemporalMemory())

add(Anomaly.create())

 

There is a little known “add” method:

add(Func1<ManualInput, ManualInput> function)

 

…which takes an RxJava class called Func1 as a parameter. It is a very simple interface which has one method “call()” which will be called automatically within the NAPI and can execute any code you like as long as it returns an org.numenta.nupic.network.Inference (or its concrete implementation org.numenta.nupic.network.ManualInput).

 

Here is a snippet from the test that provides an example of this:

 

// “mi” here is the ManualInput passed in…

Func1<ManualInput, ManualInput> addedFunc = mi -> {

return mi.customObject(“Interposed: ” + Arrays.toString(l.getSDR()));

};

 

Network n = Network.create(“Generic Test”, p)

.add(Network.createRegion(“R1”)

.add(Network.createLayer(“L1”, p)

.add(addedFunc)

.add(new SpatialPooler())));

 

The line returning with the statement, “mi.customObject(xxx):” above refers to a method on ManualObject which stores the object you create in the ManualInput, and then returns the ManualInput itself (as the generic Func1 type arguments declare). In other words, ManualInput has a field called “customObject” which can be updated with your processing result, and then passed up the chain of algorithms and eventually to the “Observer” which is listening for results.

You can add as many “functions” to a given layer as you desire. Each function can take the result of the last function (by calling getCustomObject() on the ManualInput), and operate on its contents. In this way you could possibly call out to other classes and functions, invoking other behavior as well!

This is all provided by the internal use of RxJava Observables which allows the NAPI to transform any output into any input such that algorithms can be connected in a chain of processing units which can be themselves operated upon like discrete variables!

For further insight into using RxJava Observables, see Mastering Observables (also provided as a new link within this blog’s “Essential Links” (III).

Happy Hacking…

 

BTW, If you’re interested in furthering the development of HTMs on the JVM, check this out: http://lists.numenta.org/pipermail/nupic_lists.numenta.org/2015-November/012342.html

 

Leave a Reply Text

Fork me on GitHub