[DataRow(20, 30)] //Cells =20 , iter = 30 public void CellPerColumn(int C, int loop) { string filename = "Cells=" + C + ".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 = 200; 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[] { 500 }); 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>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // Later we run the whole experiment for all the below input sequences // List<double> lst = new List<double>() { 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8 }; // List<double> lst = new List<double>() { 1, 2, 3, 1, 2, 4 }; // List<double> lst = new List<double>() { 1, 2, 3, 4, 1, 2, 3, 5 }; // List<double> lst = new List<double>() { 1, 2, 3, 4, 5, 1, 2, 3, 4, 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(), lyrOut.PredictiveCells.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----------------------------------------------------------------------------"); }
public void TestCortexLayer() { int inputBits = 100; double max = 20; int numColumns = 2048; List <double> inputValues = new List <double>(new double[] { 0.0, 1.0, 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, 12.0, 13.0, 14.0, 11.0, 12.0, 14.0, 5.0, 7.0, 6.0, 9.0, 3.0, 4.0, 3.0, 4.0, 3.0, 4.0 }); int numInputs = inputValues.Distinct().ToList().Count; var inputs = inputValues.ToArray(); 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 } }; EncoderBase encoder = new ScalarEncoder(settings); HtmConfig htmConfig = new HtmConfig(new int[] { inputBits }, new int[] { numColumns }) { Random = new ThreadSafeRandom(42), CellsPerColumn = 25, GlobalInhibition = true, LocalAreaDensity = -1, NumActiveColumnsPerInhArea = 0.02 * numColumns, PotentialRadius = 50, InhibitionRadius = 15, MaxBoost = 10.0, DutyCyclePeriod = 25, MinPctOverlapDutyCycles = 0.75, MaxNewSynapseCount = (int)(0.02 * numColumns), ActivationThreshold = 15, ConnectedPermanence = 0.5, PermanenceDecrement = 0.25, PermanenceIncrement = 0.15, PredictedSegmentDecrement = 0.1 }; Connections memory = new Connections(htmConfig); HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(memory, numInputs * 55, (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}"); } }, numOfCyclesToWaitOnChange: 25); SpatialPoolerMT spatialPooler = new SpatialPoolerMT(hpa); spatialPooler.Init(memory, UnitTestHelpers.GetMemory()); TemporalMemory temporalMemory = new TemporalMemory(); temporalMemory.Init(memory); List <CortexRegion> regions = new List <CortexRegion>(); CortexRegion region0 = new CortexRegion("1st Region"); regions.Add(region0); CortexLayer <object, object> layer1 = new CortexLayer <object, object>("L1"); region0.AddLayer(layer1); layer1.HtmModules.Add("encoder", encoder); layer1.HtmModules.Add("sp", spatialPooler); layer1.HtmModules.Add("tm", temporalMemory); bool learn = true; int maxCycles = 3500; for (int i = 0; i < maxCycles; i++) { foreach (var input in inputs) { var lyrOut = layer1.Compute(input, learn) as ComputeCycle; } } }
private void RunSpStabilityExperiment(double maxBoost, double minOverlapCycles, int inputBits, Parameters p, EncoderBase encoder, List <double> inputValues) { string path = nameof(RunSpStabilityExperiment); 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 * 30, (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($"INSTABLE!: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); } else { //Assert.IsTrue(isStable); isInStableState = true; Debug.WriteLine($"STABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); } }, numOfCyclesToWaitOnChange: 50, requiredSimilarityThreshold: 0.975); SpatialPooler sp = new SpatialPooler(hpa); p.apply(mem); sp.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", sp); HtmClassifier <double, ComputeCycle> cls = new HtmClassifier <double, ComputeCycle>(); double[] inputs = inputValues.ToArray(); Dictionary <double, List <string[]> > boostedOverlaps = new Dictionary <double, List <string[]> >(); 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 = 2000; List <(double Element, (int Cycle, double Similarity)[] Oscilations)> oscilationResult = new List <(double Element, (int Cycle, double Similarity)[] Oscilations)>();
/// <summary> /// /// </summary> private void RunExperiment(int inputBits, Parameters p, EncoderBase encoder, List <double> inputValues) { Stopwatch sw = new Stopwatch(); sw.Start(); int maxMatchCnt = 0; 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(); p.apply(mem); //bool isInStableState = false; //HtmClassifier<double, ComputeCycle> cls = new HtmClassifier<double, ComputeCycle>(); HtmClassifier <string, ComputeCycle> cls = new HtmClassifier <string, ComputeCycle>(); var numInputs = inputValues.Distinct().ToList().Count; TemporalMemory tm1 = new TemporalMemory(); HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(mem, numInputs * 55, (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}"); } Assert.IsTrue(numPatterns == numInputs); //isInStableState = true; cls.ClearState(); tm1.Reset(mem); }, numOfCyclesToWaitOnChange: 25); SpatialPoolerMT sp1 = new SpatialPoolerMT(hpa); sp1.Init(mem, UnitTestHelpers.GetMemory()); tm1.Init(mem); 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("tm", tm1); 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"); // // 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} ---------------"); 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()); previousInputs.Add(input.ToString()); if (previousInputs.Count > maxPrevInputs + 1) { previousInputs.RemoveAt(0); } 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()); Debug.WriteLine($"Current Input: {input} \t| Predicted Input: {predictedInputValue}"); lastPredictedValue = predictedInputValue; } 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 = 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 >= 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; //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 sequence five times on its own. * // We start with last predicted value. * int cnt = 5 * inputValues.Count; * * Debug.WriteLine("---- Start Predicting the Sequence -----"); * * // * // This code snippet starts with some input value and tries to predict all next inputs * // as they have been learned as a 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()), false) as ComputeCycle; * predictedInputValue = cls.GetPredictedInputValue(lyrOut.PredictiveCells.ToArray()); * predictedValues.Add(predictedInputValue); * }; * * // Now we have a sequence of elements and watch in the trace if it matches to defined input set. * 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("---- Spatial Pooler column state ----"); 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.Key} ------------"); foreach (var actCols in input.Value) { Debug.WriteLine(Helpers.StringifyVector(actCols.ToArray())); colSw.WriteLine(Helpers.StringifyVector(actCols.ToArray())); } } } Debug.WriteLine("------------ END ------------"); }
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"); }