Beispiel #1
0
        /// <summary>
        /// Invoked as the last step in learning of the SP.
        /// </summary>
        /// <param name="input">The input of the SP in the current cycle.</param>
        /// <param name="output">The output SDR of the Spatial Pooler compute cycle.</param>
        /// <returns></returns>
        public bool Compute(int[] input, int[] output)
        {
            bool res = false;

            double avgDerivation = -1;

            // We take the hash value of the input.
            var inpHash = GetHash(input);

            //
            // Here we track the number of active columns for every cycle for every input.
            // We want that this number for every input is approximately the same.
            if (m_NumOfActiveColsForInput.ContainsKey(inpHash))
            {
                ArrayUtils.PushToInterval(m_NumOfActiveColsForInput[inpHash], m_MaxPreviousElements, output.Count(c => c == 1));
            }

            //
            // If the pattern appears for the first time, add it to dictionary of seen patterns.
            if (!m_InOutMap.ContainsKey(inpHash))
            {
                m_InOutMap.Add(inpHash, output);
                m_NumOfActiveColsForInput.Add(inpHash, new int[m_MaxPreviousElements]);
                m_NumOfStableCyclesForInput.Add(inpHash, 0);
            }
            else
            {
                if (m_Cycle >= this.m_MinCycles)
                {
                    this.m_HtmMemory.HtmConfig.MaxBoost = 0.0;

                    this.m_HtmMemory.HtmConfig.MinPctOverlapDutyCycles = 0.0;

                    this.m_HtmMemory.HtmConfig.MinPctActiveDutyCycles = 0.0;
                }

                // If the input has been already seen, we calculate the similarity between already seen input
                // and the new input. The similarity is calculated as a correlation function.
                var similarity = CalcArraySimilarity(ArrayUtils.IndexWhere(m_InOutMap[inpHash], k => k == 1), ArrayUtils.IndexWhere(output, k => k == 1));

                // We replace the existing value with the new one.
                m_InOutMap[inpHash] = output;

                //
                // We cannot expect the 100% for the entire learning cycle. Sometimes some
                // SDR appear with few more or less bits than in the previous cycle.
                // If this happen we take the new SDR (output) as the winner and put it in the map.
                if (similarity >= m_RequiredSimilarityThreshold)
                {
                    // We calculate here the average change of the SDR for the given input.
                    avgDerivation = ArrayUtils.AvgDelta(m_NumOfActiveColsForInput[inpHash]);

                    //
                    // If there is no change (SDR is stable) we count nuber of stable cycles.
                    // If the average value is not 0, then we reset the number of stable cycles.
                    if (avgDerivation == 0)
                    {
                        m_NumOfStableCyclesForInput[inpHash] = m_NumOfStableCyclesForInput[inpHash] + 1;
                    }
                    else
                    {
                        m_NumOfStableCyclesForInput[inpHash] = 0;
                    }

                    if (m_Cycle >= this.m_MinCycles)
                    {
                        if (m_NumOfStableCyclesForInput[inpHash] > m_RequiredNumOfStableCycles && IsInStableState(m_NumOfStableCyclesForInput, m_RequiredNumOfStableCycles))
                        {
                            // We fire event when changed from instable to stable.
                            if (!m_IsStable)
                            {
                                this.m_OnStabilityStatusChanged(true, m_InOutMap.Keys.Count, avgDerivation, m_Cycle);
                            }

                            m_IsStable = true;
                            res        = true;
                        }
                    }
                }
                else
                {
                    m_NumOfStableCyclesForInput[inpHash] = 0;

                    // If the new SDR output for the already seen input

                    if (m_IsStable)
                    {
                        // THIS SHOULD NEVER HAPPEN! MEANS FROM STABLE TO INSTABLE!
                        m_IsStable = false;
                        this.m_OnStabilityStatusChanged(false, m_InOutMap.Keys.Count, avgDerivation, m_Cycle);
                    }
                }
            }

            this.m_Cycle++;

            return(res);
        }