-
Notifications
You must be signed in to change notification settings - Fork 159
NAPI Quick Start Guide
Here you can find a more in depth explanation of the NAPI details, together with examples, and links to example code.
Let's get started!
Here's an example of the code it takes to get a full featured network up and running:
Parameters p = NetworkDemoHarness.getParameters();
p = p.union(NetworkDemoHarness.getNetworkDemoTestEncoderParams());
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"))))));
network.start();
...and that's it! The above network (while simple), contains a full complement of all NuPIC algorithms and computational devices.
Here we see how to connect multiple layers...
Parameters p = NetworkDemoHarness.getParameters();
p = p.union(NetworkDemoHarness.getNetworkDemoTestEncoderParams());
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(Network.createLayer("Layer 4", p)
.add(new SpatialPooler()))
.add(Network.createLayer("Layer 5", p)
.add(Sensor.create(FileSensor::create, SensorParams.create(
Keys::path, "", ResourceLocator.path("rec-center-hourly.csv")))))
.connect("Layer 2/3", "Layer 4")
.connect("Layer 4", "Layer 5"));
Here we see how to connect multiple layers and multiple regions...
Parameters p = NetworkDemoHarness.getParameters();
p = p.union(NetworkDemoHarness.getNetworkDemoTestEncoderParams());
// Shared connections example
Connections connections = new Connections();
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)
.using(connections) // Demonstrates Connections sharing between Layers in same Region
.add(Anomaly.create())
.add(new TemporalMemory()))
.add(Network.createLayer("Layer 4", p)
.using(connections) // Shared with different Layer above
.add(new SpatialPooler()))
.connect("Layer 2/3", "Layer 4"))
.add(Network.createRegion("Region 2")
.add(Network.createLayer("Layer 2/3", p)
.alterParameter(KEY.AUTO_CLASSIFY, Boolean.TRUE)
.add(Anomaly.create())
.add(new TemporalMemory())
.add(new SpatialPooler()))
.add(Network.createLayer("Layer 4", p)
.add(Sensor.create(FileSensor::create, SensorParams.create(
Keys::path, "", ResourceLocator.path("rec-center-hourly.csv")))))
.connect("Layer 2/3", "Layer 4"))
.connect("Region 1", "Region 2");
-
Algorithms should not be duplicated within a single Layer (i.e. Don't have 2 SpatialPoolers in the same layer for example).
-
Don't forget to connect Layers or Regions to each other as shown above. Adding a Layer and Region is not the same as connecting them; you must do both or there will be indeterminate behavior.
-
Sensors (FileSensor, URLSensor, ObservableSensor) must be added to a layer that is connected to the bottom of process flow.
-
Connections (shown in an example above utilizing the Layer.using() method) should only be shared within and among Layers inside a single Region. Layers themselves will create their own Connections object and any SP and TM within that layer will use the same Connections object (as it should) - but the Layer.using() method overwrites the internally created Connections object with the object specified as an argument to the using() method (allowing sharing between Layers of the same Region if specified). The sharing of Connections between Regions is undefined and will likely result in indeterminate behavior if not causing an Exception.
-
Network.start() should always be called. Especially when using a FileSensor or URLSensor - but also when using an ObservableSensor and manually entering data because data must be submitted on a different thread then the thread on which the layer is running. The only time Network.start() does not need to be used is when directly entering data into the bottom layer of a Network via the Layer.compute() method. (see Layer.testBasicSetup_SpatialPooler_MANUAL_MODE() as an example of direct Layer input)
-
When using an ObservableSensor, a Publisher should be used to programmatically enter the header and to setup the sensor. See LayerTest.testLayerWithObservableInput() for an example of how this is accomplished.
-
The LayerTest class also shows how to "warm up" the SpatialPooler before forwarding data to a TemporalMemory within a given Layer. This simply means that you can specify the number of cycles to send the data through the SpatialPooler (skipping the rest of the Layer input chain), before allowing the data to be forwarded through to the rest of the Layer. This is a cool feature that optimizes initialization and learning of a Layer such that the TemporalMemory and SpatialPooler aren't learning at the same time (which can lead to sub-optimal performance).
- Introduction (Home)
- History & News Archives...
- Usability
- Architecture
- NAPI Quick Start Guide
- NAPI In Depth
- Saving Your Network: PersistenceAPI Serialization
- Roadmap
- Browse Java Docs
- Build Instructions
- Eclipse (Dev Setup)
- Anomaly Prediction
- Test Coverage Reports
- [Cortical.io Demos] (https://github.com/numenta/htm.java-examples/tree/master/src/main/java/org/numenta/nupic/examples/cortical_io)
- Hot Gym Demo
- Performance Benchmarks with jmh - blog
- BLOG: Join the "cogmission"