//[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); } } } } } }
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; } } } } } } }