Exemplo n.º 1
0
        /// <summary>
        ///  Prediction code.
        ///  This method takes a single sample of every input vector and adds
        ///  some noise to it. Then it predicts it.<param name="sp"></param>
        ///  Calculated hamming distance (percent overlap) between predicted output and output <param name="inputVectors"></param>
        ///  trained without noise is final result, which should be higher than 95% (realistic guess).
        /// </summary>
        /// <param name="activeColumnsWithZeroNoise"></param>
        /// <returns></returns>
        private static int OutputPredictionResult(SpatialPoolerMT sp, List <int[]> inputVectors, int[][] activeColumnsWithZeroNoise)
        {
            int vectorIndex = 0;

            foreach (var inputVector in inputVectors)
            {
                for (int tstIndx = 0; tstIndx < 100; tstIndx++)
                {
                    double noise = ((double)(new Random().Next(5, 25))) / 100.0;

                    var noisedInput = ArrayUtils.FlipBit(inputVector, noise);

                    var distIn = MathHelpers.GetHammingDistance(inputVector, noisedInput, true);

                    int[] activeArray = new int[64 * 64];

                    sp.compute(noisedInput, activeArray, false);

                    var distOut = MathHelpers.GetHammingDistance(activeColumnsWithZeroNoise[vectorIndex], activeArray, true);

                    Helpers.StringifyVector(ArrayUtils.IndexWhere(activeArray, (el) => el == 1));
                    Helpers.StringifyVector(ArrayUtils.IndexWhere(activeColumnsWithZeroNoise[vectorIndex], (el) => el == 1));

                    Debug.WriteLine($"Result for vector {vectorIndex} with noise {noise} - DistIn: {distIn} - DistOut: {distOut}");

                    Debug.WriteLine("------------");

                    //Assert.IsTrue(distOut >= 90);
                }

                vectorIndex++;
            }

            return(vectorIndex);
        }
Exemplo n.º 2
0
        /// <summary>
        /// ouput an Array Percentage of different between the recorded SDR(activeArray)
        /// <br>and the recent calculated SDR(from inputVectors and current sp)</br>
        /// </summary>
        /// <param name="inputVectors">original encoded data</param>
        /// <param name="activeArray">recorded array from learning</param>
        /// <param name="sp">the ref to the current spatial pooler</param>
        /// <returns></returns>
        internal double[] GetHammingArray(List <int[]> inputVectors, int[][] activeArray, SpatialPoolerMT sp)
        {
            int[]    dummyArray      = new int[activeArray[0].Length];
            double[] hammingArray    = new double[inputVectors.Count];
            int      matched         = 0;
            double   matchPercentage = 90;

            Debug.WriteLine($"hamming Array:");
            for (int i = 0; i < inputVectors.Count; i++)
            {
                sp.compute(inputVectors[i], dummyArray, false);
                Debug.WriteLine($"activeArray{i}   = {NeoCortexApi.Helpers.StringifyVector(activeArray[i])}");
                Debug.WriteLine($"computedArray{i} = {NeoCortexApi.Helpers.StringifyVector(dummyArray)}");
                hammingArray[i] = MathHelpers.GetHammingDistance(activeArray[i], dummyArray, true);
                if (hammingArray[i] > matchPercentage)
                {
                    matched++;
                }
                Debug.WriteLine($"Hamming Array{i} : {hammingArray[i]}\n" +
                                $"Hamming Distance: { hammingArray[i]} ");

                Debug.WriteLine($"Input {i} = {hammingArray[i]}");
            }

            Debug.WriteLine($"matched over {matchPercentage}: {matched}/{inputVectors.Count}");

            return(hammingArray);
        }
Exemplo n.º 3
0
        //[DataRow("Box")]
        //[DataRow("Horizontal")]
        public void ImageSimilarityExperiment(string inputPrefix)
        {
            //int stableStateCnt = 100;
            double minOctOverlapCycles = 1.0;
            double maxBoost            = 10.0;
            //int inputBits = 100;
            var colDims   = new int[] { 64, 64 };
            int numOfCols = 64 * 64;
            //int numColumns = colDims[0];

            string trainingFolder = "Similarity\\TestFiles";
            int    imgSize        = 28;
            //var colDims = new int[] { 64, 64 };
            //int numOfActCols = colDims[0] * colDims[1];

            string TestOutputFolder = $"Output-{nameof(ImageSimilarityExperiment)}";

            var trainingImages = Directory.GetFiles(trainingFolder, $"{inputPrefix}*.png");

            Directory.CreateDirectory($"{nameof(ImageSimilarityExperiment)}");

            int counter = 0;
            //var parameters = GetDefaultParams();
            ////parameters.Set(KEY.DUTY_CYCLE_PERIOD, 20);
            ////parameters.Set(KEY.MAX_BOOST, 1);
            ////parameters.setInputDimensions(new int[] { imageSize[imSizeIndx], imageSize[imSizeIndx] });
            ////parameters.setColumnDimensions(new int[] { topologies[topologyIndx], topologies[topologyIndx] });
            ////parameters.setNumActiveColumnsPerInhArea(0.02 * numOfActCols);
            //parameters.Set(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 0.06 * 4096); // TODO. Experiment with different sizes
            //parameters.Set(KEY.POTENTIAL_RADIUS, imgSize * imgSize);
            //parameters.Set(KEY.POTENTIAL_PCT, 1.0);
            //parameters.Set(KEY.GLOBAL_INHIBITION, true); // TODO: Experiment with local inhibition too. Note also the execution time of the experiment.

            //// Num of active synapces in order to activate the column.
            //parameters.Set(KEY.STIMULUS_THRESHOLD, 50.0);
            //parameters.Set(KEY.SYN_PERM_INACTIVE_DEC, 0.008);
            //parameters.Set(KEY.SYN_PERM_ACTIVE_INC, 0.05);

            //parameters.Set(KEY.INHIBITION_RADIUS, (int)0.02 * imgSize * imgSize); // TODO. check if this has influence in a case of the global inhibition. ALso check how this parameter influences the similarity of SDR.

            //parameters.Set(KEY.SYN_PERM_CONNECTED, 0.2);
            //parameters.Set(KEY.MIN_PCT_OVERLAP_DUTY_CYCLES, 0.001);
            //parameters.Set(KEY.MIN_PCT_ACTIVE_DUTY_CYCLES, 0.001);
            //parameters.Set(KEY.DUTY_CYCLE_PERIOD, 1000);
            //parameters.Set(KEY.MAX_BOOST, 100);
            //parameters.Set(KEY.WRAP_AROUND, true);
            //parameters.Set(KEY.SEED, 1969);
            //parameters.setInputDimensions(new int[] { imgSize, imgSize });
            //parameters.setColumnDimensions(colDims);

            Parameters p = Parameters.getAllDefaultParameters();

            p.Set(KEY.RANDOM, new ThreadSafeRandom(42));
            p.Set(KEY.INPUT_DIMENSIONS, new int[] { imgSize, imgSize });
            p.Set(KEY.COLUMN_DIMENSIONS, colDims);
            p.Set(KEY.CELLS_PER_COLUMN, 10);

            p.Set(KEY.MAX_BOOST, maxBoost);
            p.Set(KEY.DUTY_CYCLE_PERIOD, 50);
            p.Set(KEY.MIN_PCT_OVERLAP_DUTY_CYCLES, minOctOverlapCycles);

            // Global inhibition
            // N of 40 (40= 0.02*2048 columns) active cells required to activate the segment.
            p.Set(KEY.GLOBAL_INHIBITION, true);
            p.setNumActiveColumnsPerInhArea(0.02 * numOfCols);
            p.Set(KEY.POTENTIAL_RADIUS, (int)(0.8 * imgSize * imgSize));
            p.Set(KEY.LOCAL_AREA_DENSITY, -1); // In a case of global inhibition.
            //p.setInhibitionRadius( Automatically set on the columns pace in a case of global inhibition.);

            // Activation threshold is 10 active cells of 40 cells in inhibition area.
            p.setActivationThreshold(10);

            // Max number of synapses on the segment.
            p.setMaxNewSynapsesPerSegmentCount((int)(0.02 * numOfCols));

            bool isInStableState = false;

            var mem = new Connections();

            p.apply(mem);

            HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(mem, trainingImages.Length * 50, (isStable, numPatterns, actColAvg, seenInputs) =>
            {
                // Event should only be fired when entering the stable state.
                // Ideal SP should never enter unstable state after stable state.
                Assert.IsTrue(isStable);
                Assert.IsTrue(numPatterns == trainingImages.Length);
                isInStableState = true;
                Debug.WriteLine($"Entered STABLE state: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}");
            }, requiredSimilarityThreshold: 0.975);

            SpatialPooler sp = new SpatialPoolerMT(hpa);

            sp.Init(mem, UnitTestHelpers.GetMemory());

            string outFolder = $"{TestOutputFolder}\\{inputPrefix}";

            Directory.CreateDirectory(outFolder);

            string outputHamDistFile = $"{outFolder}\\digit{inputPrefix}_hamming.txt";

            string outputActColFile = $"{outFolder}\\digit{inputPrefix}_activeCol.txt";

            using (StreamWriter swHam = new StreamWriter(outputHamDistFile))
            {
                using (StreamWriter swActCol = new StreamWriter(outputActColFile))
                {
                    int cycle = 0;

                    Dictionary <string, int[]> sdrs         = new Dictionary <string, int[]>();
                    Dictionary <string, int[]> inputVectors = new Dictionary <string, int[]>();

                    while (true)
                    {
                        foreach (var trainingImage in trainingImages)
                        {
                            int[] activeArray = new int[numOfCols];

                            FileInfo fI = new FileInfo(trainingImage);

                            string outputImage = $"{outFolder}\\{inputPrefix}_cycle_{counter}_{fI.Name}";

                            string testName = $"{outFolder}\\{inputPrefix}_{fI.Name}";

                            string inputBinaryImageFile = NeoCortexUtils.BinarizeImage($"{trainingImage}", imgSize, testName);

                            // Read input csv file into array
                            int[] inputVector = NeoCortexUtils.ReadCsvIntegers(inputBinaryImageFile).ToArray();

                            int[]             oldArray      = new int[activeArray.Length];
                            List <double[, ]> overlapArrays = new List <double[, ]>();
                            List <double[, ]> bostArrays    = new List <double[, ]>();

                            sp.compute(inputVector, activeArray, true);

                            var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1);

                            Debug.WriteLine($"Cycle: {cycle++} - Input: {trainingImage}");
                            Debug.WriteLine($"{Helpers.StringifyVector(activeCols)}\n");

                            if (isInStableState)
                            {
                                if (sdrs.Count == trainingImages.Length)
                                {
                                    CalculateSimilarity(sdrs, inputVectors);
                                    return;
                                }

                                var distance = MathHelpers.GetHammingDistance(oldArray, activeArray, true);
                                //var similarity = MathHelpers.CalcArraySimilarity(oldArray, activeArray, true);
                                sdrs.Add(trainingImage, activeCols);
                                inputVectors.Add(trainingImage, inputVector);

                                swHam.WriteLine($"{counter++}|{distance} ");

                                oldArray = new int[numOfCols];
                                activeArray.CopyTo(oldArray, 0);

                                overlapArrays.Add(ArrayUtils.Make2DArray <double>(ArrayUtils.ToDoubleArray(mem.Overlaps), colDims[0], colDims[1]));
                                bostArrays.Add(ArrayUtils.Make2DArray <double>(mem.BoostedOverlaps, colDims[0], colDims[1]));

                                var activeStr = Helpers.StringifyVector(activeArray);
                                swActCol.WriteLine("Active Array: " + activeStr);

                                int[,] twoDimenArray = ArrayUtils.Make2DArray <int>(activeArray, colDims[0], colDims[1]);
                                twoDimenArray        = ArrayUtils.Transpose(twoDimenArray);
                                List <int[, ]> arrays = new List <int[, ]>();
                                arrays.Add(twoDimenArray);
                                arrays.Add(ArrayUtils.Transpose(ArrayUtils.Make2DArray <int>(inputVector, (int)Math.Sqrt(inputVector.Length), (int)Math.Sqrt(inputVector.Length))));

                                NeoCortexUtils.DrawBitmaps(arrays, outputImage, Color.Yellow, Color.Gray, OutImgSize, OutImgSize);
                                NeoCortexUtils.DrawHeatmaps(overlapArrays, $"{outputImage}_overlap.png", 1024, 1024, 150, 50, 5);
                                NeoCortexUtils.DrawHeatmaps(bostArrays, $"{outputImage}_boost.png", 1024, 1024, 150, 50, 5);
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 4
0
        public void SimilarityExperimentWithEncoder()
        {
            int    stableStateCnt      = 100;
            double minOctOverlapCycles = 1.0;
            double maxBoost            = 10.0;
            int    inputBits           = 100;
            var    colDims             = new int[] { 64 * 64 };
            int    numOfActCols        = colDims[0];
            int    numColumns          = colDims[0];
            string TestOutputFolder    = $"Output-{nameof(ImageSimilarityExperiment)}";

            Directory.CreateDirectory($"{nameof(ImageSimilarityExperiment)}");

            //int counter = 0;
            //var parameters = GetDefaultParams();
            ////parameters.Set(KEY.DUTY_CYCLE_PERIOD, 20);
            ////parameters.Set(KEY.MAX_BOOST, 1);
            ////parameters.setInputDimensions(new int[] { imageSize[imSizeIndx], imageSize[imSizeIndx] });
            ////parameters.setColumnDimensions(new int[] { topologies[topologyIndx], topologies[topologyIndx] });
            ////parameters.setNumActiveColumnsPerInhArea(0.02 * numOfActCols);
            //parameters.Set(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 0.06 * 4096); // TODO. Experiment with different sizes
            //parameters.Set(KEY.POTENTIAL_RADIUS, inputBits);
            //parameters.Set(KEY.POTENTIAL_PCT, 1.0);
            //parameters.Set(KEY.GLOBAL_INHIBITION, true); // TODO: Experiment with local inhibition too. Note also the execution time of the experiment.

            //// Num of active synapces in order to activate the column.
            //parameters.Set(KEY.STIMULUS_THRESHOLD, 50.0);
            //parameters.Set(KEY.SYN_PERM_INACTIVE_DEC, 0.008);
            //parameters.Set(KEY.SYN_PERM_ACTIVE_INC, 0.05);

            //parameters.Set(KEY.INHIBITION_RADIUS, (int)0.15 * inputBits); // TODO. check if this has influence in a case of the global inhibition. ALso check how this parameter influences the similarity of SDR.

            //parameters.Set(KEY.SYN_PERM_CONNECTED, 0.2);
            //parameters.Set(KEY.MIN_PCT_OVERLAP_DUTY_CYCLES, 1.0);
            //parameters.Set(KEY.MIN_PCT_ACTIVE_DUTY_CYCLES, 0.001);
            //parameters.Set(KEY.DUTY_CYCLE_PERIOD, 100);
            //parameters.Set(KEY.MAX_BOOST, 10);
            //parameters.Set(KEY.WRAP_AROUND, true);
            //parameters.Set(KEY.SEED, 1969);
            //parameters.setInputDimensions(new int[] {inputBits });
            //parameters.setColumnDimensions(colDims);

            Parameters p = Parameters.getAllDefaultParameters();

            p.Set(KEY.RANDOM, new ThreadSafeRandom(42));
            p.Set(KEY.INPUT_DIMENSIONS, new int[] { inputBits });
            p.Set(KEY.COLUMN_DIMENSIONS, colDims);
            p.Set(KEY.CELLS_PER_COLUMN, 10);

            p.Set(KEY.MAX_BOOST, maxBoost);
            p.Set(KEY.DUTY_CYCLE_PERIOD, 50);
            p.Set(KEY.MIN_PCT_OVERLAP_DUTY_CYCLES, minOctOverlapCycles);

            // Global inhibition
            // N of 40 (40= 0.02*2048 columns) active cells required to activate the segment.
            p.Set(KEY.GLOBAL_INHIBITION, true);
            p.setNumActiveColumnsPerInhArea(0.02 * numColumns);
            p.Set(KEY.POTENTIAL_RADIUS, (int)(.7 * inputBits));
            p.Set(KEY.LOCAL_AREA_DENSITY, -1); // In a case of global inhibition.
            //p.setInhibitionRadius( Automatically set on the columns pace in a case of global inhibition.);

            // Activation threshold is 10 active cells of 40 cells in inhibition area.
            p.setActivationThreshold(10);

            // Max number of synapses on the segment.
            p.setMaxNewSynapsesPerSegmentCount((int)(0.02 * numColumns));
            double max = 20;

            Dictionary <string, object> settings = new Dictionary <string, object>()
            {
                { "W", 15 },
                { "N", inputBits },
                { "Radius", -1.0 },
                { "MinVal", 0.0 },
                { "Periodic", false },
                { "Name", "scalar" },
                { "ClipInput", false },
                { "MaxVal", max }
            };

            var encoder = new ScalarEncoder(settings);

            bool isInStableState = false;

            var mem = new Connections();

            p.apply(mem);

            var inputs = new int[] { 0, 1, 2, 3, 4, 5 };

            HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(mem, inputs.Length * 150, (isStable, numPatterns, actColAvg, seenInputs) =>
            {
                // Event should only be fired when entering the stable state.
                // Ideal SP should never enter unstable state after stable state.
                Assert.IsTrue(isStable);
                //Assert.IsTrue(numPatterns == inputs.Length);
                isInStableState = true;
                Debug.WriteLine($"Entered STABLE state: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}");
            });

            SpatialPooler sp = new SpatialPoolerMT(hpa);

            sp.Init(mem, UnitTestHelpers.GetMemory());

            string outFolder = $"{TestOutputFolder}";

            Directory.CreateDirectory(outFolder);

            string outputHamDistFile = $"{outFolder}\\hamming.txt";

            string outputActColFile = $"{outFolder}\\activeCol.txt";

            using (StreamWriter swHam = new StreamWriter(outputHamDistFile))
            {
                using (StreamWriter swActCol = new StreamWriter(outputActColFile))
                {
                    int cycle = 0;

                    Dictionary <string, int[]> sdrs = new Dictionary <string, int[]>();

                    while (!isInStableState)
                    {
                        foreach (var digit in inputs)
                        {
                            int[]             activeArray   = new int[numOfActCols];
                            int[]             oldArray      = new int[activeArray.Length];
                            List <double[, ]> overlapArrays = new List <double[, ]>();
                            List <double[, ]> bostArrays    = new List <double[, ]>();

                            var inputVector = encoder.Encode(digit);

                            sp.compute(inputVector, activeArray, true);

                            string actColFileName = Path.Combine(outFolder, $"{digit}.actcols.txt");

                            if (cycle == 0 && File.Exists(actColFileName))
                            {
                                File.Delete(actColFileName);
                            }

                            var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1);

                            using (StreamWriter swCols = new StreamWriter(actColFileName, true))
                            {
                                swCols.WriteLine(Helpers.StringifyVector(activeCols));
                            }

                            Debug.WriteLine($"'Cycle: {cycle} - {digit}'");
                            Debug.WriteLine($"IN :{Helpers.StringifyVector(inputVector)}");
                            Debug.WriteLine($"OUT:{Helpers.StringifyVector(activeCols)}\n");

                            if (isInStableState)
                            {
                                if (--stableStateCnt <= 0)
                                {
                                    return;
                                }
                            }

                            /*
                             * if (isInStableState)
                             * {
                             *  swActCol.WriteLine($"\nDigit {digit}");
                             *
                             *  sdrs.Add(digit.ToString(), activeCols);
                             *
                             *  //
                             *  // To be sure that same input produces the same output after entered the stable state.
                             *  for (int i = 0; i < 100; i++)
                             *  {
                             *      activeArray = new int[numOfActCols];
                             *
                             *      sp.compute(inputVector, activeArray, true);
                             *
                             *      var distance = MathHelpers.GetHammingDistance(oldArray, activeArray, true);
                             *
                             *      var actColsIndxes = ArrayUtils.IndexWhere(activeArray, i => i == 1);
                             *      var oldActColsIndxes = ArrayUtils.IndexWhere(oldArray, i => i == 1);
                             *
                             *      var similarity = MathHelpers.CalcArraySimilarity(actColsIndxes, oldActColsIndxes);
                             *
                             *      swHam.Write($"Digit {digit}: Dist/Similarity: {distance} | {similarity}\t");
                             *      Debug.Write($"Digit {digit}: Dist/Similarity: {distance} | {similarity}\t");
                             *      Debug.WriteLine($"{Helpers.StringifyVector(actColsIndxes)}");
                             *
                             *      if (i > 5 && similarity < 100)
                             *      {
                             *
                             *      }
                             *
                             *      oldArray = new int[numOfActCols];
                             *      activeArray.CopyTo(oldArray, 0);
                             *  }
                             * }
                             *
                             * Debug.WriteLine($"Cycle {cycle++}");*/
                        }

                        cycle++;
                    }

                    CalculateSimilarity(sdrs, null);//todo
                }
            }
        }
        public void NoiseTest()
        {
            const int colDimSize = 64;

            const int noiseStepPercent = 5;

            var parameters = GetDefaultParams();

            parameters.Set(KEY.POTENTIAL_RADIUS, 32 * 32);
            parameters.Set(KEY.POTENTIAL_PCT, 1.0);
            parameters.Set(KEY.GLOBAL_INHIBITION, true);
            parameters.Set(KEY.STIMULUS_THRESHOLD, 0.5);
            parameters.Set(KEY.INHIBITION_RADIUS, (int)0.01 * colDimSize * colDimSize);
            parameters.Set(KEY.LOCAL_AREA_DENSITY, -1);
            parameters.Set(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 0.02 * colDimSize * colDimSize);
            parameters.Set(KEY.DUTY_CYCLE_PERIOD, 1000);
            parameters.Set(KEY.MAX_BOOST, 0.0);
            parameters.Set(KEY.SYN_PERM_INACTIVE_DEC, 0.008);
            parameters.Set(KEY.SYN_PERM_ACTIVE_INC, 0.01);
            parameters.Set(KEY.MIN_PCT_OVERLAP_DUTY_CYCLES, 0.001);

            parameters.Set(KEY.SEED, 42);

            parameters.setInputDimensions(new int[] { 32, 32 });
            parameters.setColumnDimensions(new int[] { colDimSize, colDimSize });

            var sp  = new SpatialPoolerMT();
            var mem = new Connections();

            //var rnd = new Random();

            parameters.apply(mem);
            sp.init(mem);

            List <int[]> inputVectors = new List <int[]>();

            inputVectors.Add(getInputVector1());
            inputVectors.Add(getInputVector2());

            int vectorIndex = 0;

            int[][] activeArrayWithZeroNoise = new int[inputVectors.Count][];

            foreach (var inputVector in inputVectors)
            {
                var x = getNumBits(inputVector);

                Debug.WriteLine("");
                Debug.WriteLine($"----- VECTOR {vectorIndex} ----------");

                //int[] activeArray = new int[64 * 64];
                activeArrayWithZeroNoise[vectorIndex] = new int[colDimSize * colDimSize];

                int[] activeArray = null;

                for (int j = 0; j < 25; j += noiseStepPercent)
                {
                    Debug.WriteLine($"--- Vector {0} - Noise Iteration {j} ----------");

                    int[] noisedInput;

                    if (j > 0)
                    {
                        noisedInput = ArrayUtils.flipBit(inputVector, (double)((double)j / 100.00));
                    }
                    else
                    {
                        noisedInput = inputVector;
                    }

                    var d = MathHelpers.GetHammingDistance(inputVector, noisedInput, true);
                    Debug.WriteLine($"Input with noise {j} - HamDist: {d}");
                    Debug.WriteLine($"Original: {Helpers.StringifyVector(inputVector)}");
                    Debug.WriteLine($"Noised:   {Helpers.StringifyVector(noisedInput)}");

                    for (int i = 0; i < 10; i++)
                    {
                        //sp.compute( noisedInput, activeArray, true);
                        activeArray = sp.Compute(noisedInput, true, returnActiveColIndiciesOnly: false) as int[];

                        if (j > 0)
                        {
                            Debug.WriteLine($"{ MathHelpers.GetHammingDistance(activeArrayWithZeroNoise[vectorIndex], activeArray, true)} -> {Helpers.StringifyVector(ArrayUtils.IndexWhere(activeArray, (el) => el == 1))}");
                        }
                    }

                    if (j == 0)
                    {
                        Array.Copy(activeArray, activeArrayWithZeroNoise[vectorIndex], activeArrayWithZeroNoise[vectorIndex].Length);
                    }

                    var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1);

                    var d2 = MathHelpers.GetHammingDistance(activeArrayWithZeroNoise[vectorIndex], activeArray, true);
                    Debug.WriteLine($"Output with noise {j} - Ham Dist: {d2}");
                    Debug.WriteLine($"Original: {Helpers.StringifyVector(ArrayUtils.IndexWhere(activeArrayWithZeroNoise[vectorIndex], (el) => el == 1))}");
                    Debug.WriteLine($"Noised:   {Helpers.StringifyVector(ArrayUtils.IndexWhere(activeArray, (el) => el == 1))}");

                    List <int[, ]> arrays = new List <int[, ]>();

                    int[,] twoDimenArray = ArrayUtils.Make2DArray <int>(activeArray, 64, 64);
                    twoDimenArray        = ArrayUtils.Transpose(twoDimenArray);

                    arrays.Add(ArrayUtils.Transpose(ArrayUtils.Make2DArray <int>(noisedInput, 32, 32)));
                    arrays.Add(ArrayUtils.Transpose(ArrayUtils.Make2DArray <int>(activeArray, 64, 64)));

                    //   NeoCortexUtils.DrawHeatmaps(bostArrays, $"{outputImage}_boost.png", 1024, 1024, 150, 50, 5);
                    NeoCortexUtils.DrawBitmaps(arrays, $"Vector_{vectorIndex}_Noise_{j * 10}.png", Color.Yellow, Color.Gray, OutImgSize, OutImgSize);
                }

                vectorIndex++;
            }

            //
            // Prediction code.
            // This part of code takes a single sample of every input vector and add
            // some noise to it. Then it predicts it.
            // Calculated hamming distance (percent overlap) between predicted output and output
            // trained without noise is final result, which should be higher than 95% (realistic guess).

            vectorIndex = 0;

            foreach (var inputVector in inputVectors)
            {
                double noise       = 7;
                var    noisedInput = ArrayUtils.flipBit(inputVector, noise / 100.00);

                int[] activeArray = new int[64 * 64];

                sp.compute(noisedInput, activeArray, false);

                var dist = MathHelpers.GetHammingDistance(activeArrayWithZeroNoise[vectorIndex], activeArray, true);
                Debug.WriteLine($"Result for vector {vectorIndex++} with noise {noise} - Ham Dist: {dist}");

                Assert.IsTrue(dist >= 95);
            }
        }
        /// <summary>
        /// Implements the experiment.
        /// </summary>
        /// <param name="cfg"></param>
        /// <param name="encoder"></param>
        /// <param name="inputValues"></param>
        private static void RunExperiment(HtmConfig cfg, EncoderBase encoder, List <int[]> inputValues)
        {
            // Creates the htm memory.
            var mem = new Connections(cfg);

            bool isInStableState = false;

            //
            // HPC extends the default Spatial Pooler algorithm.
            // The purpose of HPC is to set the SP in the new-born stage at the begining of the learning process.
            // In this stage the boosting is very active, but the SP behaves instable. After this stage is over
            // (defined by the second argument) the HPC is controlling the learning process of the SP.
            // Once the SDR generated for every input gets stable, the HPC will fire event that notifies your code
            // that SP is stable now.
            HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(mem, inputValues.Count * 40,
                                                                                      (isStable, numPatterns, actColAvg, seenInputs) =>
            {
                // Event should only be fired when entering the stable state.
                // Ideal SP should never enter unstable state after stable state.
                if (isStable == false)
                {
                    Debug.WriteLine($"INSTABLE STATE");
                    // This should usually not happen.
                    isInStableState = false;
                }
                else
                {
                    Debug.WriteLine($"STABLE STATE");
                    // Here you can perform any action if required.
                    isInStableState = true;
                }
            }, requiredSimilarityThreshold: 0.975);

            // It creates the instance of Spatial Pooler Multithreaded version.
            SpatialPooler sp = new SpatialPoolerMT(hpa);

            // Initializes the
            sp.Init(mem);

            // Holds the indicies of active columns of the SDR.
            Dictionary <string, int[]> prevActiveColIndicies = new Dictionary <string, int[]>();

            // Holds the active column SDRs.
            Dictionary <string, int[]> prevActiveCols = new Dictionary <string, int[]>();

            // Will hold the similarity of SDKk and SDRk-1 fro every input.
            Dictionary <string, double> prevSimilarity = new Dictionary <string, double>();

            //
            // Initiaize start similarity to zero.
            for (int i = 0; i < inputValues.Count; i++)
            {
                string inputKey = GetInputGekFromIndex(i);
                prevSimilarity.Add(inputKey, 0.0);
                prevActiveColIndicies.Add(inputKey, new int[0]);
            }

            // Learning process will take 1000 iterations (cycles)
            int maxSPLearningCycles = 1000;

            for (int cycle = 0; cycle < maxSPLearningCycles; cycle++)
            {
                //Debug.WriteLine($"Cycle  ** {cycle} ** Stability: {isInStableState}");

                //
                // This trains the layer on input pattern.
                for (int inputIndx = 0; inputIndx < inputValues.Count; inputIndx++)
                {
                    string inputKey = GetInputGekFromIndex(inputIndx);
                    int[]  input    = inputValues[inputIndx];

                    double similarity;

                    int[] activeColumns = new int[(int)cfg.NumColumns];

                    // Learn the input pattern.
                    // Output lyrOut is the output of the last module in the layer.
                    sp.compute(input, activeColumns, true);
                    // DrawImages(cfg, inputKey, input, activeColumns);

                    var actColsIndicies = ArrayUtils.IndexWhere(activeColumns, c => c == 1);

                    similarity = MathHelpers.CalcArraySimilarity(actColsIndicies, prevActiveColIndicies[inputKey]);

                    Debug.WriteLine($"[i={inputKey}, cols=:{actColsIndicies.Length} s={similarity}] SDR: {Helpers.StringifyVector(actColsIndicies)}");

                    prevActiveCols[inputKey]        = activeColumns;
                    prevActiveColIndicies[inputKey] = actColsIndicies;
                    prevSimilarity[inputKey]        = similarity;

                    if (isInStableState)
                    {
                        GenerateResult(cfg, inputValues, prevActiveColIndicies, prevActiveCols);
                        return;
                    }
                }
            }
        }
Exemplo n.º 7
0
        public void LearnCSI(int iteration, int colDimSize, int inputDimSize, int Hammingdim)
        {
            FolderInit();
            Debug.WriteLine("** running learning SP with Continuous Same Inputs feeding");

            /**************************************************************************************
             * |INITIATION| |SPATIALPOOLER|
             * Setting the parameters variable
             * changing the KEY's values
             */
            var parameters = GetDefaultParams();

            parameters.Set(KEY.POTENTIAL_RADIUS, inputDimSize * inputDimSize);
            parameters.Set(KEY.POTENTIAL_PCT, 0.75);
            parameters.Set(KEY.GLOBAL_INHIBITION, true);
            parameters.Set(KEY.STIMULUS_THRESHOLD, 5);//5
            parameters.Set(KEY.INHIBITION_RADIUS, (int)(0.01 * colDimSize * colDimSize));
            parameters.Set(KEY.LOCAL_AREA_DENSITY, -1);
            parameters.Set(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, (int)(0.02 * colDimSize * colDimSize));
            parameters.Set(KEY.DUTY_CYCLE_PERIOD, 1000); //1000
            parameters.Set(KEY.MAX_BOOST, 10.0);         //0
            parameters.Set(KEY.SYN_PERM_INACTIVE_DEC, 0.008);
            parameters.Set(KEY.SYN_PERM_ACTIVE_INC, 0.05);
            parameters.Set(KEY.MIN_PCT_OVERLAP_DUTY_CYCLES, 0.001);
            parameters.Set(KEY.SEED, 42);

            parameters.setInputDimensions(new int[] { inputDimSize, inputDimSize });
            parameters.setColumnDimensions(new int[] { colDimSize, colDimSize });

            var sp  = new SpatialPoolerMT();
            var mem = new Connections();

            //var rnd = new Random();

            parameters.apply(mem);
            sp.Init(mem);

            /***************************************************************************************
             * |LOGICTEST| |CONTINOUS_PATTERN_LEARNING|
             * Using input from scalar encoder
             */

            List <int[]> inputVectors;

            double[] inputDoubleArray = GetInputDoubleArray(-100, 100, Hammingdim * Hammingdim);
            inputVectors = ScalarEncoderDoubleArray(inputDoubleArray, inputDimSize, CSI);
            int vectorIndex = 0;

            Debug.WriteLine($"InputVectors.Count = {inputVectors.Count}");
            int[][] activeArray = new int[inputVectors.Count][];


            foreach (var inputVector in inputVectors)
            {
                activeArray[vectorIndex] = new int[colDimSize * colDimSize];

                for (int i = 0; i < iteration; i++)
                {
                    Debug.WriteLine(
                        $"compute VECTOR {vectorIndex} " +
                        $"iter: {i} " +
                        $"val: {NeoCortexApi.Helpers.StringifyVector(inputVector)} ");

                    sp.compute(inputVector, activeArray[vectorIndex], true);
                }
                sp.compute(inputVector, activeArray[vectorIndex], false);
                vectorIndex++;
            }
            vectorIndex = 0;
            foreach (var inputVector in inputVectors)
            {
                int[,] arrayDraw = ArrayUtils.Transpose(ArrayUtils.Make2DArray <int>(activeArray[vectorIndex], colDimSize, colDimSize));

                NeoCortexUtils.DrawBitmap(arrayDraw,
                                          OutImgSize, OutImgSize,
                                          $"{outputFolder}\\{CSI}\\{SDROuputFolder_CSI}\\Vector_{vectorIndex}.png",
                                          Color.FromArgb(44, 44, 44),
                                          Color.FromArgb(250, 100, 100),
                                          $"No.{vectorIndex} val {inputDoubleArray[vectorIndex]}");
                vectorIndex++;
            }
            vectorIndex = 0;
            //************************drawing similarities*******************************************
            int[]   dummyArray = new int[colDimSize * colDimSize];
            int[][] diffArray  = new int[inputVectors.Count][];
            for (int i = 0; i < inputVectors.Count; i++)
            {
                sp.compute(inputVectors[i], dummyArray, false);
                int[,] drawArray = ArrayUtils.Transpose(ArrayUtils.Make2DArray <int>(dummyArray, colDimSize, colDimSize));
                NeoCortexUtils.DrawBitmap(drawArray,
                                          OutImgSize, OutImgSize,
                                          $"{outputFolder}\\{CSI}\\{FreshComputed_CSI}\\Vector_{i}.png",
                                          Color.FromArgb(44, 44, 44),
                                          Color.FromArgb(100, 250, 100),
                                          $"No.{i} newCom, Val_{inputDoubleArray[i]}");
                diffArray[i] = AddArray(activeArray[i], dummyArray);
            }
            foreach (var inputVector in inputVectors)
            {
                int[,] arrayDraw = ArrayUtils.Transpose(ArrayUtils.Make2DArray <int>(diffArray[vectorIndex], colDimSize, colDimSize));
                Debug.WriteLine($"Drawing SDRdiff index : {vectorIndex} .........");
                DrawdiffArray(arrayDraw,
                              OutImgSize / colDimSize,
                              $"{outputFolder}\\{CSI}\\{SDROuputDiff_CSI}\\Vector_{vectorIndex}.png",
                              Color.FromArgb(44, 44, 44),
                              Color.FromArgb(100, 100, 250),
                              Color.FromArgb(250, 100, 100),
                              Color.FromArgb(100, 250, 100),
                              $"No.{vectorIndex} val {inputDoubleArray[vectorIndex]}");
                vectorIndex++;
            }
            //*********** Checking phase with getHammingDistance ************************************
            double[] hammingArray = GetHammingArray(inputVectors, activeArray, sp);
            LogToCSV(hammingArray, inputVectors, $"{CSI}\\{logOutputFolder}\\HammingOutput.csv");
            DrawHammingBitmap(
                ArrayUtils.Make2DArray <double>(hammingArray, Hammingdim, Hammingdim),
                50,
                $"{outputFolder}\\{CSI}\\{logOutputFolder}\\HammingBitmap.png");
        }
Exemplo n.º 8
0
        public void CreateSdrsTest()
        {
            var colDims   = new int[] { 64, 64 };
            int numOfCols = 64 * 64;

            string trainingFolder = @"..\..\..\TestFiles\Sdr";

            int imgSize = 28;

            var trainingImages = Directory.GetFiles(trainingFolder, "*.jpeg");

            Directory.CreateDirectory($"{nameof(CreateSdrsTest)}");

            int counter = 0;

            bool isInStableState = false;


            // HTM parameters
            HtmConfig htmConfig = new HtmConfig(new int[] { imgSize, imgSize }, new int[] { 64, 64 })
            {
                PotentialRadius            = 10,
                PotentialPct               = 1,
                GlobalInhibition           = true,
                LocalAreaDensity           = -1.0,
                NumActiveColumnsPerInhArea = 0.02 * numOfCols,
                StimulusThreshold          = 0.0,
                SynPermInactiveDec         = 0.008,
                SynPermActiveInc           = 0.05,
                SynPermConnected           = 0.10,
                MinPctOverlapDutyCycles    = 1.0,
                MinPctActiveDutyCycles     = 0.001,
                DutyCyclePeriod            = 100,
                MaxBoost      = 10.0,
                RandomGenSeed = 42,
                Random        = new ThreadSafeRandom(42)
            };

            Connections connections = new Connections(htmConfig);

            HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(connections, trainingImages.Length * 50, (isStable, numPatterns, actColAvg, seenInputs) =>
            {
                isInStableState = true;
                Debug.WriteLine($"Entered STABLE state: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}");
            });

            SpatialPooler sp = new SpatialPoolerMT(hpa);

            sp.Init(connections);

            string outFolder = nameof(CreateSdrsTest);

            Directory.CreateDirectory(outFolder);

            while (true)
            {
                counter++;

                Dictionary <string, int[]> sdrs = new Dictionary <string, int[]>();

                Dictionary <string, int[]> inputVectors = new Dictionary <string, int[]>();

                foreach (var trainingImage in trainingImages)
                {
                    FileInfo fI = new FileInfo(trainingImage);

                    string outputHamDistFile = $"{outFolder}\\image-{fI.Name}_hamming.txt";
                    string outputActColFile  = $"{outFolder}\\image{fI.Name}_activeCol.txt";
                    string outputActColFile1 = $"{outFolder}\\image{fI.Name}_activeCol.csv";

                    using (StreamWriter swActCol = new StreamWriter(outputActColFile))
                    {
                        using (StreamWriter swActCol1 = new StreamWriter(outputActColFile1))
                        {
                            int[] activeArray = new int[numOfCols];

                            string testName = $"{outFolder}\\{fI.Name}";

                            string inputBinaryImageFile = NeoCortexUtils.BinarizeImage($"{trainingImage}", imgSize, testName);

                            // Read input csv file into array
                            int[] inputVector = NeoCortexUtils.ReadCsvIntegers(inputBinaryImageFile).ToArray();

                            List <double[, ]> overlapArrays = new List <double[, ]>();
                            List <double[, ]> bostArrays    = new List <double[, ]>();

                            sp.compute(inputVector, activeArray, true);

                            var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1);

                            if (isInStableState)
                            {
                                CalculateResult(sdrs, inputVectors, numOfCols, activeCols, outFolder, trainingImage, inputVector);

                                overlapArrays.Add(ArrayUtils.Make2DArray <double>(ArrayUtils.ToDoubleArray(connections.Overlaps), colDims[0], colDims[1]));

                                bostArrays.Add(ArrayUtils.Make2DArray <double>(connections.BoostedOverlaps, colDims[0], colDims[1]));

                                var activeStr = Helpers.StringifyVector(activeArray);
                                swActCol.WriteLine("Active Array: " + activeStr);

                                int[,] twoDimenArray = ArrayUtils.Make2DArray <int>(activeArray, colDims[0], colDims[1]);
                                twoDimenArray        = ArrayUtils.Transpose(twoDimenArray);
                                List <int[, ]> arrays = new List <int[, ]>();
                                arrays.Add(twoDimenArray);
                                arrays.Add(ArrayUtils.Transpose(ArrayUtils.Make2DArray <int>(inputVector, (int)Math.Sqrt(inputVector.Length), (int)Math.Sqrt(inputVector.Length))));

                                //Calculating the max value of the overlap in the OverlapArray
                                int max = SdrRepresentation.TraceColumnsOverlap(overlapArrays, swActCol1, fI.Name);

                                int red   = Convert.ToInt32(max * 0.80);      // Value above this threshould would be red and below this will be yellow
                                int green = Convert.ToInt32(max * 0.50);      // Value above this threshould would be yellow and below this will be green

                                string outputImage = $"{outFolder}\\cycle-{counter}-{fI.Name}";

                                NeoCortexUtils.DrawBitmaps(arrays, outputImage, Color.Yellow, Color.Gray, OutImgSize, OutImgSize);
                                NeoCortexUtils.DrawHeatmaps(overlapArrays, $"{outputImage}_overlap.png", 1024, 1024, red, red, green);

                                if (sdrs.Count == trainingImages.Length)
                                {
                                    return;
                                }
                            }
                        }
                    }
                }
            }
        }