// Return a segmentUpdate data structure containing a list of proposed changes to segment. // Let activeSynapses be the list of active synapses where the originating cells have // their activeState output = 1 at time step t. // (This list is empty if s = -1 since the segment doesn't exist.) newSynapses is an optional argument // that defaults to false. If newSynapses is true, then newSynapseCount - count(activeSynapses) synapses // are added to activeSynapses. These synapses are randomly chosen from the set of cells that have // learnState output = 1 at time step t. public SegmentUpdate GetSegmentActiveSynapses(int t, HTMSegment segment = null, bool newSynapses = false) { SegmentUpdate segmentUpdate = new SegmentUpdate(); segmentUpdate.ActiveSynapses = new List <HTMSynapse>(); segmentUpdate.NewSynapses = new List <HTMCell>(); segmentUpdate.AddNewSynapses = newSynapses; segmentUpdate.Segment = segment; if (segmentUpdate.Segment != null) { segmentUpdate.ActiveSynapses = segment.GetActiveSynapses(t, false, false); } if (!newSynapses) { return(segmentUpdate); } int newSynapseCount = Math.Max(0, _newSynapseCount - segmentUpdate.ActiveSynapses.Count); //List<HTMCell> learningCells = GetRandomActiveCells(t); List <HTMCell> learningCells = GetRandomLearningCells(t); newSynapseCount = Math.Min(newSynapseCount, learningCells.Count); // Truncate the array of learning cells. To do : get a random sample of the array. for (int i = 0; i < newSynapseCount; i++) { segmentUpdate.NewSynapses.Add(learningCells[i]); } return(segmentUpdate); }
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); } } } } }
// Return a segmentUpdate data structure containing a list of proposed changes to segment. // Let activeSynapses be the list of active synapses where the originating cells have // their activeState output = 1 at time step t. // (This list is empty if s = -1 since the segment doesn't exist.) newSynapses is an optional argument // that defaults to false. If newSynapses is true, then newSynapseCount - count(activeSynapses) synapses // are added to activeSynapses. These synapses are randomly chosen from the set of cells that have // learnState output = 1 at time step t. public SegmentUpdate GetSegmentActiveSynapses(int t, HTMSegment segment = null, bool newSynapses = false) { SegmentUpdate segmentUpdate = new SegmentUpdate(); segmentUpdate.ActiveSynapses = new List<HTMSynapse>(); segmentUpdate.NewSynapses = new List<HTMCell>(); segmentUpdate.AddNewSynapses = newSynapses; segmentUpdate.Segment = segment; if (segmentUpdate.Segment != null) segmentUpdate.ActiveSynapses = segment.GetActiveSynapses(t, false, false); if (!newSynapses) return segmentUpdate; int newSynapseCount = Math.Max(0, _newSynapseCount - segmentUpdate.ActiveSynapses.Count); //List<HTMCell> learningCells = GetRandomActiveCells(t); List<HTMCell> learningCells = GetRandomLearningCells(t); newSynapseCount = Math.Min(newSynapseCount, learningCells.Count); // Truncate the array of learning cells. To do : get a random sample of the array. for (int i = 0 ; i < newSynapseCount; i++) segmentUpdate.NewSynapses.Add(learningCells[i]); return segmentUpdate; }