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
        // Return a segment that is/was active at time t.
        // If multiple segments are active, sequence segments are given preference.
        // Otherwise, segments with most activity are given preference.
        public HTMSegment GetActiveSegment(int t)
        {
            List <HTMSegment> activeSegs = new List <HTMSegment>();

            foreach (HTMSegment seg in _distalSegments)
            {
                if (seg.GetActive(-1, false, false))
                {
                    activeSegs.Add(seg);
                }
            }

            if (activeSegs.Count == 0)
            {
                return(null);
            }
            else if (activeSegs.Count == 1)
            {
                return(activeSegs[0]);
            }

            // There're more the one active segments so sequence segments given priority.
            List <HTMSegment> sequenceSegs = new List <HTMSegment>();

            foreach (HTMSegment seg in activeSegs)
            {
                if (seg.IsSequence)
                {
                    sequenceSegs.Add(seg);
                }
            }
            if (sequenceSegs.Count == 1)
            {
                return(sequenceSegs[0]);
            }
            else if (sequenceSegs.Count > 1)
            {
                activeSegs = sequenceSegs;
            }

            // Search the segment that had, in the previous step, the highest activity measured by the number of active synapses.
            HTMSegment mostActiveSegment = null;
            int        maxActivity       = int.MinValue;
            int        activity;

            foreach (HTMSegment seg in activeSegs)
            {
                activity = seg.GetActivity(-1);
                if (activity > maxActivity)
                {
                    maxActivity       = activity;
                    mostActiveSegment = seg;
                }
            }
            return(mostActiveSegment);
        }
Esempio n. 3
0
        // 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);
        }
Esempio n. 4
0
        // Find the segment with the largest number of active synapses.
        // This routine is aggressive in finding the best match.
        // The permanence value of synapses is allowed to be below connectedPerm.
        // The number of active synapses is allowed to be below activationThreshold,
        // but must be above minThreshold.
        public HTMSegment GetBestMatchingSegment(int t, bool sequence)
        {
            HTMSegment bestSegment      = null;
            int        bestSynapseCount = _column.Region.MinSegmentActivityForLearning;
            int        synCount;

            foreach (HTMSegment seg in _distalSegments)
            {
                synCount = seg.GetActiveSynapses(t, false, false).Count;
                if (synCount > bestSynapseCount)
                {
                    bestSynapseCount = synCount;
                    bestSegment      = seg;
                }
            }
            return(bestSegment);
        }
Esempio n. 5
0
        double _y; // The x-position of the column inside the matrix. Range from 0 to 1.

        #endregion Fields

        #region Constructors

        public HTMColumn(HTMRegionAgent region, int posX, int posY, double x, double y)
        {
            _region = region;
            _posX = posX;
            _posY = posY;
            _x = x;
            _y = y;

            _cells = new List<HTMCell>();
            for (int i = 0; i < region.CellsPerColumn; i++)
                _cells.Add(new HTMCell(this, i));
            _proximalSegment = new HTMSegment(null, _region.SegmentActivationThreshold);
            _isActive = false;
            _overlap = 0;
            _boost = 1.0;
            _activeDutyCycle = 1.0;
            _overlapDutyCycle = 1.0;
        }
Esempio n. 6
0
        public HTMColumn(HTMRegionAgent region, int posX, int posY, double x, double y)
        {
            _region = region;
            _posX   = posX;
            _posY   = posY;
            _x      = x;
            _y      = y;

            _cells = new List <HTMCell>();
            for (int i = 0; i < region.CellsPerColumn; i++)
            {
                _cells.Add(new HTMCell(this, i));
            }
            _proximalSegment  = new HTMSegment(null, _region.SegmentActivationThreshold);
            _isActive         = false;
            _overlap          = 0;
            _boost            = 1.0;
            _activeDutyCycle  = 1.0;
            _overlapDutyCycle = 1.0;
        }
Esempio n. 7
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. 8
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. 9
0
        // This function iterates through a list of segmentUpdate's and reinforces each segment.
        // For each segmentUpdate element, the following changes are performed. If positiveReinforcement is true
        // then synapses on the active list get their permanence counts incremented by permanenceInc.
        // All other synapses get their permanence counts decremented by permanenceDec.
        // If positiveReinforcement is false, then synapses on the active list get their permanence counts
        // decremented by permanenceDec. After this step, any synapses in segmentUpdate that do yet exist
        // get added with a permanence count of initialPerm.
        public void AdaptSegments(bool positiveReinforcement)
        {
            foreach (SegmentUpdate segInfo in _segmentUpdateList)
            {
                if (segInfo.Segment != null)
                {
                    if (positiveReinforcement)
                    {
                        foreach (HTMSynapse syn in segInfo.Segment.Synapses)
                            if (segInfo.ActiveSynapses.Contains(syn))
                                syn.IncreasePermanence();
                            else
                                syn.DecreasePermanence();
                    }
                    else
                        foreach (HTMSynapse syn in segInfo.ActiveSynapses)
                            syn.DecreasePermanence();
                    // TO DO : the series of negative reinforcements should bring to eliminate the entire segment.
                }

                if (segInfo.AddNewSynapses && segInfo.NewSynapses.Count > 0)
                {
                    // check wheter exist a similar segment
                    bool isFound = false;
                    foreach (HTMSegment seg in _distalSegments)
                    {
                        int foundCount = 0;
                        foreach (HTMSynapse syn in seg.Synapses)
                            if (segInfo.NewSynapses.Contains(syn.InputCell))
                                foundCount++;
                        if (foundCount == segInfo.NewSynapses.Count)
                        {
                            isFound = true;
                            break;
                        }
                    }
                    if (isFound)
                        continue;

                    // update or create a segment
                    HTMSegment segment;
                    if (segInfo.Segment != null)
                        segment = segInfo.Segment;
                    else
                    {
                        segment = new HTMSegment(this, _column.Region.SegmentActivationThreshold);
                        _distalSegments.Add(segment);
                        _column.Region.Director.Log("Created new distal segment on a cell on column " + segment.Cell.Column.PosX.ToString() + "," + segment.Cell.Column.PosY.ToString());
                    }
                    segment.IsSequence = segInfo.IsSequence;
                    foreach (HTMCell cell in segInfo.NewSynapses)
                    {
                        //
                        bool find = false;
                        foreach (HTMSynapse syn in segment.Synapses)
                        {
                            if (syn.InputCell == cell)
                            {
                                find = true;
                                break;
                            }
                        }
                        //
                        if (!find)
                            segment.Synapses.Add(new HTMSynapse(cell));

                    }
                }
            }
            _segmentUpdateList.Clear();
        }
Esempio n. 10
0
        // This function iterates through a list of segmentUpdate's and reinforces each segment.
        // For each segmentUpdate element, the following changes are performed. If positiveReinforcement is true
        // then synapses on the active list get their permanence counts incremented by permanenceInc.
        // All other synapses get their permanence counts decremented by permanenceDec.
        // If positiveReinforcement is false, then synapses on the active list get their permanence counts
        // decremented by permanenceDec. After this step, any synapses in segmentUpdate that do yet exist
        // get added with a permanence count of initialPerm.
        public void AdaptSegments(bool positiveReinforcement)
        {
            foreach (SegmentUpdate segInfo in _segmentUpdateList)
            {
                if (segInfo.Segment != null)
                {
                    if (positiveReinforcement)
                    {
                        foreach (HTMSynapse syn in segInfo.Segment.Synapses)
                        {
                            if (segInfo.ActiveSynapses.Contains(syn))
                            {
                                syn.IncreasePermanence();
                            }
                            else
                            {
                                syn.DecreasePermanence();
                            }
                        }
                    }
                    else
                    {
                        foreach (HTMSynapse syn in segInfo.ActiveSynapses)
                        {
                            syn.DecreasePermanence();
                        }
                    }
                    // TO DO : the series of negative reinforcements should bring to eliminate the entire segment.
                }

                if (segInfo.AddNewSynapses && segInfo.NewSynapses.Count > 0)
                {
                    // check wheter exist a similar segment
                    bool isFound = false;
                    foreach (HTMSegment seg in _distalSegments)
                    {
                        int foundCount = 0;
                        foreach (HTMSynapse syn in seg.Synapses)
                        {
                            if (segInfo.NewSynapses.Contains(syn.InputCell))
                            {
                                foundCount++;
                            }
                        }
                        if (foundCount == segInfo.NewSynapses.Count)
                        {
                            isFound = true;
                            break;
                        }
                    }
                    if (isFound)
                    {
                        continue;
                    }

                    // update or create a segment
                    HTMSegment segment;
                    if (segInfo.Segment != null)
                    {
                        segment = segInfo.Segment;
                    }
                    else
                    {
                        segment = new HTMSegment(this, _column.Region.SegmentActivationThreshold);
                        _distalSegments.Add(segment);
                        _column.Region.Director.Log("Created new distal segment on a cell on column " + segment.Cell.Column.PosX.ToString() + "," + segment.Cell.Column.PosY.ToString());
                    }
                    segment.IsSequence = segInfo.IsSequence;
                    foreach (HTMCell cell in segInfo.NewSynapses)
                    {
                        //
                        bool find = false;
                        foreach (HTMSynapse syn in segment.Synapses)
                        {
                            if (syn.InputCell == cell)
                            {
                                find = true;
                                break;
                            }
                        }
                        //
                        if (!find)
                        {
                            segment.Synapses.Add(new HTMSynapse(cell));
                        }
                    }
                }
            }
            _segmentUpdateList.Clear();
        }