// For the given column, return the cell with the best matching segment. // If no cell has a matching segment, then return the cell with the fewest number of segments. public CellSegmentInfo GetBestMatchingCell(bool sequence, int t) { HTMCell bestCell = null; HTMSegment bestSeg = null; int bestCount = 0; HTMSegment seg; int synapseCount; foreach (HTMCell cell in _cells) { seg = cell.GetBestMatchingSegment(t, sequence); // TO DO . to study in depth. the previsous function is aggressive in finding the segment but // nevertheless exclude segment with activation under minThreshold, this could bring // to add step by step similar segments? if (seg != null) { synapseCount = seg.GetActiveSynapses(t, false, false).Count; if (synapseCount > bestCount) { bestCell = cell; bestSeg = seg; bestCount = synapseCount; } } } if (bestCell == null) { int fewestSegmentCount = int.MaxValue; foreach (HTMCell cell in _cells) { if (cell.DistalSegments.Count < fewestSegmentCount) { fewestSegmentCount = cell.DistalSegments.Count; bestCell = cell; //if (cell.DistalSegments.Count > 0) // bestSeg = cell.DistalSegments[0]; // choose the first segment } } } CellSegmentInfo cellSegmentInfo = new CellSegmentInfo(); cellSegmentInfo.Cell = bestCell; cellSegmentInfo.Segment = bestSeg; return(cellSegmentInfo); }
public void StepTemporalPooling() { // Phase 1 // From the Numenta Docs: // The first phase calculates the active state for each cell. // For each winning column we determine which cells should become active. // If the bottom-up input was predicted by any cell (i.e. its predictiveState was 1 due to // a sequence segment in the previous time step), then those cells become active (lines 4-9). // If the bottom-up input was unexpected (i.e. no cells had predictiveState output on), // then each cell in the column becomes active (lines 11-13). foreach (HTMColumn col in _activeColumns) { bool buPredicted = false; bool lcChosen = false; foreach (HTMCell cell in col.Cells) { if (cell.GetPredicting(-1)) { // _correctPrediction++; HTMSegment segment = cell.GetActiveSegment(-1); if (segment != null && segment.IsSequence) { buPredicted = true; cell.SetActive(true); if (_doTemporalLearning) { if (segment.GetActive(-1, true, false)) { lcChosen = true; cell.SetLearning(true); } } } } } if (!buPredicted) { foreach (HTMCell cell in col.Cells) { cell.SetActive(true); } } // If the bottom-up input was not predicted, the best matching cell is chosen as the learning cell and a new segment is added to that cell. if (_doTemporalLearning) { if (!lcChosen) { CellSegmentInfo bestCellSegmentInfo = col.GetBestMatchingCell(true, -1); bestCellSegmentInfo.Cell.SetLearning(true); SegmentUpdate segmentToUpdate = bestCellSegmentInfo.Cell.GetSegmentActiveSynapses(-1, bestCellSegmentInfo.Segment, true); segmentToUpdate.IsSequence = true; if (segmentToUpdate.Segment != null || (segmentToUpdate.AddNewSynapses && segmentToUpdate.NewSynapses.Count > 0)) // queue the update only if necessary { bestCellSegmentInfo.Cell.SegmentUpdateList.Add(segmentToUpdate); } } } } // Phase 2 // The second phase calculates the predictive state for each cell. // A cell will turn on its predictive state output if one of its segments becomes active, // i.e. if enough of its lateral inputs are currently active due to feed-forward input. // In this case, the cell queues up the following changes: // a) reinforcement of the currently active segment (lines 47-48), // and b) reinforcement of a segment that could have predicted this activation, // i.e. a segment that has a (potentially weak) match to activity during the previous time step (lines 50-53). foreach (HTMColumn col in _columns) { foreach (HTMCell cell in col.Cells) { //if (cell.GetActive(0)) // Cells with active dendrite segments are put in the predictive state UNLESS they are already active due to feed-forward input. // continue; foreach (HTMSegment seg in cell.DistalSegments) { if (!seg.GetActive(0, false, false)) { continue; } cell.SetPredicting(true); // TO DO : check. Active and predictive state are mutual exclusive? // if so, the changing from active to predicting must be done // through a temporary array to avoid cell asymmetrical behavior. //cell.SetActive(false); if (_doTemporalLearning) { // a) reinforcement of the currently active segment SegmentUpdate activeSegUpdate = cell.GetSegmentActiveSynapses(0, seg); cell.SegmentUpdateList.Add(activeSegUpdate); // b) reinforcement of a segment that could have predicted this activation, HTMSegment predSegment = cell.GetBestMatchingSegment(-1, true); if (predSegment == null) { continue; } SegmentUpdate predSegUpdate = cell.GetSegmentActiveSynapses(-1, predSegment, true); cell.SegmentUpdateList.Add(predSegUpdate); } } } } // Phase 3 // The third and last phase actually carries out learning. // In this phase segment updates that have been queued up are actually // implemented once we get feed-forward input and the cell is chosen // as a learning cell (lines 56-57). Otherwise, // if the cell ever stops predicting for any reason, // we negatively reinforce the segments (lines 58-60). if (_doTemporalLearning) { foreach (HTMColumn col in _columns) { foreach (HTMCell cell in col.Cells) { if (cell.SegmentUpdateList.Count == 0) // if there isn't segment to adapt then continue. { continue; } if (cell.GetLearning(0)) { // once we get feed-forward input and the cell is chosen as a learning cell cell.AdaptSegments(true); } else // if (!cell.GetPredicting(0) && cell.GetPredicting(-1)) { // if the cell ever stops predicting for any reason, // we negatively reinforce the segments cell.AdaptSegments(false); } } } } }
// For the given column, return the cell with the best matching segment. // If no cell has a matching segment, then return the cell with the fewest number of segments. public CellSegmentInfo GetBestMatchingCell(bool sequence, int t) { HTMCell bestCell = null; HTMSegment bestSeg = null; int bestCount = 0; HTMSegment seg; int synapseCount; foreach (HTMCell cell in _cells) { seg = cell.GetBestMatchingSegment(t, sequence); // TO DO . to study in depth. the previsous function is aggressive in finding the segment but // nevertheless exclude segment with activation under minThreshold, this could bring // to add step by step similar segments? if (seg != null) { synapseCount = seg.GetActiveSynapses(t, false, false).Count; if (synapseCount > bestCount) { bestCell = cell; bestSeg = seg; bestCount = synapseCount; } } } if (bestCell == null) { int fewestSegmentCount = int.MaxValue; foreach (HTMCell cell in _cells) { if (cell.DistalSegments.Count < fewestSegmentCount) { fewestSegmentCount = cell.DistalSegments.Count; bestCell = cell; //if (cell.DistalSegments.Count > 0) // bestSeg = cell.DistalSegments[0]; // choose the first segment } } } CellSegmentInfo cellSegmentInfo = new CellSegmentInfo(); cellSegmentInfo.Cell = bestCell; cellSegmentInfo.Segment = bestSeg; return cellSegmentInfo; }