/* --------------------------------------------------------------------- * Numenta Platform for Intelligent Computing (NuPIC) * Copyright (C) 2014, Numenta, Inc. Unless you have an agreement * with Numenta, Inc., for a separate license for this software code, the * following terms and conditions apply: * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses. * * http://numenta.org/licenses/ * --------------------------------------------------------------------- */ package org.numenta.nupic.examples.sp; import java.util.Arrays; import java.util.Random; import org.numenta.nupic.Parameters; import org.numenta.nupic.Parameters.KEY; import org.numenta.nupic.algorithms.SpatialPooler; import org.numenta.nupic.model.Connections; import org.numenta.nupic.util.ArrayUtils; import org.numenta.nupic.util.Condition; /** * A simple program that demonstrates the working of the spatial pooler * * @author Neal Miller */ public class HelloSP { private SpatialPooler sp; private Parameters parameters; private Connections mem; private int[] inputArray; private int[] activeArray; private int inputSize; private int columnNumber; /** * * @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.set(KEY.INPUT_DIMENSIONS, inputDimensions); parameters.set(KEY.COLUMN_DIMENSIONS, columnDimensions); parameters.set(KEY.POTENTIAL_RADIUS, inputSize); parameters.set(KEY.GLOBAL_INHIBITION, true); parameters.set(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 0.02*columnNumber); parameters.set(KEY.SYN_PERM_ACTIVE_INC, 0.01); parameters.set(KEY.SYN_PERM_TRIM_THRESHOLD, 0.005); sp = new SpatialPooler(); mem = new Connections(); parameters.apply(mem); sp.init(mem); } /** * Create a random input vector */ public void createInput() { for (int i = 0; i < 70; i++) System.out.print("-"); System.out.print("Creating a random input vector"); for (int i = 0; i < 70; i++) System.out.print("-"); System.out.println(); inputArray = new int[inputSize]; Random rand = new Random(); for (int i = 0; i < inputSize; i++) { // nextInt(2) returns 0 or 1 inputArray[i] = rand.nextInt(2); } } /** * Run the spatial pooler with the input vector */ public void run() { for (int i = 0; i < 80; i++) System.out.print("-"); System.out.print("Computing the SDR"); for (int i = 0; i < 70; i++) System.out.print("-"); System.out.println(); sp.compute(mem, inputArray, activeArray, true); int[] res = ArrayUtils.where(activeArray, new Condition.Adapter<Object>() { public boolean eval(int n) { return n > 0; } }); System.out.println(Arrays.toString(res)); } /** * Flip the value of a fraction of input bits (add noise) * @param noiseLevel The percentage of total input bits that should be flipped */ public void addNoise(double noiseLevel) { Random rand = new Random(); for (int i = 0; i < noiseLevel*inputSize; i++) { int randomPosition = rand.nextInt(inputSize); // Flipping the bit at the randomly picked position inputArray[randomPosition] = 1 - inputArray[randomPosition]; } } 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(); } }