SensorFlags set to 'L' in HTM.java

PublisherSupplier supplier = PublisherSupplier.builder()
    .addHeader("timestamp, value")
    .addHeader("datetime, float")
    .addHeader("T, B") //see SensorFlags.java for more info
    .build();

This is a commonly used example. For the float type metric ‘value’, the sensor flag is set to ‘B’ (meaning Blank). If I set it to ‘L’ (learn), I get the following exception:
Caused by: java.lang.NumberFormatException: For input string which is ‘value’.

The type of ‘value’ is double (e.g. 4.000). It’s caused because it tries to parse the value as Integer (because Integer.parseInt(String s) is called in the stacktrace).

Any idea why?
Thanks in advance!

Could you send your stack trace?

java.lang.RuntimeException: Unhandled Exception in Sensor Layer [region1:layer2/3] Thread
at org.numenta.nupic.network.Layer$6.uncaughtException(Layer.java:2054)
at java.lang.Thread.dispatchUncaughtException(Thread.java:1959)
Caused by: java.lang.NumberFormatException: For input string: “4.000”
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at org.numenta.nupic.network.sensor.Header.process(Header.java:168)
at org.numenta.nupic.network.sensor.HTMSensor.processHeader(HTMSensor.java:631)
at org.numenta.nupic.network.sensor.HTMSensor.input(HTMSensor.java:427)
at org.numenta.nupic.network.sensor.HTMSensor.lambda$0(HTMSensor.java:362)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1812)
at java.util.stream.StreamSpliterators$WrappingSpliterator.lambda$initPartialTraversalState$0(StreamSpliterators.java:294)
at java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.fillBuffer(StreamSpliterators.java:206)
at java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.doAdvance(StreamSpliterators.java:161)
at java.util.stream.StreamSpliterators$WrappingSpliterator.tryAdvance(StreamSpliterators.java:300)
at java.util.Spliterators$1Adapter.hasNext(Spliterators.java:681)
at org.numenta.nupic.network.sensor.HTMSensor$Copy.hasNext(HTMSensor.java:280)
at java.util.Iterator.forEachRemaining(Iterator.java:115)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.numenta.nupic.network.Layer$5.run(Layer.java:2037)
java.lang.RuntimeException: Unhandled Exception in Sensor Layer [region1:layer2/3] Thread
at org.numenta.nupic.network.Layer$6.uncaughtException(Layer.java:2054)
at java.lang.Thread.dispatchUncaughtException(Thread.java:1959)

The code snippet is like this:

Publisher manualPublisher = Publisher.builder().addHeader("consumption").addHeader("float").addHeader("L").build();

When I set the header ‘B’ (Blank), my code runs fine. On setting as ‘L’, the input is interpreted as integer value by default, even though I’ve specified it as a float. Why is this and how do I fix it?

This is the code snippet that is throwing your exception

if(learnIndexes.length > 0) {
for(int i : learnIndexes) {
if(Integer.parseInt(input[i].trim()) == 1) {
isLearn = true; break;
}else{
isLearn = false;
}
}
}

More specifically, this line of code below:

            if(Integer.parseInt(input[i].trim()) == 1) {

It seems that the code expects your input to be 0 or 1, if it is 1, then it starts learning.
So it seems that it cant be a field which holds your consumption information.

I’ve found on the test set this file: rec-center-hourly-4learn.csv
Its header is like this:

timestamp,consumption
datetime,float
T,L

And its input lines are like this:

7/2/10 0:00,21.2,1
7/2/10 1:00,16.4,1
7/2/10 2:00,4.7,1

So, as you can see, the L flag is set in another field that tells HTM to learn or not that spcific input. What makes sense to me.

So, your code should be:

Publis

PubliherSupplier supplier > = PublisherSupplier.builder()
.addHeader(“consumption”)
.addHeader(“float”)
.addHeader(“,L”)
.build();

And your input should have your consumption value AND another field telling HTM to learn that input(1) or not(0).

**-> You should use PubliherSupplier in order to persist and later retrieve your network.

2 Likes

Bellow is the test case for the learning header:

@Test
public void testProcessLearn() {
Header header = new Header(getTestHeaderOff());
List<String> lines = getLines(ResourceLocator.path(“rec-center-hourly-4period.csv”));

    for(String[] line: lines) {
        header.process(line);
        assertFalse(header.isReset());
        assertTrue(header.isLearn());
    }
    
    header = new Header(getTestHeaderLearn());
    lines = getLines(ResourceLocator.path("rec-center-hourly-4learn.csv"));
   
    int idx = 0;
    for(String[] line : lines) {
        String[] shifted = new String[line.length + 1];
        System.arraycopy(line, 0, shifted, 1, line.length);
        shifted[0] = String.valueOf(idx);
        
        if(idx == 72) {
            idx = 72;
        }
        
        header.process(shifted);
        
        if(line[2].equals("1")) {
            assertTrue(header.isLearn());
        }else{
            assertFalse(header.isLearn());
        }
        idx++;
    }
}
3 Likes

I see what I did wrong. I’ll set the L flag in an additional field and run on my input.
Thank you this was extremely helpful!

4 Likes