示例#1
0
 def compile(self):
     spParams = self.setting("sp")
     self.sp = SpatialPooler(
         inputDimensions=self.input_shape,
         columnDimensions=self.output_shape,
         potentialPct=spParams.potentialPct,
         potentialRadius=spParams.potentialRadius,
         globalInhibition=True if len(self.output_shape) == 1 else False,
         localAreaDensity=spParams.localAreaDensity,
         synPermInactiveDec=spParams.synPermInactiveDec,
         synPermActiveInc=spParams.synPermActiveInc,
         synPermConnected=spParams.synPermConnected,
         boostStrength=spParams.boostStrength,
         wrapAround=True,
     )
     if self.temporal:
         tmParams = self.setting("tm")
         self.tm = TemporalMemory(
             columnDimensions=self.output_shape,
             cellsPerColumn=tmParams.cellsPerColumn,
             activationThreshold=tmParams.activationThreshold,
             initialPermanence=tmParams.initialPerm,
             connectedPermanence=spParams.synPermConnected,
             minThreshold=tmParams.minThreshold,
             maxNewSynapseCount=tmParams.newSynapseCount,
             permanenceIncrement=tmParams.permanenceInc,
             permanenceDecrement=tmParams.permanenceDec,
             predictedSegmentDecrement=0.0,
             maxSegmentsPerCell=tmParams.maxSegmentsPerCell,
             maxSynapsesPerSegment=tmParams.maxSynapsesPerSegment)
示例#2
0
    def initialize(self):
        # Setup Encoders
        self.encTimestamp = DateEncoder(timeOfDay=self.parameters["enc"]["time"]["timeOfDay"])
        for idx, (key, value) in enumerate(self.init_min_max.items()):
            self.scalar_encoders.append({
                'idx': idx,
                'name': key,
                'encoder':  self._createRDSE(min_val=value['min'], max_val=value['max'])
            })

        self.enc_width = self.encTimestamp.size + sum([enc_info.get('encoder').size for enc_info in self.scalar_encoders])

        # Make the HTM.  SpatialPooler & TemporalMemory & associated tools.
        # SpatialPooler
        spParams = self.parameters["sp"]
        self.sp = SpatialPooler(
            inputDimensions=(self.enc_width,),
            columnDimensions=(spParams["columnDimensions"],),
            potentialRadius=self.enc_width,
            potentialPct=spParams["potentialPct"],
            globalInhibition=spParams["globalInhibition"],
            localAreaDensity=spParams["localAreaDensity"],
            numActiveColumnsPerInhArea=spParams["numActiveColumnsPerInhArea"],
            stimulusThreshold=spParams["stimulusThreshold"],
            synPermInactiveDec=spParams["synPermInactiveDec"],
            synPermActiveInc=spParams["synPermActiveInc"],
            synPermConnected=spParams["synPermConnected"],
            boostStrength=spParams["boostStrength"],
            wrapAround=spParams["wrapAround"],
            minPctOverlapDutyCycle=spParams["minPctOverlapDutyCycle"],
            dutyCyclePeriod=spParams["dutyCyclePeriod"],
            seed=spParams["seed"],
        )

        # TemporalMemory
        tmParams = self.parameters["tm"]
        self.tm = TemporalMemory(
            columnDimensions=(spParams["columnDimensions"],),
            cellsPerColumn=tmParams["cellsPerColumn"],
            activationThreshold=tmParams["activationThreshold"],
            initialPermanence=tmParams["initialPermanence"],
            connectedPermanence=tmParams["connectedPermanence"],
            minThreshold=tmParams["minThreshold"],
            maxNewSynapseCount=tmParams["maxNewSynapseCount"],
            permanenceIncrement=tmParams["permanenceIncrement"],
            permanenceDecrement=tmParams["permanenceDecrement"],
            predictedSegmentDecrement=tmParams["predictedSegmentDecrement"],
            maxSegmentsPerCell=tmParams["maxSegmentsPerCell"],
            maxSynapsesPerSegment=tmParams["maxSynapsesPerSegment"],
            seed=tmParams["seed"]
        )

        anParams = self.parameters["anomaly"]["likelihood"]
        self.learningPeriod = int(math.floor(self.probationaryPeriod / 2.0))
        self.anomalyLikelihood = AnomalyLikelihood(
            learningPeriod=self.learningPeriod,
            estimationSamples=self.probationaryPeriod - self.learningPeriod,
            reestimationPeriod=anParams["reestimationPeriod"])
示例#3
0
 def __init__(self,
              din=(10, 10),
              dout=(10, 10),
              temporal=True,
              setting=param.default_parameters):
     self.input_shape = din
     self.output_shape = dout
     self.temporal = temporal
     self.learn = True
     self.setting = AttrDict(setting)
     self.sp = SpatialPooler()
     self.tm = TemporalMemory() if temporal else None
示例#4
0
def main(parameters=default_parameters, argv=None, verbose=True):

    # Load data.
    train_labels, train_images, test_labels, test_images = load_ds(
        'mnist_784', 10000, shape=[28, 28])  # HTM: ~95.6%
    #train_labels, train_images, test_labels, test_images = load_ds('Fashion-MNIST', 10000, shape=[28,28]) # HTM baseline: ~83%

    training_data = list(zip(train_images, train_labels))
    test_data = list(zip(test_images, test_labels))
    random.shuffle(training_data)

    # Setup the AI.
    enc = SDR(train_images[0].shape)
    sp = SpatialPooler(
        inputDimensions=enc.dimensions,
        columnDimensions=parameters['columnDimensions'],
        potentialRadius=parameters['potentialRadius'],
        potentialPct=parameters['potentialPct'],
        globalInhibition=True,
        localAreaDensity=parameters['localAreaDensity'],
        stimulusThreshold=int(round(parameters['stimulusThreshold'])),
        synPermInactiveDec=parameters['synPermInactiveDec'],
        synPermActiveInc=parameters['synPermActiveInc'],
        synPermConnected=parameters['synPermConnected'],
        minPctOverlapDutyCycle=parameters['minPctOverlapDutyCycle'],
        dutyCyclePeriod=int(round(parameters['dutyCyclePeriod'])),
        boostStrength=parameters['boostStrength'],
        seed=
        0,  # this is important, 0="random" seed which changes on each invocation
        spVerbosity=99,
        wrapAround=False)
    columns = SDR(sp.getColumnDimensions())
    columns_stats = Metrics(columns, 99999999)
    sdrc = Classifier()

    # Training Loop
    for i in range(len(train_images)):
        img, lbl = training_data[i]
        encode(img, enc)
        sp.compute(enc, True, columns)
        sdrc.learn(
            columns, lbl
        )  #TODO SDRClassifier could accept string as a label, currently must be int

    print(str(sp))
    print(str(columns_stats))

    # Testing Loop
    score = 0
    for img, lbl in test_data:
        encode(img, enc)
        sp.compute(enc, False, columns)
        if lbl == np.argmax(sdrc.infer(columns)):
            score += 1
    score = score / len(test_data)

    print('Score:', 100 * score, '%')
    return score
    def initialize(self, input_min=0, input_max=0):
        # setup spatial anomaly
        if self.useSpatialAnomaly:
            self.spatial_tolerance = self.parameters["spatial_tolerance"]

        ## setup Enc, SP, TM
        # Make the Encoders.  These will convert input data into binary representations.
        self.encTimestamp = DateEncoder(timeOfDay=self.parameters["enc"]["time"]["timeOfDay"])

        scalarEncoderParams = RDSE_Parameters()
        scalarEncoderParams.size = self.parameters["enc"]["value"]["size"]
        scalarEncoderParams.activeBits = self.parameters["enc"]["value"]["activeBits"]
        scalarEncoderParams.resolution = max(0.001, (input_max - input_min) / 130)
        scalarEncoderParams.seed = self.parameters["enc"]["value"]["seed"]

        self.encValue = RDSE(scalarEncoderParams)
        encodingWidth = (self.encTimestamp.size + self.encValue.size)
        self.enc_info = Metrics([encodingWidth], 999999999)

        # Make the HTM.  SpatialPooler & TemporalMemory & associated tools.
        # SpatialPooler
        spParams = self.parameters["sp"]
        self.sp = SpatialPooler(
            inputDimensions=(encodingWidth,),
            columnDimensions=(spParams["columnDimensions"],),
            potentialRadius=encodingWidth,
            potentialPct=spParams["potentialPct"],
            globalInhibition=spParams["globalInhibition"],
            localAreaDensity=spParams["localAreaDensity"],
            numActiveColumnsPerInhArea=spParams["numActiveColumnsPerInhArea"],
            stimulusThreshold=spParams["stimulusThreshold"],
            synPermInactiveDec=spParams["synPermInactiveDec"],
            synPermActiveInc=spParams["synPermActiveInc"],
            synPermConnected=spParams["synPermConnected"],
            boostStrength=spParams["boostStrength"],
            wrapAround=spParams["wrapAround"],
            minPctOverlapDutyCycle=spParams["minPctOverlapDutyCycle"],
            dutyCyclePeriod=spParams["dutyCyclePeriod"],
            seed=spParams["seed"],
        )
        self.sp_info = Metrics(self.sp.getColumnDimensions(), 999999999)

        # TemporalMemory
        tmParams = self.parameters["tm"]
        self.tm = TemporalMemory(
            columnDimensions=(spParams["columnDimensions"],),
            cellsPerColumn=tmParams["cellsPerColumn"],
            activationThreshold=tmParams["activationThreshold"],
            initialPermanence=tmParams["initialPermanence"],
            connectedPermanence=tmParams["connectedPermanence"],
            minThreshold=tmParams["minThreshold"],
            maxNewSynapseCount=tmParams["maxNewSynapseCount"],
            permanenceIncrement=tmParams["permanenceIncrement"],
            permanenceDecrement=tmParams["permanenceDecrement"],
            predictedSegmentDecrement=tmParams["predictedSegmentDecrement"],
            maxSegmentsPerCell=tmParams["maxSegmentsPerCell"],
            maxSynapsesPerSegment=tmParams["maxSynapsesPerSegment"],
            seed=tmParams["seed"]
        )
        self.tm_info = Metrics([self.tm.numberOfCells()], 999999999)

        anParams = self.parameters["anomaly"]["likelihood"]
        self.learningPeriod = int(math.floor(self.probationaryPeriod / 2.0))
        self.anomalyLikelihood = AnomalyLikelihood(
            learningPeriod=self.learningPeriod,
            estimationSamples=self.probationaryPeriod - self.learningPeriod,
            reestimationPeriod=anParams["reestimationPeriod"])

        self.kernel = self._gauss_kernel(self.historic_raw_anomaly_scores.maxlen,
                                         self.historic_raw_anomaly_scores.maxlen)
示例#6
0
  def initialize(self):
    # toggle parameters here
    if self.use_optimization:
      parameters = get_params('params.json')
    else:
      parameters = parameters_numenta_comparable

    # setup spatial anomaly
    if self.useSpatialAnomaly:
      # Keep track of value range for spatial anomaly detection
      self.minVal = None
      self.maxVal = None

    ## setup Enc, SP, TM, Likelihood
    # Make the Encoders.  These will convert input data into binary representations.
    self.encTimestamp = DateEncoder(timeOfDay= parameters["enc"]["time"]["timeOfDay"],
                                    weekend  = parameters["enc"]["time"]["weekend"])

    scalarEncoderParams            = RDSE_Parameters()
    scalarEncoderParams.size       = parameters["enc"]["value"]["size"]
    scalarEncoderParams.sparsity   = parameters["enc"]["value"]["sparsity"]
    scalarEncoderParams.resolution = parameters["enc"]["value"]["resolution"]

    self.encValue = RDSE( scalarEncoderParams )
    encodingWidth = (self.encTimestamp.size + self.encValue.size)
    self.enc_info = Metrics( [encodingWidth], 999999999 )

    # Make the HTM.  SpatialPooler & TemporalMemory & associated tools.
    # SpatialPooler
    spParams = parameters["sp"]
    self.sp = SpatialPooler(
      inputDimensions            = (encodingWidth,),
      columnDimensions           = (spParams["columnCount"],),
      potentialPct               = spParams["potentialPct"],
      potentialRadius            = encodingWidth,
      globalInhibition           = True,
      localAreaDensity           = spParams["localAreaDensity"],
      synPermInactiveDec         = spParams["synPermInactiveDec"],
      synPermActiveInc           = spParams["synPermActiveInc"],
      synPermConnected           = spParams["synPermConnected"],
      boostStrength              = spParams["boostStrength"],
      wrapAround                 = True
    )
    self.sp_info = Metrics( self.sp.getColumnDimensions(), 999999999 )

    # TemporalMemory
    tmParams = parameters["tm"]
    self.tm = TemporalMemory(
      columnDimensions          = (spParams["columnCount"],),
      cellsPerColumn            = tmParams["cellsPerColumn"],
      activationThreshold       = tmParams["activationThreshold"],
      initialPermanence         = tmParams["initialPerm"],
      connectedPermanence       = spParams["synPermConnected"],
      minThreshold              = tmParams["minThreshold"],
      maxNewSynapseCount        = tmParams["newSynapseCount"],
      permanenceIncrement       = tmParams["permanenceInc"],
      permanenceDecrement       = tmParams["permanenceDec"],
      predictedSegmentDecrement = 0.0,
      maxSegmentsPerCell        = tmParams["maxSegmentsPerCell"],
      maxSynapsesPerSegment     = tmParams["maxSynapsesPerSegment"]
    )
    self.tm_info = Metrics( [self.tm.numberOfCells()], 999999999 )

    # setup likelihood, these settings are used in NAB
    if self.useLikelihood:
      anParams = parameters["anomaly"]["likelihood"]
      learningPeriod     = int(math.floor(self.probationaryPeriod / 2.0))
      self.anomalyLikelihood = AnomalyLikelihood(
                                 learningPeriod= learningPeriod,
                                 estimationSamples= self.probationaryPeriod - learningPeriod,
                                 reestimationPeriod= anParams["reestimationPeriod"])
    # Predictor
    # self.predictor = Predictor( steps=[1, 5], alpha=parameters["predictor"]['sdrc_alpha'] )
    # predictor_resolution = 1

    # initialize pandaBaker
    if PANDA_VIS_BAKE_DATA:
      self.BuildPandaSystem(self.sp, self.tm, parameters["enc"]["value"]["size"], self.encTimestamp.size)
示例#7
0
class HtmcoreDetector(AnomalyDetector):
  """
  This detector uses an HTM based anomaly detection technique.
  """

  def __init__(self, *args, **kwargs):

    super(HtmcoreDetector, self).__init__(*args, **kwargs)

    ## API for controlling settings of htm.core HTM detector:

    # Set this to False if you want to get results based on raw scores
    # without using AnomalyLikelihood. This will give worse results, but
    # useful for checking the efficacy of AnomalyLikelihood. You will need
    # to re-optimize the thresholds when running with this setting.
    self.useLikelihood      = True
    self.useSpatialAnomaly  = True
    self.verbose            = True

    # Set this to true if you want to use the optimization.
    # If true, it reads the parameters from ./params.json
    # If false, it reads the parameters from ./best_params.json
    self.use_optimization   = False

    ## internal members 
    # (listed here for easier understanding)
    # initialized in `initialize()`
    self.encTimestamp   = None
    self.encValue       = None
    self.sp             = None
    self.tm             = None
    self.anLike         = None
    # optional debug info
    self.enc_info       = None
    self.sp_info        = None
    self.tm_info        = None
    # internal helper variables:
    self.inputs_ = []
    self.iteration_ = 0


  def getAdditionalHeaders(self):
    """Returns a list of strings."""
    return ["raw_score"] #TODO optional: add "prediction"


  def handleRecord(self, inputData):
    """Returns a tuple (anomalyScore, rawScore).

    @param inputData is a dict {"timestamp" : Timestamp(), "value" : float}

    @return tuple (anomalyScore, <any other fields specified in `getAdditionalHeaders()`>, ...)
    """
    # Send it to Numenta detector and get back the results
    return self.modelRun(inputData["timestamp"], inputData["value"]) 



  def initialize(self):
    # toggle parameters here
    if self.use_optimization:
      parameters = get_params('params.json')
    else:
      parameters = parameters_numenta_comparable

    # setup spatial anomaly
    if self.useSpatialAnomaly:
      # Keep track of value range for spatial anomaly detection
      self.minVal = None
      self.maxVal = None

    ## setup Enc, SP, TM, Likelihood
    # Make the Encoders.  These will convert input data into binary representations.
    self.encTimestamp = DateEncoder(timeOfDay= parameters["enc"]["time"]["timeOfDay"],
                                    weekend  = parameters["enc"]["time"]["weekend"])

    scalarEncoderParams            = RDSE_Parameters()
    scalarEncoderParams.size       = parameters["enc"]["value"]["size"]
    scalarEncoderParams.sparsity   = parameters["enc"]["value"]["sparsity"]
    scalarEncoderParams.resolution = parameters["enc"]["value"]["resolution"]

    self.encValue = RDSE( scalarEncoderParams )
    encodingWidth = (self.encTimestamp.size + self.encValue.size)
    self.enc_info = Metrics( [encodingWidth], 999999999 )

    # Make the HTM.  SpatialPooler & TemporalMemory & associated tools.
    # SpatialPooler
    spParams = parameters["sp"]
    self.sp = SpatialPooler(
      inputDimensions            = (encodingWidth,),
      columnDimensions           = (spParams["columnCount"],),
      potentialPct               = spParams["potentialPct"],
      potentialRadius            = encodingWidth,
      globalInhibition           = True,
      localAreaDensity           = spParams["localAreaDensity"],
      synPermInactiveDec         = spParams["synPermInactiveDec"],
      synPermActiveInc           = spParams["synPermActiveInc"],
      synPermConnected           = spParams["synPermConnected"],
      boostStrength              = spParams["boostStrength"],
      wrapAround                 = True
    )
    self.sp_info = Metrics( self.sp.getColumnDimensions(), 999999999 )

    # TemporalMemory
    tmParams = parameters["tm"]
    self.tm = TemporalMemory(
      columnDimensions          = (spParams["columnCount"],),
      cellsPerColumn            = tmParams["cellsPerColumn"],
      activationThreshold       = tmParams["activationThreshold"],
      initialPermanence         = tmParams["initialPerm"],
      connectedPermanence       = spParams["synPermConnected"],
      minThreshold              = tmParams["minThreshold"],
      maxNewSynapseCount        = tmParams["newSynapseCount"],
      permanenceIncrement       = tmParams["permanenceInc"],
      permanenceDecrement       = tmParams["permanenceDec"],
      predictedSegmentDecrement = 0.0,
      maxSegmentsPerCell        = tmParams["maxSegmentsPerCell"],
      maxSynapsesPerSegment     = tmParams["maxSynapsesPerSegment"]
    )
    self.tm_info = Metrics( [self.tm.numberOfCells()], 999999999 )

    # setup likelihood, these settings are used in NAB
    if self.useLikelihood:
      anParams = parameters["anomaly"]["likelihood"]
      learningPeriod     = int(math.floor(self.probationaryPeriod / 2.0))
      self.anomalyLikelihood = AnomalyLikelihood(
                                 learningPeriod= learningPeriod,
                                 estimationSamples= self.probationaryPeriod - learningPeriod,
                                 reestimationPeriod= anParams["reestimationPeriod"])
    # Predictor
    # self.predictor = Predictor( steps=[1, 5], alpha=parameters["predictor"]['sdrc_alpha'] )
    # predictor_resolution = 1

    # initialize pandaBaker
    if PANDA_VIS_BAKE_DATA:
      self.BuildPandaSystem(self.sp, self.tm, parameters["enc"]["value"]["size"], self.encTimestamp.size)

  def modelRun(self, ts, val):
      """
         Run a single pass through HTM model

         @params ts - Timestamp
         @params val - float input value

         @return rawAnomalyScore computed for the `val` in this step
      """
      ## run data through our model pipeline: enc -> SP -> TM -> Anomaly
      self.inputs_.append( val )
      self.iteration_ += 1
      
      # 1. Encoding
      # Call the encoders to create bit representations for each value.  These are SDR objects.
      dateBits        = self.encTimestamp.encode(ts)
      valueBits       = self.encValue.encode(float(val))
      # Concatenate all these encodings into one large encoding for Spatial Pooling.
      encoding = SDR( self.encTimestamp.size + self.encValue.size ).concatenate([valueBits, dateBits])
      self.enc_info.addData( encoding )

      # 2. Spatial Pooler
      # Create an SDR to represent active columns, This will be populated by the
      # compute method below. It must have the same dimensions as the Spatial Pooler.
      activeColumns = SDR( self.sp.getColumnDimensions() )
      # Execute Spatial Pooling algorithm over input space.
      self.sp.compute(encoding, True, activeColumns)
      self.sp_info.addData( activeColumns )

      # 3. Temporal Memory
      # Execute Temporal Memory algorithm over active mini-columns.

      # to get predictive cells we need to call activateDendrites & activateCells separately
      if PANDA_VIS_BAKE_DATA:
        # activateDendrites calculates active segments
        self.tm.activateDendrites(learn=True)
        # predictive cells are calculated directly from active segments
        predictiveCells = self.tm.getPredictiveCells()
        # activates cells in columns by TM algorithm (winners, bursting...)
        self.tm.activateCells(activeColumns, learn=True)
      else:
        self.tm.compute(activeColumns, learn=True)

      self.tm_info.addData( self.tm.getActiveCells().flatten() )

      # 4.1 (optional) Predictor #TODO optional
      #TODO optional: also return an error metric on predictions (RMSE, R2,...)

      # 4.2 Anomaly 
      # handle spatial, contextual (raw, likelihood) anomalies
      # -Spatial
      spatialAnomaly = 0.0 #TODO optional: make this computed in SP (and later improve)
      if self.useSpatialAnomaly:
        # Update min/max values and check if there is a spatial anomaly
        if self.minVal != self.maxVal:
          tolerance = (self.maxVal - self.minVal) * SPATIAL_TOLERANCE
          maxExpected = self.maxVal + tolerance
          minExpected = self.minVal - tolerance
          if val > maxExpected or val < minExpected:
            spatialAnomaly = 1.0
        if self.maxVal is None or val > self.maxVal:
          self.maxVal = val
        if self.minVal is None or val < self.minVal:
          self.minVal = val

      # -temporal (raw)
      raw= self.tm.anomaly
      temporalAnomaly = raw

      if self.useLikelihood:
        # Compute log(anomaly likelihood)
        like = self.anomalyLikelihood.anomalyProbability(val, raw, ts)
        logScore = self.anomalyLikelihood.computeLogLikelihood(like)
        temporalAnomaly = logScore #TODO optional: TM to provide anomaly {none, raw, likelihood}, compare correctness with the py anomaly_likelihood

      anomalyScore = max(spatialAnomaly, temporalAnomaly) # this is the "main" anomaly, compared in NAB

      # 5. print stats
      if self.verbose and self.iteration_ % 1000 == 0:
          # print(self.enc_info)
          # print(self.sp_info)
          # print(self.tm_info)
          pass

      # 6. panda vis
      if PANDA_VIS_BAKE_DATA:
          # ------------------HTMpandaVis----------------------
          # see more about this structure at https://github.com/htm-community/HTMpandaVis/blob/master/pandaBaker/README.md
          # fill up values
          pandaBaker.inputs["Value"].stringValue = "value: {:.2f}".format(val)
          pandaBaker.inputs["Value"].bits = valueBits.sparse

          pandaBaker.inputs["TimeOfDay"].stringValue = str(ts)
          pandaBaker.inputs["TimeOfDay"].bits = dateBits.sparse

          pandaBaker.layers["Layer1"].activeColumns = activeColumns.sparse
          pandaBaker.layers["Layer1"].winnerCells = self.tm.getWinnerCells().sparse
          pandaBaker.layers["Layer1"].predictiveCells = predictiveCells.sparse
          pandaBaker.layers["Layer1"].activeCells = self.tm.getActiveCells().sparse

          # customizable datastreams to be show on the DASH PLOTS
          pandaBaker.dataStreams["rawAnomaly"].value = temporalAnomaly
          pandaBaker.dataStreams["value"].value = val
          pandaBaker.dataStreams["numberOfWinnerCells"].value = len(self.tm.getWinnerCells().sparse)
          pandaBaker.dataStreams["numberOfPredictiveCells"].value = len(predictiveCells.sparse)
          pandaBaker.dataStreams["valueInput_sparsity"].value = valueBits.getSparsity()
          pandaBaker.dataStreams["dateInput_sparsity"].value = dateBits.getSparsity()

          pandaBaker.dataStreams["Layer1_SP_overlap_metric"].value = self.sp_info.overlap.overlap
          pandaBaker.dataStreams["Layer1_TM_overlap_metric"].value = self.sp_info.overlap.overlap
          pandaBaker.dataStreams["Layer1_SP_activation_frequency"].value = self.sp_info.activationFrequency.mean()
          pandaBaker.dataStreams["Layer1_TM_activation_frequency"].value = self.tm_info.activationFrequency.mean()
          pandaBaker.dataStreams["Layer1_SP_entropy"].value = self.sp_info.activationFrequency.mean()
          pandaBaker.dataStreams["Layer1_TM_entropy"].value = self.tm_info.activationFrequency.mean()

          pandaBaker.StoreIteration(self.iteration_-1)
          print("ITERATION: " + str(self.iteration_-1))

          # ------------------HTMpandaVis----------------------

      return (anomalyScore, raw)

  # with this method, the structure for visualization is defined
  def BuildPandaSystem(self, sp, tm, consumptionBits_size, dateBits_size):

      # we have two inputs connected to proximal synapses of Layer1
      pandaBaker.inputs["Value"] = cInput(consumptionBits_size)
      pandaBaker.inputs["TimeOfDay"] = cInput(dateBits_size)

      pandaBaker.layers["Layer1"] = cLayer(sp, tm)  # Layer1 has Spatial Pooler & Temporal Memory
      pandaBaker.layers["Layer1"].proximalInputs = [
          "Value",
          "TimeOfDay",
      ]
      pandaBaker.layers["Layer1"].distalInputs = ["Layer1"]

      # data for dash plots
      streams = ["rawAnomaly", "value", "numberOfWinnerCells", "numberOfPredictiveCells",
                 "valueInput_sparsity", "dateInput_sparsity", "Layer1_SP_overlap_metric", "Layer1_TM_overlap_metric",
                 "Layer1_SP_activation_frequency", "Layer1_TM_activation_frequency", "Layer1_SP_entropy",
                 "Layer1_TM_entropy"
                 ]

      pandaBaker.dataStreams = dict((name, cDataStream()) for name in streams)  # create dicts for more comfortable code
      # could be also written like: pandaBaker.dataStreams["myStreamName"] = cDataStream()

      pandaBaker.PrepareDatabase()
示例#8
0
def main(parameters=default_parameters, argv=None, verbose=True):
  if verbose:
    import pprint
    print("Parameters:")
    pprint.pprint(parameters, indent=4)
    print("")

  # Read the input file.
  records = []
  with open(_INPUT_FILE_PATH, "r") as fin:
    reader = csv.reader(fin)
    headers = next(reader)
    next(reader)
    next(reader)
    for record in reader:
      records.append(record)

  # Make the Encoders.  These will convert input data into binary representations.
  dateEncoder = DateEncoder(timeOfDay= parameters["enc"]["time"]["timeOfDay"], 
                            weekend  = parameters["enc"]["time"]["weekend"]) 
  
  scalarEncoderParams            = RDSE_Parameters()
  scalarEncoderParams.size       = parameters["enc"]["value"]["size"]
  scalarEncoderParams.sparsity   = parameters["enc"]["value"]["sparsity"]
  scalarEncoderParams.resolution = parameters["enc"]["value"]["resolution"]
  scalarEncoder = RDSE( scalarEncoderParams )
  encodingWidth = (dateEncoder.size + scalarEncoder.size)
  enc_info = Metrics( [encodingWidth], 999999999 )

  # Make the HTM.  SpatialPooler & TemporalMemory & associated tools.
  spParams = parameters["sp"]
  sp = SpatialPooler(
    inputDimensions            = (encodingWidth,),
    columnDimensions           = (spParams["columnCount"],),
    potentialPct               = spParams["potentialPct"],
    potentialRadius            = encodingWidth,
    globalInhibition           = True,
    localAreaDensity           = spParams["localAreaDensity"],
    synPermInactiveDec         = spParams["synPermInactiveDec"],
    synPermActiveInc           = spParams["synPermActiveInc"],
    synPermConnected           = spParams["synPermConnected"],
    boostStrength              = spParams["boostStrength"],
    wrapAround                 = True
  )
  sp_info = Metrics( sp.getColumnDimensions(), 999999999 )

  tmParams = parameters["tm"]
  tm = TemporalMemory(
    columnDimensions          = (spParams["columnCount"],),
    cellsPerColumn            = tmParams["cellsPerColumn"],
    activationThreshold       = tmParams["activationThreshold"],
    initialPermanence         = tmParams["initialPerm"],
    connectedPermanence       = spParams["synPermConnected"],
    minThreshold              = tmParams["minThreshold"],
    maxNewSynapseCount        = tmParams["newSynapseCount"],
    permanenceIncrement       = tmParams["permanenceInc"],
    permanenceDecrement       = tmParams["permanenceDec"],
    predictedSegmentDecrement = 0.0,
    maxSegmentsPerCell        = tmParams["maxSegmentsPerCell"],
    maxSynapsesPerSegment     = tmParams["maxSynapsesPerSegment"]
  )
  tm_info = Metrics( [tm.numberOfCells()], 999999999 )

  # setup likelihood, these settings are used in NAB
  anParams = parameters["anomaly"]["likelihood"]
  probationaryPeriod = int(math.floor(float(anParams["probationaryPct"])*len(records)))
  learningPeriod     = int(math.floor(probationaryPeriod / 2.0))
  anomaly_history = AnomalyLikelihood(learningPeriod= learningPeriod,
                                      estimationSamples= probationaryPeriod - learningPeriod,
                                      reestimationPeriod= anParams["reestimationPeriod"])

  predictor = Predictor( steps=[1, 5], alpha=parameters["predictor"]['sdrc_alpha'] )
  predictor_resolution = 1

  # Iterate through every datum in the dataset, record the inputs & outputs.
  inputs      = []
  anomaly     = []
  anomalyProb = []
  predictions = {1: [], 5: []}
  for count, record in enumerate(records):

    # Convert date string into Python date object.
    dateString = datetime.datetime.strptime(record[0], "%m/%d/%y %H:%M")
    # Convert data value string into float.
    consumption = float(record[1])
    inputs.append( consumption )

    # Call the encoders to create bit representations for each value.  These are SDR objects.
    dateBits        = dateEncoder.encode(dateString)
    consumptionBits = scalarEncoder.encode(consumption)

    # Concatenate all these encodings into one large encoding for Spatial Pooling.
    encoding = SDR( encodingWidth ).concatenate([consumptionBits, dateBits])
    enc_info.addData( encoding )

    # Create an SDR to represent active columns, This will be populated by the
    # compute method below. It must have the same dimensions as the Spatial Pooler.
    activeColumns = SDR( sp.getColumnDimensions() )

    # Execute Spatial Pooling algorithm over input space.
    sp.compute(encoding, True, activeColumns)
    sp_info.addData( activeColumns )

    # Execute Temporal Memory algorithm over active mini-columns.
    tm.compute(activeColumns, learn=True)
    tm_info.addData( tm.getActiveCells().flatten() )

    # Predict what will happen, and then train the predictor based on what just happened.
    pdf = predictor.infer( count, tm.getActiveCells() )
    for n in (1, 5):
      if pdf[n]:
        predictions[n].append( np.argmax( pdf[n] ) * predictor_resolution )
      else:
        predictions[n].append(float('nan'))
    predictor.learn( count, tm.getActiveCells(), int(consumption / predictor_resolution))

    anomalyLikelihood = anomaly_history.anomalyProbability( consumption, tm.anomaly )
    anomaly.append( tm.anomaly )
    anomalyProb.append( anomalyLikelihood )

  # Print information & statistics about the state of the HTM.
  print("Encoded Input", enc_info)
  print("")
  print("Spatial Pooler Mini-Columns", sp_info)
  print(str(sp))
  print("")
  print("Temporal Memory Cells", tm_info)
  print(str(tm))
  print("")

  # Shift the predictions so that they are aligned with the input they predict.
  for n_steps, pred_list in predictions.items():
    for x in range(n_steps):
        pred_list.insert(0, float('nan'))
        pred_list.pop()

  # Calculate the predictive accuracy, Root-Mean-Squared
  accuracy         = {1: 0, 5: 0}
  accuracy_samples = {1: 0, 5: 0}
  for idx, inp in enumerate(inputs):
    for n in predictions: # For each [N]umber of time steps ahead which was predicted.
      val = predictions[n][ idx ]
      if not math.isnan(val):
        accuracy[n] += (inp - val) ** 2
        accuracy_samples[n] += 1
  for n in sorted(predictions):
    accuracy[n] = (accuracy[n] / accuracy_samples[n]) ** .5
    print("Predictive Error (RMS)", n, "steps ahead:", accuracy[n])

  # Show info about the anomaly (mean & std)
  print("Anomaly Mean", np.mean(anomaly))
  print("Anomaly Std ", np.std(anomaly))

  # Plot the Predictions and Anomalies.
  if verbose:
    try:
      import matplotlib.pyplot as plt
    except:
      print("WARNING: failed to import matplotlib, plots cannot be shown.")
      return -accuracy[5]

    plt.subplot(2,1,1)
    plt.title("Predictions")
    plt.xlabel("Time")
    plt.ylabel("Power Consumption")
    plt.plot(np.arange(len(inputs)), inputs, 'red',
             np.arange(len(inputs)), predictions[1], 'blue',
             np.arange(len(inputs)), predictions[5], 'green',)
    plt.legend(labels=('Input', '1 Step Prediction, Shifted 1 step', '5 Step Prediction, Shifted 5 steps'))

    plt.subplot(2,1,2)
    plt.title("Anomaly Score")
    plt.xlabel("Time")
    plt.ylabel("Power Consumption")
    inputs = np.array(inputs) / max(inputs)
    plt.plot(np.arange(len(inputs)), inputs, 'red',
             np.arange(len(inputs)), anomaly, 'blue',)
    plt.legend(labels=('Input', 'Anomaly Score'))
    plt.show()

  return -accuracy[5]
示例#9
0
def main(parameters=default_parameters, argv=None, verbose=True):
    parser = argparse.ArgumentParser()
    parser.add_argument('--data_dir',
                        type=str,
                        default=os.path.join(os.path.dirname(__file__), '..',
                                             '..', '..', 'build', 'ThirdParty',
                                             'mnist_data', 'mnist-src'))
    args = parser.parse_args(args=argv)

    # Load data.
    train_labels, train_images, test_labels, test_images = load_mnist(
        args.data_dir)
    training_data = list(zip(train_images, train_labels))
    test_data = list(zip(test_images, test_labels))
    random.shuffle(training_data)
    random.shuffle(test_data)

    # Setup the AI.
    enc = SDR((train_images[0].shape))
    sp = SpatialPooler(
        inputDimensions=enc.dimensions,
        columnDimensions=parameters['columnDimensions'],
        potentialRadius=parameters['potentialRadius'],
        potentialPct=parameters['potentialPct'],
        globalInhibition=True,
        localAreaDensity=parameters['localAreaDensity'],
        stimulusThreshold=int(round(parameters['stimulusThreshold'])),
        synPermInactiveDec=parameters['synPermInactiveDec'],
        synPermActiveInc=parameters['synPermActiveInc'],
        synPermConnected=parameters['synPermConnected'],
        minPctOverlapDutyCycle=parameters['minPctOverlapDutyCycle'],
        dutyCyclePeriod=int(round(parameters['dutyCyclePeriod'])),
        boostStrength=parameters['boostStrength'],
        seed=0,
        spVerbosity=99,
        wrapAround=False)
    columns = SDR(sp.getColumnDimensions())
    columns_stats = Metrics(columns, 99999999)
    sdrc = Classifier()

    # Training Loop
    for i in range(len(train_images)):
        img, lbl = random.choice(training_data)
        enc.dense = img >= np.mean(img)  # Convert greyscale image to binary.
        sp.compute(enc, True, columns)
        sdrc.learn(columns, lbl)

    print(str(sp))
    print(str(columns_stats))

    # Testing Loop
    score = 0
    for img, lbl in test_data:
        enc.dense = img >= np.mean(img)  # Convert greyscale image to binary.
        sp.compute(enc, False, columns)
        if lbl == np.argmax(sdrc.infer(columns)):
            score += 1
    score = score / len(test_data)

    print('Score:', 100 * score, '%')
    return score
示例#10
0
class HTMCoreDetector(object):
    def __init__(self, inputMin, inputMax, probationaryPeriod, *args,
                 **kwargs):
        self.inputMin = inputMin
        self.inputMax = inputMax
        self.probationaryPeriod = probationaryPeriod
        ## API for controlling settings of htm.core HTM detector:

        # Set this to False if you want to get results based on raw scores
        # without using AnomalyLikelihood. This will give worse results, but
        # useful for checking the efficacy of AnomalyLikelihood. You will need
        # to re-optimize the thresholds when running with this setting.
        self.useLikelihood = True
        self.verbose = False

        ## internal members
        # (listed here for easier understanding)
        # initialized in `initialize()`
        self.encTimestamp = None
        self.encValue = None
        self.sp = None
        self.tm = None
        self.anLike = None
        # optional debug info
        self.enc_info = None
        self.sp_info = None
        self.tm_info = None
        # internal helper variables:
        self.inputs_ = []
        self.iteration_ = 0

    def handleRecord(self, ts, val):
        """Returns a tuple (anomalyScore, rawScore).
        @param ts Timestamp
        @param val float
        @return tuple (anomalyScore, <any other fields specified in `getAdditionalHeaders()`>, ...)
        """
        # Send it to Numenta detector and get back the results
        return self.modelRun(ts, val)

    def initialize(self):
        # toggle parameters here
        # parameters = default_parameters
        parameters = parameters_numenta_comparable

        ## setup Enc, SP, TM, Likelihood
        # Make the Encoders.  These will convert input data into binary representations.
        self.encTimestamp = DateEncoder(
            timeOfDay=parameters["enc"]["time"]["timeOfDay"],
            weekend=parameters["enc"]["time"]["weekend"],
            season=parameters["enc"]["time"]["season"],
            dayOfWeek=parameters["enc"]["time"]["dayOfWeek"])

        scalarEncoderParams = EncParameters()
        scalarEncoderParams.size = parameters["enc"]["value"]["size"]
        scalarEncoderParams.sparsity = parameters["enc"]["value"]["sparsity"]
        scalarEncoderParams.resolution = parameters["enc"]["value"][
            "resolution"]

        self.encValue = Encoder(scalarEncoderParams)
        encodingWidth = (self.encTimestamp.size + self.encValue.size)
        self.enc_info = Metrics([encodingWidth], 999999999)

        # Make the HTM.  SpatialPooler & TemporalMemory & associated tools.
        # SpatialPooler
        spParams = parameters["sp"]
        self.sp = SpatialPooler(
            inputDimensions=(encodingWidth, ),
            columnDimensions=(spParams["columnCount"], ),
            potentialPct=spParams["potentialPct"],
            potentialRadius=spParams["potentialRadius"],
            globalInhibition=True,
            localAreaDensity=spParams["localAreaDensity"],
            stimulusThreshold=spParams["stimulusThreshold"],
            synPermInactiveDec=spParams["synPermInactiveDec"],
            synPermActiveInc=spParams["synPermActiveInc"],
            synPermConnected=spParams["synPermConnected"],
            boostStrength=spParams["boostStrength"],
            wrapAround=True)
        self.sp_info = Metrics(self.sp.getColumnDimensions(), 999999999)

        # TemporalMemory
        tmParams = parameters["tm"]
        self.tm = TemporalMemory(
            columnDimensions=(spParams["columnCount"], ),
            cellsPerColumn=tmParams["cellsPerColumn"],
            activationThreshold=tmParams["activationThreshold"],
            initialPermanence=tmParams["initialPerm"],
            connectedPermanence=spParams["synPermConnected"],
            minThreshold=tmParams["minThreshold"],
            maxNewSynapseCount=tmParams["newSynapseCount"],
            permanenceIncrement=tmParams["permanenceInc"],
            permanenceDecrement=tmParams["permanenceDec"],
            predictedSegmentDecrement=0.0,
            maxSegmentsPerCell=tmParams["maxSegmentsPerCell"],
            maxSynapsesPerSegment=tmParams["maxSynapsesPerSegment"])
        self.tm_info = Metrics([self.tm.numberOfCells()], 999999999)

        # setup likelihood, these settings are used in NAB
        if self.useLikelihood:
            anParams = parameters["anomaly"]["likelihood"]
            learningPeriod = int(math.floor(self.probationaryPeriod / 2.0))
            self.anomalyLikelihood = AnomalyLikelihood(
                learningPeriod=learningPeriod,
                estimationSamples=self.probationaryPeriod - learningPeriod,
                reestimationPeriod=anParams["reestimationPeriod"])
        # Predictor
        # self.predictor = Predictor( steps=[1, 5], alpha=parameters["predictor"]['sdrc_alpha'] )
        # predictor_resolution = 1

    def modelRun(self, ts, val):
        """
           Run a single pass through HTM model
           @params ts - Timestamp
           @params val - float input value
           @return rawAnomalyScore computed for the `val` in this step
        """
        ## run data through our model pipeline: enc -> SP -> TM -> Anomaly
        self.inputs_.append(val)
        self.iteration_ += 1

        # 1. Encoding
        # Call the encoders to create bit representations for each value.  These are SDR objects.
        dateBits = self.encTimestamp.encode(ts)
        valueBits = self.encValue.encode(float(val))
        # Concatenate all these encodings into one large encoding for Spatial Pooling.
        encoding = SDR(self.encTimestamp.size +
                       self.encValue.size).concatenate([valueBits, dateBits])
        self.enc_info.addData(encoding)

        # 2. Spatial Pooler
        # Create an SDR to represent active columns, This will be populated by the
        # compute method below. It must have the same dimensions as the Spatial Pooler.
        activeColumns = SDR(self.sp.getColumnDimensions())
        # Execute Spatial Pooling algorithm over input space.
        self.sp.compute(encoding, True, activeColumns)
        self.sp_info.addData(activeColumns)

        # 3. Temporal Memory
        # Execute Temporal Memory algorithm over active mini-columns.
        self.tm.compute(activeColumns, learn=True)
        self.tm_info.addData(self.tm.getActiveCells().flatten())

        # 4.1 (optional) Predictor #TODO optional
        # TODO optional: also return an error metric on predictions (RMSE, R2,...)

        # 4.2 Anomaly
        # handle contextual (raw, likelihood) anomalies
        # -temporal (raw)
        raw = self.tm.anomaly
        temporalAnomaly = raw

        if self.useLikelihood:
            # Compute log(anomaly likelihood)
            like = self.anomalyLikelihood.anomalyProbability(val, raw, ts)
            logScore = self.anomalyLikelihood.computeLogLikelihood(like)
            temporalAnomaly = logScore  # TODO optional: TM to provide anomaly {none, raw, likelihood}, compare correctness with the py anomaly_likelihood

        anomalyScore = temporalAnomaly  # this is the "main" anomaly, compared in NAB

        # 5. print stats
        if self.verbose and self.iteration_ % 1000 == 0:
            print(self.enc_info)
            print(self.sp_info)
            print(self.tm_info)
            pass

        return anomalyScore, raw
示例#11
0
def SystemSetup(parameters, verbose=True):
    global agent, sensorEncoder, env, sensorLayer_sp, sensorLayer_SDR_columns
    global gridCellEncoder, locationlayer_SDR_cells
    global sensorLayer_tm

    if verbose:
        import pprint

        print("Parameters:")
        pprint.pprint(parameters, indent=4)
        print("")

    # create environment and the agent
    env = htm2d.environment.TwoDimensionalEnvironment(20, 20)
    agent = htm2d.agent.Agent()

    # load object from yml file
    with open(os.path.join(_OBJECTS_DIR, OBJECT_FILENAME), "r") as stream:
        try:
            env.load_object(stream)
        except yaml.YAMLError as exc:
            print(exc)

    # SENSOR LAYER --------------------------------------------------------------
    # setup sensor encoder
    sensorEncoderParams = RDSE_Parameters()
    sensorEncoderParams.category = True
    sensorEncoderParams.size = parameters["enc"]["size"]
    sensorEncoderParams.sparsity = parameters["enc"]["sparsity"]
    sensorEncoderParams.seed = parameters["enc"]["seed"]
    sensorEncoder = RDSE(sensorEncoderParams)

    # Create SpatialPooler
    spParams = parameters["sensorLayer_sp"]
    sensorLayer_sp = SpatialPooler(
        inputDimensions=(sensorEncoder.size, ),
        columnDimensions=(spParams["columnCount"], ),
        potentialPct=spParams["potentialPct"],
        potentialRadius=sensorEncoder.size,
        globalInhibition=True,
        localAreaDensity=spParams["localAreaDensity"],
        synPermInactiveDec=spParams["synPermInactiveDec"],
        synPermActiveInc=spParams["synPermActiveInc"],
        synPermConnected=spParams["synPermConnected"],
        boostStrength=spParams["boostStrength"],
        wrapAround=True,
    )
    sp_info = Metrics(sensorLayer_sp.getColumnDimensions(), 999999999)

    # Create an SDR to represent active columns, This will be populated by the
    # compute method below. It must have the same dimensions as the Spatial Pooler.
    sensorLayer_SDR_columns = SDR(spParams["columnCount"])

    # LOCATION LAYER ------------------------------------------------------------
    # Grid cell modules
    locParams = parameters["locationLayer"]

    gridCellEncoder = GridCellEncoder(
        size=locParams["cellCount"],
        sparsity=locParams["sparsity"],
        periods=locParams["periods"],
        seed=locParams["seed"],
    )

    locationlayer_SDR_cells = SDR(gridCellEncoder.dimensions)

    tmParams = parameters["sensorLayer_tm"]
    sensorLayer_tm = TemporalMemory(
        columnDimensions=(spParams["columnCount"], ),
        cellsPerColumn=tmParams["cellsPerColumn"],
        activationThreshold=tmParams["activationThreshold"],
        initialPermanence=tmParams["initialPerm"],
        connectedPermanence=spParams["synPermConnected"],
        minThreshold=tmParams["minThreshold"],
        maxNewSynapseCount=tmParams["newSynapseCount"],
        permanenceIncrement=tmParams["permanenceInc"],
        permanenceDecrement=tmParams["permanenceDec"],
        predictedSegmentDecrement=0.0,
        maxSegmentsPerCell=tmParams["maxSegmentsPerCell"],
        maxSynapsesPerSegment=tmParams["maxSynapsesPerSegment"],
        externalPredictiveInputs=locParams["cellCount"],
    )
    tm_info = Metrics([sensorLayer_tm.numberOfCells()], 999999999)
示例#12
0
class Experiment:
    def __init__(self):
        self.anomalyHistData = []
        self.iterationNo = 0

        self.enc_info = None
        self.sp_info = None
        self.tm_info = None

    def SystemSetup(self, verbose=True):

        if verbose:
            import pprint

            print("Parameters:")
            pprint.pprint(parameters, indent=4)
            print("")

        # create environment and the agent
        self.env = htm2d.environment.TwoDimensionalEnvironment(20, 20)
        self.agent = htm2d.agent.Agent()

        # load object from yml file
        with open(os.path.join(_OBJECTS_DIR, OBJECT_FILENAME), "r") as stream:
            try:
                self.env.load_object(stream)
            except yaml.YAMLError as exc:
                print(exc)

        # SENSOR LAYER --------------------------------------------------------------
        # setup sensor encoder
        sensorEncoderParams = RDSE_Parameters()
        sensorEncoderParams.category = True
        sensorEncoderParams.size = parameters["enc"]["size"]
        sensorEncoderParams.sparsity = parameters["enc"]["sparsity"]
        sensorEncoderParams.seed = parameters["enc"]["seed"]
        self.sensorEncoder = RDSE(sensorEncoderParams)

        # Create SpatialPooler

        self.sensorLayer_sp = SpatialPooler(
            inputDimensions=(self.sensorEncoder.size, ),
            columnDimensions=(spParams["columnCount"], ),
            potentialPct=spParams["potentialPct"],
            potentialRadius=self.sensorEncoder.size,
            globalInhibition=True,
            localAreaDensity=spParams["localAreaDensity"],
            synPermInactiveDec=spParams["synPermInactiveDec"],
            synPermActiveInc=spParams["synPermActiveInc"],
            synPermConnected=spParams["synPermConnected"],
            boostStrength=spParams["boostStrength"],
            wrapAround=True,
        )
        self.sp_info = Metrics(self.sensorLayer_sp.getColumnDimensions(),
                               999999999)

        # Create an SDR to represent active columns, This will be populated by the
        # compute method below. It must have the same dimensions as the Spatial Pooler.
        self.sensorLayer_SDR_columns = SDR(spParams["columnCount"])

        # LOCATION LAYER ------------------------------------------------------------
        # Grid cell modules

        self.gridCellEncoder = GridCellEncoder(
            size=locParams["cellCount"],
            sparsity=locParams["sparsity"],
            periods=locParams["periods"],
            seed=locParams["seed"],
        )

        self.locationlayer_SDR_cells = SDR(self.gridCellEncoder.dimensions)

        initParams = {
            "columnCount": spParams["columnCount"],
            "cellsPerColumn": tmParams["cellsPerColumn"],
            "basalInputSize": locParams["cellCount"],
            "activationThreshold": tmParams["activationThreshold"],
            "reducedBasalThreshold": 13,
            "initialPermanence": tmParams["initialPerm"],
            "connectedPermanence": spParams["synPermConnected"],
            "minThreshold": tmParams["minThreshold"],
            "sampleSize": 20,
            "permanenceIncrement": tmParams["permanenceInc"],
            "permanenceDecrement": tmParams["permanenceDec"],
            "basalPredictedSegmentDecrement": 0.0,
            "apicalPredictedSegmentDecrement": 0.0,
            "maxSynapsesPerSegment": tmParams["maxSynapsesPerSegment"]
        }

        self.sensoryLayer_tm = ApicalTiebreakPairMemory(**initParams)

        # self.sensoryLayer_tm = TemporalMemory(
        #     columnDimensions=(spParams["columnCount"],),
        #     cellsPerColumn=tmParams["cellsPerColumn"],
        #     activationThreshold=tmParams["activationThreshold"],
        #     initialPermanence=tmParams["initialPerm"],
        #     connectedPermanence=spParams["synPermConnected"],
        #     minThreshold=tmParams["minThreshold"],
        #     maxNewSynapseCount=tmParams["newSynapseCount"],
        #     permanenceIncrement=tmParams["permanenceInc"],
        #     permanenceDecrement=tmParams["permanenceDec"],
        #     predictedSegmentDecrement=0.0,
        #     maxSegmentsPerCell=tmParams["maxSegmentsPerCell"],
        #     maxSynapsesPerSegment=tmParams["maxSynapsesPerSegment"],
        #     externalPredictiveInputs=locParams["cellCount"],
        # )
        self.tm_info = Metrics([self.sensoryLayer_tm.numberOfCells()],
                               999999999)

    def CellsToColumns(self, cells, cellsPerColumn, columnsCount):
        array = []
        for cell in cells.sparse:
            col = int(cell / cellsPerColumn)
            if col not in array:  #each column max once
                array += [col]

        columns = SDR(columnsCount)
        columns.sparse = array
        return columns

    def SystemCalculate(self, feature, learning):
        global fig_environment, fig_graphs
        # ENCODE DATA TO SDR--------------------------------------------------
        # Convert sensed feature to int
        self.sensedFeature = 1 if feature == "X" else 0
        self.sensorSDR = self.sensorEncoder.encode(self.sensedFeature)

        # ACTIVATE COLUMNS IN SENSORY LAYER ----------------------------------
        # Execute Spatial Pooling algorithm on Sensory Layer with sensorSDR as proximal input
        self.sensorLayer_sp.compute(self.sensorSDR, learning,
                                    self.sensorLayer_SDR_columns)

        # SIMULATE LOCATION LAYER --------------------------------------------
        # Execute Location Layer - it is just GC encoder
        self.gridCellEncoder.encode(self.agent.get_position(),
                                    self.locationlayer_SDR_cells)

        #
        # Execute Temporal memory algorithm over the Sensory Layer, with mix of
        # Location Layer activity and Sensory Layer activity as distal input
        externalDistalInput = self.locationlayer_SDR_cells

        tm_input = {
            "activeColumns": self.sensorLayer_SDR_columns.sparse,
            "basalInput": externalDistalInput.sparse,
            "basalGrowthCandidates": None,
            "learn": learning
        }
        self.sensoryLayer_tm.compute(**tm_input)

        #self.sensoryLayer_tm.activateCells(self.sensorLayer_SDR_columns, learning)

        # activateDendrites calculates active segments
        #self.sensoryLayer_tm.activateDendrites(learn=learning, externalPredictiveInputsActive=externalDistalInput,
        #externalPredictiveInputsWinners=externalDistalInput)
        # predictive cells are calculated directly from active segments
        self.predictiveCellsSDR = SDR(spParams["columnCount"] *
                                      tmParams["cellsPerColumn"])
        self.predictiveCellsSDR.sparse = self.sensoryLayer_tm.predictedCells

        if self.iterationNo != 0:
            # and calculate anomaly - compare how much of active columns had some predictive cells
            self.rawAnomaly = Anomaly.calculateRawAnomaly(
                self.sensorLayer_SDR_columns,
                self.CellsToColumns(
                    self.predictiveCellsSDR,
                    parameters["sensoryLayer_tm"]["cellsPerColumn"],
                    parameters["sensoryLayer_sp"]["columnCount"]))
        else:
            self.rawAnomaly = 0

        # PANDA VIS
        if PANDA_VIS_BAKE_DATA:
            # ------------------HTMpandaVis----------------------
            # fill up values
            pandaBaker.inputs[
                "FeatureSensor"].stringValue = "Feature: {:.2f}".format(
                    self.sensedFeature)
            pandaBaker.inputs["FeatureSensor"].bits = self.sensorSDR.sparse

            pandaBaker.inputs["LocationLayer"].stringValue = str(
                self.agent.get_position())
            pandaBaker.inputs[
                "LocationLayer"].bits = self.locationlayer_SDR_cells.sparse

            pandaBaker.layers[
                "SensoryLayer"].activeColumns = self.sensorLayer_SDR_columns.sparse
            pandaBaker.layers[
                "SensoryLayer"].winnerCells = self.sensoryLayer_tm.getWinnerCells(
                )
            pandaBaker.layers[
                "SensoryLayer"].predictiveCells = self.predictiveCellsSDR.sparse
            pandaBaker.layers[
                "SensoryLayer"].activeCells = self.sensoryLayer_tm.getActiveCells(
                )

            # customizable datastreams to be show on the DASH PLOTS
            pandaBaker.dataStreams["rawAnomaly"].value = self.rawAnomaly
            pandaBaker.dataStreams["numberOfWinnerCells"].value = len(
                self.sensoryLayer_tm.getWinnerCells())
            pandaBaker.dataStreams["numberOfPredictiveCells"].value = len(
                self.predictiveCellsSDR.sparse)
            pandaBaker.dataStreams[
                "sensor_sparsity"].value = self.sensorSDR.getSparsity() * 100
            pandaBaker.dataStreams[
                "location_sparsity"].value = self.locationlayer_SDR_cells.getSparsity(
                ) * 100

            pandaBaker.dataStreams[
                "SensoryLayer_SP_overlap_metric"].value = self.sp_info.overlap.overlap
            pandaBaker.dataStreams[
                "SensoryLayer_TM_overlap_metric"].value = self.sp_info.overlap.overlap
            pandaBaker.dataStreams[
                "SensoryLayer_SP_activation_frequency"].value = self.sp_info.activationFrequency.mean(
                )
            pandaBaker.dataStreams[
                "SensoryLayer_TM_activation_frequency"].value = self.tm_info.activationFrequency.mean(
                )
            pandaBaker.dataStreams[
                "SensoryLayer_SP_entropy"].value = self.sp_info.activationFrequency.mean(
                )
            pandaBaker.dataStreams[
                "SensoryLayer_TM_entropy"].value = self.tm_info.activationFrequency.mean(
                )

            pandaBaker.StoreIteration(self.iterationNo)

            # ------------------HTMpandaVis----------------------

        print("Position:" + str(self.agent.get_position()))
        print("Feature:" + str(self.sensedFeature))
        print("Anomaly score:" + str(self.rawAnomaly))
        self.anomalyHistData += [self.rawAnomaly]

        if PLOT_ENV:
            # Plotting and visualising environment-------------------------------------------
            if (
                    fig_environment == None or isNotebook()
            ):  # create figure only if it doesn't exist yet or we are in interactive console
                fig_environment, _ = plt.subplots(nrows=1,
                                                  ncols=1,
                                                  figsize=(6, 4))
            else:
                fig_environment.axes[0].clear()

            plotEnvironment(fig_environment.axes[0], "Environment", self.env,
                            self.agent.get_position())
            fig_environment.canvas.draw()

            plt.show(block=False)
            plt.pause(0.001)  # delay is needed for proper redraw

        self.iterationNo += 1

        if PLOT_GRAPHS:
            # ---------------------------
            if (
                    fig_graphs == None or isNotebook()
            ):  # create figure only if it doesn't exist yet or we are in interactive console
                fig_graphs, _ = plt.subplots(nrows=1, ncols=1, figsize=(5, 2))
            else:
                fig_graphs.axes[0].clear()

            fig_graphs.axes[0].set_title("Anomaly score")
            fig_graphs.axes[0].plot(self.anomalyHistData)
            fig_graphs.canvas.draw()

            #if agent.get_position() != [3, 4]:  # HACK ALERT! Ignore at this pos (after reset)
            #    anomalyHistData += [sensoryLayer_tm.anomaly]

    def BuildPandaSystem(self):

        pandaBaker.inputs["FeatureSensor"] = cInput(self.sensorEncoder.size)

        pandaBaker.layers["SensoryLayer"] = cLayer(self.sensorLayer_sp,
                                                   self.sensoryLayer_tm)
        pandaBaker.layers["SensoryLayer"].proximalInputs = ["FeatureSensor"]
        pandaBaker.layers["SensoryLayer"].distalInputs = ["LocationLayer"]

        pandaBaker.inputs["LocationLayer"] = cInput(
            self.gridCellEncoder.size
        )  # for now, Location layer is just position encoder

        # data for dash plots
        streams = [
            "rawAnomaly", "numberOfWinnerCells", "numberOfPredictiveCells",
            "sensor_sparsity", "location_sparsity",
            "SensoryLayer_SP_overlap_metric", "SensoryLayer_TM_overlap_metric",
            "SensoryLayer_SP_activation_frequency",
            "SensoryLayer_TM_activation_frequency", "SensoryLayer_SP_entropy",
            "SensoryLayer_TM_entropy"
        ]

        pandaBaker.dataStreams = dict(
            (name, cDataStream())
            for name in streams)  # create dicts for more comfortable code
        # could be also written like: pandaBaker.dataStreams["myStreamName"] = cDataStream()

        pandaBaker.PrepareDatabase()

    def RunExperiment1(self):
        global fig_expect

        # put agent in the environment
        self.agent.set_env(self.env, 1, 1, 1,
                           1)  # is on [1,1] and will go to [1,1]

        agentDir = Direction.RIGHT

        self.iterationNo = 0

        for i in range(3):
            for x in range(2, 18):
                for y in range(2, 18):
                    print("Iteration:" + str(self.iterationNo))
                    self.agent.move(x, y)
                    self.SystemCalculate(self.agent.get_feature(Direction.UP),
                                         learning=True)

        expectedObject = [x[:] for x in [[0] * 20] * 20]

        A = [x[:] for x in [[0] * 20] * 20]
        B = [x[:] for x in [[0] * 20] * 20]

        predSDR1 = SDR(self.predictiveCellsSDR)
        predSDR2 = SDR(self.predictiveCellsSDR)

        # calculate what kind of object will system expect
        for x in range(2, 18):
            for y in range(2, 18):  # for sensor UP !
                self.agent.move(x, y)

                self.SystemCalculate("X", learning=False)
                scoreWithFeature = self.rawAnomaly

                self.SystemCalculate(" ", learning=False)
                scoreWithoutFeature = self.rawAnomaly

                # y -1 because we are using sensor UP
                A[x][y - 1] = scoreWithFeature
                B[x][y - 1] = scoreWithoutFeature
                expectedObject[x][
                    y - 1] = 1 if scoreWithFeature < scoreWithoutFeature else 0

        print(A)
        print(B)
        print(expectedObject)

        # Plotting and visualising environment-------------------------------------------
        if (
                fig_expect == None or isNotebook()
        ):  # create figure only if it doesn't exist yet or we are in interactive console
            fig_expect, _ = plt.subplots(nrows=1, ncols=1, figsize=(6, 4))
        else:
            fig_expect.axes[0].clear()

        plotBinaryMap(fig_expect.axes[0], "Expectation", expectedObject)
        fig_expect.canvas.draw()

        plt.show(block=True)
        #plt.pause(20)  # delay is needed for proper redraw

    def RunExperiment2(self):
        global fig_expect

        # put agent in the environment
        self.agent.set_env(self.env, 1, 1, 1,
                           1)  # is on [1,1] and will go to [1,1]

        self.iterationNo = 0
        random.seed = 42

        for i in range(1000):
            print("Iteration:" + str(self.iterationNo))
            self.SystemCalculate(self.agent.get_feature(Direction.UP),
                                 learning=True)
            # this tells agent where he will make movement next time & it will make previously requested movement
            self.agent.nextMove(random.randint(3, 10), random.randint(3, 10))
示例#13
0
class Layer:
    def __init__(self,
                 din=(10, 10),
                 dout=(10, 10),
                 temporal=True,
                 setting=param.default_parameters):
        self.input_shape = din
        self.output_shape = dout
        self.temporal = temporal
        self.learn = True
        self.setting = AttrDict(setting)
        self.sp = SpatialPooler()
        self.tm = TemporalMemory() if temporal else None

    def compile(self):
        spParams = self.setting("sp")
        self.sp = SpatialPooler(
            inputDimensions=self.input_shape,
            columnDimensions=self.output_shape,
            potentialPct=spParams.potentialPct,
            potentialRadius=spParams.potentialRadius,
            globalInhibition=True if len(self.output_shape) == 1 else False,
            localAreaDensity=spParams.localAreaDensity,
            synPermInactiveDec=spParams.synPermInactiveDec,
            synPermActiveInc=spParams.synPermActiveInc,
            synPermConnected=spParams.synPermConnected,
            boostStrength=spParams.boostStrength,
            wrapAround=True,
        )
        if self.temporal:
            tmParams = self.setting("tm")
            self.tm = TemporalMemory(
                columnDimensions=self.output_shape,
                cellsPerColumn=tmParams.cellsPerColumn,
                activationThreshold=tmParams.activationThreshold,
                initialPermanence=tmParams.initialPerm,
                connectedPermanence=spParams.synPermConnected,
                minThreshold=tmParams.minThreshold,
                maxNewSynapseCount=tmParams.newSynapseCount,
                permanenceIncrement=tmParams.permanenceInc,
                permanenceDecrement=tmParams.permanenceDec,
                predictedSegmentDecrement=0.0,
                maxSegmentsPerCell=tmParams.maxSegmentsPerCell,
                maxSynapsesPerSegment=tmParams.maxSynapsesPerSegment)

    def forward(self, encoding):
        activeColumns = SDR(self.sp.getColumnDimensions())
        self.sp.compute(encoding, self.learn, activeColumns)

        predictedColumns = None
        if self.temporal:
            self.tm.compute(activeColumns, self.learn)
            self.tm.activateDendrites(self.learn)
            predictedColumnIndices = {
                self.tm.columnForCell(i)
                for i in self.tm.getPredictiveCells().sparse
            }
            predictedColumns = SDR(self.sp.getColumnDimensions())
            predictedColumns.sparse = list(predictedColumnIndices)
        return activeColumns, predictedColumns

    def train(self):
        self.learn = True

    def eval(self):
        self.learn = False

    def anomaly(self):
        return float(self.tm.anomaly) if self.temporal else None

    def reset(self):
        if self.temporal:
            self.tm.reset()

    def save(self, path):
        print('Saving Model...')
        print(str(self.sp))

        self.sp.saveToFile(param.sp_model.format(path))
        if self.temporal:
            print(str(self.tm))
            self.tm.saveToFile(param.tm_model.format(path))

    def load(self, path):
        print('Loading Model...')
        self.sp.loadFromFile(param.sp_model.format(path))
        print(str(self.sp))
        if self.temporal:
            self.tm.loadFromFile(param.tm_model.format(path))
            print(str(self.tm))
示例#14
0
class MultivHTMDetector(object):
    """
    This detector uses an HTM based anomaly detection technique.
    """

    def __init__(self, name, probationaryPeriod, params=None, verbose=False):
        self.verbose = verbose
        self.name = name  # for logging

        self.probationaryPeriod = probationaryPeriod

        if params is not None:
            self.parameters = params
        else:
            self.parameters = parameters_best

        self.encTimestamp = None
        self.scalar_encoders = []
        self.enc_width = None
        self.sp = None
        self.tm = None
        self.anomalyLikelihood = None

        # for initialization
        self.init_data = []
        self.init_min_max = {}
        self.is_initialized = False
        self.iteration_ = 0

        self.learningPeriod = None

    def _createRDSE(self, min_val=0, max_val=0):
        scalarEncoderParams = RDSE_Parameters()
        scalarEncoderParams.size = self.parameters["enc"]["value"]["size"]
        scalarEncoderParams.activeBits = self.parameters["enc"]["value"]["activeBits"]
        scalarEncoderParams.resolution = max(0.001, (max_val - min_val) / 130)
        scalarEncoderParams.seed = self.parameters["enc"]["value"]["seed"]
        return RDSE(scalarEncoderParams)

    def initialize(self):
        # Setup Encoders
        self.encTimestamp = DateEncoder(timeOfDay=self.parameters["enc"]["time"]["timeOfDay"])
        for idx, (key, value) in enumerate(self.init_min_max.items()):
            self.scalar_encoders.append({
                'idx': idx,
                'name': key,
                'encoder':  self._createRDSE(min_val=value['min'], max_val=value['max'])
            })

        self.enc_width = self.encTimestamp.size + sum([enc_info.get('encoder').size for enc_info in self.scalar_encoders])

        # Make the HTM.  SpatialPooler & TemporalMemory & associated tools.
        # SpatialPooler
        spParams = self.parameters["sp"]
        self.sp = SpatialPooler(
            inputDimensions=(self.enc_width,),
            columnDimensions=(spParams["columnDimensions"],),
            potentialRadius=self.enc_width,
            potentialPct=spParams["potentialPct"],
            globalInhibition=spParams["globalInhibition"],
            localAreaDensity=spParams["localAreaDensity"],
            numActiveColumnsPerInhArea=spParams["numActiveColumnsPerInhArea"],
            stimulusThreshold=spParams["stimulusThreshold"],
            synPermInactiveDec=spParams["synPermInactiveDec"],
            synPermActiveInc=spParams["synPermActiveInc"],
            synPermConnected=spParams["synPermConnected"],
            boostStrength=spParams["boostStrength"],
            wrapAround=spParams["wrapAround"],
            minPctOverlapDutyCycle=spParams["minPctOverlapDutyCycle"],
            dutyCyclePeriod=spParams["dutyCyclePeriod"],
            seed=spParams["seed"],
        )

        # TemporalMemory
        tmParams = self.parameters["tm"]
        self.tm = TemporalMemory(
            columnDimensions=(spParams["columnDimensions"],),
            cellsPerColumn=tmParams["cellsPerColumn"],
            activationThreshold=tmParams["activationThreshold"],
            initialPermanence=tmParams["initialPermanence"],
            connectedPermanence=tmParams["connectedPermanence"],
            minThreshold=tmParams["minThreshold"],
            maxNewSynapseCount=tmParams["maxNewSynapseCount"],
            permanenceIncrement=tmParams["permanenceIncrement"],
            permanenceDecrement=tmParams["permanenceDecrement"],
            predictedSegmentDecrement=tmParams["predictedSegmentDecrement"],
            maxSegmentsPerCell=tmParams["maxSegmentsPerCell"],
            maxSynapsesPerSegment=tmParams["maxSynapsesPerSegment"],
            seed=tmParams["seed"]
        )

        anParams = self.parameters["anomaly"]["likelihood"]
        self.learningPeriod = int(math.floor(self.probationaryPeriod / 2.0))
        self.anomalyLikelihood = AnomalyLikelihood(
            learningPeriod=self.learningPeriod,
            estimationSamples=self.probationaryPeriod - self.learningPeriod,
            reestimationPeriod=anParams["reestimationPeriod"])

    def modelRun(self, ts, data):
        """
           Run a single pass through HTM model
           @config ts - Timestamp
           @config val - float input value
           @return rawAnomalyScore computed for the `val` in this step
        """
        self.iteration_ += 1

        # 0. During the probation period, gather the data and return 0.01.
        if self.iteration_ <= self.probationaryPeriod:
            self.init_data.append((ts, data))
            for col_name, val in data.items():
                if val is None:
                    continue
                if col_name not in self.init_min_max:
                    self.init_min_max[col_name] = {}
                if 'min' not in self.init_min_max[col_name] or val < self.init_min_max[col_name]['min']:
                    self.init_min_max[col_name]['min'] = val
                if 'max' not in self.init_min_max[col_name] or val > self.init_min_max[col_name]['max']:
                    self.init_min_max[col_name]['max'] = val
            return 0.01, 0.01

        if self.is_initialized is False:
            if self.verbose:
                print("[{}] Initializing".format(self.name))
            temp_iteration = self.iteration_
            self.initialize()
            self.is_initialized = True
            for ts, data in self.init_data:
                self.modelRun(ts, data)
            self.iteration_ = temp_iteration
            if self.verbose:
                print("[{}] Initialization done".format(self.name))

        # run data through model pipeline: enc -> SP -> TM -> Anomaly
        # 1. Encoding
        # Call the encoders to create bit representations for each value. These are SDR objects.
        dateBits = self.encTimestamp.encode(ts)
        scalarBits = []
        for enc_info in sorted(self.scalar_encoders, key=lambda i: i.get('idx')):
            name = enc_info.get('name')
            encoder = enc_info.get('encoder')
            val = data.get(name)
            if val is None:
                raise Exception('Value for {} is None. Aborting.'.format(name))
            scalarBits.append(encoder.encode(float(val)))

        encoding = SDR(self.enc_width).concatenate([dateBits] + scalarBits)

        # 2. Spatial Pooler
        # Create an SDR to represent active columns, This will be populated by the
        # compute method below. It must have the same dimensions as the Spatial Pooler.
        activeColumns = SDR(self.sp.getColumnDimensions())
        # Execute Spatial Pooling algorithm over input space.
        self.sp.compute(encoding, True, activeColumns)

        # 3. Temporal Memory
        # Execute Temporal Memory algorithm over active mini-columns.
        self.tm.compute(activeColumns, learn=True)

        # 4. Anomaly
        raw = self.tm.anomaly
        like = self.anomalyLikelihood.anomalyProbability(data, raw, ts)
        logScore = self.anomalyLikelihood.computeLogLikelihood(like)
        anomalyScore = logScore

        return anomalyScore, raw
class UnivHTMDetector(object):
    """
    This detector uses an HTM based anomaly detection technique.
    """

    def __init__(self, name, probationaryPeriod, smoothingKernelSize, htmParams=None, verbose=False):
        self.useSpatialAnomaly = True
        self.verbose = verbose
        self.name = name  # for logging

        self.probationaryPeriod = probationaryPeriod
        self.parameters = parameters_best

        self.minVal = None
        self.maxVal = None
        self.spatial_tolerance = None
        self.encTimestamp = None
        self.encValue = None
        self.sp = None
        self.tm = None
        self.anomalyLikelihood = None

        # optional debug info
        self.enc_info = None
        self.sp_info = None
        self.tm_info = None

        # for initialization
        self.init_data = []
        self.is_initialized = False
        self.iteration_ = 0

        # for smoothing with gaussian
        self.historic_raw_anomaly_scores = deque(maxlen=smoothingKernelSize)
        self.kernel = None
        self.learningPeriod = None

    def initialize(self, input_min=0, input_max=0):
        # setup spatial anomaly
        if self.useSpatialAnomaly:
            self.spatial_tolerance = self.parameters["spatial_tolerance"]

        ## setup Enc, SP, TM
        # Make the Encoders.  These will convert input data into binary representations.
        self.encTimestamp = DateEncoder(timeOfDay=self.parameters["enc"]["time"]["timeOfDay"])

        scalarEncoderParams = RDSE_Parameters()
        scalarEncoderParams.size = self.parameters["enc"]["value"]["size"]
        scalarEncoderParams.activeBits = self.parameters["enc"]["value"]["activeBits"]
        scalarEncoderParams.resolution = max(0.001, (input_max - input_min) / 130)
        scalarEncoderParams.seed = self.parameters["enc"]["value"]["seed"]

        self.encValue = RDSE(scalarEncoderParams)
        encodingWidth = (self.encTimestamp.size + self.encValue.size)
        self.enc_info = Metrics([encodingWidth], 999999999)

        # Make the HTM.  SpatialPooler & TemporalMemory & associated tools.
        # SpatialPooler
        spParams = self.parameters["sp"]
        self.sp = SpatialPooler(
            inputDimensions=(encodingWidth,),
            columnDimensions=(spParams["columnDimensions"],),
            potentialRadius=encodingWidth,
            potentialPct=spParams["potentialPct"],
            globalInhibition=spParams["globalInhibition"],
            localAreaDensity=spParams["localAreaDensity"],
            numActiveColumnsPerInhArea=spParams["numActiveColumnsPerInhArea"],
            stimulusThreshold=spParams["stimulusThreshold"],
            synPermInactiveDec=spParams["synPermInactiveDec"],
            synPermActiveInc=spParams["synPermActiveInc"],
            synPermConnected=spParams["synPermConnected"],
            boostStrength=spParams["boostStrength"],
            wrapAround=spParams["wrapAround"],
            minPctOverlapDutyCycle=spParams["minPctOverlapDutyCycle"],
            dutyCyclePeriod=spParams["dutyCyclePeriod"],
            seed=spParams["seed"],
        )
        self.sp_info = Metrics(self.sp.getColumnDimensions(), 999999999)

        # TemporalMemory
        tmParams = self.parameters["tm"]
        self.tm = TemporalMemory(
            columnDimensions=(spParams["columnDimensions"],),
            cellsPerColumn=tmParams["cellsPerColumn"],
            activationThreshold=tmParams["activationThreshold"],
            initialPermanence=tmParams["initialPermanence"],
            connectedPermanence=tmParams["connectedPermanence"],
            minThreshold=tmParams["minThreshold"],
            maxNewSynapseCount=tmParams["maxNewSynapseCount"],
            permanenceIncrement=tmParams["permanenceIncrement"],
            permanenceDecrement=tmParams["permanenceDecrement"],
            predictedSegmentDecrement=tmParams["predictedSegmentDecrement"],
            maxSegmentsPerCell=tmParams["maxSegmentsPerCell"],
            maxSynapsesPerSegment=tmParams["maxSynapsesPerSegment"],
            seed=tmParams["seed"]
        )
        self.tm_info = Metrics([self.tm.numberOfCells()], 999999999)

        anParams = self.parameters["anomaly"]["likelihood"]
        self.learningPeriod = int(math.floor(self.probationaryPeriod / 2.0))
        self.anomalyLikelihood = AnomalyLikelihood(
            learningPeriod=self.learningPeriod,
            estimationSamples=self.probationaryPeriod - self.learningPeriod,
            reestimationPeriod=anParams["reestimationPeriod"])

        self.kernel = self._gauss_kernel(self.historic_raw_anomaly_scores.maxlen,
                                         self.historic_raw_anomaly_scores.maxlen)

    def modelRun(self, ts, val):
        """
           Run a single pass through HTM model
           @config ts - Timestamp
           @config val - float input value
           @return rawAnomalyScore computed for the `val` in this step
        """
        self.iteration_ += 1

        # 0. During the probation period, gather the data and return 0.01.
        if self.iteration_ <= self.probationaryPeriod:
            self.init_data.append((ts, val))
            return 0.01

        if self.is_initialized is False:
            if self.verbose:
                print("[{}] Initializing".format(self.name))
            temp_iteration = self.iteration_
            vals = [i[1] for i in self.init_data]
            self.initialize(input_min=min(vals), input_max=max(vals))
            self.is_initialized = True
            for ts, val in self.init_data:
                self.modelRun(ts, val)
            self.iteration_ = temp_iteration
            if self.verbose:
                print("[{}] Initialization done".format(self.name))


        ## run data through our model pipeline: enc -> SP -> TM -> Anomaly
        # 1. Encoding
        # Call the encoders to create bit representations for each value.  These are SDR objects.
        dateBits = self.encTimestamp.encode(ts)
        valueBits = self.encValue.encode(float(val))
        # Concatenate all these encodings into one large encoding for Spatial Pooling.
        encoding = SDR(self.encTimestamp.size + self.encValue.size).concatenate([valueBits, dateBits])
        self.enc_info.addData(encoding)

        # 2. Spatial Pooler
        # Create an SDR to represent active columns, This will be populated by the
        # compute method below. It must have the same dimensions as the Spatial Pooler.
        activeColumns = SDR(self.sp.getColumnDimensions())
        # Execute Spatial Pooling algorithm over input space.
        self.sp.compute(encoding, True, activeColumns)
        self.sp_info.addData(activeColumns)

        # 3. Temporal Memory
        # Execute Temporal Memory algorithm over active mini-columns.
        self.tm.compute(activeColumns, learn=True)
        self.tm_info.addData(self.tm.getActiveCells().flatten())

        # 4. Anomaly
        # handle spatial, contextual (raw, likelihood) anomalies
        # -Spatial
        spatialAnomaly = 0.0
        if self.useSpatialAnomaly:
            # Update min/max values and check if there is a spatial anomaly
            if self.minVal != self.maxVal:
                tolerance = (self.maxVal - self.minVal) * self.spatial_tolerance
                maxExpected = self.maxVal + tolerance
                minExpected = self.minVal - tolerance
                if val > maxExpected or val < minExpected:
                    spatialAnomaly = 1.0
            if self.maxVal is None or val > self.maxVal:
                self.maxVal = val
            if self.minVal is None or val < self.minVal:
                self.minVal = val

        # -Temporal
        raw = self.tm.anomaly
        like = self.anomalyLikelihood.anomalyProbability(val, raw, ts)
        logScore = self.anomalyLikelihood.computeLogLikelihood(like)
        temporalAnomaly = logScore

        anomalyScore = max(spatialAnomaly, temporalAnomaly)  # this is the "main" anomaly, compared in NAB

        # 5. Apply smoothing
        self.historic_raw_anomaly_scores.append(anomalyScore)
        historic_scores = np.asarray(self.historic_raw_anomaly_scores)
        convolved = np.convolve(historic_scores, self.kernel, 'valid')
        anomalyScore = convolved[-1]

        return anomalyScore

    @staticmethod
    def estimateNormal(sampleData, performLowerBoundCheck=True):
        """
        :param sampleData:
        :type sampleData: Numpy array.
        :param performLowerBoundCheck:
        :type performLowerBoundCheck: bool
        :returns: A dict containing the parameters of a normal distribution based on
            the ``sampleData``.
        """
        mean = np.mean(sampleData)
        variance = np.var(sampleData)
        st_dev = 0

        if performLowerBoundCheck:
            # Handle edge case of almost no deviations and super low anomaly scores. We
            # find that such low anomaly means can happen, but then the slightest blip
            # of anomaly score can cause the likelihood to jump up to red.
            if mean < 0.03:
                mean = 0.03

            # Catch all for super low variance to handle numerical precision issues
            if variance < 0.0003:
                variance = 0.0003

        # Compute standard deviation
        if variance > 0:
            st_dev = math.sqrt(variance)

        return mean, variance, st_dev

    @staticmethod
    def _calcSkipRecords(numIngested, windowSize, learningPeriod):
        """Return the value of skipRecords for passing to estimateAnomalyLikelihoods

        If `windowSize` is very large (bigger than the amount of data) then this
        could just return `learningPeriod`. But when some values have fallen out of
        the historical sliding window of anomaly records, then we have to take those
        into account as well so we return the `learningPeriod` minus the number
        shifted out.

        :param numIngested - (int) number of data points that have been added to the
          sliding window of historical data points.
        :param windowSize - (int) size of sliding window of historical data points.
        :param learningPeriod - (int) the number of iterations required for the
          algorithm to learn the basic patterns in the dataset and for the anomaly
          score to 'settle down'.
        """
        numShiftedOut = max(0, numIngested - windowSize)
        return min(numIngested, max(0, learningPeriod - numShiftedOut))

    @staticmethod
    def _gauss_kernel(std, size):
        def _norm_pdf(x, mean, sd):
            var = float(sd) ** 2
            denom = (2 * math.pi * var) ** .5
            num = math.exp(-(float(x) - float(mean)) ** 2 / (2 * var))
            return num / denom

        kernel = [2 * _norm_pdf(idx, 0, std) for idx in list(range(-size + 1, 1))]
        kernel = np.array(kernel)
        kernel = np.flip(kernel)
        kernel = kernel / sum(kernel)
        return kernel
示例#16
0
def building_htm(len_data):
    global enc_info
    global sp_info
    global tm_info
    global anomaly_history
    global predictor
    global predictor_resolution
    global tm
    global sp
    global scalarEncoder
    global encodingWidth
    global dateEncoder

    # Initial message
    print("Building HTM for predicting trends...")

    # Default parameters in HTM
    default_parameters = {
        # There are 2 (3) encoders: "value" (RDSE) & "time" (DateTime weekend, timeOfDay)
        'enc': {
            "value": {
                'resolution': 0.88,
                'size': 700,
                'sparsity': 0.02
            },
            "time": {
                'timeOfDay': (30, 1)
            }  #, 'weekend': 21}
        },
        'predictor': {
            'sdrc_alpha': 0.1
        },
        'sp': {
            'boostStrength': 3.0,
            'columnCount': 1638,
            'localAreaDensity': 0.04395604395604396,
            'potentialPct': 0.85,
            'synPermActiveInc': 0.04,
            'synPermConnected': 0.13999999999999999,
            'synPermInactiveDec': 0.006
        },
        'tm': {
            'activationThreshold': 17,
            'cellsPerColumn': 13,
            'initialPerm': 0.21,
            'maxSegmentsPerCell': 128,
            'maxSynapsesPerSegment': 64,
            'minThreshold': 10,
            'newSynapseCount': 32,
            'permanenceDec': 0.1,
            'permanenceInc': 0.1
        },
        'anomaly': {
            'likelihood': {
                'probationaryPct': 0.1,
                'reestimationPeriod': 100
            }
        }
    }

    # Make the encoder
    print("- Make the encoder")
    dateEncoder = DateEncoder(
        timeOfDay=default_parameters["enc"]["time"]["timeOfDay"])
    scalarEncoderParams = RDSE_Parameters()
    scalarEncoderParams.size = default_parameters["enc"]["value"]["size"]
    scalarEncoderParams.sparsity = default_parameters["enc"]["value"][
        "sparsity"]
    scalarEncoderParams.resolution = default_parameters["enc"]["value"][
        "resolution"]
    scalarEncoder = RDSE(scalarEncoderParams)
    encodingWidth = (dateEncoder.size + scalarEncoder.size)
    enc_info = Metrics([encodingWidth], 999999999)

    # Make the SP
    print("- Make the SP")
    spParams = default_parameters["sp"]
    sp = SpatialPooler(inputDimensions=(encodingWidth, ),
                       columnDimensions=(spParams["columnCount"], ),
                       potentialPct=spParams["potentialPct"],
                       potentialRadius=encodingWidth,
                       globalInhibition=True,
                       localAreaDensity=spParams["localAreaDensity"],
                       synPermInactiveDec=spParams["synPermInactiveDec"],
                       synPermActiveInc=spParams["synPermActiveInc"],
                       synPermConnected=spParams["synPermConnected"],
                       boostStrength=spParams["boostStrength"],
                       wrapAround=True)
    sp_info = Metrics(sp.getColumnDimensions(), 999999999)

    # Temporal Memory Parameters
    print("- Make the TM")
    tmParams = default_parameters["tm"]
    tm = TemporalMemory(
        columnDimensions=(spParams["columnCount"], ),
        cellsPerColumn=tmParams["cellsPerColumn"],
        activationThreshold=tmParams["activationThreshold"],
        initialPermanence=tmParams["initialPerm"],
        connectedPermanence=spParams["synPermConnected"],
        minThreshold=tmParams["minThreshold"],
        maxNewSynapseCount=tmParams["newSynapseCount"],
        permanenceIncrement=tmParams["permanenceInc"],
        permanenceDecrement=tmParams["permanenceDec"],
        predictedSegmentDecrement=0.0,
        maxSegmentsPerCell=tmParams["maxSegmentsPerCell"],
        maxSynapsesPerSegment=tmParams["maxSynapsesPerSegment"])
    tm_info = Metrics([tm.numberOfCells()], 999999999)

    # Setup Likelihood
    print("- Make Anomaly Score/Likelihood")
    anParams = default_parameters["anomaly"]["likelihood"]
    probationaryPeriod = int(
        math.floor(float(anParams["probationaryPct"]) * len_data))
    learningPeriod = int(math.floor(probationaryPeriod / 2.0))
    anomaly_history = AnomalyLikelihood(
        learningPeriod=learningPeriod,
        estimationSamples=probationaryPeriod - learningPeriod,
        reestimationPeriod=anParams["reestimationPeriod"])

    # Make predictor
    print("- Make the predictor")
    predictor = Predictor(steps=[1, 5],
                          alpha=default_parameters["predictor"]['sdrc_alpha'])
    predictor_resolution = 1

    # End message
    print("- Finish the building of HTM!")
dateEncoder = DateEncoder(timeOfDay=(30, 1), weekend=21)

scalarEncoderParams = RDSE_Parameters()
scalarEncoderParams.size = 700
scalarEncoderParams.sparsity = 0.02
scalarEncoderParams.resolution = 0.88
scalarEncoder = RDSE(scalarEncoderParams)
encodingWidth = (dateEncoder.size + scalarEncoder.size)

sp = SpatialPooler(inputDimensions=(encodingWidth, ),
                   columnDimensions=(1638, ),
                   potentialPct=0.85,
                   potentialRadius=encodingWidth,
                   globalInhibition=True,
                   localAreaDensity=0.04395604395604396,
                   synPermInactiveDec=0.006,
                   synPermActiveInc=0.04,
                   synPermConnected=0.13999999999999999,
                   boostStrength=3.0,
                   wrapAround=True)

tm = TemporalMemory(
    columnDimensions=(1638, ),  #sp.columnDimensions
    cellsPerColumn=13,
    activationThreshold=17,
    initialPermanence=0.21,
    connectedPermanence=0.13999999999999999,  #sp.synPermConnected
    minThreshold=10,
    maxNewSynapseCount=32,
    permanenceIncrement=0.1,
示例#18
0
def spatial_pooler_encoer(pooler_data):
    sp1 = SpatialPooler(
        inputDimensions=(8000,),
        columnDimensions=(8000,),
        potentialPct=0.85,
        globalInhibition=True,
        localAreaDensity=0.0335,
        synPermInactiveDec=0.006,
        synPermActiveInc=0.04,
        synPermConnected=0.13999999999999999,
        boostStrength=4.0,
        wrapAround=True
    )
    sdr_array = []
    # We run SP over there epochs and in the third epoch collect the results
    # this technique yield betters results than  a single epoch
    for encoding in pooler_data:
        activeColumns1 = SDR(sp1.getColumnDimensions())
        sp1.compute(encoding, True, activeColumns1)
    for encoding in pooler_data:
        activeColumns2 = SDR(sp1.getColumnDimensions())
        sp1.compute(encoding, True, activeColumns2)
    for encoding in pooler_data:
        activeColumns3 = SDR(sp1.getColumnDimensions())
        sp1.compute(encoding, True, activeColumns3)
        sdr_array.append(activeColumns3)
    # To make sure the we can relate SP output to real images
    # we take out specific SDR which corrospond to known images.
    hold_out = sdr_array[10000]
    hold_out1 = sdr_array[10001]
    hold_out2 = sdr_array[10002]
    (x_train, _), (x_test, _) = mnist.load_data()
    anm = np.asarray(PIL.Image.open('images/anm.jpg').convert('L')).reshape((1, 28, 28, 1)) / (255 - 1)
    anm1 = np.asarray(PIL.Image.open('images/anm1.jpg').convert('L')).reshape((1, 28, 28, 1)) / (255 - 1)
    anm2 = np.asarray(PIL.Image.open('images/anm2.jpg').convert('L')).reshape((1, 28, 28, 1)) / (255 - 1)
    x_train = x_train.astype('float32') / (255 - 1)
    x_test = x_test.astype('float32') / (255 - 1)
    x_train = np.reshape(x_train, (len(x_train), 28, 28, 1))  # adapt this if using `channels_first` image data format
    x_test = np.reshape(x_test, (len(x_test), 28, 28, 1))  # adapt this if using `channels_first` image data format
    x_test = np.concatenate((x_test, anm, anm1, anm2))
    counter = 0
    # finally we loop over the SP SDR and related image to get the once
    # which have a greater overlap with the image we are searching for
    for _s, _img in zip(sdr_array, x_test):
        _x_ = hold_out2.getOverlap(_s)
        if _x_ > MATCH_FACTOR : # Adjust as required.
            _img_ = _img.reshape((28, 28))
            _img_ = (_img_ * 254).astype(np.uint8)
            im = Image.fromarray(_img_).convert('RGB')
            im.save('test_results/' + str(counter) + 'outfile.jpg')
            print('Sparsity - ' + str(_s.getSparsity()))
            print(_x_)
            print(str('counter - ') + str(counter))
            counter += 1
示例#19
0
    def initialize(self):
        # toggle parameters here
        # parameters = default_parameters
        parameters = parameters_numenta_comparable

        ## setup Enc, SP, TM, Likelihood
        # Make the Encoders.  These will convert input data into binary representations.
        self.encTimestamp = DateEncoder(
            timeOfDay=parameters["enc"]["time"]["timeOfDay"],
            weekend=parameters["enc"]["time"]["weekend"],
            season=parameters["enc"]["time"]["season"],
            dayOfWeek=parameters["enc"]["time"]["dayOfWeek"])

        scalarEncoderParams = EncParameters()
        scalarEncoderParams.size = parameters["enc"]["value"]["size"]
        scalarEncoderParams.sparsity = parameters["enc"]["value"]["sparsity"]
        scalarEncoderParams.resolution = parameters["enc"]["value"][
            "resolution"]

        self.encValue = Encoder(scalarEncoderParams)
        encodingWidth = (self.encTimestamp.size + self.encValue.size)
        self.enc_info = Metrics([encodingWidth], 999999999)

        # Make the HTM.  SpatialPooler & TemporalMemory & associated tools.
        # SpatialPooler
        spParams = parameters["sp"]
        self.sp = SpatialPooler(
            inputDimensions=(encodingWidth, ),
            columnDimensions=(spParams["columnCount"], ),
            potentialPct=spParams["potentialPct"],
            potentialRadius=spParams["potentialRadius"],
            globalInhibition=True,
            localAreaDensity=spParams["localAreaDensity"],
            stimulusThreshold=spParams["stimulusThreshold"],
            synPermInactiveDec=spParams["synPermInactiveDec"],
            synPermActiveInc=spParams["synPermActiveInc"],
            synPermConnected=spParams["synPermConnected"],
            boostStrength=spParams["boostStrength"],
            wrapAround=True)
        self.sp_info = Metrics(self.sp.getColumnDimensions(), 999999999)

        # TemporalMemory
        tmParams = parameters["tm"]
        self.tm = TemporalMemory(
            columnDimensions=(spParams["columnCount"], ),
            cellsPerColumn=tmParams["cellsPerColumn"],
            activationThreshold=tmParams["activationThreshold"],
            initialPermanence=tmParams["initialPerm"],
            connectedPermanence=spParams["synPermConnected"],
            minThreshold=tmParams["minThreshold"],
            maxNewSynapseCount=tmParams["newSynapseCount"],
            permanenceIncrement=tmParams["permanenceInc"],
            permanenceDecrement=tmParams["permanenceDec"],
            predictedSegmentDecrement=0.0,
            maxSegmentsPerCell=tmParams["maxSegmentsPerCell"],
            maxSynapsesPerSegment=tmParams["maxSynapsesPerSegment"])
        self.tm_info = Metrics([self.tm.numberOfCells()], 999999999)

        # setup likelihood, these settings are used in NAB
        if self.useLikelihood:
            anParams = parameters["anomaly"]["likelihood"]
            learningPeriod = int(math.floor(self.probationaryPeriod / 2.0))
            self.anomalyLikelihood = AnomalyLikelihood(
                learningPeriod=learningPeriod,
                estimationSamples=self.probationaryPeriod - learningPeriod,
                reestimationPeriod=anParams["reestimationPeriod"])