Hello, all. I am working on understanding the inner works of the ColumnPooler and am curious about why the ColumnPooler exceeds the target size when there is insufficient lateral support and not enough inertia from the prior state to achieve the target. I understand the how of as documented in the code (line 404 from column_pooler.py):
# If we haven't filled the sdrSize quorum, add cells that have feedforward
# support and no lateral support.
discrepancy = self.sdrSize - len(chosenCells)
if discrepancy > 0:
remainingFFcells = np.setdiff1d(feedforwardSupportedCells, chosenCells)
# Inhibit cells proportionally to the number of cells that have already
# been chosen. If ~0 have been chosen activate ~all of the feedforward
# supported cells. If ~sdrSize have been chosen, activate very few of
# the feedforward supported cells.
# Use the discrepancy:sdrSize ratio to determine the number of cells to
# activate.
n = (len(remainingFFcells) * discrepancy) // self.sdrSize
# Activate at least 'discrepancy' cells.
n = max(n, discrepancy)
# If there aren't 'n' available, activate all of the available cells.
n = min(n, len(remainingFFcells))
if len(remainingFFcells) > n:
selected = self._random.sample(remainingFFcells, n)
chosenCells = np.append(chosenCells, selected)
else:
chosenCells = np.append(chosenCells, remainingFFcells)
I am just curious why you would not take the top-k (where k = target sdr size) based on on forward overlaps. This would still give a blend of possible states if the forward in ambiguous. It seems, though, the code is suggesting that you want more than “just a blend”. The test case for this assumes a 100% union (line 219 from column_pooler_test.py):
# feed unions of patterns in objects A and B
pattern = objectA[0] | objectB[0]
self.pooler.reset()
self.infer(feedforwardPattern=pattern)
self.assertEqual(
self._getActiveRepresentation(),
representationA | representationB,
"The active representation is incorrect"
)
Thanks for any guidance.
EDIT: was calling it ContextPooler instead of ColumnPooler. Corrected.