Question on Temporal Memory (Phase 1)

Hi all, just a quick question about phase 1 of the temporal memory code (activating correctly predicted cells):

What is the significance of ‘prevMatchingCells’ in the following code and why is it necessary to loop over them as opposed to ‘prevPreditiveCells’ as in the first for loop?:

for cell in prevPredictiveCells:
  column = self.columnForCell(cell)

  if column in activeColumns:
    activeCells.add(cell)
    winnerCells.add(cell)
    predictedActiveColumns.add(column)

if self.predictedSegmentDecrement > 0:
  for cell in **prevMatchingCells**:
    column = self.columnForCell(cell)

    if column not in activeColumns:
      predictedInactiveCells.add(cell)

I ask because I don’t understand what is meant by ‘prevMatchingCells’ or why it is necessary to search through them as opposed to ‘prevPredictiveCells’ as done intially. In other words, why not just have the following?:

for cell in prevPredictiveCells:
  column = self.columnForCell(cell)

  if column in activeColumns:
    activeCells.add(cell)
    winnerCells.add(cell)
    predictedActiveColumns.add(column)

  else:
    if self.predictedSegmentDecrement > 0 :
      predictiveInactiveCells.add(cell)

I notice that ‘prevMatchingCells’ are taken as an argument to the ‘activeCorrectlyPredictedCells’ function, though they’re not in the parameters listed:

@param prevPredictiveCells (set) Indices of predictive cells in `t-1`
@param activeColumns       (set) Indices of active columns in `t`

Also the pseudocode provided only mentions one for loop over the predicted cells:

  - for each prev predictive cell
    - if in active column
      - mark it as active
      - mark it as winner cell
      - mark column as predicted => active
    - if not in active column
      - mark it as an predicted but inactive cell

So I just wonder what would be lost by skipping the second for loop over ‘prevMatchingCells’ and just looping over ‘prevPredictedCells’ as I proposed in the alternative code above. Thanks!!

Hello @sheiser1, this will be a bit late but hopefully will be clear. Although my implementation also have these, I may have some stuff wrong so keep that in mind.

If you wanted to decrease the false positive predictions of CLA, then you would have to introduce some sort of distal segment decay. False positive in this case is, the segment was predictive (which makes the cell predictive) but the cell did not get activated in the next iteration. To decrease the false positives, you would go through all the previously predictive cells and decay (lower the permanence of the synapses) all its distal segments that were predictive.

However, you would actually want to strongly forget segments if they never result in true positives (activated predictions) for a proper decay emulation. If you only decay segments when they are in predictive state, then those segments would be only decayed until they are below the predictive threshold (activationThreshold). So you have to have a way to prevent remembering instantly after so many false predictions which causes oscillations (instability) sometimes.

What you do is you check the activity on segments regardless of synapse permanence and mark them as matching when it gets above minThreshold. When the activation on the distal segment’s potential synapses (notice I am not saying connected synapses) exceed this threshold, you add it to the matching segments list and the belonging cell to the matching cells list. A matching segment means that, if the current pattern appears frequent enough, this segment has the potential to connect its synapses and produce actual predictions. Though at the moment the segment is not predicting because it’s synapses have some permanence (> 0) but not connected. Same logic of potential activity is used when picking a distal segment to learn on when it is false negative (missed actvation). It is important to note that matching segments/cells include the predictive segments/cells due to this design.

So when a false positive distal segment gives enough predictions (prevPredictiveCells), it’s synapses will decay up to a point where the segment will not give predictions anymore . After that point the segment will still continue to decay because it will still be a matching one (prevMatchingCells) until it is decayed below the minThreshold and strongly forgotten

I believe this is not a major part of the implementation but rather an optimization to provide better stability. So you can in fact iterate over the prevPrediveCells rather than prevMatchingCells but it causes instant remembering and oscillations sometimes. It also allows you to decay or even delete segments even if they are not predicting.

I could not come up with a better word than strongly forgetting :slight_smile: Hope that is clear enough for you.

1 Like

Thanks @sunguralikaan! This makes sense. It was only after I posted the question when I realized that ‘prevMatchingSegments’ is a larger set containing ‘prevActiveSegments’ and ‘prevMatchingCells’ likewise contains ‘prevPredictiveCells’. I think I understand this now, so here’s my attempted recap:

It’s clear from phase 4 of the code that ‘matchingSegments’ is much less exclusive than ‘activeSegments’ since the synapses are only required to have permanence values > 0 to be ‘active’ (though not ‘connected’), and there only need be ‘minThreshold’ of them on the segment (instead of ‘activationThreshold’). Naturally these more loosely associated segments would yield more loosely associated ‘matchingCells’, yielding more false positive predictions.

Keeping track of these false positives by accumulating a set of ‘predictedInactiveCells’ is used in phase 3 of the code to adapt all the ‘prevMatchingSegments’ that led to those false predictions, by decrementing all the perm’s of all active synapses. I think of it as adjusting all the synapses on wrongly-predicting segments by decrementing the perm’s of all those that voted for the bad prediction. This is different than the way the ‘adaptSegment’ function is used earlier in phase 3, when it looks at all correctly-predicting segments and increments those synapses that were active (did vote for the prediction) and decrements those that weren’t.

It makes sense to me that actively decrementing those synapses that supported the bad predictions, not just those that failed to support the good ones, would lean out the number of false positives. Does this logic align with what’s going on?? If there’s anything I still seem to be missing/off base on please let me know if you would! And thanks again for your responses, they’re much appreciated :smile:

Yes, this is more or less what I believe is happening. You definitely put it in a more understandable fashion and your welcome:)