Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Classifier Region #761

Closed
dkeeney opened this issue Nov 20, 2019 · 5 comments
Closed

Classifier Region #761

dkeeney opened this issue Nov 20, 2019 · 5 comments
Assignees

Comments

@dkeeney
Copy link

dkeeney commented Nov 20, 2019

I started looking at what it will take to build a Predictor Region.
The Predictor class is in SDRClassifier.cpp along with the Classifier class.

It looks like the Predictor class usage is quite different from the Classifier. Perhaps different enough that perhaps I should have a PredictorRegion and a separate ClassifierRegion.

@dkeeney
Copy link
Author

dkeeney commented Nov 21, 2019

Looking just at the PredictorRegion: The comments in the code are not much help in figuring out how to use this thing. I am having to do a lot of guessing and I am not sure I have it right.

This is what I have so far for the Spec

  {name: "PredictorRegion",
      parameters: {
          steps:        { description: "The number of steps into the future to learn and predict.  This is an array.",
                               type: UInt32, count: 0, default: "0"},  
          alpha:         { description: "The alpha used to adapt the weight matrix during learning. A larger alpha results in faster adaptation to the data.",
                               type: Real32,  default: "0.001"},
          resolution:  { description: "?? ", 
                               type: UInt32,   default: "1"}
          infer:           { description: "if true, it performs the infer step",
                               type: Bool, default: "true"}
          learn:          { description: "if true, it performs the learn step".
                               type: Bool, default: "true"}
           categories:  { description: "The categories or buckets used by the encoder",
                                type: Real64 }
           predictions: { description: "Predictions for the next n steps. The values are a PDF (probability distribution function), of the result being in each bucket or category"
                               type:  ??, count: 0, access: ReadOnly } 
            accuracy:    { description: "How accurate were the predictions. One number for each category.",
                               type:  Real64, count: 0, access: ReadOnly }
      },
      inputs: {
          rawdata: { description: "the same thing passed to encoder, for the learn step",
                           type: Real64,  count: 1},  
          reset:       {type: Bool, count: 1}
          pattern:  {description:  "activeCells from TM",  
                          type: SDR } 
      }, 
      outputs: {
      }
}
  • infer, learn flags indicate if the infer or learn steps are to happen respectively.
  • The predictions parameter should be a map containing a vector of Reals for each category. We don't have a way to return that. Something to think about. Maybe I could have the predictions parameter return a vector for a specific key or category.
  • At the end of a run an app would access the predictions and accuracy parameters and use those for the plot. I have these as parameters so that all of those calculations don't occur until we want to get the data. But if we want to pass these to another region they would have to be outputs.
  • What we really need is a way to tell NetworkAPI to pass this to a region for ploting AFTER all iterations are complete. Currently all regions are executed during an execution cycle and nothing after. Perhaps we need an "initialization" phase and a "wrapup" phase that regions can be assigned to. Something more to consider.

@dkeeney dkeeney self-assigned this Nov 21, 2019
@breznak
Copy link
Member

breznak commented Nov 22, 2019

@dkeeney I'll try to answer the questions.

Perhaps different enough that perhaps I should have a PredictorRegion and a separate ClassifierRegion

I'd start with a ClassifierRegion and then we'll see. But Likely yes.

steps: { description: "The number of steps into the future to learn and predict.

"Array of n-steps ahead we want to learn and predict" (value 0 makes no sense for a Predictor, it degrades it to a Classifier)

alpha:

the learning should be quite simple for the MLP given SDR, so users typically don't need to fiddle with that.

resolution:

I think this should not be a param of the Region. There's no resolution used in a Classifier/Predictor.
The doc uses it to illustrate how to get desired number of categories, if you don't know it be default (ie in MNIST you know it - 10)

// Estimate a scalar value. The Classifier only accepts categories, so

  • // put real valued inputs into bins (AKA buckets) by subtracting the
  • // minimum value and dividing by a resolution.

categories:

must be an integer. This is the problem above, converting "any real" values into integer type bins (aggregating)

predictions: { description: "Predictions for the next n steps. The values are a PDF (probability distribution function), of the result being in each bucket or category"
type: ??

type either just PDF (which is vector<Real>)

accuracy: { description: "How accurate were the predictions. One number for each category."

interesting, we don't have that in the Classifier. Might add. Maybe better computed overall than for each cat.

The predictions parameter should be a map containing a vector of Reals for each category

not vector for each cat, but a real for each. I'm not sure how this was meant.

What we really need is a way to tell NetworkAPI to pass this to a region for ploting AFTER all iterations are complete

I think the plotting should be online, ie redrawn for each iteration (internally the plotter would do some caching for efficiency). But I don't think we should worry about a plot now.

@dkeeney
Copy link
Author

dkeeney commented Nov 22, 2019

Thanks for your comments.

I'd start with a ClassifierRegion

I think you are right. I will do that first.
Basically a classifier is something like this:

      TM ---pattern--->[ Classifier ] ---PDF---->
``
If the user wants a predictor they can line up multiple Classifiers, one for each n-steps into the future.

@dkeeney dkeeney changed the title Predictor Region Classifier Region Nov 29, 2019
@dkeeney
Copy link
Author

dkeeney commented Nov 29, 2019

Unless I am missing something, the SDRClassifier depends on knowing all of the buckets that were used by the original encoding. It needs the list of titles, indexed by the bucket index. Its output is an array giving the probability for each of the bucket indexes.

The RDSE encoder cannot give us the buckets. So that encoder would not be directly usable with the SDRClassifier. However, I got to thinking about how we might make it usable. Perhaps we could do this by recorded the actual values mapped to the indexes that were actually used (the index that is hashed). Of course the RDSE encoder only works if the number of indexes actually used is significantly smaller than the width of the hash so that the number of collisions is held to a minimum. We really should have a tool that can be used to evaluate the data set to determine if the RDSE encoder is even appropriate. But that is another topic.

Anyway, what if we had an array which held the quantized floating point value that corresponds to each of the buckets that were actually used rather than the buckets that could possibility be used. The SDRClassifier could then be given an index into that array along with the pattern while learning. The RDSE encoder could build a map and each time it found a value that it did not already have, it would add it to this map. But that complicates the RDSE encoder and adds extra computations for a structure that would be used only if an SDRClassifier was also being used. So, what if we moved that to the Classifier. Let the Classifier accumulate the' actual used map'.

  • when starting out, the array of used values would be empty.
  • as each value is encoded, its original value is also passed to the SDRClassifier along with the pattern and if this is a new value it is added to the array.
  • As time went by the array of used values would accumulate and it would learn new correspondences to the resulting patterns.
  • Classifier would start out with really bad results but eventually I would think it would converge as the number of actually used values stabilizes.

Anyway, what do you think?

@dkeeney
Copy link
Author

dkeeney commented Nov 30, 2019

I was reading the comments on PR #680 and it sounds like I was evolving in that same direction. A map in the SDRClassifier to use in mapping patterns back to their original values...which in my case were doubles from the RDSE encoder. Perhaps with a little more thought we could come up with a way that decodes multiple decodings when multiple encoders are used (i.e. date encoder, etc).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants