public void TestColumnSerialize() { //Thread.Sleep(5000); //Pool pool = new Pool(10, 10); Cell cell = new Cell(); DistalDendrite dist = new DistalDendrite(cell, 0, 0, 0, 0.5, 10); dist.Synapses.Add(new Synapse(cell, null, 0, 0.5)); Synapse syn = new Synapse(cell, dist, 0, 0); var dict = UnitTestHelpers.GetMemory(); Column col = new Column(10, 0, 0.01, 10); col.ProximalDendrite = new ProximalDendrite(0, 0.01, 10); col.ProximalDendrite.Synapses = new List <Synapse>(); col.ProximalDendrite.Synapses.Add(syn); dict.ColumnDictionary.Add(0, col); var serCol = AkkaSb.Net.ActorReference.SerializeMsg(col); Assert.IsTrue(dict.ColumnDictionary[0].ProximalDendrite.Synapses[0].Segment != null); }
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)>();
internal static void InitPooler(PoolerMode poolerMode, SpatialPooler sp, Connections mem, Parameters parameters = null) { if (poolerMode == PoolerMode.Multinode) { sp.init(mem, UnitTestHelpers.GetMemory(mem.HtmConfig)); } else if (poolerMode == PoolerMode.Multicore) { sp.init(mem, UnitTestHelpers.GetMemory()); } else { sp.init(mem); } }
/// <summary> /// /// </summary> private void RunExperiment(int inputBits, Parameters p, EncoderBase encoder, List <double> inputValues) { Stopwatch sw = new Stopwatch(); sw.Start(); //INeuroVisualizer vis = new WSNeuroVisualizer(); //vis.InitModelAsync(new NeuroModel(null, (new long [10, 0]), 6)); int maxMatchCnt = 0; bool learn = true; //INeuroVisualizer vis = new WSNeuroVisualizer(); //GenerateNeuroModel model = new GenerateNeuroModel(); //vis.InitModel(model.CreateNeuroModel(new int[] { 1}, (long[,])p[KEY.COLUMN_DIMENSIONS], (int)p[KEY.CELLS_PER_COLUMN])); CortexNetwork net = new CortexNetwork("my cortex"); List <CortexRegion> regions = new List <CortexRegion>(); CortexRegion region0 = new CortexRegion("1st Region"); regions.Add(region0); SpatialPoolerMT sp1 = new SpatialPoolerMT(); TemporalMemory tm1 = new TemporalMemory(); var mem = new Connections(); p.apply(mem); sp1.init(mem, UnitTestHelpers.GetMemory()); tm1.init(mem); 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 = 5; List <(double Element, (int Cycle, double Similarity)[] Oscilations)> oscilationResult = new List <(double Element, (int Cycle, double Similarity)[] Oscilations)>();
/// <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 SPInitTest(PoolerMode poolerMode) { //Thread.Sleep(2000); int numOfColsInDim = 12; int numInputs = 128; Parameters parameters = Parameters.getAllDefaultParameters(); parameters.Set(KEY.POTENTIAL_RADIUS, 5); parameters.Set(KEY.POTENTIAL_PCT, 0.5); parameters.Set(KEY.GLOBAL_INHIBITION, false); parameters.Set(KEY.LOCAL_AREA_DENSITY, -1.0); parameters.Set(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 3.0); parameters.Set(KEY.STIMULUS_THRESHOLD, 0.0); parameters.Set(KEY.SYN_PERM_INACTIVE_DEC, 0.01); parameters.Set(KEY.SYN_PERM_ACTIVE_INC, 0.1); parameters.Set(KEY.SYN_PERM_CONNECTED, 0.1); parameters.Set(KEY.MIN_PCT_OVERLAP_DUTY_CYCLES, 0.1); parameters.Set(KEY.MIN_PCT_ACTIVE_DUTY_CYCLES, 0.1); parameters.Set(KEY.DUTY_CYCLE_PERIOD, 10); parameters.Set(KEY.MAX_BOOST, 10.0); parameters.Set(KEY.RANDOM, new ThreadSafeRandom(42)); parameters.Set(KEY.INPUT_DIMENSIONS, new int[] { numInputs, numInputs }); parameters.Set(KEY.COLUMN_DIMENSIONS, new int[] { numOfColsInDim, numOfColsInDim }); parameters.setPotentialRadius(5); //This is 0.3 in Python version due to use of dense // permanence instead of sparse (as it should be) parameters.setPotentialPct(0.5); parameters.setGlobalInhibition(false); parameters.setLocalAreaDensity(-1.0); parameters.setNumActiveColumnsPerInhArea(3); parameters.setStimulusThreshold(1); parameters.setSynPermInactiveDec(0.01); parameters.setSynPermActiveInc(0.1); parameters.setMinPctOverlapDutyCycles(0.1); parameters.setMinPctActiveDutyCycles(0.1); parameters.setDutyCyclePeriod(10); parameters.setMaxBoost(10); parameters.setSynPermTrimThreshold(0); //This is 0.5 in Python version due to use of dense // permanence instead of sparse (as it should be) parameters.setPotentialPct(1); parameters.setSynPermConnected(0.1); //SpatialPooler sp = UnitTestHelpers.CreatePooler(poolerMode) ; var sp = new SpatialPoolerParallel(); var mem = new Connections(); parameters.apply(mem); sp.Init(mem, UnitTestHelpers.GetMemory(mem.HtmConfig)); //sp.init(mem); //int[] inputVector = new int[] { 1, 0, 1, 0, 1, 0, 0, 1, 1 }; //int[] activeArray = new int[] { 0, 0, 0, 0, 0 }; //for (int i = 0; i < 20; i++) //{ // sp.compute(mem, inputVector, activeArray, true); //} }
public void RunPowerPredictionExperiment() { const int inputBits = 300; /* without datetime component */ // 13420; /* with 4096 scalar bits */ // 10404 /* with 1024 bits */; Parameters p = Parameters.getAllDefaultParameters(); p.Set(KEY.RANDOM, new ThreadSafeRandom(42)); p.Set(KEY.COLUMN_DIMENSIONS, new int[] { 2048 }); p.Set(KEY.INPUT_DIMENSIONS, new int[] { inputBits }); p.Set(KEY.CELLS_PER_COLUMN, 10 /* 50 */); p.Set(KEY.GLOBAL_INHIBITION, true); p.Set(KEY.CONNECTED_PERMANENCE, 0.1); // N of 40 (40= 0.02*2048 columns) active cells required to activate the segment. p.setNumActiveColumnsPerInhArea(0.02 * 2048); // Activation threshold is 10 active cells of 40 cells in inhibition area. p.setActivationThreshold(10 /*15*/); p.setInhibitionRadius(15); p.Set(KEY.MAX_BOOST, 0.0); p.Set(KEY.DUTY_CYCLE_PERIOD, 100000); p.setActivationThreshold(10); p.setMaxNewSynapsesPerSegmentCount((int)(0.02 * 2048)); p.setPermanenceIncrement(0.17); //p.Set(KEY.MAX_SYNAPSES_PER_SEGMENT, 32); //p.Set(KEY.MAX_SEGMENTS_PER_CELL, 128); //p.Set(KEY.MAX_NEW_SYNAPSE_COUNT, 200); //p.Set(KEY.POTENTIAL_RADIUS, 700); //p.Set(KEY.POTENTIAL_PCT, 0.5); //p.Set(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 42); //p.Set(KEY.LOCAL_AREA_DENSITY, -1); CortexRegion region0 = new CortexRegion("1st Region"); SpatialPoolerMT sp1 = new SpatialPoolerMT(); TemporalMemory tm1 = new TemporalMemory(); var mem = new Connections(); p.apply(mem); sp1.Init(mem, UnitTestHelpers.GetMemory()); tm1.Init(mem); Dictionary <string, object> settings = new Dictionary <string, object>(); CortexLayer <object, object> layer1 = new CortexLayer <object, object>("L1"); region0.AddLayer(layer1); layer1.HtmModules.Add("sp", sp1); HtmClassifier <double, ComputeCycle> cls = new HtmClassifier <double, ComputeCycle>(); Stopwatch sw = new Stopwatch(); sw.Start(); Train(inputBits, layer1, cls, true); // New born mode. sw.Stop(); Debug.WriteLine($"NewBorn stage duration: {sw.ElapsedMilliseconds / 1000} s"); layer1.AddModule("tm", tm1); sw.Start(); int hunderdAccCnt = 0; for (int i = 0; i < 1000; i++) { float acc = Train(inputBits, layer1, cls, false); Debug.WriteLine($"Accuracy = {acc}, Cycle = {i}"); if (acc == 100.0) { hunderdAccCnt++; } if (hunderdAccCnt >= 10) { break; } //tm1.reset(mem); } if (hunderdAccCnt >= 10) { Debug.WriteLine($"EXPERIMENT SUCCESS. Accurracy 100% reached."); } else { Debug.WriteLine($"Experiment FAILED!. Accurracy 100% was not reached."); } cls.TraceState(); sw.Stop(); Debug.WriteLine($"Training duration: {sw.ElapsedMilliseconds / 1000} s"); }
[DataRow(5, 100, 2500, 30)] // Cells=5, InputBits(N)=200, MiniColumns=2500 iter=30 public void ComplexSequence(int C, int N, int CD, int loop) { string filename = "Complex" + C + N + CD + ".csv"; using (StreamWriter writer = new StreamWriter(filename)) { Debug.WriteLine($"Learning Cycles: {400}"); Debug.WriteLine("Cycle;Similarity"); // Parent Loop //This loop defines the number of times the experiment will run for the given data for (int j = 0; j < loop; j++) { int inputBits = N; bool learn = true; Parameters p = Parameters.getAllDefaultParameters(); p.Set(KEY.RANDOM, new ThreadSafeRandom(42)); p.Set(KEY.INPUT_DIMENSIONS, new int[] { inputBits }); p.Set(KEY.COLUMN_DIMENSIONS, new int[] { CD }); p.Set(KEY.CELLS_PER_COLUMN, C); CortexNetwork net = new CortexNetwork("my cortex"); List <CortexRegion> regions = new List <CortexRegion>(); CortexRegion region0 = new CortexRegion("1st Region"); regions.Add(region0); SpatialPoolerMT sp1 = new SpatialPoolerMT(); TemporalMemory tm1 = new TemporalMemory(); var mem = new Connections(); p.apply(mem); sp1.Init(mem, UnitTestHelpers.GetMemory()); tm1.Init(mem); Dictionary <string, object> settings = new Dictionary <string, object>() { { "W", 15 }, { "N", inputBits }, { "Radius", -1.0 }, { "MinVal", 0.0 }, // { "MaxVal", 20.0 }, { "Periodic", false }, { "Name", "scalar" }, { "ClipInput", false }, }; double max = 10; List <double> lst = new List <double>() { 9, 8, 7, 6, 9, 8, 7, 5 }; settings["MaxVal"] = max; EncoderBase encoder = new ScalarEncoder(settings); 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 = lst.ToArray(); // // This trains SP. foreach (var input in inputs) { Debug.WriteLine($" ** {input} **"); for (int i = 0; i < 3; i++) { var lyrOut = layer1.Compute((object)input, learn) as ComputeCycle; } } // Here we add TM module to the layer. layer1.HtmModules.Add("tm", tm1); int cycle = 0; int matches = 0; double lastPredictedValue = 0; // // Now, training with SP+TM. SP is pretrained on pattern. //Child loop / Inner loop for (int i = 0; i < 400; i++) { matches = 0; cycle++; foreach (var input in inputs) { var lyrOut = layer1.Compute(input, learn) as ComputeCycle; cls.Learn(input, lyrOut.ActiveCells.ToArray()); Debug.WriteLine($"-------------- {input} ---------------"); if (learn == false) { Debug.WriteLine($"Inference mode"); } Debug.WriteLine($"W: {Helpers.StringifyVector(lyrOut.WinnerCells.Select(c => c.Index).ToArray())}"); Debug.WriteLine($"P: {Helpers.StringifyVector(lyrOut.PredictiveCells.Select(c => c.Index).ToArray())}"); var predictedValue = cls.GetPredictedInputValue(lyrOut.PredictiveCells.ToArray()); Debug.WriteLine($"Current Input: {input} \t| - Predicted value in previous cycle: {lastPredictedValue} \t| Predicted Input for the next cycle: {predictedValue}"); if (input == lastPredictedValue) { matches++; Debug.WriteLine($"Match {input}"); } else { Debug.WriteLine($"Missmatch Actual value: {input} - Predicted value: {lastPredictedValue}"); } lastPredictedValue = predictedValue; } if (i == 500) { Debug.WriteLine("Stop Learning From Here. Entering inference mode."); learn = false; } //tm1.reset(mem); Debug.WriteLine($"Cycle: {cycle}\tMatches={matches} of {inputs.Length}\t {(double)matches / (double)inputs.Length * 100.0}%"); if ((double)matches / (double)inputs.Length == 1) { writer.WriteLine($"{cycle}"); break; } } } Debug.WriteLine("New Iteration"); } //cls.TraceState(); Debug.WriteLine("------------------------------------------------------------------------\n----------------------------------------------------------------------------"); }
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)>();
public void InitDistributedTest(bool isMultinode) { Thread.Sleep(5000); for (int test = 0; test < 3; test++) { Stopwatch sw = new Stopwatch(); sw.Start(); int inputBits = 1024; int numOfColumns = 4096; ThreadSafeRandom rnd = new ThreadSafeRandom(42); var parameters = Parameters.getAllDefaultParameters(); parameters.Set(KEY.POTENTIAL_RADIUS, inputBits); 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 * numOfColumns); parameters.Set(KEY.LOCAL_AREA_DENSITY, -1); parameters.Set(KEY.POTENTIAL_RADIUS, inputBits); 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.INHIBITION_RADIUS, (int)0.025 * inputBits); 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, 1956); int[] inputDims = new int[] { (int)Math.Sqrt(inputBits), (int)Math.Sqrt(inputBits) }; parameters.setInputDimensions(inputDims); int[] colDims = new int[] { (int)Math.Sqrt(numOfColumns), (int)Math.Sqrt(numOfColumns) }; parameters.setColumnDimensions(colDims); SpatialPooler sp; if (isMultinode) { sp = new SpatialPoolerParallel(); } else { sp = new SpatialPoolerMT(); } var mem = new Connections(); parameters.apply(mem); if (isMultinode) { sp.init(mem, UnitTestHelpers.GetMemory(mem.HtmConfig)); } else { sp.init(mem, UnitTestHelpers.GetMemory()); } sw.Stop(); Console.Write($"{(float)sw.ElapsedMilliseconds / (float)1000} | "); } }
public void CategorySequenceExperiment() { bool learn = true; Parameters p = Parameters.getAllDefaultParameters(); p.Set(KEY.RANDOM, new ThreadSafeRandom(42)); p.Set(KEY.INPUT_DIMENSIONS, new int[] { 100 }); p.Set(KEY.CELLS_PER_COLUMN, 30); string[] categories = new string[] { "A", "B", "C", "D" }; //string[] categories = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "K", "L" , "M", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Ö" }; CortexNetwork net = new CortexNetwork("my cortex"); List <CortexRegion> regions = new List <CortexRegion>(); CortexRegion region0 = new CortexRegion("1st Region"); regions.Add(region0); SpatialPoolerMT sp1 = new SpatialPoolerMT(); TemporalMemory tm1 = new TemporalMemory(); var mem = new Connections(); p.apply(mem); sp1.Init(mem, UnitTestHelpers.GetMemory()); tm1.Init(mem); Dictionary <string, object> settings = new Dictionary <string, object>(); //settings.Add("W", 25); settings.Add("N", 100); //settings.Add("Radius", 1); EncoderBase encoder = new CategoryEncoder(categories, settings); //encoder.Encode() CortexLayer <object, object> layer1 = new CortexLayer <object, object>("L1"); region0.AddLayer(layer1); layer1.HtmModules.Add("encoder", encoder); layer1.HtmModules.Add("sp", sp1); //layer1.HtmModules.Add(tm1); //layer1.Compute(); //IClassifier<string, ComputeCycle> cls = new HtmClassifier<string, ComputeCycle>(); HtmClassifier <string, ComputeCycle> cls = new HtmClassifier <string, ComputeCycle>(); HtmUnionClassifier <string, ComputeCycle> cls1 = new HtmUnionClassifier <string, ComputeCycle>(); //string[] inputs = new string[] { "A", "B", "C", "D" }; string[] inputs = new string[] { "A", "B", "C", "D" }; // // This trains SP. foreach (var input in inputs) { Debug.WriteLine($" ** {input} **"); for (int i = 0; i < 3; i++) { var lyrOut = layer1.Compute((object)input, learn) as ComputeCycle; } } // Here we add TM module to the layer. layer1.HtmModules.Add("tm", tm1); // // Now, training with SP+TM. SP is pretrained on pattern. for (int i = 0; i < 200; i++) { foreach (var input in inputs) { var lyrOut = layer1.Compute(input, learn) as ComputeCycle; //cls1.Learn(input, lyrOut.activeCells.ToArray(), learn); //Debug.WriteLine($"Current Input: {input}"); cls.Learn(input, lyrOut.ActiveCells.ToArray()); Debug.WriteLine($"Current Input: {input}"); if (learn == false) { Debug.WriteLine($"Predict Input When Not Learn: {cls.GetPredictedInputValue(lyrOut.PredictiveCells.ToArray())}"); } else { Debug.WriteLine($"Predict Input: {cls.GetPredictedInputValue(lyrOut.PredictiveCells.ToArray())}"); } Debug.WriteLine("-----------------------------------------------------------\n----------------------------------------------------------"); } if (i == 10) { Debug.WriteLine("Stop Learning From Here----------------------------"); learn = false; } // tm1.reset(mem); } Debug.WriteLine("------------------------------------------------------------------------\n----------------------------------------------------------------------------"); /* * learn = false; * for (int i = 0; i < 19; i++) * { * foreach (var input in inputs) * { * layer1.Compute((object)input, learn); * } * } */ }
public void SimpleSequenceExperiment() { int inputBits = 50; //int inputBits = 5; bool learn = true; Parameters p = Parameters.getAllDefaultParameters(); p.Set(KEY.RANDOM, new ThreadSafeRandom(42)); p.Set(KEY.INPUT_DIMENSIONS, new int[] { inputBits }); //p.Set(KEY.CELLS_PER_COLUMN, 100); p.Set(KEY.CELLS_PER_COLUMN, 5); p.Set(KEY.COLUMN_DIMENSIONS, new int[] { 500 }); //p.Set(KEY.COLUMN_DIMENSIONS, new int[] { 5 }); //p.setStimulusThreshold(1); //p.setMinThreshold(1); CortexNetwork net = new CortexNetwork("my cortex"); List <CortexRegion> regions = new List <CortexRegion>(); CortexRegion region0 = new CortexRegion("1st Region"); regions.Add(region0); SpatialPoolerMT sp1 = new SpatialPoolerMT(); TemporalMemory tm1 = new TemporalMemory(); var mem = new Connections(); p.apply(mem); sp1.Init(mem, UnitTestHelpers.GetMemory()); tm1.Init(mem); Dictionary <string, object> settings = new Dictionary <string, object>() { { "W", 7 }, //{ "W", 1}, { "N", inputBits }, { "Radius", -1.0 }, { "MinVal", 0.0 }, // { "MaxVal", 20.0 }, { "Periodic", false }, { "Name", "scalar" }, { "ClipInput", false }, }; double max = 10; List <double> lst = new List <double>(); for (double i = max - 1; i >= 0; i--) { lst.Add(i); } settings["MaxVal"] = max; EncoderBase encoder = new ScalarEncoder(settings); 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 = lst.ToArray(); // // This trains SP. foreach (var input in inputs) { Debug.WriteLine($" ** {input} **"); for (int i = 0; i < 3; i++) { var lyrOut = layer1.Compute((object)input, learn) as ComputeCycle; } } // Here we add TM module to the layer. layer1.HtmModules.Add("tm", tm1); int cycle = 0; int matches = 0; double lastPredictedValue = 0; // // Now, training with SP+TM. SP is pretrained on pattern. for (int i = 0; i < 460; i++) { matches = 0; cycle++; foreach (var input in inputs) { var lyrOut = layer1.Compute(input, learn) as ComputeCycle; cls.Learn(input, lyrOut.ActiveCells.ToArray()); Debug.WriteLine($"-------------- {input} ---------------"); if (learn == false) { Debug.WriteLine($"Inference mode"); } Debug.WriteLine($"Col SDR: {Helpers.StringifyVector(lyrOut.ActivColumnIndicies)}"); Debug.WriteLine($"Cell SDR: {Helpers.StringifyVector(lyrOut.ActiveCells.Select(c => c.Index).ToArray())}"); Debug.WriteLine($"W: {Helpers.StringifyVector(lyrOut.WinnerCells.Select(c => c.Index).ToArray())}"); Debug.WriteLine($"P: {Helpers.StringifyVector(lyrOut.PredictiveCells.Select(c => c.Index).ToArray())}"); var predictedValue = cls.GetPredictedInputValue(lyrOut.PredictiveCells.ToArray()); Debug.WriteLine($"Current Input: {input} \t| - Predicted value in previous cycle: {lastPredictedValue} \t| Predicted Input for the next cycle: {predictedValue}"); if (input == lastPredictedValue) { matches++; Debug.WriteLine($"Match. Actual value: {input} - Predicted value: {lastPredictedValue}"); } else { Debug.WriteLine($"Missmatch! Actual value: {input} - Predicted value: {lastPredictedValue}"); } lastPredictedValue = predictedValue; } if (i == 500) { Debug.WriteLine("Stop Learning From Here. Entering inference mode."); learn = false; } //tm1.reset(mem); Debug.WriteLine($"Cycle: {cycle}\tMatches={matches} of {inputs.Length}\t {(double)matches / (double)inputs.Length * 100.0}%"); } cls.TraceState(); Debug.WriteLine("------------------------------------------------------------------------\n----------------------------------------------------------------------------"); }
public void LongerSequenceExperiment() { int inputBits = 1024; bool learn = true; Parameters p = Parameters.getAllDefaultParameters(); p.Set(KEY.RANDOM, new ThreadSafeRandom(42)); p.Set(KEY.INPUT_DIMENSIONS, new int[] { inputBits }); p.Set(KEY.CELLS_PER_COLUMN, 10); p.Set(KEY.COLUMN_DIMENSIONS, new int[] { 2048 }); CortexNetwork net = new CortexNetwork("my cortex"); List <CortexRegion> regions = new List <CortexRegion>(); CortexRegion region0 = new CortexRegion("1st Region"); regions.Add(region0); SpatialPoolerMT sp1 = new SpatialPoolerMT(); TemporalMemory tm1 = new TemporalMemory(); var mem = new Connections(); p.apply(mem); sp1.Init(mem, UnitTestHelpers.GetMemory()); tm1.Init(mem); Dictionary <string, object> settings = new Dictionary <string, object>() { { "W", 21 }, { "N", inputBits }, { "Radius", -1.0 }, { "MinVal", 0.0 }, // { "MaxVal", 20.0 }, { "Periodic", false }, { "Name", "scalar" }, { "ClipInput", false }, }; double max = 50; List <double> lst = new List <double>(); for (double i = 0; i < max; i++) { lst.Add(i); } settings["MaxVal"] = max; EncoderBase encoder = new ScalarEncoder(settings); 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 = lst.ToArray(); // // This trains SP. foreach (var input in inputs) { Debug.WriteLine($" ** {input} **"); for (int i = 0; i < 3; i++) { var lyrOut = layer1.Compute((object)input, learn) as ComputeCycle; } } // Here we add TM module to the layer. layer1.HtmModules.Add("tm", tm1); // // Now, training with SP+TM. SP is pretrained on pattern. for (int i = 0; i < 200; i++) { foreach (var input in inputs) { var lyrOut = layer1.Compute(input, learn) as ComputeCycle; cls.Learn(input, lyrOut.ActiveCells.ToArray()); Debug.WriteLine($"-------------- {input} ---------------"); if (learn == false) { Debug.WriteLine($"Inference mode"); } Debug.WriteLine($"W: {Helpers.StringifyVector(lyrOut.WinnerCells.Select(c => c.Index).ToArray())}"); Debug.WriteLine($"P: {Helpers.StringifyVector(lyrOut.PredictiveCells.Select(c => c.Index).ToArray())}"); Debug.WriteLine($"Current Input: {input} \t| Predicted Input: {cls.GetPredictedInputValue(lyrOut.PredictiveCells.ToArray())}"); } if (i == 50) { Debug.WriteLine("Stop Learning From Here. Entering inference mode."); learn = false; } tm1.Reset(mem); } cls.TraceState(); Debug.WriteLine("------------------------------------------------------------------------\n----------------------------------------------------------------------------"); }
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); } } } }
public void SimilarityExperimentWithEncoder() { int stableStateCnt = 100; double minOctOverlapCycles = 1.0; double maxBoost = 10.0; int inputBits = 100; var colDims = new int[] { 64 * 64 }; int numOfActCols = colDims[0]; int numColumns = colDims[0]; string TestOutputFolder = $"Output-{nameof(ImageSimilarityExperiment)}"; Directory.CreateDirectory($"{nameof(ImageSimilarityExperiment)}"); //int counter = 0; //var parameters = GetDefaultParams(); ////parameters.Set(KEY.DUTY_CYCLE_PERIOD, 20); ////parameters.Set(KEY.MAX_BOOST, 1); ////parameters.setInputDimensions(new int[] { imageSize[imSizeIndx], imageSize[imSizeIndx] }); ////parameters.setColumnDimensions(new int[] { topologies[topologyIndx], topologies[topologyIndx] }); ////parameters.setNumActiveColumnsPerInhArea(0.02 * numOfActCols); //parameters.Set(KEY.NUM_ACTIVE_COLUMNS_PER_INH_AREA, 0.06 * 4096); // TODO. Experiment with different sizes //parameters.Set(KEY.POTENTIAL_RADIUS, inputBits); //parameters.Set(KEY.POTENTIAL_PCT, 1.0); //parameters.Set(KEY.GLOBAL_INHIBITION, true); // TODO: Experiment with local inhibition too. Note also the execution time of the experiment. //// Num of active synapces in order to activate the column. //parameters.Set(KEY.STIMULUS_THRESHOLD, 50.0); //parameters.Set(KEY.SYN_PERM_INACTIVE_DEC, 0.008); //parameters.Set(KEY.SYN_PERM_ACTIVE_INC, 0.05); //parameters.Set(KEY.INHIBITION_RADIUS, (int)0.15 * inputBits); // TODO. check if this has influence in a case of the global inhibition. ALso check how this parameter influences the similarity of SDR. //parameters.Set(KEY.SYN_PERM_CONNECTED, 0.2); //parameters.Set(KEY.MIN_PCT_OVERLAP_DUTY_CYCLES, 1.0); //parameters.Set(KEY.MIN_PCT_ACTIVE_DUTY_CYCLES, 0.001); //parameters.Set(KEY.DUTY_CYCLE_PERIOD, 100); //parameters.Set(KEY.MAX_BOOST, 10); //parameters.Set(KEY.WRAP_AROUND, true); //parameters.Set(KEY.SEED, 1969); //parameters.setInputDimensions(new int[] {inputBits }); //parameters.setColumnDimensions(colDims); Parameters p = Parameters.getAllDefaultParameters(); p.Set(KEY.RANDOM, new ThreadSafeRandom(42)); p.Set(KEY.INPUT_DIMENSIONS, new int[] { inputBits }); p.Set(KEY.COLUMN_DIMENSIONS, colDims); p.Set(KEY.CELLS_PER_COLUMN, 10); p.Set(KEY.MAX_BOOST, maxBoost); p.Set(KEY.DUTY_CYCLE_PERIOD, 50); p.Set(KEY.MIN_PCT_OVERLAP_DUTY_CYCLES, minOctOverlapCycles); // Global inhibition // N of 40 (40= 0.02*2048 columns) active cells required to activate the segment. p.Set(KEY.GLOBAL_INHIBITION, true); p.setNumActiveColumnsPerInhArea(0.02 * numColumns); p.Set(KEY.POTENTIAL_RADIUS, (int)(.7 * inputBits)); p.Set(KEY.LOCAL_AREA_DENSITY, -1); // In a case of global inhibition. //p.setInhibitionRadius( Automatically set on the columns pace in a case of global inhibition.); // Activation threshold is 10 active cells of 40 cells in inhibition area. p.setActivationThreshold(10); // Max number of synapses on the segment. p.setMaxNewSynapsesPerSegmentCount((int)(0.02 * numColumns)); double max = 20; Dictionary <string, object> settings = new Dictionary <string, object>() { { "W", 15 }, { "N", inputBits }, { "Radius", -1.0 }, { "MinVal", 0.0 }, { "Periodic", false }, { "Name", "scalar" }, { "ClipInput", false }, { "MaxVal", max } }; var encoder = new ScalarEncoder(settings); bool isInStableState = false; var mem = new Connections(); p.apply(mem); var inputs = new int[] { 0, 1, 2, 3, 4, 5 }; HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(mem, inputs.Length * 150, (isStable, numPatterns, actColAvg, seenInputs) => { // Event should only be fired when entering the stable state. // Ideal SP should never enter unstable state after stable state. Assert.IsTrue(isStable); //Assert.IsTrue(numPatterns == inputs.Length); isInStableState = true; Debug.WriteLine($"Entered STABLE state: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); }); SpatialPooler sp = new SpatialPoolerMT(hpa); sp.Init(mem, UnitTestHelpers.GetMemory()); string outFolder = $"{TestOutputFolder}"; Directory.CreateDirectory(outFolder); string outputHamDistFile = $"{outFolder}\\hamming.txt"; string outputActColFile = $"{outFolder}\\activeCol.txt"; using (StreamWriter swHam = new StreamWriter(outputHamDistFile)) { using (StreamWriter swActCol = new StreamWriter(outputActColFile)) { int cycle = 0; Dictionary <string, int[]> sdrs = new Dictionary <string, int[]>(); while (!isInStableState) { foreach (var digit in inputs) { int[] activeArray = new int[numOfActCols]; int[] oldArray = new int[activeArray.Length]; List <double[, ]> overlapArrays = new List <double[, ]>(); List <double[, ]> bostArrays = new List <double[, ]>(); var inputVector = encoder.Encode(digit); sp.compute(inputVector, activeArray, true); string actColFileName = Path.Combine(outFolder, $"{digit}.actcols.txt"); if (cycle == 0 && File.Exists(actColFileName)) { File.Delete(actColFileName); } var activeCols = ArrayUtils.IndexWhere(activeArray, (el) => el == 1); using (StreamWriter swCols = new StreamWriter(actColFileName, true)) { swCols.WriteLine(Helpers.StringifyVector(activeCols)); } Debug.WriteLine($"'Cycle: {cycle} - {digit}'"); Debug.WriteLine($"IN :{Helpers.StringifyVector(inputVector)}"); Debug.WriteLine($"OUT:{Helpers.StringifyVector(activeCols)}\n"); if (isInStableState) { if (--stableStateCnt <= 0) { return; } } /* * if (isInStableState) * { * swActCol.WriteLine($"\nDigit {digit}"); * * sdrs.Add(digit.ToString(), activeCols); * * // * // To be sure that same input produces the same output after entered the stable state. * for (int i = 0; i < 100; i++) * { * activeArray = new int[numOfActCols]; * * sp.compute(inputVector, activeArray, true); * * var distance = MathHelpers.GetHammingDistance(oldArray, activeArray, true); * * var actColsIndxes = ArrayUtils.IndexWhere(activeArray, i => i == 1); * var oldActColsIndxes = ArrayUtils.IndexWhere(oldArray, i => i == 1); * * var similarity = MathHelpers.CalcArraySimilarity(actColsIndxes, oldActColsIndxes); * * swHam.Write($"Digit {digit}: Dist/Similarity: {distance} | {similarity}\t"); * Debug.Write($"Digit {digit}: Dist/Similarity: {distance} | {similarity}\t"); * Debug.WriteLine($"{Helpers.StringifyVector(actColsIndxes)}"); * * if (i > 5 && similarity < 100) * { * * } * * oldArray = new int[numOfActCols]; * activeArray.CopyTo(oldArray, 0); * } * } * * Debug.WriteLine($"Cycle {cycle++}");*/ } cycle++; } CalculateSimilarity(sdrs, null);//todo } } }
//[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); } } } } } }
/// <summary> /// /// </summary> private async Task RunExperimentNeuroVisualizer(int inputBits, Parameters p, EncoderBase encoder, List <double> inputValues) { Stopwatch sw = new Stopwatch(); sw.Start(); int maxMatchCnt = 0; bool learn = true; INeuroVisualizer vis = new WSNeuroVisualizer(); GenerateNeuroModel model = new GenerateNeuroModel(); await vis.ConnectToWSServerAsync(); await vis.InitModelAsync(model.CreateNeuroModel(new int[] { 1 }, (long[, ])p[KEY.COLUMN_DIMENSIONS], (int)p[KEY.CELLS_PER_COLUMN])); CortexNetwork net = new CortexNetwork("my cortex"); List <CortexRegion> regions = new List <CortexRegion>(); CortexRegion region0 = new CortexRegion("1st Region"); regions.Add(region0); SpatialPoolerMT sp1 = new SpatialPoolerMT(); TemporalMemory tm1 = new TemporalMemory(); var mem = new Connections(); p.apply(mem); sp1.Init(mem, UnitTestHelpers.GetMemory()); tm1.Init(mem); 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>(); HtmClassifier <string, ComputeCycle> cls = new HtmClassifier <string, ComputeCycle>(); double[] inputs = inputValues.ToArray(); int[] prevActiveCols = new int[0]; int maxSPLearningCycles = 50; // // This trains SP on input pattern. // It performs some kind of unsupervised new-born learning. foreach (var input in inputs) { List <(int Cycle, double Similarity)> elementOscilationResult = new List <(int Cycle, double Similarity)>(); Debug.WriteLine($"Learning ** {input} **"); for (int i = 0; i < maxSPLearningCycles; i++) { var lyrOut = layer1.Compute((object)input, learn) as ComputeCycle; var activeColumns = layer1.GetResult("sp") as int[]; var actCols = activeColumns.OrderBy(c => c).ToArray(); var similarity = MathHelpers.CalcArraySimilarity(prevActiveCols, actCols); await vis.UpdateColumnAsync(GetColumns(actCols)); Debug.WriteLine($" {i.ToString("D4")} SP-OUT: [{actCols.Length}/{similarity.ToString("0.##")}] - {Helpers.StringifyVector(actCols)}"); prevActiveCols = activeColumns; } } // Here we add TM module to the layer. layer1.HtmModules.Add("tm", tm1); 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; // // Now training with SP+TM. SP is pretrained on the given input pattern. for (int i = 0; i < maxCycles; i++) { matches = 0; cycle++; Debug.WriteLine($"-------------- Cycle {cycle} ---------------"); string prevInput = "-1.0"; // // Activate the 'New - Born' effect. //if (i == 300) //{ // mem.setMaxBoost(0.0); // mem.updateMinPctOverlapDutyCycles(0.0); // cls.ClearState(); //} foreach (var input in inputs) { Debug.WriteLine($"-------------- {input} ---------------"); var lyrOut = layer1.Compute(input, learn) as ComputeCycle; var activeColumns = layer1.GetResult("sp") as int[]; activeColumnsLst[input].Add(activeColumns.ToList()); //cls.Learn(input, lyrOut.ActiveCells.ToArray()); cls.Learn(GetKey(prevInput, input), lyrOut.ActiveCells.ToArray()); List <Synapse> synapses = new List <Synapse>(); Cell cell = new Cell(0, 1, 6, 0, CellActivity.ActiveCell); // where to get all these values Synapse synap = new Synapse(cell, 1, 1, 0.78); // here is just supposed to update the permanence, all other values remains same; where do we get all other values synapses.Add(synap); await vis.UpdateSynapsesAsync(synapses); //update Synapse or add new ones await vis.UpdateCellsAsync(GetCells(lyrOut.ActiveCells)); if (learn == false) { Debug.WriteLine($"Inference mode"); } if (GetKey(prevInput, input) == lastPredictedValue) { matches++; Debug.WriteLine($"Match {input}"); } else { Debug.WriteLine($"Missmatch Actual value: {GetKey(prevInput, input)} - Predicted value: {lastPredictedValue}"); } if (lyrOut.PredictiveCells.Count > 0) { var predictedInputValue = cls.GetPredictedInputValue(lyrOut.PredictiveCells.ToArray()); Debug.WriteLine($"Current Input: {input} \t| Predicted Input: {predictedInputValue}"); lastPredictedValue = predictedInputValue; } else { Debug.WriteLine($"NO CELLS PREDICTED for next cycle."); } prevInput = input.ToString(); } //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."); if (maxMatchCnt >= 20) { sw.Stop(); Debug.WriteLine($"Exit experiment in the stable state after 10 repeats with 100% of accuracy. Elapsed time: {sw.ElapsedMilliseconds / 1000 / 60} min."); learn = false; //var testInputs = new double[] { 0.0, 2.0, 3.0, 4.0, 5.0, 6.0, 5.0, 4.0, 3.0, 7.0, 1.0, 9.0, 12.0, 11.0, 0.0, 1.0 }; // C-0, D-1, E-2, F-3, G-4, H-5 //var testInputs = new double[] { 0.0, 0.0, 4.0, 4.0, 5.0, 5.0, 4.0, 3.0, 3.0, 2.0, 2.0, 1.0, 1.0, 0.0 }; //// Traverse the sequence and check prediction. //foreach (var input in inputValues) //{ // var lyrOut = layer1.Compute(input, learn) as ComputeCycle; // predictedInputValue = cls.GetPredictedInputValue(lyrOut.predictiveCells.ToArray()); // Debug.WriteLine($"I={input} - P={predictedInputValue}"); //} // // Here we let the HTM predict seuence five times on its own. // We start with last predicted value. int cnt = 5 * inputValues.Count; Debug.WriteLine("---- Start Predicting the Sequence -----"); // We take a random value to start somwhere in the sequence. var predictedInputValue = inputValues[new Random().Next(0, inputValues.Count - 1)].ToString(); List <string> predictedValues = new List <string>(); while (--cnt > 0) { //var lyrOut = layer1.Compute(predictedInputValue, learn) as ComputeCycle; var lyrOut = layer1.Compute(double.Parse(predictedInputValue[predictedInputValue.Length - 1].ToString()), learn) as ComputeCycle; predictedInputValue = cls.GetPredictedInputValue(lyrOut.PredictiveCells.ToArray()); predictedValues.Add(predictedInputValue); } ; foreach (var item in predictedValues) { Debug.Write(item); Debug.Write(" ,"); } 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("---- cell state trace ----"); cls.TraceState($"cellState_MinPctOverlDuty-{p[KEY.MIN_PCT_OVERLAP_DUTY_CYCLES]}_MaxBoost-{p[KEY.MAX_BOOST]}.csv"); Debug.WriteLine("---- column state trace ----"); foreach (var input in activeColumnsLst) { using (StreamWriter colSw = new StreamWriter($"ColumState_MinPctOverlDuty-{p[KEY.MIN_PCT_OVERLAP_DUTY_CYCLES]}_MaxBoost-{p[KEY.MAX_BOOST]}_input-{input.Key}.csv")) { Debug.WriteLine($"------------ {input} ------------"); foreach (var actCols in input.Value) { Debug.WriteLine(Helpers.StringifyVector(actCols.ToArray())); colSw.WriteLine(Helpers.StringifyVector(actCols.ToArray())); } } } Debug.WriteLine("------------ END ------------"); }