Esempio n. 1
0
        // 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);
        }
Esempio n. 2
0
        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);
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        // 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;
        }