Skip to content

Commit

Permalink
Merge pull request #993 from htm-community/tm-repeating-inputs
Browse files Browse the repository at this point in the history
Fix TM static inputs issue.
  • Loading branch information
dkeeney authored Jan 23, 2023
2 parents 34a6853 + c877b27 commit f3d2905
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 10 deletions.
17 changes: 17 additions & 0 deletions bindings/py/tests/algorithms/temporal_memory_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,23 @@ def testGetMethods(self):
self.assertEqual(parameters1["tm"]["maxSynapsesPerSegment"], maxSynapsesPerSegment, "using Method (getMaxSynapsesPerSegment) failed")
self.assertEqual(True, checkInputs, "using Method (getCheckInputs) failed")

def testStaticInputs(self):
""" Check that repeating the same input results in the same output. """
cols = 100
tm = TM([cols])
# Train on a square wave.
inp_a = SDR(cols).randomize( .2 )
inp_b = SDR(cols).randomize( .2 )
for i in range(10): tm.compute( inp_a, True )
for i in range(10): tm.compute( inp_b, True )
# Test that it reached a steady state.
self.assertEqual(tm.anomaly, 0.0)
out_1 = tm.getActiveCells()
tm.compute( inp_b, True )
self.assertEqual(tm.anomaly, 0.0)
out_2 = tm.getActiveCells()
self.assertTrue(all(out_1.sparse == out_2.sparse))

def _print(txt):
if debugPrint:
print(txt)
Expand Down
29 changes: 19 additions & 10 deletions src/htm/algorithms/TemporalMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ void TemporalMemory::activatePredictedColumn_(


void TemporalMemory::burstColumn_(
const UInt column,
vector<Segment>::const_iterator columnMatchingSegmentsBegin,
vector<Segment>::const_iterator columnMatchingSegmentsEnd,
const UInt column,
const vector<Segment>::const_iterator columnMatchingSegmentsBegin,
const vector<Segment>::const_iterator columnMatchingSegmentsEnd,
const SDR &prevActiveCells,
const vector<CellIdx> &prevWinnerCells,
const bool learn) {
Expand All @@ -208,19 +208,28 @@ void TemporalMemory::burstColumn_(
numActivePotentialSynapsesForSegment_[b]);
});

const CellIdx winnerCell =
(bestMatchingSegment != columnMatchingSegmentsEnd)
? connections.cellForSegment(*bestMatchingSegment)
: getLeastUsedCell_(column); //TODO replace (with random?) this is extremely costly, removing makes TM 6x faster!

CellIdx winnerCell;
if(bestMatchingSegment != columnMatchingSegmentsEnd) {
winnerCell = connections.cellForSegment(*bestMatchingSegment);
}
else {
// Check for previous winner cells in this minicolumn.
const auto prevWinnerPtr = std::lower_bound(prevWinnerCells.begin(), prevWinnerCells.end(), column,
[&](const CellIdx cell, const UInt col) { return columnForCell(cell) < col; });
if(prevWinnerPtr != prevWinnerCells.end() && columnForCell(*prevWinnerPtr) == column) {
winnerCell = *prevWinnerPtr;
}
else {
winnerCell = getLeastUsedCell_(column);
}
}
winnerCells_.push_back(winnerCell);

// Learn.
if (learn) {
if (bestMatchingSegment != columnMatchingSegmentsEnd) {
// Learn on the best matching segment.
connections_.adaptSegment(*bestMatchingSegment, prevActiveCells,
permanenceIncrement_, permanenceDecrement_, true, minThreshold_); //TODO consolidate SP.stimulusThreshold_ & TM.minThreshold_ into Conn.stimulusThreshold ? (replacing segmentThreshold arg used in some methods in Conn)
permanenceIncrement_, permanenceDecrement_, true, minThreshold_);

const Int32 nGrowDesired = maxNewSynapseCount_ - numActivePotentialSynapsesForSegment_[*bestMatchingSegment];
if (nGrowDesired > 0) {
Expand Down

0 comments on commit f3d2905

Please sign in to comment.