public void StableOutputOnSameInputTest() { var parameters = GetDefaultParams(); parameters.Set(KEY.POTENTIAL_RADIUS, 64 * 64); parameters.Set(KEY.POTENTIAL_PCT, 1.0); parameters.Set(KEY.GLOBAL_INHIBITION, false); parameters.Set(KEY.STIMULUS_THRESHOLD, 0.5); parameters.Set(KEY.INHIBITION_RADIUS, (int)0.25 * 64 * 64); parameters.Set(KEY.LOCAL_AREA_DENSITY, -1); parameters.Set(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 0.1 * 64 * 64); parameters.Set(KEY.DUTY_CYCLE_PERIOD, 1000000); parameters.Set(KEY.MAX_BOOST, 5); parameters.setInputDimensions(new int[] { 32, 32 }); parameters.setColumnDimensions(new int[] { 64, 64 }); parameters.setNumActiveColumnsPerInhArea(0.02 * 64 * 64); var sp = new SpatialPooler(); var mem = new Connections(); //List<int> intList = ArrayUtils.ReadCsvFileTest("TestFiles\\digit1_binary_32bit.txt"); //intList.Clear(); //List<int> intList = new List<int>(); int[] inputVector = new int[1024]; for (int i = 0; i < 31; i++) { for (int j = 0; j < 32; j++) { if (i > 2 && i < 5 && j > 2 && j < 8) { inputVector[i * 32 + j] = 1; } else { inputVector[i * 32 + j] = 0; } } } parameters.apply(mem); sp.Init(mem); //int[] activeArray = new int[64 * 64]; for (int i = 0; i < 10; i++) { //sp.compute( inputVector, activeArray, true); var activeArray = sp.Compute(inputVector, true) as int[]; //var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1); var str = Helpers.StringifyVector(activeArray); Debug.WriteLine(str); } }
public void CollSynapsesToInput() { var parameters = GetDefaultParams(); parameters.setInputDimensions(new int[] { 32 }); parameters.setColumnDimensions(new int[] { 128 }); parameters.setNumActiveColumnsPerInhArea(0.02 * 128); var sp = new SpatialPooler(); var mem = new Connections(); parameters.apply(mem); sp.Init(mem); int[] activeArray = new int[128]; int[] inputVector = Helpers.GetRandomVector(32, parameters.Get <Random>(KEY.RANDOM)); for (int i = 0; i < 100; i++) { sp.compute(inputVector, activeArray, true); var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1); var str = Helpers.StringifyVector(activeCols); Debug.WriteLine(str); } }
public void SPTutorialTest() { var parameters = GetDefaultParams(); parameters.setInputDimensions(new int[] { 1000 }); parameters.setColumnDimensions(new int[] { 2048 }); parameters.setNumActiveColumnsPerInhArea(0.02 * 2048); parameters.setGlobalInhibition(false); var sp = new SpatialPooler(); var mem = new Connections(); parameters.apply(mem); sp.Init(mem); int[] activeArray = new int[2048]; int[] inputVector = Helpers.GetRandomVector(1000, parameters.Get <Random>(KEY.RANDOM)); sp.compute(inputVector, activeArray, true); var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1); var str = Helpers.StringifyVector(activeCols); Debug.WriteLine(str); }
private void InitSp() { sp = new SpatialPooler(); mem = new Connections(); parameters.Apply(mem); sp.Init(mem); }
public HtmModuleNet(Parameters[] parametersList) { foreach (var prms in parametersList) { var mem = new Connections(); prms.apply(mem); var colDims = prms.Get <int[]>(KEY.COLUMN_DIMENSIONS); int numCols = 1; for (int i = 0; i < colDims.Length; i++) { numCols *= colDims[i]; } this.m_ActiveArrays.Add(new int[numCols]); this.m_Connections.Add(mem); SpatialPooler sp = new SpatialPooler(); sp.Init(mem, null); m_Poolers.Add(sp); } }
public HtmModuleNet(Parameters parameters, int[] levels) { for (int levelIndx = 0; levelIndx < levels.Length; levelIndx++) { int levelIn; int levelOut; if (levelIndx == 0) { levelIn = levelOut = levels[levelIndx]; } else { levelIn = m_Connections[levelIndx - 1].HtmConfig.ColumnDimensions[0]; levelOut = levels[levelIndx]; } parameters.setInputDimensions(new int[] { levelIn, levelIn }); parameters.setColumnDimensions(new int[] { levelOut, levelOut }); parameters.Set(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 0.1 * levelOut * levelOut); var mem = new Connections(); parameters.apply(mem); this.m_ActiveArrays.Add(new int[levelOut * levelOut]); this.m_Connections.Add(mem); SpatialPooler sp = new SpatialPooler(); sp.Init(mem, null); m_Poolers.Add(sp); } }
public void StableOutputWithPersistence() { var parameters = GetDefaultParams(); parameters.setInputDimensions(new int[] { 32, 32 }); parameters.setColumnDimensions(new int[] { 64, 64 }); parameters.setNumActiveColumnsPerInhArea(0.02 * 64 * 64); var mem = new Connections(); parameters.apply(mem); var sp = new SpatialPooler(); sp.Init(mem); int[] activeArray = new int[64 * 64]; int[] inputVector = Helpers.GetRandomVector(32 * 32, parameters.Get <Random>(KEY.RANDOM)); string str1 = String.Empty; for (int i = 0; i < 2; i++) { sp.compute(inputVector, activeArray, true); var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1); str1 = Helpers.StringifyVector(activeCols); Debug.WriteLine(str1); } var settings = new JsonSerializerSettings { ContractResolver = new ContractResolver(), Formatting = Formatting.Indented }; var jsonSp = JsonConvert.SerializeObject(sp, settings); var sp2 = JsonConvert.DeserializeObject <SpatialPooler>(jsonSp, settings); activeArray = new int[activeArray.Length]; for (int i = 10; i < 20; i++) { sp2.compute(inputVector, activeArray, true); var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1); var str2 = Helpers.StringifyVector(activeCols); Debug.WriteLine(str2); Assert.IsTrue(str1.SequenceEqual(str2)); } }
private void RunSpStabilityExperiment_1(int inputBits, Parameters p, EncoderBase encoder, List <double> inputValues) { string path = nameof(SpatialPooler_Stability_Experiment_1); if (Directory.Exists(path)) { Directory.Delete(path, true); } while (true) { Directory.CreateDirectory(path); if (Directory.Exists(path) == false) { Thread.Sleep(300); } else { break; } } Stopwatch sw = new Stopwatch(); sw.Start(); bool learn = true; CortexNetwork net = new CortexNetwork("my cortex"); List <CortexRegion> regions = new List <CortexRegion>(); CortexRegion region0 = new CortexRegion("1st Region"); regions.Add(region0); SpatialPooler sp1 = new SpatialPooler(); var mem = new Connections(); p.apply(mem); sp1.Init(mem, UnitTestHelpers.GetMemory()); CortexLayer <object, object> layer1 = new CortexLayer <object, object>("L1"); // // NewBorn learning stage. region0.AddLayer(layer1); layer1.HtmModules.Add("encoder", encoder); layer1.HtmModules.Add("sp", sp1); HtmClassifier <double, ComputeCycle> cls = new HtmClassifier <double, ComputeCycle>(); double[] inputs = inputValues.ToArray(); int[] prevActiveCols = new int[0]; int maxSPLearningCycles = 10000; List <(double Element, (int Cycle, double Similarity)[] Oscilations)> oscilationResult = new List <(double Element, (int Cycle, double Similarity)[] Oscilations)>();
public void SPInhibitionTest() { var parameters = GetDefaultParams(); parameters.setInputDimensions(new int[] { 10 }); parameters.setColumnDimensions(new int[] { 1024 }); parameters.setNumActiveColumnsPerInhArea(0.2 * 32 * 32); parameters.setGlobalInhibition(false); var sp = new SpatialPooler(); var mem = new Connections(); parameters.apply(mem); sp.Init(mem); //int[] inputVector = NeoCortexUtils.ReadCsvFileTest("Testfiles\\digit8_binary_32bit.txt").ToArray(); // var inputString = Helpers.StringifyVector(inputVector); //Debug.WriteLine("Input Array: " + inputString); int[] inputVector = new int[] { 1, 0, 0, 0, 1, 1, 1, 0, 1, 1 }; int[] activeArray = new int[32 * 32]; //int iteration = -1; String str = ""; for (int i = 0; i < 10; i++) { var overlaps = sp.CalculateOverlap(mem, inputVector); var strOverlaps = Helpers.StringifyVector(overlaps); var inhibitions = sp.InhibitColumns(mem, ArrayUtils.ToDoubleArray(overlaps)); var strInhibitions = Helpers.StringifyVector(inhibitions); activeArray = sp.Compute(inputVector, true) as int[]; //Debug.WriteLine(result); //sp.compute( inputVector, activeArray, true); var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1); var strActiveArr = Helpers.StringifyVector(activeArray); Debug.WriteLine("Active array: " + strActiveArr); var strActiveCols = Helpers.StringifyVector(activeCols); Debug.WriteLine("Number of Active Column: " + activeCols.Length); str = strActiveCols; Debug.WriteLine($"{i} - {strActiveCols}"); } var strOutput = Helpers.StringifyVector(activeArray); Debug.WriteLine("Output: " + strOutput); }
public void TestMaxDims() { var parameters = SpatialPoolerResearchTests.GetDefaultParams(); parameters.Set(KEY.POTENTIAL_RADIUS, 64 * 64); parameters.Set(KEY.POTENTIAL_PCT, 1.0); parameters.Set(KEY.GLOBAL_INHIBITION, false); parameters.Set(KEY.STIMULUS_THRESHOLD, 0.5); parameters.Set(KEY.INHIBITION_RADIUS, (int)0.25 * 64 * 64); parameters.Set(KEY.LOCAL_AREA_DENSITY, -1); parameters.Set(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 0.1 * 64 * 64); parameters.Set(KEY.DUTY_CYCLE_PERIOD, 1000000); parameters.Set(KEY.MAX_BOOST, 5); parameters.setInputDimensions(new int[] { 320, 320 }); parameters.setColumnDimensions(new int[] { 2048, 2048 }); parameters.setNumActiveColumnsPerInhArea(0.02 * 64 * 64); var sp = new SpatialPooler(); var mem = new Connections(); //List<int> intList = ArrayUtils.ReadCsvFileTest("TestFiles\\digit1_binary_32bit.txt"); //intList.Clear(); //List<int> intList = new List<int>(); int[] inputVector = new int[1024]; for (int i = 0; i < 31; i++) { for (int j = 0; j < 32; j++) { if (i > 2 && i < 5 && j > 2 && j < 8) { inputVector[i * 32 + j] = 1; } else { inputVector[i * 32 + j] = 0; } } } parameters.apply(mem); sp.Init(mem, null); }
public void NeighborhoodTest() { var parameters = GetDefaultParams(); int cellsDim1 = 64; int cellsDim2 = 64; parameters.setInputDimensions(new int[] { 32 }); parameters.setColumnDimensions(new int[] { cellsDim1 }); var sp = new SpatialPooler(); var mem = new Connections(); parameters.apply(mem); sp.Init(mem); for (int rad = 1; rad < 10; rad++) { using (StreamWriter sw = new StreamWriter($"neighborhood-test-rad{rad}-center-from-{cellsDim1}-to-{0}.csv")) { sw.WriteLine($"{cellsDim1}|{cellsDim2}|{rad}|First column defines center of neiborhood. All other columns define indicies of neiborhood columns"); for (int center = 0; center < 64; center++) { var nbs = HtmCompute.GetNeighborhood(center, rad, mem.HtmConfig.ColumnTopology.HtmTopology); StringBuilder sb = new StringBuilder(); sb.Append(center); sb.Append('|'); foreach (var neighobordCellIndex in nbs) { sb.Append(neighobordCellIndex); sb.Append('|'); } string str = sb.ToString(); sw.WriteLine(str.TrimEnd('|')); } } } }
/// <summary> /// /// </summary> private void RunSpStabilityExperiment(int inputBits, Parameters p, EncoderBase encoder, List <double> inputValues) { Stopwatch sw = new Stopwatch(); sw.Start(); bool learn = true; CortexNetwork net = new CortexNetwork("my cortex"); List <CortexRegion> regions = new List <CortexRegion>(); CortexRegion region0 = new CortexRegion("1st Region"); regions.Add(region0); SpatialPooler sp1 = new SpatialPooler(); var mem = new Connections(); p.apply(mem); sp1.Init(mem, UnitTestHelpers.GetMemory()); CortexLayer <object, object> layer1 = new CortexLayer <object, object>("L1"); // // NewBorn learning stage. region0.AddLayer(layer1); layer1.HtmModules.Add("encoder", encoder); layer1.HtmModules.Add("sp", sp1); HtmClassifier <double, ComputeCycle> cls = new HtmClassifier <double, ComputeCycle>(); double[] inputs = inputValues.ToArray(); int[] prevActiveCols = new int[0]; int maxSPLearningCycles = 25000; List <(double Element, (int Cycle, double Similarity)[] Oscilations)> oscilationResult = new List <(double Element, (int Cycle, double Similarity)[] Oscilations)>();
public void ExperimentTest(string inputBinarizedFile) { var parameters = SetupParameters(32, 64, 4096, true); parameters.Set(KEY.DUTY_CYCLE_PERIOD, 100000); parameters.Set(KEY.MAX_BOOST, 1.0); parameters.Set(KEY.IS_BUMPUP_WEAKCOLUMNS_DISABLED, true); var sp = new SpatialPooler(); var mem = new Connections(); int[] inputVector = NeoCortexUtils.ReadCsvFileTest(inputBinarizedFile).ToArray(); int[] activeArray = new int[4096]; parameters.apply(mem); sp.Init(mem); for (int i = 0; i < 1000; i++) { sp.compute(inputVector, activeArray, true); var activeCols = activeArray.IndexWhere((el) => el == 1); var str = Helpers.StringifyVector(activeCols); Debug.WriteLine(str); } }
public void SerializationTestWithTrainedData() { // TODO: see SpatialPooler_Stability_Experiment_3() // use it here. var parameters = GetDefaultParams(); parameters.setInputDimensions(new int[] { 16 * 16 }); parameters.setColumnDimensions(new int[] { 32 * 32 }); parameters.setNumActiveColumnsPerInhArea(0.02 * 32 * 32); parameters.setMinPctOverlapDutyCycles(0.01); var mem = new Connections(); parameters.apply(mem); var sp1 = new SpatialPooler(); sp1.Init(mem); int[] output = new int[32 * 32]; int[] inputVector = Helpers.GetRandomVector(16 * 16, parameters.Get <Random>(KEY.RANDOM)); /* int [] inputVector = { * 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, * 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, * 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, * 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, * 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, * 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, * 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, * 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, * 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, * 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, * 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1, * 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, * 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, * 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, * 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, * 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 }; * */ string str1 = String.Empty; for (int i = 0; i < 5; i++) { sp1.compute(inputVector, output, true); var activeCols1 = ArrayUtils.IndexWhere(output, (el) => el == 1); // Remember SDR for every input. // if(i >= 4) // sdrs.Add(output) str1 = Helpers.StringifyVector(activeCols1); Debug.WriteLine(str1); } // if stable // HtmSerializer ser = new HtmSerializer(); // ser.Serialize(sp, "sp.json"); // var sp2 = HtmSerializer.Load("sp.json"); // Implement a code to compare sdrs of sp2 that have been learned with sp1. string ser1 = File.ReadAllText("spTrain1.json"); //var sp2 = SpatialPooler.Deserializer("spTrain1.json"); //sp2.Serializer("spTrainDes1.json"); //string des1 = File.ReadAllText("spTrainDes1.json"); //Assert.IsTrue(ser1.SequenceEqual(des1)); //for (int i = 5; i < 10; i++) //{ // sp1.compute(inputVector, sdrArray, false); // var sdr2 = ArrayUtils.IndexWhere(sdrArray, (el) => el == 1); // // Compare sdr with sdr1 of the same input // var str2 = Helpers.StringifyVector(sdr2); // Debug.WriteLine(str2); // Assert.IsTrue(str1.SequenceEqual(str2)); //} }
private void RunSerializationExperiment(double maxBoost, double minOverlapCycles, int inputBits, Parameters p, EncoderBase encoder, List <double> inputValues) { string path = nameof(RunSerializationExperiment); if (Directory.Exists(path)) { Directory.Delete(path, true); } Directory.CreateDirectory(path); Stopwatch sw = new Stopwatch(); sw.Start(); bool learn = true; CortexNetwork net = new CortexNetwork("my cortex"); List <CortexRegion> regions = new List <CortexRegion>(); CortexRegion region0 = new CortexRegion("1st Region"); regions.Add(region0); var mem = new Connections(); bool isInStableState = false; HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(mem, inputValues.Count * 15, (isStable, numPatterns, actColAvg, seenInputs) => { Assert.IsTrue(numPatterns == inputValues.Count); // Event should only be fired when entering the stable state. // Ideal SP should never enter unstable state after stable state. if (isStable == false) { isInStableState = false; Debug.WriteLine($"UNSTABLE!: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); } else { //Assert.IsTrue(isStable); isInStableState = true; Debug.WriteLine($"STABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); } }); SpatialPooler sp1 = new SpatialPooler(hpa); p.apply(mem); sp1.Init(mem, UnitTestHelpers.GetMemory()); CortexLayer <object, object> layer1 = new CortexLayer <object, object>("L1"); region0.AddLayer(layer1); layer1.HtmModules.Add("encoder", encoder); layer1.HtmModules.Add("sp", sp1); HtmClassifier <double, ComputeCycle> cls = new HtmClassifier <double, ComputeCycle>(); double[] inputs = inputValues.ToArray(); Dictionary <double, int[]> prevActiveCols = new Dictionary <double, int[]>(); Dictionary <double, double> prevSimilarity = new Dictionary <double, double>(); foreach (var input in inputs) { prevSimilarity.Add(input, 0.0); prevActiveCols.Add(input, new int[0]); } int maxSPLearningCycles = 5000; List <(double Element, (int Cycle, double Similarity)[] Oscilations)> oscilationResult = new List <(double Element, (int Cycle, double Similarity)[] Oscilations)>();
// [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.ReadCsvIntegers(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.ReadCsvIntegers(inputBinaryImageFile).ToArray(); int[] inputVectorShifted = NeoCortexUtils.ReadCsvIntegers(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())); } } } } } }
private void RunExperiment(int inputBits, HtmConfig cfgL4, EncoderBase encoder, List <double> inputValues, HtmConfig cfgL2) { Stopwatch swL2 = new Stopwatch(); int maxMatchCnt = 0; bool learn = true; bool isSP4Stable = false; bool isSP2STable = false; Connections memL4 = new Connections(cfgL4); Connections memL2 = new Connections(cfgL2); int numInputs = inputValues.Distinct <double>().ToList().Count; HtmClassifier <string, ComputeCycle> cls = new HtmClassifier <string, ComputeCycle>(); layerL4 = new CortexLayer <object, object>("L4"); layerL2 = new CortexLayer <object, object>("L2"); //tm4 = new TemporalMemoryMT(); //tm2 = new TemporalMemoryMT(); tm4 = new TemporalMemory(); tm2 = new TemporalMemory(); // // HPC for Layer 4 SP HomeostaticPlasticityController hpa_sp_L4 = new HomeostaticPlasticityController(memL4, numInputs * 50, (isStable, numPatterns, actColAvg, seenInputs) => { if (isStable) { Debug.WriteLine($"SP L4 STABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); } else { Debug.WriteLine($"SP L4 INSTABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); } learn = isSP4Stable = isStable; cls.ClearState(); }, numOfCyclesToWaitOnChange: 50); // // HPC for Layer 2 SP HomeostaticPlasticityController hpa_sp_L2 = new HomeostaticPlasticityController(memL2, numInputs * 50, (isStable, numPatterns, actColAvg, seenInputs) => { if (isStable) { Debug.WriteLine($"SP L2 STABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); } else { Debug.WriteLine($"SP L2 INSTABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); } learn = isSP2STable = isStable; cls.ClearState(); }, numOfCyclesToWaitOnChange: 50); SpatialPooler sp4 = new SpatialPooler(hpa_sp_L4); SpatialPooler sp2 = new SpatialPooler(hpa_sp_L2); sp4.Init(memL4); sp2.Init(memL2); // memL2.TraceInputPotential(); tm4.Init(memL4); tm2.Init(memL2); layerL4.HtmModules.Add("encoder", encoder); layerL4.HtmModules.Add("sp", sp4); layerL4.HtmModules.Add("tm", tm4); layerL2.HtmModules.Add("sp", sp2); layerL2.HtmModules.Add("tm", tm2); int[] inpCellsL4ToL2 = new int[cfgL4.CellsPerColumn * cfgL4.NumColumns]; double[] inputs = inputValues.ToArray(); int[] prevActiveCols = new int[0]; int cycle = 0; int matches = 0; string lastPredictedValue = "0"; int maxCycles = 3500; int maxPrevInputs = inputValues.Count - 1; List <string> previousInputs = new List <string>(); // // Training SP at Layer 4 to get stable. New-born stage. // using (StreamWriter swL4Sdrs = new StreamWriter($"L4-SDRs-in_{cfgL2.NumInputs}-col_{cfgL2.NumColumns}-r_{cfgL2.PotentialRadius}.txt")) { using (StreamWriter sw = new StreamWriter($"in_{cfgL2.NumInputs}-col_{cfgL2.NumColumns}-r_{cfgL2.PotentialRadius}.txt")) { for (int i = 0; i < maxCycles; i++) { matches = 0; cycle = i; Debug.WriteLine($"-------------- Newborn Cycle {cycle} at L4 SP region ---------------"); foreach (double input in inputs) { Debug.WriteLine($" INPUT: '{input}'\t Cycle:{cycle}"); Debug.Write("L4: "); object lyrOut = layerL4.Compute(input, learn); int[] activeColumns = layerL4.GetResult("sp") as int[]; int[] cellSdrL4Indexes = memL4.ActiveCells.Select(c => c.Index).ToArray(); Debug.WriteLine($"L4out Active Coloumn for input: {input}: {Helpers.StringifyVector(activeColumns)}"); Debug.WriteLine($"L4out SDR for input: {input}: {Helpers.StringifyVector(cellSdrL4Indexes)}"); if (isSP4Stable) { /// <summary> /// Checking Layer4 SP is giving similar or different /// Active Cell Sdr Indexes After it reaches to stable state. /// This portion is actuallly to hold all acive cell sdr /// indexes after Layer 4 SP reaches at stable state via HPC. /// /// But why we have done this? /// /// Actually, In Necortex api we have obeserved during severel /// experiments that whenvever Layer4 SP reaches to STABLE sate /// it doesnt give us smilar pattern of Active Cell SDR Indexes /// for each particular input data. /// /// Instead active cell sdr patern of L4 varried though it has reached /// to stable sate! /// /// So we want to obeserve whether Layer 4 SP is giving similar active cell sdr indexes /// or different acrive cell sdr indexes after it reaches to stable state. /// /// If we receive similar acrive cell sdr indexes from Layer 4 sp after it reaches /// to stable state then do train Layer 2 sp by as usual process in NeocortexApi by /// calling Layer4.Compute(). /// /// But if we receive different active cell sdr indexes then we will train Layer 2 sp /// from L4_ActiveCell_sdr_log so that during training /// Layer 2 SP gets similar stable active cell sdr indexes of layer4 /// from that dictionary. As a result, L2 SP will get similar sequence /// of active cell sdr indexes during SP Tarining and reach to STABLE state /// </summary> Array.Sort(cellSdrL4Indexes); if (!L4_ActiveCell_sdr_log.ContainsKey(input)) { L4_ActiveCell_sdr_log.Add(input, cellSdrL4Indexes); } else { if (L4_ActiveCell_sdr_log[input].SequenceEqual(cellSdrL4Indexes)) { Debug.WriteLine($"Layer4.Compute() is giving similar cell sdr indexes for input : {input} after reaching to stable state"); isSimilar_L4_active_cell_sdr = true; } else { isSimilar_L4_active_cell_sdr = false; Debug.WriteLine($"Layer4.Compute() is giving different cell sdr indexes for input : {input} after reaching to stable state"); Debug.WriteLine($"Sdr Mismatch with L4_ActiveCell_sdr_log after reaching to stable state"); Debug.WriteLine($" L4_ActiveCell_sdr_log output for input {input}: { Helpers.StringifyVector(L4_ActiveCell_sdr_log[input])}"); Debug.WriteLine($"L4 out sdr input:{input} {Helpers.StringifyVector(cellSdrL4Indexes)}"); //Debug.WriteLine($"L4 out ac input: {input}: {Helpers.StringifyVector(activeColumns)}"); } } if (!isSimilar_L4_active_cell_sdr) { cellSdrL4Indexes = L4_ActiveCell_sdr_log[input]; } // // Training SP at Layer 2 to get stable. New-born stage. // // Write SDR as output of L4 and input of L2 // swL4Sdrs.WriteLine($"{input} - {Helpers.StringifyVector(cellSdrL4Indexes)}"); // Set the output active cell array InitArray(inpCellsL4ToL2, 0); ArrayUtils.SetIndexesTo(inpCellsL4ToL2, cellSdrL4Indexes, 1); Debug.WriteLine($"L4 cell sdr to L2 SP Train for Input {input}: "); layerL2.Compute(inpCellsL4ToL2, true); int[] overlaps = ArrayUtils.IndexWhere(memL2.Overlaps, o => o > 0); string strOverlaps = Helpers.StringifyVector(overlaps); Debug.WriteLine($"Potential columns: {overlaps.Length}, overlaps: {strOverlaps}"); } } if (isSP4Stable && isSP2STable) { break; } } } } // // SP+TM at L2 for (int i = 0; i < maxCycles; i++) { matches = 0; cycle = i; Debug.WriteLine($"-------------- L2 TM Train region Cycle {cycle} ---------------"); foreach (double input in inputs) { Debug.WriteLine($"-------------- {input} ---------------"); // Reset tha array //var cellSdrL4Indexes = L4_ActiveCell_sdr_log[input]; object layerL4Out = layerL4.Compute(input, learn); previousInputs.Add(input.ToString()); if (previousInputs.Count > (maxPrevInputs + 1)) { previousInputs.RemoveAt(0); } if (previousInputs.Count < maxPrevInputs) { continue; } key = GetKey(previousInputs, input); List <Cell> actCells; InitArray(inpCellsL4ToL2, 0); int[] cellSdrL4Indexes; if (!isSimilar_L4_active_cell_sdr) { cellSdrL4Indexes = L4_ActiveCell_sdr_log[input]; } else { cellSdrL4Indexes = memL4.ActiveCells.Select(c => c.Index).ToArray(); } // Set the output active cell array ArrayUtils.SetIndexesTo(inpCellsL4ToL2, cellSdrL4Indexes, 1); ComputeCycle layerL2Out = layerL2.Compute(inpCellsL4ToL2, true) as ComputeCycle; if (layerL2Out.ActiveCells.Count == layerL2Out.WinnerCells.Count) { actCells = layerL2Out.ActiveCells; } else { actCells = layerL2Out.WinnerCells; } /// <summary> /// HTM Classifier has added for Layer 2 /// </summary> cls.Learn(key, actCells.ToArray()); if (key == lastPredictedValue) { matches++; Debug.WriteLine($"Match. Actual Sequence: {key} - Last Predicted Sequence: {lastPredictedValue}"); } else { Debug.WriteLine($"Missmatch! Actual Sequence: {key} - Last Predicted Sequence: {lastPredictedValue}"); } /// <summary> /// Classifier is taking Predictive Cells from Layer 2 /// </summary> if (layerL2Out.PredictiveCells.Count > 0) { string predictedInputValue = cls.GetPredictedInputValue(layerL2Out.PredictiveCells.ToArray()); Debug.WriteLine($"Current Input: {input} \t| New Predicted Input Sequence: {predictedInputValue}"); lastPredictedValue = predictedInputValue; } else { Debug.WriteLine($"NO CELLS PREDICTED for next cycle."); lastPredictedValue = String.Empty; } } double accuracy = (double)matches / (double)inputs.Length * 100.0; Debug.WriteLine($"Cycle: {cycle}\tMatches={matches} of {inputs.Length}\t {accuracy}%"); if (accuracy >= 100.0) { maxMatchCnt++; Debug.WriteLine($"100% accuracy reched {maxMatchCnt} times."); // // Experiment is completed if we are 20 cycles long at the 100% accuracy. if (maxMatchCnt >= 20) { Debug.WriteLine($"Exit experiment in the stable state after 20 repeats with 100% of accuracy."); learn = false; break; } } else if (maxMatchCnt > 0) { Debug.WriteLine($"At 100% accuracy after {maxMatchCnt} repeats we get a drop of accuracy with {accuracy}. This indicates instable state. Learning will be continued."); } } }
/// <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); } } } }
public void SchemaImageClassificationTest() { var imagesFolder = "..\\..\\..\\TestFiles\\SchemaImageClassification\\image"; var csvPath = "..\\..\\..\\TestFiles\\SchemaImageClassification\\csv"; string[] files = Directory.GetFiles(imagesFolder, "*", SearchOption.AllDirectories); string path, name; (path, name) = GetPathAndName(files[0]); int activeColumn = 60; int inputDimension = 32; string[] imageNames = new string[files.Length]; SpatialPooler sp = new SpatialPooler(); Connections mem = new Connections(); Parameters config = GetParam(inputDimension, activeColumn); config.apply(mem); sp.Init(mem); List <int[]> activeArray = new List <int[]>();// to store n active sequences for n images // For each image in this directory for (int i = 0; i < files.Length; i++) { // TODO: activeArray: is a buffer to store active column sequence from spatial pooler activeArray.Add(new int[activeColumn * activeColumn]); (path, name) = GetPathAndName(files[i]); imageNames[i] = name; string binaryImagePath = BinarizeImage(path, inputDimension, inputDimension, csvPath, name); int[] inputVector = ReadCsvFileTest(binaryImagePath).ToArray(); // 1D binary of a image List <int[]> tempArr = new List <int[]>(); tempArr.Add(new int[activeColumn * activeColumn]); tempArr.Add(new int[activeColumn * activeColumn]); int iter = -1; int id = 0; while (true) // Train spatial pooler with a single image until stable active column sequence is achieve { id = (++iter & 1) == 0 ? 0 : 1; for (int i_x = 0; i_x < tempArr[id].Length; i_x++) { tempArr[id][i_x] = 0; } sp.compute(inputVector, tempArr[id], true); if (iter == 1) { continue; } var d = GetHammingDistance(tempArr[id], tempArr[id ^ 1], false); if (d != double.NegativeInfinity) { Console.WriteLine(d); } /*Note: GetHamming distance will return a distance between 0 and 100. * if two sequences are the same the return value will be 100. Therefore, the similarity is (100==distance). * To give a four digit precision, < is used instead of ==. */ if ((100.0 - d) < 0.00001) { for (int i_x = 0; i_x < tempArr[id].Length; i_x++) { activeArray[i][i_x] = tempArr[id][i_x]; } break; } } Console.WriteLine("finished image : " + i); } int[] parent = new int[files.Length]; bool[] hasFolder = new bool[files.Length]; List <double[]> distance = new List <double[]>(); for (int k = 0; k < files.Length; k++) { distance.Add(new double[files.Length]); for (int kk = 0; kk < files.Length; kk++) { distance[k].Append(0); } } for (int k = 0; k < files.Length; k++) { parent[k] = k; hasFolder[k] = false; } for (int i = 0; i < activeArray.Count; i++) { for (int j = i; j < activeArray.Count; j++) { double d = Math.Min(GetHammingDistance(activeArray[i], activeArray[j], true), GetHammingDistance(activeArray[j], activeArray[i], true)); //double d = GetHammingDistance(activeArray[i], activeArray[j], false); distance[i][j] = d; distance[j][i] = d; } } SaveOutput(activeArray, path, imageNames); Groupping(distance, imageNames, path); Report(distance, imageNames); }
/// <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> /// 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 <double> 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; } }); // It creates the instance of Spatial Pooler Multithreaded version. SpatialPooler sp = new SpatialPooler(hpa); // Initializes the sp.Init(mem, new DistributedMemory() { ColumnDictionary = new InMemoryDistributedDictionary <int, NeoCortexApi.Entities.Column>(1) }); // mem.TraceProximalDendritePotential(true); // It creates the instance of the neo-cortex layer. // Algorithm will be performed inside of that layer. CortexLayer <object, object> cortexLayer = new CortexLayer <object, object>("L1"); // Add encoder as the very first module. This model is connected to the sensory input cells // that receive the input. Encoder will receive the input and forward the encoded signal // to the next module. cortexLayer.HtmModules.Add("encoder", encoder); // The next module in the layer is Spatial Pooler. This module will receive the output of the // encoder. cortexLayer.HtmModules.Add("sp", sp); double[] inputs = inputValues.ToArray(); // Will hold the SDR of every inputs. Dictionary <double, int[]> prevActiveCols = new Dictionary <double, int[]>(); // Will hold the similarity of SDKk and SDRk-1 fro every input. Dictionary <double, double> prevSimilarity = new Dictionary <double, double>(); // // Initiaize start similarity to zero. foreach (var input in inputs) { prevSimilarity.Add(input, 0.0); prevActiveCols.Add(input, 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. foreach (var input in inputs) { double similarity; // Learn the input pattern. // Output lyrOut is the output of the last module in the layer. // var lyrOut = cortexLayer.Compute((object)input, true) as int[]; // This is a general way to get the SpatialPooler result from the layer. var activeColumns = cortexLayer.GetResult("sp") as int[]; var actCols = activeColumns.OrderBy(c => c).ToArray(); similarity = MathHelpers.CalcArraySimilarity(activeColumns, prevActiveCols[input]); Debug.WriteLine($"[cycle={cycle.ToString("D4")}, i={input}, cols=:{actCols.Length} s={similarity}] SDR: {Helpers.StringifyVector(actCols)}"); prevActiveCols[input] = activeColumns; prevSimilarity[input] = similarity; } } }
//[TestMethod, DeploymentItem("Resources/DataSets/OCR/characters/cmr_all.xml")] public void TestVisionBench() { // Set some training paths string trainingDataset = "cmr_all.xml"; string testingDataset = "Resources/DataSets/OCR/characters/cmr_all.xml"; double minAccuracy = 100.0; // force max training cycles int maxTrainingCycles = 5; // Create spatial parameters Parameters p = Parameters.Empty(); p.SetParameterByKey(Parameters.KEY.INPUT_DIMENSIONS, new[] { 32, 32 }); // Size of image patch p.SetParameterByKey(Parameters.KEY.COLUMN_DIMENSIONS, new[] { 32, 32 }); p.SetParameterByKey(Parameters.KEY.POTENTIAL_RADIUS, 10000); // Ensures 100% potential pool p.SetParameterByKey(Parameters.KEY.POTENTIAL_PCT, 0.8); p.SetParameterByKey(Parameters.KEY.GLOBAL_INHIBITION, true); p.SetParameterByKey(Parameters.KEY.LOCAL_AREA_DENSITY, -1.0); // Using numActiveColumnsPerInhArea p.SetParameterByKey(Parameters.KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 64.0); // All input activity can contribute to feature output p.SetParameterByKey(Parameters.KEY.STIMULUS_THRESHOLD, 0.0); p.SetParameterByKey(Parameters.KEY.SYN_PERM_INACTIVE_DEC, 0.001); p.SetParameterByKey(Parameters.KEY.SYN_PERM_ACTIVE_INC, 0.001); p.SetParameterByKey(Parameters.KEY.SYN_PERM_CONNECTED, 0.3); p.SetParameterByKey(Parameters.KEY.MIN_PCT_OVERLAP_DUTY_CYCLES, 0.001); p.SetParameterByKey(Parameters.KEY.MIN_PCT_ACTIVE_DUTY_CYCLES, 0.001); p.SetParameterByKey(Parameters.KEY.DUTY_CYCLE_PERIOD, 1000); p.SetParameterByKey(Parameters.KEY.MAX_BOOST, 1.0); p.SetParameterByKey(Parameters.KEY.SEED, 1956); // The seed that Grok uses p.SetParameterByKey(Parameters.KEY.RANDOM, new XorshiftRandom(1956)); // The seed that Grok uses p.SetParameterByKey(Parameters.KEY.SP_VERBOSITY, 1); p.SetParameterByKey(Parameters.KEY.SP_PARALLELMODE, true); Connections cn = new Connections(); p.Apply(cn); // Instantiate our spatial pooler SpatialPooler sp = new SpatialPooler(); sp.Init(cn); // Instantiate the spatial pooler test bench. VisionTestBench tb = new VisionTestBench(cn, sp); // Instantiate the classifier KNNClassifier clf = KNNClassifier.GetBuilder().Apply(p); // Get testing images and convert them to vectors. var tupleTraining = DatasetReader.GetImagesAndTags(trainingDataset); var trainingImages = (List <Bitmap>)tupleTraining.Get(0); var trainingTags = tupleTraining.Get(1) as List <string>; var trainingVectors = trainingImages.Select((i, index) => new { index, vector = i.ToVector() }) .ToDictionary(k => k.index, v => v.vector); // Train the spatial pooler on trainingVectors. int numcycles = tb.Train(trainingVectors, trainingTags, clf, maxTrainingCycles, minAccuracy); // Get testing images and convert them to vectors. var tupleTesting = DatasetReader.GetImagesAndTags(trainingDataset); var testingImages = (List <System.Drawing.Bitmap>)tupleTesting.Get(0); var testingTags = tupleTesting.Get(1) as List <string>; var testingVectors = testingImages.Select((i, index) => new { index, vector = i.ToVector() }) .ToDictionary(k => k.index, v => v.vector); // Reverse the order of the vectors and tags for testing testingTags.Reverse(); testingVectors.Reverse(); // Test the spatial pooler on testingVectors. var accurancy = tb.Test(testingVectors, testingTags, clf, learn: true); Debug.WriteLine("Number of training cycles : " + numcycles); Debug.WriteLine("Accurancy : " + accurancy); tb.SavePermsAndConns("C:\\temp\\permsAndConns.jpg"); }
//[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.ReadCsvIntegers(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); } } } } } }
public void Execute(string dataSet = TrainingDataSet, double minAccuracy = 100.0, int maxTrainingCycles = 5) { var tupleTraining = DatasetReader.GetImagesAndTags(dataSet); // Get training images and convert them to vectors. var trainingImages = (List <Bitmap>)tupleTraining.Get(0); var trainingTags = tupleTraining.Get(1) as List <string>; var trainingVectors = trainingImages.Select((i, index) => new { index, vector = i.ToVector() }) .ToDictionary(k => k.index, v => v.vector); // Specify parameter values to search CombinationParameters parameters = new CombinationParameters(); parameters.Define("synPermConn", new List <object> { 0.5 }); parameters.Define("synPermDecFrac", new List <object> { 1.0, 0.5, 0.1 }); parameters.Define("synPermIncFrac", new List <object> { 1.0, 0.5, 0.1 }); // Run the model until all combinations have been tried while (parameters.GetNumResults() < parameters.GetNumCombinations()) { // Pick a combination of parameter values parameters.NextCombination(); double synPermConnected = (double)parameters.GetValue("synPermConn"); var synPermDec = synPermConnected * (double)parameters.GetValue("synPermDecFrac"); var synPermInc = synPermConnected * (double)parameters.GetValue("synPermIncFrac"); // Instantiate our spatial pooler Parameters p = Parameters.GetAllDefaultParameters(); p.SetParameterByKey(Parameters.KEY.INPUT_DIMENSIONS, new[] { 32, 32 }); // Size of image patch p.SetParameterByKey(Parameters.KEY.COLUMN_DIMENSIONS, new[] { 32, 32 }); p.SetParameterByKey(Parameters.KEY.POTENTIAL_RADIUS, 10000); // Ensures 100% potential pool p.SetParameterByKey(Parameters.KEY.POTENTIAL_PCT, 0.8); p.SetParameterByKey(Parameters.KEY.GLOBAL_INHIBITION, true); p.SetParameterByKey(Parameters.KEY.LOCAL_AREA_DENSITY, -1.0); // Using numActiveColumnsPerInhArea p.SetParameterByKey(Parameters.KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 64.0); // All input activity can contribute to feature output p.SetParameterByKey(Parameters.KEY.STIMULUS_THRESHOLD, 0.0); p.SetParameterByKey(Parameters.KEY.SYN_PERM_INACTIVE_DEC, synPermDec); p.SetParameterByKey(Parameters.KEY.SYN_PERM_ACTIVE_INC, synPermInc); p.SetParameterByKey(Parameters.KEY.SYN_PERM_CONNECTED, synPermConnected); p.SetParameterByKey(Parameters.KEY.DUTY_CYCLE_PERIOD, 1000); p.SetParameterByKey(Parameters.KEY.MAX_BOOST, 1.0); p.SetParameterByKey(Parameters.KEY.SEED, 1956); // The seed that Grok uses p.SetParameterByKey(Parameters.KEY.RANDOM, new XorshiftRandom(1956)); // The seed that Grok uses p.SetParameterByKey(Parameters.KEY.SP_VERBOSITY, 1); Connections cn = new Connections(); p.Apply(cn); SpatialPooler sp = new SpatialPooler(); sp.Init(cn); // Instantiate the spatial pooler test bench. VisionTestBench tb = new VisionTestBench(cn, sp); // Instantiate the classifier KNNClassifier clf = KNNClassifier.GetBuilder().Apply(p); int numCycles = tb.Train(trainingVectors, trainingTags, clf, maxTrainingCycles, minAccuracy); // Get testing images and convert them to vectors. var tupleTesting = DatasetReader.GetImagesAndTags(dataSet); var testingImages = (List <System.Drawing.Bitmap>)tupleTesting.Get(0); var testingTags = tupleTesting.Get(1) as List <string>; var testingVectors = testingImages.Select((i, index) => new { index, vector = i.ToVector() }) .ToDictionary(k => k.index, v => v.vector); // Reverse the order of the vectors and tags for testing testingTags.Reverse(); testingVectors.Reverse(); // Test the spatial pooler on testingVectors. var accurancy = tb.Test(testingVectors, testingTags, clf, learn: true); // Add results to the list parameters.AppendResults(new List <object> { accurancy, numCycles }); } parameters.PrintResults(new[] { "Percent Accuracy", "Training Cycles" }, new[] { "\t{0}", "\t{0}" }); Console.WriteLine("The maximum number of training cycles is set to: {0}", maxTrainingCycles); }
/// <summary> /// /// </summary> private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, List <double> inputValues) { Stopwatch sw = new Stopwatch(); sw.Start(); int maxMatchCnt = 0; bool learn = true; var mem = new Connections(cfg); bool isInStableState = false; HtmClassifier <string, ComputeCycle> cls = new HtmClassifier <string, ComputeCycle>(); var numInputs = inputValues.Distinct <double>().ToList().Count; CortexLayer <object, object> layer1 = new CortexLayer <object, object>("L1"); TemporalMemory tm = new TemporalMemory(); HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(mem, numInputs * 150, (isStable, numPatterns, actColAvg, seenInputs) => { if (isStable) { // Event should be fired when entering the stable state. Debug.WriteLine($"STABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); } else { // Ideal SP should never enter unstable state after stable state. Debug.WriteLine($"INSTABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); } // We are not learning in instable state. learn = isInStableState = isStable; //if (isStable && layer1.HtmModules.ContainsKey("tm") == false) // layer1.HtmModules.Add("tm", tm); // Clear all learned patterns in the classifier. cls.ClearState(); // Clear active and predictive cells. //tm.Reset(mem); }, numOfCyclesToWaitOnChange: 50); SpatialPooler sp = new SpatialPooler(hpa); sp.Init(mem); tm.Init(mem); layer1.HtmModules.Add("encoder", encoder); layer1.HtmModules.Add("sp", sp); double[] inputs = inputValues.ToArray(); int[] prevActiveCols = new int[0]; int cycle = 0; int matches = 0; string lastPredictedValue = "0"; //Dictionary<double, List<List<int>>> activeColumnsLst = new Dictionary<double, List<List<int>>>(); //foreach (var input in inputs) //{ // if (activeColumnsLst.ContainsKey(input) == false) // activeColumnsLst.Add(input, new List<List<int>>()); //} int maxCycles = 3500; int maxPrevInputs = inputValues.Count - 1; List <string> previousInputs = new List <string>(); previousInputs.Add("-1.0"); // // Training SP to get stable. New-born stage. // for (int i = 0; i < maxCycles; i++) { matches = 0; cycle++; Debug.WriteLine($"-------------- Newborn Cycle {cycle} ---------------"); foreach (var input in inputs) { Debug.WriteLine($" -- {input} --"); var lyrOut = layer1.Compute(input, learn); if (isInStableState) { break; } } if (isInStableState) { break; } } layer1.HtmModules.Add("tm", tm); // // Now training with SP+TM. SP is pretrained on the given input pattern set. for (int i = 0; i < maxCycles; i++) { matches = 0; cycle++; Debug.WriteLine($"-------------- Cycle {cycle} ---------------"); foreach (var input in inputs) { Debug.WriteLine($"-------------- {input} ---------------"); var lyrOut = layer1.Compute(input, learn) as ComputeCycle; // lyrOut is null when the TM is added to the layer inside of HPC callback by entering of the stable state. //if (isInStableState && lyrOut != null) { var activeColumns = layer1.GetResult("sp") as int[]; //layer2.Compute(lyrOut.WinnerCells, true); //activeColumnsLst[input].Add(activeColumns.ToList()); previousInputs.Add(input.ToString()); if (previousInputs.Count > (maxPrevInputs + 1)) { previousInputs.RemoveAt(0); } // In the pretrained SP with HPC, the TM will quickly learn cells for patterns // In that case the starting sequence 4-5-6 might have the sam SDR as 1-2-3-4-5-6, // Which will result in returning of 4-5-6 instead of 1-2-3-4-5-6. // HtmClassifier allways return the first matching sequence. Because 4-5-6 will be as first // memorized, it will match as the first one. if (previousInputs.Count < maxPrevInputs) { continue; } string key = GetKey(previousInputs, input); List <Cell> actCells; if (lyrOut.ActiveCells.Count == lyrOut.WinnerCells.Count) { actCells = lyrOut.ActiveCells; } else { actCells = lyrOut.WinnerCells; } cls.Learn(key, actCells.ToArray()); if (learn == false) { Debug.WriteLine($"Inference mode"); } Debug.WriteLine($"Col SDR: {Helpers.StringifyVector(lyrOut.ActivColumnIndicies)}"); Debug.WriteLine($"Cell SDR: {Helpers.StringifyVector(actCells.Select(c => c.Index).ToArray())}"); if (key == lastPredictedValue) { matches++; Debug.WriteLine($"Match. Actual value: {key} - Predicted value: {lastPredictedValue}"); } else { Debug.WriteLine($"Missmatch! Actual value: {key} - Predicted value: {lastPredictedValue}"); } if (lyrOut.PredictiveCells.Count > 0) { //var predictedInputValue = cls.GetPredictedInputValue(lyrOut.PredictiveCells.ToArray()); var predictedInputValues = cls.GetPredictedInputValues(lyrOut.PredictiveCells.ToArray(), 3); foreach (var item in predictedInputValues) { Debug.WriteLine($"Current Input: {input} \t| Predicted Input: {item}"); } lastPredictedValue = predictedInputValues.First().PredictedInput; } else { Debug.WriteLine($"NO CELLS PREDICTED for next cycle."); lastPredictedValue = String.Empty; } } } // The brain does not do that this way, so we don't use it. // tm1.reset(mem); double accuracy = (double)matches / (double)inputs.Length * 100.0; Debug.WriteLine($"Cycle: {cycle}\tMatches={matches} of {inputs.Length}\t {accuracy}%"); if (accuracy == 100.0) { maxMatchCnt++; Debug.WriteLine($"100% accuracy reched {maxMatchCnt} times."); // // Experiment is completed if we are 30 cycles long at the 100% accuracy. if (maxMatchCnt >= 30) { sw.Stop(); Debug.WriteLine($"Exit experiment in the stable state after 30 repeats with 100% of accuracy. Elapsed time: {sw.ElapsedMilliseconds / 1000 / 60} min."); learn = false; break; } } else if (maxMatchCnt > 0) { Debug.WriteLine($"At 100% accuracy after {maxMatchCnt} repeats we get a drop of accuracy with {accuracy}. This indicates instable state. Learning will be continued."); maxMatchCnt = 0; } } Debug.WriteLine("------------ END ------------"); }