Recently I ported the core parts of the Nupic project to Go.
Nupic is Numenta’s current open source implementation of Jeff Hawkin’s hierarchical temporal memory(HTM) model. It currently consists of the CLA (cortical learning algorithm) which is a single stage/layer of the HTM implemented in a mix of python and C++.
In an effort to better understand the difference between the current implementation and the whitepaper I decided to try and port the spatial and temporal poolers to Go. Porting line by line gave me the opportunity to understand the design better as well as it’s dependencies: python, numpy, etc…
One of the more difficult parts of this project was interpreting the numpy expressions and translating them into a statically typed language. A few nested numpy expressions can easily end up being 10 of lines of Go.
The result is 2 simple APIs for the spatial and temporal pooler which are go gettable.
12
go get github.com/zacg/htm
go get github.com/zacg/htm/utils
packagemainimport("fmt""github.com/zacg/htm""github.com/zacg/htm/utils")funcmain(){tps:=htm.NewTemporalPoolerParams()tps.Verbosity=0tps.NumberOfCols=50tps.CellsPerColumn=2tps.ActivationThreshold=8tps.MinThreshold=10tps.InitialPerm=0.5tps.ConnectedPerm=0.5tps.NewSynapseCount=10tps.PermanenceDec=0.0tps.PermanenceInc=0.1tps.GlobalDecay=0tps.BurnIn=1tps.PamLength=10tps.CollectStats=truetp:=htm.NewTemporalPooler(*tps)//Mock encoding of ABCDEinputs:=make([][]bool,5)inputs[0]=boolRange(0,9,50)//bits 0-9 are "on"inputs[1]=boolRange(10,19,50)//bits 10-19 are "on"inputs[2]=boolRange(20,29,50)//bits 20-29 are "on"inputs[3]=boolRange(30,39,50)//bits 30-39 are "on"inputs[4]=boolRange(40,49,50)//bits 40-49 are "on"//Learning and prediction can be done at the same time//Learn 5 sequences abovefori:=0;i<10;i++{forp:=0;p<5;p++{tp.Compute(inputs[p],true,false)}tp.Reset()//not required}//Predict sequencesfori:=0;i<4;i++{tp.Compute(inputs[i],false,true)p:=tp.DynamicState.InfPredictedStatefmt.Printf("Predicted: %v From input: %v \n",p.NonZeroRows(),utils.OnIndices(inputs[i]))}}//helper method for creating boolean sequencesfuncboolRange(startint,endint,lengthint)[]bool{result:=make([]bool,length)fori:=start;i<=end;i++{result[i]=true}returnresult}