예제 #1
0
        /**
         * Uses the specified {@link Connections} object to Build the structural
         * anatomy needed by this {@code TemporalMemory} to implement its algorithms.
         *
         * The connections object holds the {@link Column} and {@link Cell} infrastructure,
         * and is used by both the {@link SpatialPooler} and {@link TemporalMemory}. Either of
         * these can be used separately, and therefore this Connections object may have its
         * Columns and Cells initialized by either the init method of the SpatialPooler or the
         * init method of the TemporalMemory. We check for this so that complete initialization
         * of both Columns and Cells occurs, without either being redundant (initialized more than
         * once). However, {@link Cell}s only get created when initializing a TemporalMemory, because
         * they are not used by the SpatialPooler.
         *
         * @param   c       {@link Connections} object
         */
        public static void Init(Connections c)
        {
            SparseObjectMatrix <Column> matrix = c.GetMemory() ?? new SparseObjectMatrix <Column>(c.GetColumnDimensions());

            c.SetMemory(matrix);

            int numColumns = matrix.GetMaxIndex() + 1;

            c.SetNumColumns(numColumns);
            int cellsPerColumn = c.GetCellsPerColumn();

            Cell[] cells = new Cell[numColumns * cellsPerColumn];

            //Used as flag to determine if Column objects have been created.
            Column colZero = matrix.GetObject(0);

            for (int i = 0; i < numColumns; i++)
            {
                Column column = colZero == null ? new Column(cellsPerColumn, i) : matrix.GetObject(i);
                for (int j = 0; j < cellsPerColumn; j++)
                {
                    cells[i * cellsPerColumn + j] = column.GetCell(j);
                }
                //If columns have not been previously configured
                if (colZero == null)
                {
                    matrix.Set(i, column);
                }
            }
            //Only the TemporalMemory initializes cells so no need to test for redundancy
            c.SetCells(cells);
        }
예제 #2
0
        /**
         * {@inheritDoc}
         */
        public override List <EncoderResult> GetBucketInfo(int[] buckets)
        {
            SparseObjectMatrix <int[]> topDownMapping = GetTopDownMapping();

            //The "category" is simply the bucket index
            int category = buckets[0];

            int[] encoding = topDownMapping.GetObject(category);

            //Which input value does this correspond to?
            double inputVal;

            if (IsPeriodic())
            {
                inputVal = GetMinVal() + GetResolution() / 2 + category * GetResolution();
            }
            else
            {
                inputVal = GetMinVal() + category * GetResolution();
            }

            return(new List <EncoderResult> {
                new EncoderResult(inputVal, inputVal, encoding)
            });
        }
예제 #3
0
        private List <EncoderResult> GetEncoderResultsByIndex(SparseObjectMatrix <int[]> topDownMapping, int categoryIndex)
        {
            List <EncoderResult> result = new List <EncoderResult>();
            string category             = _sdrByCategory.GetCategory(categoryIndex);

            int[] encoding = topDownMapping.GetObject(categoryIndex);
            result.Add(new EncoderResult(category, categoryIndex, encoding));
            return(result);
        }
예제 #4
0
        /**
         * {@inheritDoc}
         */
        public override List <EncoderResult> TopDownCompute(int[] encoded)
        {
            //Get/generate the topDown mapping table
            SparseObjectMatrix <int[]> topDownMapping = scalarEncoder.GetTopDownMapping();
            // See which "category" we match the closest.
            int category = ArrayUtils.Argmax(RightVecProd(topDownMapping, encoded));

            return(GetBucketInfo(new int[] { category }));
        }
예제 #5
0
 /**
  * Returns a list of items, one for each bucket defined by this encoder.
  * Each item is the value assigned to that bucket, this is the same as the
  * EncoderResult.value that would be returned by GetBucketInfo() for that
  * bucket and is in the same format as the input that would be passed to
  * encode().
  *
  * This call is faster than calling GetBucketInfo() on each bucket individually
  * if all you need are the bucket values.
  *
  * @param	returnType      class type parameter so that this method can return encoder
  *                          specific value types
  *
  * @return list of items, each item representing the bucket value for that
  *        bucket.
  */
 public override List <S> GetBucketValues <S>(Type t)
 {
     if (bucketValues == null)
     {
         SparseObjectMatrix <int[]> topDownMapping = GetTopDownMapping();
         int numBuckets = topDownMapping.GetMaxIndex() + 1;
         bucketValues = new List <double>();
         for (int i = 0; i < numBuckets; i++)
         {
             ((List <double>)bucketValues).Add((double)GetBucketInfo(new[] { i })[0].Get(1));
         }
     }
     return((List <S>)bucketValues);
 }
예제 #6
0
        /**
         * Returns a list of items, one for each bucket defined by this encoder.
         * Each item is the value assigned to that bucket, this is the same as the
         * EncoderResult.value that would be returned by getBucketInfo() for that
         * bucket and is in the same format as the input that would be passed to
         * encode().
         *
         * This call is faster than calling getBucketInfo() on each bucket individually
         * if all you need are the bucket values.
         *
         * @param	returnType      class type parameter so that this method can return encoder
         *                          specific value types
         *
         * @return list of items, each item representing the bucket value for that
         *        bucket.
         */
        public override List <T> GetBucketValues <T>(Type t)
        {
            if (bucketValues == null)
            {
                SparseObjectMatrix <int[]> topDownMapping = scalarEncoder.GetTopDownMapping();
                int numBuckets = topDownMapping.GetMaxIndex() + 1;
                bucketValues = new List <string>();
                for (int i = 0; i < numBuckets; i++)
                {
                    ((List <string>)bucketValues).Add((string)GetBucketInfo(new int[] { i })[0].GetValue());
                }
            }

            return((List <T>)bucketValues);
        }
예제 #7
0
 /**
  * Return the internal topDownMapping matrix used for handling the
  * {@link #getBucketInfo(int[])}  and {@link #topDownCompute(int[])} methods. This is a matrix, one row per
  * category (bucket) where each row contains the encoded output for that
  * category.
  *
  * @return {@link SparseObjectMatrix}
  */
 public SparseObjectMatrix <int[]> GetTopDownMapping()
 {
     if (topDownMapping == null)
     {
         topDownMapping = new SparseObjectMatrix <int[]>(new int[] { _sdrByCategory.Count });
         int[]         outputSpace = new int[GetN()];
         List <string> categories  = _sdrByCategory.Keys.ToList();
         int           inx         = 0;
         foreach (string category in categories)
         {
             EncodeIntoArray(category, outputSpace);
             topDownMapping.Set(inx, Arrays.CopyOf(outputSpace, outputSpace.Length));
             inx++;
         }
     }
     return(topDownMapping);
 }
예제 #8
0
        /**
         * Return the internal topDownMapping matrix used for handling the
         * bucketInfo() and topDownCompute() methods. This is a matrix, one row per
         * category (bucket) where each row contains the encoded output for that
         * category.
         *
         * @param c		the connections memory
         * @return		the internal topDownMapping
         */
        public SparseObjectMatrix <int[]> GetTopDownMapping()
        {
            if (base.topDownMapping == null)
            {
                //The input scalar value corresponding to each possible output encoding
                if (IsPeriodic())
                {
                    SetTopDownValues(
                        ArrayUtils.Arrange(GetMinVal() + GetResolution() / 2.0,
                                           GetMaxVal(), GetResolution()));
                }
                else
                {
                    //Number of values is (max-min)/resolutions
                    SetTopDownValues(
                        ArrayUtils.Arrange(GetMinVal(), GetMaxVal() + GetResolution() / 2.0,
                                           GetResolution()));
                }
            }

            //Each row represents an encoded output pattern
            int numCategories = GetTopDownValues().Length;
            SparseObjectMatrix <int[]> topDownMapping;

            SetTopDownMapping(
                topDownMapping = new SparseObjectMatrix <int[]>(
                    new int[] { numCategories }));

            double[] topDownValues = GetTopDownValues();
            int[]    outputSpace   = new int[GetN()];
            double   minVal        = GetMinVal();
            double   maxVal        = GetMaxVal();

            for (int i = 0; i < numCategories; i++)
            {
                double value = topDownValues[i];
                value = Math.Max(value, minVal);
                value = Math.Min(value, maxVal);
                EncodeIntoArray(value, outputSpace);
                topDownMapping.Set(i, Arrays.CopyOf(outputSpace, outputSpace.Length));
            }

            return(topDownMapping);
        }
예제 #9
0
        /**
         * Uses the specified {@link Connections} object to Build the structural
         * anatomy needed by this {@code TemporalMemory} to implement its algorithms.
         *
         * The connections object holds the {@link Column} and {@link Cell} infrastructure,
         * and is used by both the {@link SpatialPooler} and {@link TemporalMemory}. Either of
         * these can be used separately, and therefore this Connections object may have its
         * Columns and Cells initialized by either the init method of the SpatialPooler or the
         * init method of the TemporalMemory. We check for this so that complete initialization
         * of both Columns and Cells occurs, without either being redundant (initialized more than
         * once). However, {@link Cell}s only get created when initializing a TemporalMemory, because
         * they are not used by the SpatialPooler.
         *
         * @param   c       {@link Connections} object
         */


        public void init(Connections conn)
        {
            this.connections = conn;

            SparseObjectMatrix <Column> matrix = this.connections.getMemory() == null ?
                                                 new SparseObjectMatrix <Column>(this.connections.getColumnDimensions()) :
                                                 (SparseObjectMatrix <Column>) this.connections.getMemory();

            this.connections.setMemory(matrix);

            int numColumns = matrix.getMaxIndex() + 1;

            this.connections.setNumColumns(numColumns);
            int cellsPerColumn = this.connections.getCellsPerColumn();

            Cell[] cells = new Cell[numColumns * cellsPerColumn];

            //Used as flag to determine if Column objects have been created.
            Column colZero = matrix.getObject(0);

            for (int i = 0; i < numColumns; i++)
            {
                Column column = colZero == null ? new Column(cellsPerColumn, i, this.connections.getSynPermConnected(), this.connections.NumInputs) : matrix.getObject(i);
                for (int j = 0; j < cellsPerColumn; j++)
                {
                    cells[i * cellsPerColumn + j] = column.Cells[j];
                }
                //If columns have not been previously configured
                if (colZero == null)
                {
                    matrix.set(i, column);
                }
            }
            //Only the TemporalMemory initializes cells so no need to test for redundancy
            this.connections.setCells(cells);
        }
        /// <summary>
        /// Performs the remote initialization ot the SP on actor nodes.
        /// </summary>
        /// <param name="c"></param>
        /// <param name="distMem"></param>
        public override void InitMatrices(Connections c, DistributedMemory distMem)
        {
            IHtmDistCalculus remoteHtm = distMem?.ColumnDictionary as IHtmDistCalculus;

            if (remoteHtm == null)
            {
                throw new ArgumentException("Must implement IHtmDistCalculus!");
            }

            this.distMemConfig = distMem;

            SparseObjectMatrix <Column> mem = (SparseObjectMatrix <Column>)c.HtmConfig.Memory;

            c.HtmConfig.Memory = mem == null ? mem = new SparseObjectMatrix <Column>(c.HtmConfig.ColumnDimensions, dict: distMem.ColumnDictionary) : mem;

            c.HtmConfig.InputMatrix = new SparseBinaryMatrix(c.HtmConfig.InputDimensions);

            // Initiate the topologies
            c.HtmConfig.ColumnTopology = new Topology(c.HtmConfig.ColumnDimensions);
            c.HtmConfig.InputTopology  = new Topology(c.HtmConfig.InputDimensions);

            //Calculate numInputs and numColumns
            int numInputs  = c.HtmConfig.InputMatrix.GetMaxIndex() + 1;
            int numColumns = c.HtmConfig.Memory.GetMaxIndex() + 1;

            if (numColumns <= 0)
            {
                throw new ArgumentException("Invalid number of columns: " + numColumns);
            }
            if (numInputs <= 0)
            {
                throw new ArgumentException("Invalid number of inputs: " + numInputs);
            }
            c.HtmConfig.NumInputs  = numInputs;
            c.HtmConfig.NumColumns = numColumns;

            if (distMem != null)
            {
                //var distHtmCla = distMem.ColumnDictionary as HtmSparseIntDictionary<Column>;
                var distHtmCla = distMem.ColumnDictionary;// as ActorSbDistributedDictionaryBase<Column>;

                distHtmCla.HtmConfig = c.HtmConfig;
            }

            //
            // Fill the sparse matrix with column objects
            //var numCells = c.getCellsPerColumn();

            // var partitions = mem.GetPartitions();


            List <KeyPair> colList = new List <KeyPair>();

            for (int i = 0; i < numColumns; i++)
            {
                //colList.Add(new KeyPair() { Key = i, Value = new Column(numCells, i, c.getSynPermConnected(), c.NumInputs) });
                colList.Add(new KeyPair()
                {
                    Key = i, Value = c.HtmConfig
                });
            }

            Stopwatch sw = new Stopwatch();

            sw.Start();

            remoteHtm.InitializeColumnPartitionsDist(colList);

            //mem.set(colList);

            sw.Stop();
            //c.setPotentialPools(new SparseObjectMatrix<Pool>(c.getMemory().getDimensions(), dict: distMem == null ? null : distMem.PoolDictionary));

            Debug.WriteLine($" Upload time: {sw.ElapsedMilliseconds}");

            // Already initialized by creating of columns.
            //c.setConnectedMatrix(new SparseBinaryMatrix(new int[] { numColumns, numInputs }));

            //Initialize state meta-management statistics
            c.HtmConfig.OverlapDutyCycles    = new double[numColumns];
            c.HtmConfig.ActiveDutyCycles     = new double[numColumns];
            c.HtmConfig.MinOverlapDutyCycles = new double[numColumns];
            c.HtmConfig.MinActiveDutyCycles  = new double[numColumns];
            c.BoostFactors = (new double[numColumns]);
            ArrayUtils.FillArray(c.BoostFactors, 1);
        }
        /// <summary>
        /// Implements muticore initialization of pooler.
        /// </summary>
        /// <param name="c"></param>
        protected override void ConnectAndConfigureInputs(Connections c)
        {
            IHtmDistCalculus remoteHtm = this.distMemConfig.ColumnDictionary as IHtmDistCalculus;

            if (remoteHtm == null)
            {
                throw new ArgumentException("");
            }

            List <double> avgSynapsesConnected = remoteHtm.ConnectAndConfigureInputsDist(c.HtmConfig);


            //List<KeyPair> colList = new List<KeyPair>();

            //ConcurrentDictionary<int, KeyPair> colList2 = new ConcurrentDictionary<int, KeyPair>();

            //int numColumns = c.NumColumns;

            //// Parallel implementation of initialization
            //ParallelOptions opts = new ParallelOptions();
            ////int synapseCounter = 0;



            //Parallel.For(0, numColumns, opts, (indx) =>
            //{

            //    //Random rnd = new Random(42);

            //    //int i = (int)indx;
            //    //var data = new ProcessingDataParallel();

            //    //// Gets RF
            //    //data.Potential = HtmCompute.MapPotential(c.HtmConfig, i, rnd);
            //    //data.Column = c.getColumn(i);

            //    //// This line initializes all synases in the potential pool of synapses.
            //    //// It creates the pool on proximal dendrite segment of the column.
            //    //// After initialization permancences are set to zero.
            //    ////connectColumnToInputRF(c.HtmConfig, data.Potential, data.Column);
            //    //data.Column.CreatePotentialPool(c.HtmConfig, data.Potential, -1);

            //    ////Interlocked.Add(ref synapseCounter, data.Column.ProximalDendrite.Synapses.Count);

            //    ////colList.Add(new KeyPair() { Key = i, Value = column });

            //    //data.Perm = HtmCompute.InitSynapsePermanences(c.HtmConfig, data.Potential, rnd);

            //    //data.AvgConnected = GetAvgSpanOfConnectedSynapses(c, i);

            //    //HtmCompute.UpdatePermanencesForColumn(c.HtmConfig, data.Perm, data.Column, data.Potential, true);

            //    if (!colList2.TryAdd(i, new KeyPair() { Key = i, Value = data }))
            //    {

            //    }
            //});

            ////c.setProximalSynapseCount(synapseCounter);

            //List<double> avgSynapsesConnected = new List<double>();

            //foreach (var item in colList2.Values)
            ////for (int i = 0; i < numColumns; i++)
            //{
            //    int i = (int)item.Key;

            //    ProcessingDataParallel data = (ProcessingDataParallel)item.Value;
            //    //ProcessingData data = new ProcessingData();

            //    // Debug.WriteLine(i);
            //    //data.Potential = mapPotential(c, i, c.isWrapAround());

            //    //var st = string.Join(",", data.Potential);
            //    //Debug.WriteLine($"{i} - [{st}]");

            //    //var counts = c.getConnectedCounts();

            //    //for (int h = 0; h < counts.getDimensions()[0]; h++)
            //    //{
            //    //    // Gets the synapse mapping between column-i with input vector.
            //    //    int[] slice = (int[])counts.getSlice(h);
            //    //    Debug.Write($"{slice.Count(y => y == 1)} - ");
            //    //}
            //    //Debug.WriteLine(" --- ");
            //    // Console.WriteLine($"{i} - [{String.Join(",", ((ProcessingData)item.Value).Potential)}]");

            //    // This line initializes all synases in the potential pool of synapses.
            //    // It creates the pool on proximal dendrite segment of the column.
            //    // After initialization permancences are set to zero.
            //    //var potPool = data.Column.createPotentialPool(c, data.Potential);
            //    //connectColumnToInputRF(c, data.Potential, data.Column);

            //    //data.Perm = initPermanence(c.getSynPermConnected(), c.getSynPermMax(),
            //    //      c.getRandom(), c.getSynPermTrimThreshold(), c, data.Potential, data.Column, c.getInitConnectedPct());

            //    //updatePermanencesForColumn(c, data.Perm, data.Column, data.Potential, true);

            //    avgSynapsesConnected.Add(data.AvgConnected);

            //    colList.Add(new KeyPair() { Key = i, Value = data.Column });
            //}

            SparseObjectMatrix <Column> mem = (SparseObjectMatrix <Column>)c.HtmConfig.Memory;

            //if (mem.IsRemotelyDistributed)
            //{
            //    // Pool is created and attached to the local instance of Column.
            //    // Here we need to update the pool on remote Column instance.
            //    mem.set(colList);
            //}

            // The inhibition radius determines the size of a column's local
            // neighborhood.  A cortical column must overcome the overlap score of
            // columns in its neighborhood in order to become active. This radius is
            // updated every learning round. It grows and shrinks with the average
            // number of connected synapses per column.
            UpdateInhibitionRadius(c, avgSynapsesConnected);
        }