func TestUpdateBoostFactors(t *testing.T) { sp := SpatialPooler{} sp.MaxBoost = 10.0 sp.numColumns = 6 sp.minActiveDutyCycles = make([]float64, sp.numColumns) for i, _ := range sp.minActiveDutyCycles { sp.minActiveDutyCycles[i] = -0.0000001 } sp.activeDutyCycles = []float64{0.1, 0.3, 0.02, 0.04, 0.7, 0.12} sp.boostFactors = make([]float64, sp.numColumns) trueBoostFactors := []float64{1, 1, 1, 1, 1, 1} sp.updateBoostFactors() for i, _ := range sp.boostFactors { assert.Equal(t, trueBoostFactors[i], sp.boostFactors[i]) } sp.MaxBoost = 10.0 sp.numColumns = 6 sp.minActiveDutyCycles = []float64{0.1, 0.3, 0.02, 0.04, 0.7, 0.12} sp.activeDutyCycles = []float64{0.1, 0.3, 0.02, 0.04, 0.7, 0.12} trueBoostFactors = []float64{1, 1, 1, 1, 1, 1} sp.updateBoostFactors() for i, _ := range sp.boostFactors { diff := math.Abs(trueBoostFactors[i] - sp.boostFactors[i]) assert.True(t, diff <= 0.0000001) } sp.MaxBoost = 10.0 sp.numColumns = 6 sp.minActiveDutyCycles = []float64{0.1, 0.2, 0.02, 0.03, 0.7, 0.12} sp.activeDutyCycles = []float64{0.01, 0.02, 0.002, 0.003, 0.07, 0.012} trueBoostFactors = []float64{9.1, 9.1, 9.1, 9.1, 9.1, 9.1} sp.updateBoostFactors() for i, _ := range sp.boostFactors { diff := math.Abs(trueBoostFactors[i] - sp.boostFactors[i]) assert.True(t, diff <= 0.0000001) } sp.MaxBoost = 10.0 sp.numColumns = 6 sp.minActiveDutyCycles = []float64{0.1, 0.2, 0.02, 0.03, 0.7, 0.12} sp.activeDutyCycles = make([]float64, sp.numColumns) trueBoostFactors = utils.MakeSliceFloat64(6, sp.MaxBoost) sp.updateBoostFactors() for i, _ := range sp.boostFactors { diff := math.Abs(trueBoostFactors[i] - sp.boostFactors[i]) assert.True(t, diff <= 0.0000001) } }
func phase2(t *testing.T, bt *boostTest) { y := make([]bool, bt.sp.numColumns) // Do 9 training batch through the input patterns for i := 0; i < 9; i++ { for idx, input := range bt.x { utils.FillSliceBool(y, false) bt.sp.Compute(input, true, y, bt.sp.InhibitColumns) for j, winner := range y { if winner { bt.winningIteration[j] = bt.sp.IterationLearnNum } } bt.lastSDR[idx] = y } } // The boost factor for all columns should be at 1. assert.Equal(t, bt.sp.numColumns, utils.CountFloat64(bt.sp.boostFactors, 1), "Boost factors are not all 1") // Roughly half of the columns should have never been active. winners := utils.CountInt(bt.winningIteration, 0) assert.True(t, winners >= int(0.4*float64(bt.sp.numColumns)), "More than 60% of the columns have been active") // All the never-active columns should have duty cycle of 0 activeSum := 0.0 for idx, val := range bt.sp.activeDutyCycles { if bt.winningIteration[idx] == 0 { activeSum += val } } assert.Equal(t, 0, activeSum, "Inactive columns have positive duty cycle.") dutyAvg := 0.0 dutyCount := 0 for _, val := range bt.sp.activeDutyCycles { if val > 0 { dutyAvg += val dutyCount++ } } // The average at-least-once-active columns should have duty cycle >= 0.15 // and <= 0.25 dutyAvg = dutyAvg / float64(dutyCount) assert.True(t, dutyAvg >= 0.15, "Average on-columns duty cycle is too low.") assert.True(t, dutyAvg <= 0.30, "Average on-columns duty cycle is too high.") verifySDRProps(t, bt) }
func phase1(t *testing.T, bt *boostTest) { y := make([]bool, bt.sp.numColumns) // Do one training batch through the input patterns for idx, input := range bt.x { utils.FillSliceBool(y, false) bt.sp.Compute(input, true, y, bt.sp.InhibitColumns) for j, winner := range y { if winner { bt.winningIteration[j] = bt.sp.IterationLearnNum } } bt.lastSDR[idx] = y } //The boost factor for all columns should be at 1. assert.Equal(t, bt.sp.numColumns, utils.CountFloat64(bt.sp.boostFactors, 1), "Boost factors are not all 1") //At least half of the columns should have never been active. winners := utils.CountInt(bt.winningIteration, 0) assert.True(t, winners >= bt.sp.numColumns/2, "More than half of the columns have been active") //All the never-active columns should have duty cycle of 0 //All the at-least-once-active columns should have duty cycle >= 0.2 activeSum := 0.0 for idx, val := range bt.sp.activeDutyCycles { if bt.winningIteration[idx] == 0 { //assert.Equal(t, expected, actual, ...) activeSum += val } } assert.Equal(t, 0, activeSum, "Inactive columns have positive duty cycle.") winningMin := 100000.0 for idx, val := range bt.sp.activeDutyCycles { if bt.winningIteration[idx] > 0 { if val < winningMin { winningMin = val } } } assert.True(t, winningMin >= 0.2, "Active columns have duty cycle that is too low.") verifySDRProps(t, bt) }
func TestLearnPredict(t *testing.T) { tps := NewTemporalPoolerParams() tps.Verbosity = 0 tps.NumberOfCols = 50 tps.CellsPerColumn = 2 tps.ActivationThreshold = 8 tps.MinThreshold = 10 tps.InitialPerm = 0.5 tps.ConnectedPerm = 0.5 tps.NewSynapseCount = 10 tps.PermanenceDec = 0.0 tps.PermanenceInc = 0.1 tps.GlobalDecay = 0 tps.BurnIn = 1 tps.PamLength = 10 //tps.DoPooling = true tps.CollectStats = true tp := NewTemporalPooler(*tps) inputs := make([][]bool, 5) // inputs[0] = GenerateRandSequence(80, 50) // inputs[1] = GenerateRandSequence(80, 50) // inputs[2] = GenerateRandSequence(80, 50) inputs[0] = boolRange(0, 9, 50) inputs[1] = boolRange(10, 19, 50) inputs[2] = boolRange(20, 29, 50) inputs[3] = boolRange(30, 39, 50) inputs[4] = boolRange(40, 49, 50) //Learn 5 sequences above for i := 0; i < 10; i++ { for p := 0; p < 5; p++ { tp.Compute(inputs[p], true, false) } tp.Reset() } //Predict sequences for i := 0; i < 4; i++ { tp.Compute(inputs[i], false, true) p := tp.DynamicState.InfPredictedState.Entries() fmt.Println(p) assert.Equal(t, 10, len(p)) for _, val := range p { next := i + 1 if next > 4 { next = 4 } assert.True(t, inputs[next][val.Row]) } } }
func verifySDRProps(t *testing.T, bt *boostTest) { /* Verify that all SDRs have the properties desired for this test. The bounds for checking overlap are set fairly loosely here since there is some variance due to randomness and the artificial parameters used in this test. */ // Verify that all SDR's are unique for i := 0; i <= 4; i++ { for j := 1; j <= 4; j++ { eq := 0 for k := 0; k < len(bt.lastSDR[i]); k++ { if bt.lastSDR[i][k] == bt.lastSDR[j][k] { eq++ } } if eq == len(bt.lastSDR[i]) { //equal assert.Fail(t, "All SDR's are not unique") } } } //Verify that the first two SDR's have some overlap. expected := computeOverlap(bt.lastSDR[0], bt.lastSDR[1]) > 9 assert.True(t, expected, "First two SDR's don't overlap much") // Verify the last three SDR's have low overlap with everyone else. for i := 2; i <= 4; i++ { for j := 0; j <= 4; j++ { if i != j { overlap := computeOverlap(bt.lastSDR[i], bt.lastSDR[j]) expected := overlap < 18 assert.True(t, expected, "One of the last three SDRs has high overlap") } } } }
func phase3(t *testing.T, bt *boostTest) { //Do two more training batches through the input patterns y := make([]bool, bt.sp.numColumns) for i := 0; i < 2; i++ { for idx, input := range bt.x { utils.FillSliceBool(y, false) bt.sp.Compute(input, true, y, bt.sp.InhibitColumns) for j, winner := range y { if winner { bt.winningIteration[j] = bt.sp.IterationLearnNum } } bt.lastSDR[idx] = y } } // The boost factor for all columns that just won should be at 1. for idx, val := range y { if val { if bt.sp.boostFactors[idx] != 1 { assert.Fail(t, "Boost factors of winning columns not 1") } } } // By now, every column should have been sufficiently boosted to win at least // once. The number of columns that have never won should now be 0 for _, val := range bt.winningIteration { if val == 0 { assert.Fail(t, "Expected all columns to have won atleast once.") } } // Because of the artificially induced thrashing, even the first two patterns // should have low overlap. Verify that the first two SDR's now have little // overlap overlap := computeOverlap(bt.lastSDR[0], bt.lastSDR[1]) assert.True(t, overlap < 7, "First two SDR's overlap significantly when they should not") }