/// <summary> /// Multi encoder for day month and segment /// </summary> /// <returns></returns> public static EncoderBase FetchDateTimeEncoder() { EncoderBase dayEncoder = FetchDayEncoder(); EncoderBase monthEncoder = FetchMonthEncoder(); EncoderBase segmentEncoder = FetchSegmentEncoder(); EncoderBase dayOfWeek = FetchWeekDayEncoder(); List <EncoderBase> encoder = new List <EncoderBase>(); encoder.Add(dayEncoder); encoder.Add(monthEncoder); encoder.Add(segmentEncoder); encoder.Add(dayOfWeek); MultiEncoder encoderSetting = new MultiEncoder(encoder); return(encoderSetting); }
/// <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> /// Shows the encoder settings dialog and check overwrite exist file. /// </summary> /// <param name="filename">The filename.</param> /// <param name="encoder">The encoder.</param> /// <param name="canAddImagesToExistingFile">The value indicating whether encoder can add images to the existing multipage image file.</param> /// <param name="askIfFileCanBeOverwritten">The value indicating whether we need to ask that the existing file must be overwritten.</param> /// <returns> /// <b>True</b> if encoder is initialized; otherwise, <b>false</b>. /// </returns> private bool ShowEncoderSettingsDialogAndCheckOverwrite( string filename, ref EncoderBase encoder, bool canAddImagesToExistingFile, bool askIfFileCanBeOverwritten) { // // show the encoder settings dialog and initialize the encoder bool result = ShowEncoderSettingsDialog(ref encoder, canAddImagesToExistingFile); // if encoder is not initialized if (!result) { // exit return(false); } // if file exists if (File.Exists(filename)) { // if we need to ask that the existing file must be overwritten if (askIfFileCanBeOverwritten) { // if encoder is multipage encoder if (encoder is MultipageEncoderBase) { // if encoder must create new image file if (((MultipageEncoderBase)encoder).CreateNewFile) { ShowDialogAndAskIfFileMustBeOverwritten(filename); } } // if encoder is NOT multipage encoder else { ShowDialogAndAskIfFileMustBeOverwritten(filename); } } } return(true); }
/// <summary> /// Returns the multipage encoder for the specified <paramref name="filename"/>. /// </summary> /// <param name="filename">The filename.</param> /// <param name="multipageEncoder">The multipage encoder.</param> /// <returns> /// <b>True</b> if the multipage encoder is created and initialized; otherwise, <b>false</b>. /// </returns> public bool GetMultipageEncoder(string filename, out MultipageEncoderBase multipageEncoder) { // create encoder EncoderBase encoder = AvailableEncoders.CreateEncoder(filename); // indicates whether the encoder can add images to the existing multipage image file bool canAddImagesToExistingFile = false; // if encoder can add images to the existing multipage image file if (CanAddImagesToExistingFile) { // if file exists if (File.Exists(filename)) { // specify that encoder can add images to the existing multipage image file canAddImagesToExistingFile = true; } } // get the multipage encoder multipageEncoder = encoder as MultipageEncoderBase; // if encoder is not multipage if (multipageEncoder == null) { return(false); } // set encoder settings bool result = ShowEncoderSettingsDialogAndCheckOverwrite( filename, ref encoder, canAddImagesToExistingFile, multipageEncoder.CreateNewFile); multipageEncoder = encoder as MultipageEncoderBase; return(result); }
/// <summary> /// Sets the rendering settings if necessary. /// </summary> /// <param name="images">The images.</param> /// <param name="encoder">The encoder.</param> /// <param name="defaultRenderingSettings">The default rendering settings.</param> public static void SetRenderingSettingsIfNeed( ImageCollection images, EncoderBase encoder, RenderingSettings defaultRenderingSettings) { if (encoder == null || !(encoder is IPdfEncoder)) { for (int i = 0; i < images.Count; i++) { if (images[i].IsVectorImage) { RenderingSettingsForm settingsForm = new RenderingSettingsForm(defaultRenderingSettings.CreateClone()); if (settingsForm.ShowDialog() == DialogResult.OK) { images.SetRenderingSettings(settingsForm.RenderingSettings); } else { return; } break; } } } }
/// <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)>();
/// <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 * 15, (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"); // This should usually not happen. isInStableState = false; } else { Debug.WriteLine($"STABILITY"); // Here you can perform any action if required. isInStableState = true; } }); // It creates the instance of Spatial Pooler Multithreaded version. SpatialPooler sp = new SpatialPoolerMT(hpa); // Initializes the sp.Init(mem, new DistributedMemory() { ColumnDictionary = new InMemoryDistributedDictionary <int, NeoCortexApi.Entities.Column>(1) }); // 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; } } }
/// <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 <int[]> 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; } }, requiredSimilarityThreshold: 0.975); // It creates the instance of Spatial Pooler Multithreaded version. SpatialPooler sp = new SpatialPoolerMT(hpa); // Initializes the sp.Init(mem); // Holds the indicies of active columns of the SDR. Dictionary <string, int[]> prevActiveColIndicies = new Dictionary <string, int[]>(); // Holds the active column SDRs. Dictionary <string, int[]> prevActiveCols = new Dictionary <string, int[]>(); // Will hold the similarity of SDKk and SDRk-1 fro every input. Dictionary <string, double> prevSimilarity = new Dictionary <string, double>(); // // Initiaize start similarity to zero. for (int i = 0; i < inputValues.Count; i++) { string inputKey = GetInputGekFromIndex(i); prevSimilarity.Add(inputKey, 0.0); prevActiveColIndicies.Add(inputKey, 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. for (int inputIndx = 0; inputIndx < inputValues.Count; inputIndx++) { string inputKey = GetInputGekFromIndex(inputIndx); int[] input = inputValues[inputIndx]; double similarity; int[] activeColumns = new int[(int)cfg.NumColumns]; // Learn the input pattern. // Output lyrOut is the output of the last module in the layer. sp.compute(input, activeColumns, true); // DrawImages(cfg, inputKey, input, activeColumns); var actColsIndicies = ArrayUtils.IndexWhere(activeColumns, c => c == 1); similarity = MathHelpers.CalcArraySimilarity(actColsIndicies, prevActiveColIndicies[inputKey]); Debug.WriteLine($"[i={inputKey}, cols=:{actColsIndicies.Length} s={similarity}] SDR: {Helpers.StringifyVector(actColsIndicies)}"); prevActiveCols[inputKey] = activeColumns; prevActiveColIndicies[inputKey] = actColsIndicies; prevSimilarity[inputKey] = similarity; if (isInStableState) { GenerateResult(cfg, inputValues, prevActiveColIndicies, prevActiveCols); return; } } } }
/// <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 ------------"); }
/// <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); SpatialPoolerMT sp = new SpatialPoolerMT(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()); 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 = (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 ------------"); }
/// <summary> /// /// </summary> private static void RunExperiment(int inputBits, HtmConfig cfg, 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(cfg); bool isInStableState; HtmClassifier <string, ComputeCycle> cls = new HtmClassifier <string, ComputeCycle>(); var numInputs = inputValues.Distinct <double>().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}"); } if (numPatterns != numInputs) { throw new InvalidOperationException("Stable state must observe all input patterns"); } isInStableState = true; cls.ClearState(); tm1.Reset(mem); }, numOfCyclesToWaitOnChange: 25); SpatialPoolerMT sp1 = new SpatialPoolerMT(hpa); sp1.Init(mem, new DistributedMemory() { ColumnDictionary = new InMemoryDistributedDictionary <int, NeoCortexApi.Entities.Column>(1), }); 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"; String prediction = null; 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); cls.Learn(key, lyrOut.ActiveCells.ToArray()); 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())}"); 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.GetPredictedInputValues(lyrOut.PredictiveCells.ToArray(), 3); Debug.WriteLine($"Current Input: {input}"); Debug.WriteLine("The predictions with similarity greater than 50% are"); foreach (var t in predictedInputValue) { if (t.Similarity >= (double)50.00) { Debug.WriteLine($"Predicted Input: {string.Join(", ", t.PredictedInput)},\tSimilarity Percentage: {string.Join(", ", t.Similarity)}, \tNumber of Same Bits: {string.Join(", ", t.NumOfSameBits)}"); } } lastPredictedValue = predictedInputValue.First().PredictedInput; } 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."); 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("---- cell state trace ----"); cls.TraceState($"cellState_MinPctOverlDuty-{cfg.MinPctOverlapDutyCycles}_MaxBoost-{cfg.MaxBoost}.csv"); Debug.WriteLine("---- Spatial Pooler column state ----"); foreach (var input in activeColumnsLst) { using (StreamWriter colSw = new StreamWriter($"ColumState_MinPctOverlDuty-{cfg.MinPctOverlapDutyCycles}_MaxBoost-{cfg.MaxBoost}_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 ------------"); Console.WriteLine("\n Please enter a number that has been learnt"); int inputNumber = Convert.ToInt16(Console.ReadLine()); Inference(inputNumber, false, layer1, cls); }
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."); } } }
public Encoder(EncoderBase encoder) { Name = encoder?.Name; }
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 StreamEngine(Socket fd, Options options, String endpoint) { m_handle = fd; // inbuf = null; m_insize = 0; m_inputError = false; // outbuf = null; m_outsize = 0; m_handshaking = true; m_session = null; m_options = options; m_plugged = false; m_endpoint = endpoint; m_socket = null; m_encoder = null; m_decoder = null; // Put the socket into non-blocking mode. Utils.UnblockSocket(m_handle); // Set the socket buffer limits for the underlying socket. if (m_options.SendBuffer != 0) { m_handle.SendBufferSize = m_options.SendBuffer; } if (m_options.ReceiveBuffer != 0) { m_handle.ReceiveBufferSize = m_options.ReceiveBuffer; } }
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; var memL4 = new Connections(cfgL4); var memL2 = new Connections(cfgL2); var 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(); // 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; }, 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 SpatialPoolerMT(hpa_sp_L4); SpatialPooler sp2 = new SpatialPoolerMT(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 (var input in inputs) { Debug.WriteLine($" INPUT: '{input}'\tCycle:{cycle}"); Debug.Write("L4: "); //L4 SP pre train layerL4.Compute(input, learn); InitArray(inpCellsL4ToL2, 0); if (isSP4Stable) { var cellSdrL4Indexes = memL4.ActiveCells.Select(c => c.Index).ToArray(); // Write SDR as output of L4 and input of L2 swL4Sdrs.WriteLine($"{input} - {Helpers.StringifyVector(cellSdrL4Indexes)}"); // Set the output active cell array ArrayUtils.SetIndexesTo(inpCellsL4ToL2, cellSdrL4Indexes, 1); Debug.WriteLine($"L4 out sdr: {Helpers.StringifyVector(cellSdrL4Indexes)}"); Debug.WriteLine("L2: "); swL2.Restart(); /// <summary> /// This part is for to make SP of Layer2 stable thourgh help /// of HPC Boosting Algo from new born stage. /// </summary> layerL2.Compute(inpCellsL4ToL2, true); swL2.Stop(); Debug.WriteLine($"{swL2.ElapsedMilliseconds / 1000}"); sw.WriteLine($"{swL2.ElapsedMilliseconds / 1000}"); sw.Flush(); var overlaps = ArrayUtils.IndexWhere(memL2.Overlaps, o => o > 0); var strOverlaps = Helpers.StringifyVector(overlaps); Debug.WriteLine($"Potential columns: {overlaps.Length}, overlaps: {strOverlaps}"); } } if (isSP4Stable && isSP2STable) { break; } } } } // SP+TM at L4 for (int i = 0; i < maxCycles; i++) { matches = 0; cycle = i; Debug.WriteLine($"-------------- L4 TM Train region Cycle {cycle} ---------------"); foreach (var input in inputs) { Debug.WriteLine($"-------------- {input} ---------------"); var layerL4Out = layerL4.Compute(input, learn) as ComputeCycle; previousInputs.Add(input.ToString()); if (previousInputs.Count > (maxPrevInputs + 1)) { previousInputs.RemoveAt(0); } if (previousInputs.Count < maxPrevInputs) { continue; } string key = GetKey(previousInputs, input); List <Cell> actCells; if (layerL4Out.ActiveCells.Count == layerL4Out.WinnerCells.Count) { // SP+TM at L2 Debug.WriteLine($"-------------- L2 TM Train region Cycle {cycle} ---------------"); // Reset tha array InitArray(inpCellsL4ToL2, 0); var cellSdrL4Indexes = memL4.ActiveCells.Select(c => c.Index).ToArray(); // Set the output active cell array ArrayUtils.SetIndexesTo(inpCellsL4ToL2, cellSdrL4Indexes, 1); var layerL2Out = layerL2.Compute(inpCellsL4ToL2, true) as ComputeCycle; int[] overlaps = ArrayUtils.IndexWhere(memL2.Overlaps, o => o > 0); var strOverlaps = Helpers.StringifyVector(overlaps); Debug.WriteLine($"Potential columns: {overlaps.Length}, overlaps: {strOverlaps}"); if (layerL2Out.ActiveCells.Count == layerL2Out.WinnerCells.Count) { actCells = layerL2Out.ActiveCells; } else { actCells = layerL2Out.WinnerCells; } cls.Learn(key, actCells.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 (layerL2Out.PredictiveCells.Count > 0) { var predictedInputValue = cls.GetPredictedInputValue(layerL2Out.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; } } } 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."); maxMatchCnt = 0; } } }
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 isSP1Stable = false; bool isSP2STable = false; var memL4 = new Connections(cfgL4); var memL2 = new Connections(cfgL2); var 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(); // // 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 = isSP1Stable = 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 SpatialPoolerMT(hpa_sp_L4); SpatialPooler sp2 = new SpatialPoolerMT(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++; Debug.WriteLine($"-------------- Newborn Cycle {cycle} at L4 SP region ---------------"); foreach (var input in inputs) { Debug.WriteLine($" INPUT: '{input}'\tCycle:{cycle}"); Debug.Write("L4: "); var lyrOut = layerL4.Compute(input, learn); InitArray(inpCellsL4ToL2, 0); if (isSP1Stable) { var cellSdrL4Indexes = memL4.ActiveCells.Select(c => c.Index).ToArray(); // Write SDR as output of L4 and input of L2 swL4Sdrs.WriteLine($"{input} - {Helpers.StringifyVector(cellSdrL4Indexes)}"); // Set the output active cell array ArrayUtils.SetIndexesTo(inpCellsL4ToL2, cellSdrL4Indexes, 1); Debug.Write("L2: "); swL2.Restart(); layerL2.Compute(inpCellsL4ToL2, true); swL2.Stop(); Debug.WriteLine($"{swL2.ElapsedMilliseconds / 1000}"); sw.WriteLine($"{swL2.ElapsedMilliseconds / 1000}"); sw.Flush(); Debug.WriteLine($"L4 out sdr: {Helpers.StringifyVector(cellSdrL4Indexes)}"); var overlaps = ArrayUtils.IndexWhere(memL2.Overlaps, o => o > 0); var strOverlaps = Helpers.StringifyVector(overlaps); Debug.WriteLine($"Potential columns: {overlaps.Length}, overlaps: {strOverlaps}"); } if (isSP1Stable && isSP2STable) { break; } } } } } Debug.WriteLine($"-------------- L4 SP region is {isSP1Stable} ---------------"); //layerL4.HtmModules.Add("tm", tm4); // SP+TM at L4 for (int i = 0; i < maxCycles; i++) { matches -= 0; cycle++; Debug.WriteLine($"-------------- L4 TM Train region Cycle {cycle} ---------------"); foreach (var input in inputs) { Debug.WriteLine($"-------------- {input} ---------------"); var lyrOut = layerL4.Compute(input, learn) as ComputeCycle; previousInputs.Add(input.ToString()); if (previousInputs.Count > (maxPrevInputs + 1)) { previousInputs.RemoveAt(0); } if (previousInputs.Count < maxPrevInputs) { continue; } if (lyrOut.ActiveCells.Count == lyrOut.WinnerCells.Count) { /*var activeColumns = L4.GetResult("sp") as int[]; * foreach (var item in activeColumns) * { * L2.Compute(item, true); * }*/ // Reset tha array InitArray(inpCellsL4ToL2, 0); // Set the output active cell array ArrayUtils.SetIndexesTo(inpCellsL4ToL2, memL4.ActiveCells.Select(c => c.Index).ToArray(), 1); // 4102,25072, 25363, 25539, 25738, 25961, 26009, 26269, 26491, 26585, 26668, 26920, 26934, 27040, 27107, 27262, 27392, 27826, 27948, 28174, 28243, 28270, 28294, 28308, 28429, 28577, 28671, 29139, 29618, 29637, 29809, 29857, 29897, 29900, 29969, 30057, 30727, 31111, 49805, 49972, layerL2.Compute(inpCellsL4ToL2, true); /*foreach (var item in lyrOut.ActiveCells) * { * L2.Compute(item, true); * }*/ //var activeCell = Helpers.StringifyVector(lyrOut.ActiveCells.Select(c => c.Index).ToArray()); //L2.Compute(activeCell, true); } } } }
/// <summary> /// /// </summary> private HtmPredictionEngine RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Dictionary <string, List <double> > sequences) { Stopwatch sw = new Stopwatch(); sw.Start(); int maxMatchCnt = 0; var mem = new Connections(cfg); bool isInStableState = false; HtmClassifier <string, ComputeCycle> cls = new HtmClassifier <string, ComputeCycle>(); var numUniqueInputs = GetNumberOfInputs(sequences); CortexLayer <object, object> layer1 = new CortexLayer <object, object>("L1"); TemporalMemory tm = new TemporalMemory(); // For more information see following paper: https://www.scitepress.org/Papers/2021/103142/103142.pdf HomeostaticPlasticityController hpc = new HomeostaticPlasticityController(mem, numUniqueInputs * 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. isInStableState = isStable; // Clear active and predictive cells. //tm.Reset(mem); }, numOfCyclesToWaitOnChange: 50); SpatialPoolerMT sp = new SpatialPoolerMT(hpc); sp.Init(mem); tm.Init(mem); // Please note that we do not add here TM in the layer. // This is omitted for practical reasons, because we first eneter the newborn-stage of the algorithm // In this stage we want that SP get boosted and see all elements before we start learning with TM. // All would also work fine with TM in layer, but it would work much slower. // So, to improve the speed of experiment, we first ommit the TM and then after the newborn-stage we add it to the layer. 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; var lastPredictedValues = new List <string>(new string[] { "0" }); int maxCycles = 3500; // // Training SP to get stable. New-born stage. // for (int i = 0; i < maxCycles && isInStableState == false; i++) { matches = 0; cycle++; Debug.WriteLine($"-------------- Newborn Cycle {cycle} ---------------"); foreach (var inputs in sequences) { foreach (var input in inputs.Value) { Debug.WriteLine($" -- {inputs.Key} - {input} --"); var lyrOut = layer1.Compute(input, true); if (isInStableState) { break; } } if (isInStableState) { break; } } } // Clear all learned patterns in the classifier. cls.ClearState(); // We activate here the Temporal Memory algorithm. layer1.HtmModules.Add("tm", tm); // // Loop over all sequences. foreach (var sequenceKeyPair in sequences) { Debug.WriteLine($"-------------- Sequences {sequenceKeyPair.Key} ---------------"); int maxPrevInputs = sequenceKeyPair.Value.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 set. for (int i = 0; i < maxCycles; i++) { matches = 0; cycle++; Debug.WriteLine(""); Debug.WriteLine($"-------------- Cycle {cycle} ---------------"); Debug.WriteLine(""); foreach (var input in sequenceKeyPair.Value) { Debug.WriteLine($"-------------- {input} ---------------"); var lyrOut = layer1.Compute(input, true) as ComputeCycle; var activeColumns = layer1.GetResult("sp") as int[]; 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, sequenceKeyPair.Key); List <Cell> actCells; if (lyrOut.ActiveCells.Count == lyrOut.WinnerCells.Count) { actCells = lyrOut.ActiveCells; } else { actCells = lyrOut.WinnerCells; } cls.Learn(key, actCells.ToArray()); Debug.WriteLine($"Col SDR: {Helpers.StringifyVector(lyrOut.ActivColumnIndicies)}"); Debug.WriteLine($"Cell SDR: {Helpers.StringifyVector(actCells.Select(c => c.Index).ToArray())}"); // // If the list of predicted values from the previous step contains the currently presenting value, // we have a match. if (lastPredictedValues.Contains(key)) { matches++; Debug.WriteLine($"Match. Actual value: {key} - Predicted value: {lastPredictedValues.FirstOrDefault(key)}."); } else { Debug.WriteLine($"Missmatch! Actual value: {key} - Predicted values: {String.Join(',', lastPredictedValues)}"); } 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.PredictedInput} - {item.Similarity}"); } lastPredictedValues = predictedInputValues.Select(v => v.PredictedInput).ToList(); } else { Debug.WriteLine($"NO CELLS PREDICTED for next cycle."); lastPredictedValues = new List <string> (); } } // The first element (a single element) in the sequence cannot be predicted double maxPossibleAccuraccy = (double)((double)sequenceKeyPair.Value.Count - 1) / (double)sequenceKeyPair.Value.Count * 100.0; double accuracy = (double)matches / (double)sequenceKeyPair.Value.Count * 100.0; Debug.WriteLine($"Cycle: {cycle}\tMatches={matches} of {sequenceKeyPair.Value.Count}\t {accuracy}%"); if (accuracy >= maxPossibleAccuraccy) { 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($"Sequence learned. The algorithm is in the stable state after 30 repeats with with accuracy {accuracy} of maximum possible {maxMatchCnt}. Elapsed sequence {sequenceKeyPair.Key} learning time: {sw.Elapsed}."); break; } } else if (maxMatchCnt > 0) { Debug.WriteLine($"At 100% accuracy after {maxMatchCnt} repeats we get a drop of accuracy with accuracy {accuracy}. This indicates instable state. Learning will be continued."); maxMatchCnt = 0; } // This resets the learned state, so the first element starts allways from the beginning. tm.Reset(mem); } } Debug.WriteLine("------------ END ------------"); return(new HtmPredictionEngine { Layer = layer1, Classifier = cls, Connections = mem }); }
/// <summary> /// Shows the encoder settings dialog. /// </summary> /// <param name="encoder">The encoder.</param> /// <param name="canAddImagesToExistingFile">The value indicating whether encoder can add images to the existing multipage image file.</param> /// <returns> /// <b>True</b> if settings are applied to the encoder; otherwise, <b>false</b>. /// </returns> protected override bool ShowEncoderSettingsDialog( ref EncoderBase encoder, bool canAddImagesToExistingFile) { if (base.ShowEncoderSettingsDialog(ref encoder, canAddImagesToExistingFile)) { return(true); } // set encoder settings switch (encoder.Name) { case "Jpeg2000": using (Jpeg2000EncoderSettingsForm jpeg2000EncoderSettingsForm = new Jpeg2000EncoderSettingsForm()) { SetEncoderSettingsDialogProperties(jpeg2000EncoderSettingsForm); if (jpeg2000EncoderSettingsForm.ShowDialog() != DialogResult.OK) { return(false); } ((IJpeg2000Encoder)encoder).Settings = jpeg2000EncoderSettingsForm.EncoderSettings; return(true); } #if !REMOVE_PDF_PLUGIN && !REMOVE_DOCCLEANUP_PLUGIN case "Pdf": using (PdfEncoderSettingsForm pdfEncoderSettingsForm = new PdfEncoderSettingsForm()) { SetEncoderSettingsDialogProperties(pdfEncoderSettingsForm); pdfEncoderSettingsForm.AppendExistingDocumentEnabled = canAddImagesToExistingFile; if (pdfEncoderSettingsForm.ShowDialog() != DialogResult.OK) { return(false); } if (pdfEncoderSettingsForm.MrcCompressionSettings != null && pdfEncoderSettingsForm.MrcCompressionSettings.EnableMrcCompression) { encoder.Dispose(); encoder = new PdfMrcEncoder(); ((PdfMrcEncoder)encoder).MrcCompressionSettings = pdfEncoderSettingsForm.MrcCompressionSettings; } ((IPdfEncoder)encoder).Settings = pdfEncoderSettingsForm.EncoderSettings; ((MultipageEncoderBase)encoder).CreateNewFile = !pdfEncoderSettingsForm.AppendExistingDocument; return(true); } #endif case "Jbig2": using (Jbig2EncoderSettingsForm jbig2EncoderSettingsForm = new Jbig2EncoderSettingsForm()) { SetEncoderSettingsDialogProperties(jbig2EncoderSettingsForm); jbig2EncoderSettingsForm.AppendExistingDocumentEnabled = canAddImagesToExistingFile; if (jbig2EncoderSettingsForm.ShowDialog() != DialogResult.OK) { return(false); } ((IJbig2Encoder)encoder).Settings = jbig2EncoderSettingsForm.EncoderSettings; ((MultipageEncoderBase)encoder).CreateNewFile = !jbig2EncoderSettingsForm.AppendExistingDocument; return(true); } } return(false); }
/// <summary> /// Shows the encoder settings dialog and initializes the encoder. /// </summary> /// <param name="encoder">The encoder.</param> /// <param name="canAddImagesToExistingFile">The value indicating whether encoder can add images to the existing multipage image file.</param> /// <returns> /// <b>True</b> if settings are applied to the encoder; otherwise, <b>false</b>. /// </returns> protected virtual bool ShowEncoderSettingsDialog( ref EncoderBase encoder, bool canAddImagesToExistingFile) { // set encoder settings switch (encoder.Name) { case "Bmp": using (BmpEncoderSettingsForm bmpEncoderSettingsForm = new BmpEncoderSettingsForm()) { SetEncoderSettingsDialogProperties(bmpEncoderSettingsForm); if (bmpEncoderSettingsForm.ShowDialog() != DialogResult.OK) { return(false); } BmpEncoder bmpEncoder = (BmpEncoder)encoder; bmpEncoder.Settings = bmpEncoderSettingsForm.EncoderSettings; return(true); } case "Png": using (PngEncoderSettingsForm pngEncoderSettingsForm = new PngEncoderSettingsForm()) { SetEncoderSettingsDialogProperties(pngEncoderSettingsForm); if (pngEncoderSettingsForm.ShowDialog() != DialogResult.OK) { return(false); } PngEncoder pngEncoder = (PngEncoder)encoder; pngEncoder.Settings = pngEncoderSettingsForm.EncoderSettings; return(true); } case "Gif": using (GifEncoderSettingsForm gifEncoderSettingsForm = new GifEncoderSettingsForm()) { SetEncoderSettingsDialogProperties(gifEncoderSettingsForm); gifEncoderSettingsForm.CanAddImagesToExistingFile = canAddImagesToExistingFile; if (gifEncoderSettingsForm.ShowDialog() != DialogResult.OK) { return(false); } GifEncoder gifEncoder = (GifEncoder)encoder; gifEncoder.Settings = gifEncoderSettingsForm.EncoderSettings; gifEncoder.CreateNewFile = !gifEncoderSettingsForm.AddImagesToExistingFile; return(true); } case "Jpeg": using (JpegEncoderSettingsForm jpegEncoderSettingsForm = new JpegEncoderSettingsForm()) { SetEncoderSettingsDialogProperties(jpegEncoderSettingsForm); if (jpegEncoderSettingsForm.ShowDialog() != DialogResult.OK) { return(false); } JpegEncoder jpegEncoder = (JpegEncoder)encoder; jpegEncoder.Settings = jpegEncoderSettingsForm.EncoderSettings; return(true); } case "Tiff": using (TiffEncoderSettingsForm tiffEncoderSettingsForm = new TiffEncoderSettingsForm()) { SetEncoderSettingsDialogProperties(tiffEncoderSettingsForm); tiffEncoderSettingsForm.CanAddImagesToExistingFile = canAddImagesToExistingFile; if (tiffEncoderSettingsForm.ShowDialog() != DialogResult.OK) { return(false); } TiffEncoder tiffEncoder = (TiffEncoder)encoder; tiffEncoder.Settings = tiffEncoderSettingsForm.EncoderSettings; tiffEncoder.CreateNewFile = !tiffEncoderSettingsForm.AddImagesToExistingFile; return(true); } case "Svg": using (SvgEncoderSettingsForm svgEncoderSettingsForm = new SvgEncoderSettingsForm()) { SetEncoderSettingsDialogProperties(svgEncoderSettingsForm); if (svgEncoderSettingsForm.ShowDialog() != DialogResult.OK) { return(false); } SvgEncoder svgEncoder = (SvgEncoder)encoder; svgEncoder.Settings = svgEncoderSettingsForm.EncoderSettings; return(true); } } return(false); }
/// <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 ------------"); }
private bool Handshake() { Debug.Assert(m_handshaking); // Receive the greeting. while (m_greetingBytesRead < GreetingSize) { ByteArraySegment greetingSegment = new ByteArraySegment(m_greeting, m_greetingBytesRead); int n = Read(greetingSegment, GreetingSize - m_greetingBytesRead); if (n == -1) { Error(); return false; } if (n == 0) return false; m_greetingBytesRead += n; // We have received at least one byte from the peer. // If the first byte is not 0xff, we know that the // peer is using unversioned protocol. if (m_greeting[0] != 0xff) break; if (m_greetingBytesRead < 10) continue; // Inspect the right-most bit of the 10th byte (which coincides // with the 'flags' field if a regular message was sent). // Zero indicates this is a header of identity message // (i.e. the peer is using the unversioned protocol). if ((m_greeting[9] & 0x01) == 0) break; // The peer is using versioned protocol. // Send the rest of the greeting, if necessary. if (!(((byte[]) m_outpos) == ((byte[]) m_greetingOutputBuffer) && m_outpos.Offset + m_outsize == GreetingSize)) { if (m_outsize == 0) m_ioObject.SetPollout(m_handle); m_outpos[m_outsize++] = 1; // Protocol version m_outpos[m_outsize++] = (byte) m_options.SocketType; } } // Is the peer using the unversioned protocol? // If so, we send and receive rests of identity // messages. if (m_greeting[0] != 0xff || (m_greeting[9] & 0x01) == 0) { m_encoder = new Encoder(Config.OutBatchSize); m_encoder.SetMsgSource(m_session); m_decoder = new Decoder(Config.InBatchSize, m_options.Maxmsgsize); m_decoder.SetMsgSink(m_session); // We have already sent the message header. // Since there is no way to tell the encoder to // skip the message header, we simply throw that // header data away. int headerSize = m_options.IdentitySize + 1 >= 255 ? 10 : 2; byte[] tmp = new byte[10]; ByteArraySegment bufferp = new ByteArraySegment(tmp); int bufferSize = headerSize; m_encoder.GetData(ref bufferp, ref bufferSize); Debug.Assert(bufferSize == headerSize); // Make sure the decoder sees the data we have already received. m_inpos = new ByteArraySegment(m_greeting); m_insize = m_greetingBytesRead; // To allow for interoperability with peers that do not forward // their subscriptions, we inject a phony subsription // message into the incomming message stream. To put this // message right after the identity message, we temporarily // divert the message stream from session to ourselves. if (m_options.SocketType == ZmqSocketType.Pub || m_options.SocketType == ZmqSocketType.Xpub) m_decoder.SetMsgSink(this); } else if (m_greeting[VersionPos] == 0) { // ZMTP/1.0 framing. m_encoder = new Encoder(Config.OutBatchSize); m_encoder.SetMsgSource(m_session); m_decoder = new Decoder(Config.InBatchSize, m_options.Maxmsgsize); m_decoder.SetMsgSink(m_session); } else { // v1 framing protocol. m_encoder = new V1Encoder(Config.OutBatchSize, m_session); m_decoder = new V1Decoder(Config.InBatchSize, m_options.Maxmsgsize, m_session); } // Start polling for output if necessary. if (m_outsize == 0) m_ioObject.SetPollout(m_handle); // Handshaking was successful. // Switch into the normal message flow. m_handshaking = false; return true; }