NuPIC

Numenta Platform for Intelligent Computing

For more information on Numenta, Inc. or Grok for IT Analytics, please visit our website or follow us on Facebook or Twitter.

10 Feb 2015

HTM.java Receives Benchmark Harness

They say in order to lead, one must have someplace to go. It’s also true that in order to arrive, one must have departed from someplace (duh! :-P). In software optimization, knowing where it is one came from, (and establishing baselines), is a very large part of the battle; and the same things that make Java™ such an attractive and ubiquitous platform, also make it one of the hardest environments to benchmark.

Unlike C, which is a statically compiled language, Java is very dynamic and undergoes very aggressive optimization and runtime profiling while it compiles down to native code on the fly! As such, there are many pitfalls one can come across when benchmarking Java code; which is why JMH was chosen for HTM.java’s benchmark tool. JMH was developed as part of the OpenJDK project (the incubator Oracle draws from to create their “official” JDK), and while it doesn’t make benchmarks infallible, it will help surmount some of the hardest issues benchmarking Java can present (such as accounting for optimizations: see Loop Unrolling, Dead Code Elimination, and Escape Analysis)

For more detailed information about benchmarking Java please watch: the talk by Aleksey Shipilev, it’s a crucial and informative watch.

Uhm… Back to HTM.java, right?

Right! :)

HTM.java’s new benchmarking package is not the end of the road - it is just the beginning. It is a place to “depart” (using the previously established vernacular). The package can be found in the “src/jmh/java” directory, and is comprised of 4 classes to start off with:

Gradle Build Integration

The build.gradle file, is configured to run the above benchmarks (they only take one minute) during Travis CI, continuous integration builds.

Fun Fact: The SpatialPooler benchmark is run 1000 times for the “warm up” and 1000 times for the “timing run”; likewise the TemporalPooler is run 45,000 times for each) A lot can happen in one minute!

These can also be run on the command line using:

Human readable results can be found in: “<git source dir>/build/reports/jmh/human.txt”.

The jar file created by the “gradle check” command can be found at: “<source dir>/build/libs/htm.java-0.40-jmh.jar”. The following command can be executed (from inside the “<source dir>/build/libs” directory) to simply run the benchmarks after “gradle check” has been run at least once.

java -jar htm.java-0.40-jmh.jar

The “0.40” part of the file name may change when new versions of HTM.java are released.

You can contribute too!

In addition, any classes found in the “src/jmh/java” directory will be automagically run during “gradle check”.

The “src/jmh/java” directory was chosen by the author of the jmh gradle plugin as a means of allowing the integration of benchmarks into any project without having to create a separate project directory structure. (Big Kudos to Cedric Champeau) Thanks!

In addition, there is a text file located here entitled “jmh_defaults.txt” which lists all the jmh command line flags the gradle plugin supports - for your convenience!

Happy Benchmarking!

David Ray
Lead Programmer, HTM.java

Comments on Reddit


Top

03 Dec 2014

HTM in Java!

Introducing the feature-complete htm.java project!

Thanks to a lot of effort by David Ray, the NuPIC hacker community, and Numenta’s own development staff, a fully usable version of NuPIC (minus swarming and OPF functionality ➟ coming soon!) is now available in Java.

This port is 100% functionally equivalent to NuPIC’s Network API.

See the complete javadocs here!

Bringing NuPIC to Java is an important milestone in NuPIC technology due to the size and significance of Java’s user base. Because Java is the world’s most used programming language, HTM now has the advantage of being exposed to an extraordinary amount of new developers and users.

htm.java is easy to setup and configure, and because the JVM is such a common runtime, that means instant availability on platforms like Windows and all Linux flavors without the use of a virtual machine (not to mention mobile devices!)

The community is fully committed to adding all the support tools and infrastructure the Python version enjoys, and those are the next milestones to be worked on. There is already a “HelloSP” example created by a community member. Here is the constructor:

/**
 * 
 * @param inputDimensions         The size of the input.  {m, n} will give a size of m x n
 * @param columnDimensions        The size of the 2 dimensional array of columns
 */
HelloSP(int[] inputDimensions, int[] columnDimensions) {
    inputSize = 1;
    columnNumber = 1;
    for (int x : inputDimensions) {
        inputSize *= x;
    }
    for (int x : columnDimensions) {
        columnNumber *= x;
    }
    activeArray = new int[columnNumber];
    
    parameters = Parameters.getSpatialDefaultParameters();
    parameters.setParameterByKey(KEY.INPUT_DIMENSIONS, inputDimensions);
    parameters.setParameterByKey(KEY.COLUMN_DIMENSIONS, columnDimensions);
    parameters.setParameterByKey(KEY.POTENTIAL_RADIUS, inputSize);
    parameters.setParameterByKey(KEY.GLOBAL_INHIBITIONS, true);
    parameters.setParameterByKey(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 0.02*columnNumber);
    parameters.setParameterByKey(KEY.SYN_PERM_ACTIVE_INC, 0.01);
    parameters.setParameterByKey(KEY.SYN_PERM_TRIM_THRESHOLD, 0.005);

    sp = new SpatialPooler();
    mem = new Connections();
    parameters.apply(mem);
    sp.init(mem);
}

And here is the usage:

public static void main(String args[]) {
    HelloSP example = new HelloSP(new int[]{32, 32}, new int[]{64, 64});
    
    // Lesson 1
    System.out.println("\n \nFollowing columns represent the SDR");
    System.out.println("Different set of columns each time since we randomize the input");
    System.out.println("Lesson - different input vectors give different SDRs\n\n");
    
    //Trying random vectors
    for (int i = 0; i < 3; i++) {
        example.createInput();
        example.run();
    }
    
    //Lesson 2
    System.out.println("\n\nIdentical SDRs because we give identical inputs");
    System.out.println("Lesson - identical inputs give identical SDRs\n\n");

    for (int i = 0; i < 75; i++) System.out.print("-");
    System.out.print("Using identical input vectors");
    for (int i = 0; i < 75; i++) System.out.print("-");
    System.out.println();

    //Trying identical vectors
    for (int i = 0; i < 2; i++) {
      example.run();
    }
    
    // Lesson 3
    System.out.println("\n\nNow we are changing the input vector slightly.");
    System.out.println("We change a small percentage of 1s to 0s and 0s to 1s.");
    System.out.println("The resulting SDRs are similar, but not identical to the original SDR");
    System.out.println("Lesson - Similar input vectors give similar SDRs\n\n");

    // Adding 10% noise to the input vector
    // Notice how the output SDR hardly changes at all
    for (int i = 0; i < 75; i++) System.out.print("-");
    System.out.print("After adding 10% noise to the input vector");
    for (int i = 0; i < 75; i++) System.out.print("-");
    example.addNoise(0.1);
    example.run();

    // Adding another 20% noise to the already modified input vector
    // The output SDR should differ considerably from that of the previous output
    for (int i = 0; i < 75; i++) System.out.print("-");
    System.out.print("After adding another 20% noise to the input vector");
    for (int i = 0; i < 75; i++) System.out.print("-");
    example.addNoise(0.2);
    example.run();
}

Running this example code prints out the resulting SDRs to the console like this:

Now we are changing the input vector slightly.
We change a small percentage of 1s to 0s and 0s to 1s.
The resulting SDRs are similar, but not identical to the original SDR
Lesson - Similar input vectors give similar SDRs


---------------------------------------------------------------------------After adding 10% noise to the input vector-----------------------------------------------------------------------------------------------------------------------------------------------------------Computing the SDR----------------------------------------------------------------------
[63, 197, 286, 360, 400, 517, 518, 559, 561, 587, 590, 611, 619, 645, 704, 811, 1022, 1065, 1184, 1407, 1461, 1554, 1574, 1652, 1686, 1704, 1765, 1772, 1849, 1871, 1945, 2090, 2125, 2159, 2203, 2213, 2233, 2288, 2358, 2367, 2415, 2434, 2462, 2599, 2609, 2617, 2755, 2862, 2889, 2938, 2967, 2976, 2995, 3010, 3018, 3057, 3104, 3126, 3226, 3341, 3370, 3373, 3394, 3398, 3399, 3479, 3484, 3540, 3637, 3662, 3669, 3712, 3754, 3817, 3875, 3915, 3941, 3977, 3989, 4034, 4082]
---------------------------------------------------------------------------After adding another 20% noise to the input vector-----------------------------------------------------------------------------------------------------------------------------------------------------------Computing the SDR----------------------------------------------------------------------
[63, 197, 286, 310, 360, 400, 418, 517, 518, 559, 561, 587, 611, 619, 704, 811, 1022, 1065, 1184, 1248, 1461, 1485, 1552, 1554, 1574, 1611, 1652, 1669, 1686, 1704, 1772, 1849, 2090, 2125, 2159, 2203, 2213, 2233, 2367, 2415, 2434, 2462, 2545, 2599, 2609, 2617, 2755, 2846, 2862, 2889, 2938, 2967, 2976, 2995, 3008, 3010, 3018, 3057, 3104, 3106, 3126, 3226, 3264, 3341, 3370, 3394, 3399, 3479, 3484, 3540, 3637, 3664, 3669, 3712, 3875, 3915, 3959, 3977, 3989, 4034, 4082]

This is an outstanding milestone for Numenta, NuPIC and the NuPIC community because of all the advantages the Java language brings with it. It shows that the NuPIC community contains a full and vibrant user base that is very committed to the success of NuPIC and HTM technologies. The development of the Java version by the NuPIC community also validates the choice of making NuPIC open source, showing that its community desires a fully compliant version of NuPIC that is easy to manage, install and widely applicable.

Want to get involved?

Are you a Java programmer interested in neocortically-inspired machine intelligence? Check out the htm.java road map and find out where we need help. Create some sample applications and get your feet wet with HTM on the JVM.


On a personal note, I’d like to give a big thank you to David Ray. He came to us earlier this year with a plan for this Java port and the full intention of giving the codebase over to Numenta for management. Over the past several months, he has worked tirelessly reading the NuPIC codebase and painstakingly creating Java versions of all our algorithms. Congratulations to David for reaching this milestone and creating a complete port of NuPIC.

Matt Taylor
Open Source Community Flag-Bearer
Numenta, Inc.

Comments on Reddit


Top

24 Nov 2014

Introducing NuPIC Studio

Hello NuPICers!

I am introducing a nice tool for the NuPIC community. NuPIC Studio is a powerful all-in-one tool that allows users create an HTM network from scratch, train it, collect statistics, and share it among the members of the community.

NuStudio Screenshot

It is not just a visualization tool but an HTM builder, debugger and laboratory for experiments. It is ideal for newbies with little intimacy with NuPIC code as well as experts that wish for better productivity. Among its features and advantages are:

NuStudio Screenshot

NuStudio Screenshot

The project’s site is: https://github.com/nupic-community/nupic.studio

Enjoy!

David Ragazzi
NuPIC Committer
MSc in Software Engineering (University of Liverpool)

Comments on Reddit


Top