/// <summary>
        /// This function train the input image and write result to text files in folder @"/OutputDutyCycle"
        /// The result text files include speed comparison between global inhibition and local inhibition,
        /// the stable of the out put array (by comparing hamming distance arrays).
        /// Finally this method draw an image of active column as .png file.
        /// This training method is used for testing speed of training with different value of max boost and duty cycle
        /// </summary>
        /// <param name="inputBinarizedFile">input image after binarized</param>
        /// <param name="hammingFile">Path to hamming distance output file</param>
        /// <param name="outputSpeedFile">Path to speed comparison output file</param>
        /// <param name="outputImage">Path to active column after training output file (as .png image file)</param>
        /// <param name="parameters">Parameter setup</param>
        private static void Training(string inputBinarizedFile, string hammingFile, string outputSpeedFile, string outputImage, Parameters parameters)
        {
            int outputImageSize = 1024;
            int topology        = parameters.Get <int[]>(KEY.COLUMN_DIMENSIONS)[0];
            int activeColumn    = topology * topology;
            var stopwatch       = new Stopwatch();

            using (StreamWriter swHamming = new StreamWriter(hammingFile))
            {
                using (StreamWriter swSpeed = new StreamWriter(outputSpeedFile, true))
                {
                    var sp  = new SpatialPooler();
                    var mem = new Connections();

                    parameters.apply(mem);

                    stopwatch.Start();
                    sp.Init(mem);
                    stopwatch.Stop();

                    int   actiColumnLength = activeColumn;
                    int[] activeArray      = new int[actiColumnLength];

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

                    stopwatch.Restart();

                    int   iterations = 1000;
                    int[] oldArray   = new int[activeArray.Length];

                    for (int k = 0; k < iterations; k++)
                    {
                        sp.compute(inputVector, activeArray, true);

                        var activeCols = activeArray.IndexWhere((el) => el == 1);
                        var distance   = MathHelpers.GetHammingDistance(oldArray, activeArray);
                        var similarity = MathHelpers.CalcArraySimilarity(oldArray, activeArray);
                        swHamming.WriteLine($"{distance} | {similarity}");
                        var str = Helpers.StringifyVector(activeCols);
                        Debug.WriteLine(str);
                        oldArray = new int[actiColumnLength];
                        activeArray.CopyTo(oldArray, 0);
                    }

                    var activeArrayString = Helpers.StringifyVector(activeArray);

                    stopwatch.Stop();

                    Debug.WriteLine("Active Array: " + activeArrayString);

                    int    potentialRadius    = parameters.Get <int>(KEY.POTENTIAL_RADIUS);
                    bool   isGlobalInhibition = parameters.Get <bool>(KEY.GLOBAL_INHIBITION);
                    string inhibition         = isGlobalInhibition ? "Global" : "Local";
                    double milliseconds       = stopwatch.ElapsedMilliseconds;
                    double seconds            = milliseconds / 1000;
                    swSpeed.WriteLine($"Column dimension: {topology.ToString().PadRight(5)} |Potential Radius: {potentialRadius}| Inhibition type: {inhibition.PadRight(7)} | Total time: {milliseconds:N0} milliseconds ({seconds:N2} seconds).");

                    int[,] twoDimenArray = ArrayUtils.Make2DArray(activeArray, topology, topology);
                    twoDimenArray        = ArrayUtils.Transpose(twoDimenArray);

                    NeoCortexUtils.DrawBitmap(twoDimenArray, outputImageSize, outputImageSize, outputImage);
                }
            }
        }
        /// <summary>
        /// This function train the input image and write result to text files in folder @"/Output"
        /// The result text files include speed comparison between global inhibition and local inhibition,
        /// the stable of the out put array (by comparing hamming distance arrays).
        /// Finally this method draw an image of active column as .png file.
        /// </summary>
        /// <param name="imageSize">Size of the image (image has same width and height)</param>
        /// <param name="columnDimension">List of sparse space size.(with same width and height)</param>
        /// <param name="inputBinarizedFile">input image after binarized</param>
        /// <param name="hammingFile">Path to hamming distance output file </param>
        /// <param name="outputSpeedFile">Path to speed comparison output file</param>
        /// <param name="activeColumnFile">Path to active column after training output file (as array text)</param>
        /// <param name="outputImage">Path to active column after training output file (as .png image file)</param>
        /// <param name="isGlobalInhibition">is using Global inhibition algorithms or not (if false using local inhibition)</param>
        private static void Training(int imageSize, int columnDimension, string inputBinarizedFile, string hammingFile, string outputSpeedFile, string activeColumnFile, string outputImage, bool isGlobalInhibition)
        {
            int outputImageSize = 1024;
            int activeColumn    = columnDimension * columnDimension;
            var stopwatch       = new Stopwatch();

            using (StreamWriter swHamming = new StreamWriter(hammingFile))
            {
                using (StreamWriter swSpeed = new StreamWriter(outputSpeedFile, true))
                {
                    using (StreamWriter swActiveColumn = new StreamWriter(activeColumnFile))
                    {
                        var parameters = SetupParameters(imageSize, columnDimension, isGlobalInhibition);
                        var sp         = new SpatialPooler();
                        var mem        = new Connections();

                        parameters.apply(mem);

                        stopwatch.Start();
                        sp.Init(mem);
                        stopwatch.Stop();

                        int   actiColumnLength = activeColumn;
                        int[] activeArray      = new int[actiColumnLength];

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

                        stopwatch.Restart();

                        int   iterations = 300;
                        int[] oldArray   = new int[activeArray.Length];

                        for (int k = 0; k < iterations; k++)
                        {
                            sp.compute(inputVector, activeArray, true);

                            var activeCols = activeArray.IndexWhere((el) => el == 1);
                            var distance   = MathHelpers.GetHammingDistance(oldArray, activeArray);
                            var similarity = MathHelpers.CalcArraySimilarity(oldArray, activeArray);
                            swHamming.WriteLine($"{distance} | {similarity}");
                            var str = Helpers.StringifyVector(activeCols);
                            Debug.WriteLine(str);
                            oldArray = new int[actiColumnLength];
                            activeArray.CopyTo(oldArray, 0);
                        }

                        stopwatch.Stop();
                        var activeArrayString = Helpers.StringifyVector(activeArray);
                        swActiveColumn.WriteLine("Active Array: " + activeArrayString);

                        string inhibition   = isGlobalInhibition ? "Global" : "Local";
                        double milliseconds = stopwatch.ElapsedMilliseconds;
                        double seconds      = milliseconds / 1000;
                        swSpeed.WriteLine($"Topology: {columnDimension.ToString().PadRight(5)} | Inhibition type: {inhibition.PadRight(7)} | Total time: {milliseconds:N0} milliseconds ({seconds:N2} seconds).");

                        int[,] twoDimenArray = ArrayUtils.Make2DArray(activeArray, columnDimension, columnDimension);
                        twoDimenArray        = ArrayUtils.Transpose(twoDimenArray);

                        NeoCortexUtils.DrawBitmap(twoDimenArray, outputImageSize, outputImageSize, outputImage);
                    }
                }
            }
        }
        //[DataRow("MnistTestImages\\digit7.png", 128, 30)]
        public void CalculateSpeedOfLearningTest(string mnistImage, int[] imageSize, int[] topologies)
        {
            int    index1 = mnistImage.IndexOf("\\") + 1;
            int    index2 = mnistImage.IndexOf(".");
            string sub1   = mnistImage.Substring(0, index2);
            string sub2   = mnistImage.Substring(0, index1);
            string name   = mnistImage.Substring(index1, sub1.Length - sub2.Length);

            for (int imSizeIndx = 0; imSizeIndx < imageSize.Length; imSizeIndx++)
            {
                string testName             = $"{name}_{imageSize[imSizeIndx]}";
                string outputSpeedFile      = $"Output\\{testName}_speed.txt";
                string inputBinaryImageFile = BinarizeImage("Output\\" + mnistImage, imageSize[imSizeIndx], testName);
                for (int topologyIndx = 0; topologyIndx < topologies.Length; topologyIndx++)
                {
                    string finalName         = $"{testName}_{topologies[topologyIndx]}";
                    string outputHamDistFile = $"Output\\{finalName}_hamming.txt";
                    string outputActColFile  = $"Output\\{finalName}_activeCol.txt";

                    string outputImage = $"Output\\{finalName}.png";

                    int numOfActCols = 0;
                    var sw           = new Stopwatch();
                    using (StreamWriter swHam = new StreamWriter(outputHamDistFile))
                    {
                        using (StreamWriter swSpeed = new StreamWriter(outputSpeedFile, true))
                        {
                            using (StreamWriter swActCol = new StreamWriter(outputActColFile))
                            {
                                numOfActCols = topologies[topologyIndx] * topologies[topologyIndx];
                                var parameters = GetDefaultParams();
                                parameters.setInputDimensions(new int[] { imageSize[imSizeIndx], imageSize[imSizeIndx] });
                                parameters.setColumnDimensions(new int[] { topologies[topologyIndx], topologies[topologyIndx] });
                                parameters.setNumActiveColumnsPerInhArea(0.02 * numOfActCols);

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

                                parameters.apply(mem);
                                sw.Start();

                                sp.init(mem);

                                sw.Stop();
                                swSpeed.WriteLine($"{topologies[topologyIndx]}|{(double)sw.ElapsedMilliseconds / (double)1000}");

                                int   actiColLen  = numOfActCols;
                                int[] activeArray = new int[actiColLen];

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

                                int   iterations = 2;
                                int[] oldArray   = new int[activeArray.Length];
                                for (int k = 0; k < iterations; k++)
                                {
                                    sp.compute(inputVector, activeArray, true);

                                    var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1);
                                    var distance   = MathHelpers.GetHammingDistance(oldArray, activeArray);
                                    swHam.WriteLine(distance + "\n");
                                    var str = Helpers.StringifyVector(activeCols);

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

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

                                sw.Stop();

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

                                NeoCortexUtils.DrawBitmap(twoDimenArray, OutImgSize, OutImgSize, outputImage);
                            }
                        }
                    }
                }
            }
        }
        // [DataRow("MnistTestImages\\digit7.png", 128, 30)]
        public void LearningimageDoubleShiftStble(string mnistImage, string shiftedImage, int[] imageSize, int[] topologies)
        {
            var path        = Path.Combine(Directory.GetParent(Environment.CurrentDirectory).Parent.Parent.FullName, mnistImage);
            var pathShifted = Path.Combine(Directory.GetParent(Environment.CurrentDirectory).Parent.Parent.FullName, shiftedImage);

            Console.WriteLine("Test started");
            Console.WriteLine(mnistImage);
            Console.WriteLine(shiftedImage);
            const int OutImgSize = 1024;

            int    index1 = mnistImage.IndexOf("\\") + 1;
            int    index2 = mnistImage.IndexOf(".");
            string sub1   = mnistImage.Substring(0, index2);
            string sub2   = mnistImage.Substring(0, index1);
            string name   = mnistImage.Substring(index1, sub1.Length - sub2.Length);

            int    index1Shift = shiftedImage.IndexOf("\\") + 1;
            int    index2Shift = shiftedImage.IndexOf(".");
            string sub1Shift   = shiftedImage.Substring(0, index2Shift);
            string sub2Shift   = shiftedImage.Substring(0, index1Shift);
            string nameShift   = shiftedImage.Substring(index1Shift, sub1Shift.Length - sub2Shift.Length);

            for (int imSizeIndx = 0; imSizeIndx < imageSize.Length; imSizeIndx++)
            {
                Console.WriteLine(String.Format("Image Size: \t{0}", imageSize[imSizeIndx]));

                string testName        = $"{name}_{imageSize[imSizeIndx]}";
                string outputSpeedFile = $"Output\\{testName}_speed.txt";

                string testNameShifted        = $"{nameShift}_{imageSize[imSizeIndx]}";
                string outputSpeedFileShifted = $"Output\\{testNameShifted}_speed.txt";

                string inputBinaryImageFile        = BinarizeImage(path, imageSize[imSizeIndx], testName);
                string inputBinaryImageShiftedFile = BinarizeImage(pathShifted, imageSize[imSizeIndx], testNameShifted);

                //string inputBinaryImageFile = BinarizeImage("Output\\" + mnistImage, imageSize[imSizeIndx], testName);
                for (int topologyIndx = 0; topologyIndx < topologies.Length; topologyIndx++)
                {
                    Console.WriteLine(String.Format("Topology: \t{0}", topologies[topologyIndx]));

                    string finalName         = $"{testName}_{topologies[topologyIndx]}";
                    string outputHamDistFile = $"Output\\{finalName}_hamming.txt";
                    string outputActColFile  = $"Output\\{finalName}_activeCol.txt";

                    string outputImage = $"Output\\{finalName}.png";

                    string finalNameShifted         = $"{testNameShifted}_{topologies[topologyIndx]}";
                    string outputHamDistFileShifted = $"Output\\{finalNameShifted}_hamming.txt";
                    string outputActColFileShifted  = $"Output\\{finalNameShifted}_activeCol.txt";

                    string outputImageShifted = $"Output\\{finalNameShifted}.png";


                    //File.Create(finalName);
                    //Directory.CreateDirectory("Output");
                    //File.Create(outputHamDistFile);
                    //File.Create(outputActColFile);

                    int numOfActCols = 0;
                    var sw           = new Stopwatch();
                    using (StreamWriter swHam = new StreamWriter(outputHamDistFile))
                    {
                        using (StreamWriter swSpeed = new StreamWriter(outputSpeedFile, true))
                        {
                            using (StreamWriter swActCol = new StreamWriter(outputActColFile))
                            {
                                numOfActCols = topologies[topologyIndx] * topologies[topologyIndx];
                                var parameters = GetDefaultParams();
                                parameters.setInputDimensions(new int[] { imageSize[imSizeIndx], imageSize[imSizeIndx] });
                                parameters.setColumnDimensions(new int[] { topologies[topologyIndx], topologies[topologyIndx] });
                                parameters.setNumActiveColumnsPerInhArea(0.02 * numOfActCols);

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

                                parameters.apply(mem);
                                sw.Start();

                                sp.init(mem);

                                sw.Stop();
                                swSpeed.WriteLine($"{topologies[topologyIndx]}|{(double)sw.ElapsedMilliseconds / (double)1000}");

                                int   actiColLen  = numOfActCols;
                                int[] activeArray = new int[actiColLen];

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

                                var inputOverlap  = new List <double>();
                                var outputOverlap = new List <double>();

                                int[]      newActiveArray       = new int[topologies[topologyIndx] * topologies[topologyIndx]];
                                double[][] newActiveArrayDouble = new double[1][];
                                newActiveArrayDouble[0] = new double[newActiveArray.Length];

                                //Training
                                sp.compute(inputVector, activeArray, true);

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

                                double[][] oldActiveArray = new double[1][];
                                oldActiveArray[0] = new double[activeArray.Length];
                                for (int a = 0; a < activeArray.Length; a++)
                                {
                                    oldActiveArray[0][a] = activeArray[a];
                                }

                                int isTrained = 0;

                                while (isTrained == 0)
                                {
                                    sp.compute(inputVector, newActiveArray, true);

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



                                    for (int a = 0; a < newActiveArray.Length; a++)
                                    {
                                        newActiveArrayDouble[0][a] = newActiveArray[a];
                                    }

                                    if (MathHelpers.GetHammingDistance(oldActiveArray, newActiveArrayDouble, true)[0] == 100)
                                    {
                                        isTrained = 1;
                                    }
                                    else
                                    {
                                        isTrained      = 0;
                                        oldActiveArray = newActiveArrayDouble;
                                    }
                                }

                                var str = Helpers.StringifyVector(activeCols);


                                int[] oldInputVector = NeoCortexUtils.ReadCsvFileTest(inputBinaryImageFile).ToArray();

                                int[] inputVectorShifted = NeoCortexUtils.ReadCsvFileTest(inputBinaryImageShiftedFile).ToArray();

                                int[]      activeArrayShifted       = new int[topologies[topologyIndx] * topologies[topologyIndx]];
                                double[][] activeArrayShiftedDouble = new double[1][];
                                activeArrayShiftedDouble[0] = new double[activeArrayShifted.Length];

                                sw.Restart();

                                //Prediction
                                sp.compute(inputVectorShifted, activeArrayShifted, false);

                                var resActiveColsPercent = ArrayUtils.IndexWhere(activeArrayShifted, (el) => el == 1);

                                var resStrPercent = Helpers.StringifyVector(activeArrayShifted);


                                for (int a = 0; a < activeArrayShifted.Length; a++)
                                {
                                    activeArrayShiftedDouble[0][a] = activeArrayShifted[a];
                                }



                                var distance    = MathHelpers.GetHammingDistance(newActiveArrayDouble, activeArrayShiftedDouble, false)[0];
                                var distPercent = ((100 - distance) * 100) / (topologies[topologyIndx] * topologies[topologyIndx]);
                                swHam.WriteLine(distance + "\t" + (100 - distance) + "\t" + distPercent + "\t" + (1 - (distPercent / 100.0)) + "\n");

                                outputOverlap.Add(1 - (distPercent / 100.0));

                                swActCol.WriteLine(String.Format(@"Active Cols: {0}", Helpers.StringifyVector(resActiveColsPercent)));

                                Console.WriteLine(resStrPercent);
                                swActCol.WriteLine("Active Array: " + resStrPercent);

                                sw.Stop();

                                int[,] twoDimenArray = ArrayUtils.Make2DArray <int>(activeArrayShifted, topologies[topologyIndx], topologies[topologyIndx]);
                                twoDimenArray        = ArrayUtils.Transpose(twoDimenArray);

                                NeoCortexUtils.DrawBitmap(twoDimenArray, OutImgSize, OutImgSize, outputImage);
                                //NeoCortexUtils.DrawBitmap(twoDimenArray, OutImgSize, OutImgSize, "D:\\Project_Latest\\FromGit\\se-dystsys-2018-2019-softwareengineering\\outputs\\eight");


                                swActCol.WriteLine("inputOverlaps: " + Helpers.StringifyVector(inputOverlap.ToArray()));

                                swActCol.WriteLine("outputOverlaps: " + Helpers.StringifyVector(outputOverlap.ToArray()));
                            }
                        }
                    }
                }
            }
        }
Beispiel #5
0
        public void SparseSingleMnistImageTest(string trainingFolder, string digit, int imageSize, int columnTopology)
        {
            //Thread.Sleep(3000);

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

            var trainingImages = Directory.GetFiles(Path.Combine(trainingFolder, digit));

            //if (Directory.Exists(TestOutputFolder))
            //    Directory.Delete(TestOutputFolder, true);

            Directory.CreateDirectory(TestOutputFolder);

            Directory.CreateDirectory($"{TestOutputFolder}\\{digit}");

            int counter      = 0;
            var numOfActCols = columnTopology * columnTopology;

            ThreadSafeRandom rnd = new ThreadSafeRandom(42);

            var parameters = Parameters.getAllDefaultParameters();

            parameters.Set(KEY.POTENTIAL_RADIUS, imageSize * imageSize);
            parameters.Set(KEY.POTENTIAL_PCT, 1.0);
            parameters.Set(KEY.GLOBAL_INHIBITION, true);

            parameters.Set(KEY.RANDOM, rnd);

            parameters.Set(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 0.02 * 64 * 64);
            parameters.Set(KEY.LOCAL_AREA_DENSITY, -1);

            parameters.Set(KEY.POTENTIAL_RADIUS, imageSize * imageSize);
            parameters.Set(KEY.POTENTIAL_PCT, 1.0);

            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.STIMULUS_THRESHOLD, 0.0);       //***
            //parameters.Set(KEY.SYN_PERM_INACTIVE_DEC, 0.0);   //***
            //parameters.Set(KEY.SYN_PERM_ACTIVE_INC, 0.0);      //***

            parameters.Set(KEY.INHIBITION_RADIUS, (int)0.025 * imageSize * imageSize);

            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, -1);
            parameters.setInputDimensions(new int[] { imageSize, imageSize });
            parameters.setColumnDimensions(new int[] { columnTopology, columnTopology });

            var sp = new SpatialPoolerParallel();

            var mem = new Connections();

            parameters.apply(mem);

            Stopwatch sw = new Stopwatch();

            sw.Start();
            sp.init(mem, UnitTestHelpers.GetMemory(new HtmConfig()));
            sw.Stop();
            Debug.WriteLine($"Init time: {sw.ElapsedMilliseconds}");
            int actiColLen = numOfActCols;

            int[] activeArray = new int[actiColLen];

            string outFolder = $"{TestOutputFolder}\\{digit}\\{columnTopology}x{columnTopology}";

            Directory.CreateDirectory(outFolder);

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

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

            using (StreamWriter swHam = new StreamWriter(outputHamDistFile))
            {
                using (StreamWriter swActCol = new StreamWriter(outputActColFile))
                {
                    foreach (var mnistImage in trainingImages)
                    {
                        FileInfo fI = new FileInfo(mnistImage);

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

                        string testName = $"{outFolder}\\digit_{digit}_{fI.Name}_{columnTopology}";

                        string inputBinaryImageFile = Helpers.BinarizeImage($"{mnistImage}", imageSize, testName);

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

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

                        for (int k = 0; k < numIterationsPerImage; k++)
                        {
                            sw.Reset();
                            sw.Start();
                            sp.compute(inputVector, activeArray, true);
                            sw.Stop();
                            Debug.WriteLine($"Compute time: {sw.ElapsedMilliseconds}");

                            var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1);
                            var distance   = MathHelpers.GetHammingDistance(oldArray, activeArray);
                            swHam.WriteLine($"{counter++}|{distance} ");

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

                            //var mem = sp.GetMemory(layer);
                            overlapArrays.Add(ArrayUtils.Make2DArray <double>(ArrayUtils.toDoubleArray(mem.Overlaps), columnTopology, columnTopology));
                            bostArrays.Add(ArrayUtils.Make2DArray <double>(mem.BoostedOverlaps, columnTopology, columnTopology));
                        }

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

                        int[,] twoDimenArray = ArrayUtils.Make2DArray <int>(activeArray, columnTopology, columnTopology);
                        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))));

                        const int OutImgSize = 1024;
                        NeoCortexUtils.DrawBitmaps(arrays, outputImage, Color.Yellow, Color.Gray, OutImgSize, OutImgSize);
                        //NeoCortexUtils.DrawHeatmaps(overlapArrays, $"{outputImage}_overlap.png", OutImgSize, OutImgSize, 150, 50, 5);
                        //NeoCortexUtils.DrawHeatmaps(bostArrays, $"{outputImage}_boost.png", OutImgSize, OutImgSize, 150, 50, 5);
                    }
                }
            }
        }