def _getCellsWithFewestSegments(self, connections, columns): """ For each column, get the cell that has the fewest total basal segments. Break ties randomly. @param connections (SparseMatrixConnections) @param rng (Random) @param columns (numpy array) Columns to check @return (numpy array) One cell for each of the provided columns """ candidateCells = np2.getAllCellsInColumns(columns, self.cellsPerColumn) # Arrange the segment counts into one row per minicolumn. segmentCounts = np.reshape(connections.getSegmentCounts(candidateCells), newshape=(len(columns), self.cellsPerColumn)) # Filter to just the cells that are tied for fewest in their minicolumn. minSegmentCounts = np.amin(segmentCounts, axis=1, keepdims=True) candidateCells = candidateCells[np.flatnonzero(segmentCounts == minSegmentCounts)] # Filter to one cell per column, choosing randomly from the minimums. # To do the random choice, add a random offset to each index in-place, using # casting to floor the result. _, onePerColumnFilter, numCandidatesInColumns = np.unique(candidateCells // self.cellsPerColumn, return_index=True, return_counts=True) offsetPercents = np.empty(len(columns), dtype="float64") self.rng.initializeReal64Array(offsetPercents) np.add(onePerColumnFilter, offsetPercents*numCandidatesInColumns, out=onePerColumnFilter, casting="unsafe") return candidateCells[onePerColumnFilter]
def activateCells(self, activeColumns, basalReinforceCandidates, apicalReinforceCandidates, basalGrowthCandidates, apicalGrowthCandidates, learn=True): """ Activate cells in the specified columns, using the result of the previous 'depolarizeCells' as predictions. Then learn. @param activeColumns (numpy array) List of active columns @param basalReinforceCandidates SDR List of bits that the active cells may reinforce basal synapses to. @param apicalReinforceCandidates SDR List of bits that the active cells may reinforce apical synapses to. @param basalGrowthCandidates (numpy array) List of bits that the active cells may grow new basal synapses to. @param apicalGrowthCandidates (numpy array) List of bits that the active cells may grow new apical synapses to @param learn (bool) Whether to grow / reinforce / punish synapses """ # Calculate active cells correctPredictedCells, burstingColumns = np2.setCompare(self.predictedCells, activeColumns, self.predictedCells // self.cellsPerColumn, rightMinusLeft=True) newActiveCells = np.concatenate((correctPredictedCells, np2.getAllCellsInColumns(burstingColumns, self.cellsPerColumn))) # Calculate learning (learningActiveBasalSegments, learningMatchingBasalSegments, basalSegmentsToPunish, newBasalSegmentCells, learningCells) = self._calculateBasalLearning(activeColumns, burstingColumns, correctPredictedCells) (learningActiveApicalSegments, learningMatchingApicalSegments, apicalSegmentsToPunish, newApicalSegmentCells) = self._calculateApicalLearning(learningCells, activeColumns) # Learn if learn: # Learn on existing segments for learningSegments in (learningActiveBasalSegments, learningMatchingBasalSegments): self._learn(self.basalConnections, learningSegments, basalReinforceCandidates, basalGrowthCandidates, self.basalPotentialOverlaps) for learningSegments in (learningActiveApicalSegments, learningMatchingApicalSegments): self._learn(self.apicalConnections, learningSegments, apicalReinforceCandidates, apicalGrowthCandidates, self.apicalPotentialOverlaps) # Punish incorrect predictions if self.basalPredictedSegmentDecrement != 0.0: for segment in basalSegmentsToPunish: self.basalConnections.adaptSegment(segment, basalReinforceCandidates, -self.basalPredictedSegmentDecrement, 0.0, False) if self.apicalPredictedSegmentDecrement != 0.0: for segment in apicalSegmentsToPunish: self.apicalConnections.adaptSegment(segment, apicalReinforceCandidates, -self.apicalPredictedSegmentDecrement, 0.0, False) # Grow new segments if len(basalGrowthCandidates) > 0: self._learnOnNewSegments(self.basalConnections, newBasalSegmentCells, basalGrowthCandidates) if len(apicalGrowthCandidates) > 0: self._learnOnNewSegments(self.apicalConnections, newApicalSegmentCells, apicalGrowthCandidates) # Save the results newActiveCells.sort() learningCells.sort() self.activeCells = newActiveCells self.winnerCells = learningCells self.predictedActiveCells = correctPredictedCells