Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Panda vis implementation #33

Merged
merged 9 commits into from
Apr 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ was a lack of developer activity in the upstream repo.
- [x] additional community-provided detectors:
- `htmcore`: currently the only HTM implementation able to run in NAB natively in python 3. (with many improvements in [Community HTM implementation, successor of nupic.core](https://github.com/htm-community/htm.core/).
- `numenta`, `numenta_TM` detectors (original from Numenta) made compatible with the Py3 codebase (only requires Py2 installed)
- [x] the HTM visualization tool [HTMPandaVis](https://github.com/htm-community/HTMpandaVis) could be used with htm_core_detector (set PANDA_VIS_ENABLED flag to True)
- [ ] additional datasets
- TBD, none so far

Expand Down
104 changes: 103 additions & 1 deletion nab/detectors/htmcore/htmcore_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@
# has been seen so far.
SPATIAL_TOLERANCE = 0.05

PANDA_VIS_ENABLED = False # if we want to run pandaVis tool (repo at https://github.com/htm-community/HTMpandaVis )

if PANDA_VIS_ENABLED:
from PandaVis.pandaComm.server import PandaServer
from PandaVis.pandaComm.dataExchange import ServerData, dataHTMObject, dataLayer, dataInput

pandaServer = PandaServer()

parameters_numenta_comparable = {
# there are 2 (3) encoders: "value" (RDSE) & "time" (DateTime weekend, timeOfDay)
'enc': {
Expand Down Expand Up @@ -115,6 +123,11 @@ def __init__(self, *args, **kwargs):
self.inputs_ = []
self.iteration_ = 0

# initialize pandaVis server
if PANDA_VIS_ENABLED:
pandaServer.Start()
self.BuildPandaSystem(parameters_numenta_comparable)


def getAdditionalHeaders(self):
"""Returns a list of strings."""
Expand Down Expand Up @@ -238,9 +251,25 @@ def modelRun(self, ts, val):

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

# the tm.compute() execute activateDendrites() - calculateAnomaly()/getPredictiveCells() - activateCells()
# but to get insight into system with visTool, we need to have different execution order
# Note: pandaVis retrieves synapses etc. by requesting data from sp/tm python objects, so data validity is crucial
if PANDA_VIS_ENABLED:
# activates cells in columns by TM algorithm (winners, bursting...)
self.tm.activateCells(activeColumns, learn=True)
# activateDendrites calculates active segments
self.tm.activateDendrites(learn=True)
# predictive cells are calculated directly from active segments
predictiveCells = self.tm.getPredictiveCells()
else:
self.tm.compute(activeColumns, learn=True)

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

if PANDA_VIS_ENABLED:
self.PandaUpdateData(ts, val, valueBits, dateBits , activeColumns, predictiveCells)

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

Expand Down Expand Up @@ -280,4 +309,77 @@ def modelRun(self, ts, val):
# print(self.tm_info)
pass

if PANDA_VIS_ENABLED:
pandaServer.BlockExecution()


return (anomalyScore, raw)

def BuildPandaSystem(self,modelParams):
Zbysekz marked this conversation as resolved.
Show resolved Hide resolved
global serverData
serverData = ServerData()
serverData.HTMObjects["HTM1"] = dataHTMObject()
serverData.HTMObjects["HTM1"].inputs["Value"] = dataInput()
serverData.HTMObjects["HTM1"].inputs["TimeOfDay"] = dataInput()

serverData.HTMObjects["HTM1"].layers["Layer1"] = dataLayer(
modelParams["sp"]["columnCount"],
modelParams["tm"]["cellsPerColumn"],
)
serverData.HTMObjects["HTM1"].layers["Layer1"].proximalInputs = ["Value","TimeOfDay"]
serverData.HTMObjects["HTM1"].layers["Layer1"].distalInputs = ["Layer1"]


def PandaUpdateData(self, timestamp, value, valueSDR, datetimeSDR, activeColumns, predictiveCells):

pandaServer.currentIteration = self.iteration_ # update server's iteration number
# do not update if we are running GOTO iteration command
if (not pandaServer.cmdGotoIteration or (
pandaServer.cmdGotoIteration and pandaServer.gotoIteration == pandaServer.currentIteration)):
# ------------------HTMpandaVis----------------------
# fill up values
serverData.iterationNo = pandaServer.currentIteration
serverData.HTMObjects["HTM1"].inputs["Value"].stringValue = "VALUE:" + str(value)
serverData.HTMObjects["HTM1"].inputs["Value"].bits = valueSDR.sparse
serverData.HTMObjects["HTM1"].inputs["Value"].count = valueSDR.size

serverData.HTMObjects["HTM1"].inputs["TimeOfDay"].stringValue = "TIME OF DAY:" + str(timestamp)
serverData.HTMObjects["HTM1"].inputs["TimeOfDay"].bits = datetimeSDR.sparse
serverData.HTMObjects["HTM1"].inputs["TimeOfDay"].count = datetimeSDR.size

serverData.HTMObjects["HTM1"].layers["Layer1"].activeColumns = activeColumns.sparse

serverData.HTMObjects["HTM1"].layers["Layer1"].winnerCells = self.tm.getWinnerCells().sparse
serverData.HTMObjects["HTM1"].layers["Layer1"].activeCells = self.tm.getActiveCells().sparse
serverData.HTMObjects["HTM1"].layers["Layer1"].predictiveCells = predictiveCells.sparse

# print("ACTIVECOLS:"+str(serverData.HTMObjects["HTM1"].layers["SensoryLayer"].activeColumns ))
# print("WINNERCELLS:"+str(serverData.HTMObjects["HTM1"].layers["SensoryLayer"].winnerCells))
# print("ACTIVECELLS:" + str(serverData.HTMObjects["HTM1"].layers["SensoryLayer"].activeCells))
# print("PREDICTCELLS:"+str(serverData.HTMObjects["HTM1"].layers["SensoryLayer"].predictiveCells))

pandaServer.serverData = serverData

pandaServer.spatialPoolers["HTM1"] = self.sp
pandaServer.temporalMemories["HTM1"] = self.tm
pandaServer.NewStateDataReady()


# WHILE USING PANDAVIS
# SPECIFY HERE FOR WHAT DATA YOU WANT TO RUN THIS DETECTOR
if PANDA_VIS_ENABLED:
import pandas as pd
import os.path as path
from nab.corpus import Corpus
dataDir = path.abspath(path.join(__file__ ,"../../../..","data"))

corpus = Corpus(dataDir)

dataSet = corpus.dataFiles["artificialWithAnomaly/art_daily_flatmiddle.csv"]

detector = HtmcoreDetector(dataSet=dataSet,
probationaryPercent=0.15)

detector.initialize()

detector.run()