Multi Step Predictions in Java

Hi
Pls let me know how to configure java code to get future predictions . suppose I want to know next 6 predictions . I found lot of examples in Python not in Java

It seems current HTM Java version is not giving option to developer to pass number of steps ,
the below piece of code in Layer.java limiting multi step prediction in java , I made some change to in order to work.

ca[i] = new SDRClassifier();

  /**
     * Creates the {@link NamedTuple} of names to encoders used in the
     * observable sequence.
     * 
     * @param encoder
     * @return
     */
    @SuppressWarnings("unchecked")
    NamedTuple makeClassifiers(MultiEncoder encoder) {
        Map<String, Class<? extends Classifier>> inferredFields = (Map<String, Class<? extends Classifier>>) params.get(KEY.INFERRED_FIELDS);
        if(inferredFields == null || inferredFields.entrySet().size() == 0) {
            throw new IllegalStateException(
                    "KEY.AUTO_CLASSIFY has been set to \"true\", but KEY.INFERRED_FIELDS is null or\n\t" +
                    "empty. Must specify desired Classifier for at least one input field in\n\t" +
                    "KEY.INFERRED_FIELDS or set KEY.AUTO_CLASSIFY to \"false\" (which is its default\n\t" +
                    "value in Parameters)."
            );
        }
        String[] names = new String[encoder.getEncoders(encoder).size()];
        Classifier[] ca = new Classifier[names.length];
        int i = 0;
        for(EncoderTuple et : encoder.getEncoders(encoder)) {
            names[i] = et.getName();
            Class fieldClassifier = inferredFields.get(et.getName());
            if(fieldClassifier == null) {
                LOGGER.info("Not classifying \"" + et.getName() + "\" input field");
            }
            else if(CLAClassifier.class.isAssignableFrom(fieldClassifier)) {
                LOGGER.info("Classifying \"" + et.getName() + "\" input field with CLAClassifier");
                ca[i] = new CLAClassifier();
            }
            else if(SDRClassifier.class.isAssignableFrom(fieldClassifier)) {
                LOGGER.info("Classifying \"" + et.getName() + "\" input field with SDRClassifier");

                ca[i] = new SDRClassifier();
            }
            else {
                throw new IllegalStateException(
                        "Invalid Classifier class token, \"" + fieldClassifier + "\",\n\t" +
                        "specified for, \"" + et.getName() + "\", input field.\n\t" +
                        "Valid class tokens are CLAClassifier.class and SDRClassifier.class"
                );
            }
            i++;
        }
        return new NamedTuple(names, (Object[])ca);
    }

I had to make some change in the

@wip_user Today is a holiday (actually it has been a 4-day weekend for many) in the US so @cogmission probably won’t see this for a bit.

No Issues , I can wait long I dont want to disturb anyone holidays including your holidays :slight_smile:

1 Like

Hi @wip_user,

(Thanks @rhyolight, I was indeed AFK for a couple of days)

It’s true that the current version of HTM.Java’s Network API doesn’t offer the setting of more than one step ahead with predictions. At the time, it wasn’t seen as critical feature to support - but if you’d like, you can create an issue in the project and I can take a look at it and add the feature? Or you can fill out a Contributor’s License and submit a Pull Request with your own work? It can be very rewarding to contribute to open source, if you haven’t done it before… It’s up to you - I’m happy to work on it if you’d rather that?

Also, if anyone else would like to work on that feature, it should be fairly straightforward and could possibly lead to Fame and Fortune! :slight_smile:

1 Like

Thanks David , currently I have done in crude way , I will find out right way of doing .

Thanks & Regards
MH

1 Like

Please, tell how could I contrbute. Could you point me the directions? I’d be glad to contribute.

1 Like

Cogmission, I think the main change I have to do is bellow:

Replace this line

ca[i] = new SDRClassifier();

With this one:

ca[i] = new SDRClassifier(new TIntArrayList(steps), 0.001, 0.3, 0);

Now, my doubt is: where do I find the inferred field steps configuration in order to fill the step array?

I think I will have to create a new parameter in Parameter.java like this:

INFERENCE_STEPS(“inferenceSteps”, int[].class),

It is working now!

MyNetworkHarness.java

p.set(KEY.INFERRED_FIELDS, getInferredFieldsMap(inferenceField, SDRClassifier.class));
p.set(KEY.INFERRED_STEPS, new int[]{1, 2, 3, 10, 100});

`

defaultEncoderParams.put(KEY.INFERRED_STEPS, new int{1});

`

The new method on Layer.java

@SuppressWarnings("unchecked")
    NamedTuple makeClassifiers(MultiEncoder encoder) {
        Map<String, Class<? extends Classifier>> inferredFields = (Map<String, Class<? extends Classifier>>) params.get(KEY.INFERRED_FIELDS);
        int[] steps  = (int[]) params.get(KEY.INFERRED_STEPS);
        if(inferredFields == null || inferredFields.entrySet().size() == 0) {
            throw new IllegalStateException(
                    "KEY.AUTO_CLASSIFY has been set to \"true\", but KEY.INFERRED_FIELDS is null or\n\t" +
                    "empty. Must specify desired Classifier for at least one input field in\n\t" +
                    "KEY.INFERRED_FIELDS or set KEY.AUTO_CLASSIFY to \"false\" (which is its default\n\t" +
                    "value in Parameters)."
            );
        }
        
        String[] names = new String[encoder.getEncoders(encoder).size()];
        Classifier[] ca = new Classifier[names.length];
        int i = 0;
        for(EncoderTuple et : encoder.getEncoders(encoder)) {
            names[i] = et.getName();
            Class fieldClassifier = inferredFields.get(et.getName());
            if(fieldClassifier == null) {
                LOGGER.info("Not classifying \"" + et.getName() + "\" input field");
            }
            else if(CLAClassifier.class.isAssignableFrom(fieldClassifier)) {
                LOGGER.info("Classifying \"" + et.getName() + "\" input field with CLAClassifier");            
                ca[i] = new CLAClassifier(new TIntArrayList(steps), 0.001, 0.3, 0);
            }
            else if(SDRClassifier.class.isAssignableFrom(fieldClassifier)) {
                LOGGER.info("Classifying \"" + et.getName() + "\" input field with SDRClassifier");
                ca[i] = new  SDRClassifier(new TIntArrayList(steps), 0.001, 0.3, 0);
            }
            else {
                throw new IllegalStateException(
                        "Invalid Classifier class token, \"" + fieldClassifier + "\",\n\t" +
                        "specified for, \"" + et.getName() + "\", input field.\n\t" +
                        "Valid class tokens are CLAClassifier.class and SDRClassifier.class"
                );
            }
            i++;
        }
        return new NamedTuple(names, (Object[])ca);
    }
1 Like

Now, how do I submit this code to the github project?

@Matheus_Araujo,

Hi,

Congrats for getting your code working! That’s very exciting!

In order to submit code, there are a few steps… I will start from the assumption however that you are already familiar with Git, because the subject of git management is a lengthy conversation.

  1. You will need to create an issue in the project.
  2. You will have to fill out the Numenta Contributor’s License which will then be approved by @rhyolight (Matt Taylor).
  3. You will need to fork the project, and create a branch off of “Main” to submit your code.
  4. You then commit your code on that branch and push it up to your repository.
  5. You then create a PR (Pull Request) and in the topic you put the words “Fixes #”. (see other PR’s under closed to see how it looks)

It’s a shorter process than what it looks like here. Only made longer because this is your first time…

Good luck! Let me know if you have any other questions?

Cheers,
David

cogmission, I had created created an issue long ago and I have signed th contributor license too. Now I created a new pull request but haven’t done the FIX# thing…

And I see now that I hae sent some modifications I made to some files in order to have it running under my corporate proxy through cntlm proxy tunneling.

My pull request: https://github.com/numenta/htm.java/pull/544

My fork: https://github.com/matheus-fatguys/htm.java

My Issues:


Sorry, but this is my first free software contribution and I’m not used to it.

I’ve updated the PR comment and now it is as bellow:

Fixes #543 #542
Enabling the Network API to create multi step inferences and fixing a bug in multiencoder that prevented one from using coordinate encoder