From 62c763db7736f1b316c0d56703a53ae6a44b7fe1 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Sun, 27 Dec 2020 11:27:38 +0100 Subject: [PATCH 01/24] remived optional arg optionalSegmentArg from GetNumSynapses --- NeoCortexApi/NeoCortexEntities/Entities/Connections.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs index 880168fd9..dd83ef328 100644 --- a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs +++ b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs @@ -1186,7 +1186,7 @@ private Synapse MinPermanenceSynapse(DistalDendrite dd) /// /// An optional Segment to specify the context of the synapse count. /// Either the total number of synapses or the number on a specified segment. - public long GetNumSynapses(DistalDendrite optionalSegmentArg = null) + public long GetNumSynapses(DistalDendrite optionalSegmentArg ) { if (optionalSegmentArg != null) { From eb24a8d67fdfcf20c2daf4235efbd0b57700d7c6 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Sun, 27 Dec 2020 11:32:40 +0100 Subject: [PATCH 02/24] full PDB enabled --- .../DistributedComputeLib/DistributedComputeLib.csproj | 2 ++ NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj | 2 ++ NeoCortexApi/NeoCortexApi/TemporalMemory.cs | 8 ++++---- NeoCortexApi/NeoCortexArrayLib/NeoCortexArrayLib.csproj | 4 +++- NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj | 2 ++ NeoCortexApi/NeoCortexUtils/NeoCortexUtils.csproj | 2 ++ .../Samples/NeoCortexApiSample/NeoCortexApiSample.csproj | 5 +++++ 7 files changed, 20 insertions(+), 5 deletions(-) diff --git a/NeoCortexApi/DistributedComputeLib/DistributedComputeLib.csproj b/NeoCortexApi/DistributedComputeLib/DistributedComputeLib.csproj index d1886a6ca..3b4e1f27d 100644 --- a/NeoCortexApi/DistributedComputeLib/DistributedComputeLib.csproj +++ b/NeoCortexApi/DistributedComputeLib/DistributedComputeLib.csproj @@ -7,6 +7,8 @@ C:\dev\NeoCortexAPI\neocortexapi\NeoCortexApi\DistributedComputeLib\DistributedComputeLib.xml + full + true diff --git a/NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj b/NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj index 7d43021b2..2e1a2f94b 100644 --- a/NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj +++ b/NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj @@ -26,6 +26,8 @@ 7.3 C:\dev\git\neocortexapi\NeoCortexApi\NeoCortexApi\NeoCortexApi.xml TRACE;USE_AKKA + full + true diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs index ff7617334..d715f3720 100644 --- a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs +++ b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs @@ -71,7 +71,7 @@ public void Init(Connections conn) } //StreamWriter tmperf1 = new StreamWriter("tm-perf-100000-10cells.csv"); - + /// /// Performs the whole calculation of Temporal memory algorithm. @@ -90,9 +90,9 @@ public ComputeCycle Compute(int[] activeColumns, bool learn) //Stopwatch sw = new Stopwatch(); //sw.Start(); ComputeCycle cycle = ActivateCells(this.connections, activeColumns, learn); - + ActivateDendrites(this.connections, cycle, learn); - + //sw.Stop(); //tmperf1.WriteLine($"{sw.ElapsedMilliseconds}"); @@ -686,7 +686,7 @@ public void AdaptSegment(Connections conn, DistalDendrite segment, ICollection synapsesToDestroy = new List(); //DD oreach (Synapse synapse in conn.GetSynapses(segment)) - foreach (Synapse synapse in segment.Synapses) + foreach (Synapse synapse in segment.Synapses) { double permanence = synapse.Permanence; diff --git a/NeoCortexApi/NeoCortexArrayLib/NeoCortexArrayLib.csproj b/NeoCortexApi/NeoCortexArrayLib/NeoCortexArrayLib.csproj index 24caf7f23..3364d1a2f 100644 --- a/NeoCortexApi/NeoCortexArrayLib/NeoCortexArrayLib.csproj +++ b/NeoCortexApi/NeoCortexArrayLib/NeoCortexArrayLib.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,8 @@ C:\dev\NeoCortexAPI\neocortexapi\NeoCortexApi\NeoCortexArrayLib\NeoCortexArrayLib.xml + full + true diff --git a/NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj b/NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj index 2a6661dd8..e6a6c2c33 100644 --- a/NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj +++ b/NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj @@ -9,6 +9,8 @@ TRACE;USE_AKKA C:\dev\NeoCortexAPI\neocortexapi\NeoCortexApi\NeoCortexEntities\NeoCortexEntities.xml + full + true TRACE;USE_AKKA diff --git a/NeoCortexApi/NeoCortexUtils/NeoCortexUtils.csproj b/NeoCortexApi/NeoCortexUtils/NeoCortexUtils.csproj index 66ea6fa96..280c14deb 100644 --- a/NeoCortexApi/NeoCortexUtils/NeoCortexUtils.csproj +++ b/NeoCortexApi/NeoCortexUtils/NeoCortexUtils.csproj @@ -6,6 +6,8 @@ C:\dev\NeoCortexAPI\neocortexapi\NeoCortexApi\NeoCortexUtils\NeoCortexUtils.xml + full + true diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/NeoCortexApiSample.csproj b/NeoCortexApi/Samples/NeoCortexApiSample/NeoCortexApiSample.csproj index 9c5700835..caed2ae9f 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/NeoCortexApiSample.csproj +++ b/NeoCortexApi/Samples/NeoCortexApiSample/NeoCortexApiSample.csproj @@ -6,6 +6,11 @@ + + full + true + + From 1bb115fccbe8727a2fd9d4a0ec002d702c881028 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Sun, 27 Dec 2020 11:37:13 +0100 Subject: [PATCH 03/24] full PDB --- NeoCortexApi/AkkaSb.Net/AkkaSb.Net.csproj | 2 ++ NeoCortexApi/HtmAkkaHost/HtmAkkaHost.csproj | 5 +++++ NeoCortexApi/UnitTestsProject/UnitTestsProject.csproj | 2 ++ .../WebSocketNeuroVisualizer.csproj | 7 ++++++- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/NeoCortexApi/AkkaSb.Net/AkkaSb.Net.csproj b/NeoCortexApi/AkkaSb.Net/AkkaSb.Net.csproj index 69e93ace1..724f66c66 100644 --- a/NeoCortexApi/AkkaSb.Net/AkkaSb.Net.csproj +++ b/NeoCortexApi/AkkaSb.Net/AkkaSb.Net.csproj @@ -10,6 +10,8 @@ C:\dev\NeoCortexAPI\neocortexapi\NeoCortexApi\AkkaSb.Net\AkkaSb.Net.xml Auto + full + true diff --git a/NeoCortexApi/HtmAkkaHost/HtmAkkaHost.csproj b/NeoCortexApi/HtmAkkaHost/HtmAkkaHost.csproj index bca410414..8140e786d 100644 --- a/NeoCortexApi/HtmAkkaHost/HtmAkkaHost.csproj +++ b/NeoCortexApi/HtmAkkaHost/HtmAkkaHost.csproj @@ -6,6 +6,11 @@ Linux + + full + true + + diff --git a/NeoCortexApi/UnitTestsProject/UnitTestsProject.csproj b/NeoCortexApi/UnitTestsProject/UnitTestsProject.csproj index edac8748a..f9d575f01 100644 --- a/NeoCortexApi/UnitTestsProject/UnitTestsProject.csproj +++ b/NeoCortexApi/UnitTestsProject/UnitTestsProject.csproj @@ -8,6 +8,8 @@ TRACE;USE_AKKA + full + true diff --git a/NeoCortexApi/WebSocketNeuroVisualizer/WebSocketNeuroVisualizer.csproj b/NeoCortexApi/WebSocketNeuroVisualizer/WebSocketNeuroVisualizer.csproj index fef1422de..8d795e1c7 100644 --- a/NeoCortexApi/WebSocketNeuroVisualizer/WebSocketNeuroVisualizer.csproj +++ b/NeoCortexApi/WebSocketNeuroVisualizer/WebSocketNeuroVisualizer.csproj @@ -1,9 +1,14 @@ - + netstandard2.1 + + full + true + + From d62062368482d62f50425820e8ca6270f30e4f9c Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Sun, 27 Dec 2020 13:56:46 +0100 Subject: [PATCH 04/24] Full debug info enabled. --- NeoCortexApi/AkkaSb.Net/AkkaSb.Net.csproj | 5 +++++ .../DistributedComputeLib/DistributedComputeLib.csproj | 5 +++++ NeoCortexApi/HtmAkkaHost/HtmAkkaHost.csproj | 5 +++++ NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj | 5 +++++ NeoCortexApi/NeoCortexArrayLib/NeoCortexArrayLib.csproj | 5 +++++ NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj | 2 ++ NeoCortexApi/NeoCortexUtils/NeoCortexUtils.csproj | 5 +++++ .../Samples/NeoCortexApiSample/NeoCortexApiSample.csproj | 5 +++++ NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs | 2 +- NeoCortexApi/UnitTestsProject/UnitTestsProject.csproj | 5 +++++ .../WebSocketNeuroVisualizer/WebSocketNeuroVisualizer.csproj | 5 +++++ 11 files changed, 48 insertions(+), 1 deletion(-) diff --git a/NeoCortexApi/AkkaSb.Net/AkkaSb.Net.csproj b/NeoCortexApi/AkkaSb.Net/AkkaSb.Net.csproj index 724f66c66..7661894c9 100644 --- a/NeoCortexApi/AkkaSb.Net/AkkaSb.Net.csproj +++ b/NeoCortexApi/AkkaSb.Net/AkkaSb.Net.csproj @@ -14,6 +14,11 @@ true + + full + true + + diff --git a/NeoCortexApi/DistributedComputeLib/DistributedComputeLib.csproj b/NeoCortexApi/DistributedComputeLib/DistributedComputeLib.csproj index 3b4e1f27d..72bc9c55b 100644 --- a/NeoCortexApi/DistributedComputeLib/DistributedComputeLib.csproj +++ b/NeoCortexApi/DistributedComputeLib/DistributedComputeLib.csproj @@ -11,6 +11,11 @@ true + + full + true + + diff --git a/NeoCortexApi/HtmAkkaHost/HtmAkkaHost.csproj b/NeoCortexApi/HtmAkkaHost/HtmAkkaHost.csproj index 8140e786d..ab1d8e89c 100644 --- a/NeoCortexApi/HtmAkkaHost/HtmAkkaHost.csproj +++ b/NeoCortexApi/HtmAkkaHost/HtmAkkaHost.csproj @@ -11,6 +11,11 @@ true + + full + true + + diff --git a/NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj b/NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj index 2e1a2f94b..3c0084eae 100644 --- a/NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj +++ b/NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj @@ -30,6 +30,11 @@ true + + full + true + + diff --git a/NeoCortexApi/NeoCortexArrayLib/NeoCortexArrayLib.csproj b/NeoCortexApi/NeoCortexArrayLib/NeoCortexArrayLib.csproj index 3364d1a2f..7e692a13d 100644 --- a/NeoCortexApi/NeoCortexArrayLib/NeoCortexArrayLib.csproj +++ b/NeoCortexApi/NeoCortexArrayLib/NeoCortexArrayLib.csproj @@ -10,4 +10,9 @@ true + + full + true + + diff --git a/NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj b/NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj index e6a6c2c33..31606eed8 100644 --- a/NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj +++ b/NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj @@ -14,6 +14,8 @@ TRACE;USE_AKKA + full + true diff --git a/NeoCortexApi/NeoCortexUtils/NeoCortexUtils.csproj b/NeoCortexApi/NeoCortexUtils/NeoCortexUtils.csproj index 280c14deb..503f5041e 100644 --- a/NeoCortexApi/NeoCortexUtils/NeoCortexUtils.csproj +++ b/NeoCortexApi/NeoCortexUtils/NeoCortexUtils.csproj @@ -10,6 +10,11 @@ true + + full + true + + diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/NeoCortexApiSample.csproj b/NeoCortexApi/Samples/NeoCortexApiSample/NeoCortexApiSample.csproj index caed2ae9f..0b0780bb8 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/NeoCortexApiSample.csproj +++ b/NeoCortexApi/Samples/NeoCortexApiSample/NeoCortexApiSample.csproj @@ -11,6 +11,11 @@ true + + full + true + + diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs index 0810aebb2..30bb08a7a 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs +++ b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs @@ -144,7 +144,7 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li activeColumnsLst.Add(input, new List>()); } - int maxCycles = 100;// 3500; + int maxCycles = 3500; int maxPrevInputs = inputValues.Count - 1; List previousInputs = new List(); previousInputs.Add("-1.0"); diff --git a/NeoCortexApi/UnitTestsProject/UnitTestsProject.csproj b/NeoCortexApi/UnitTestsProject/UnitTestsProject.csproj index f9d575f01..da09e5312 100644 --- a/NeoCortexApi/UnitTestsProject/UnitTestsProject.csproj +++ b/NeoCortexApi/UnitTestsProject/UnitTestsProject.csproj @@ -12,6 +12,11 @@ true + + full + true + + diff --git a/NeoCortexApi/WebSocketNeuroVisualizer/WebSocketNeuroVisualizer.csproj b/NeoCortexApi/WebSocketNeuroVisualizer/WebSocketNeuroVisualizer.csproj index 8d795e1c7..b2bb61db5 100644 --- a/NeoCortexApi/WebSocketNeuroVisualizer/WebSocketNeuroVisualizer.csproj +++ b/NeoCortexApi/WebSocketNeuroVisualizer/WebSocketNeuroVisualizer.csproj @@ -9,6 +9,11 @@ true + + full + true + + From ef992a0a02cfacf5be659c801366ae4f4199de08 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Sun, 27 Dec 2020 14:41:30 +0100 Subject: [PATCH 05/24] Working on TMMT --- NeoCortexApi/NeoCortexApi/TemporalMemory.cs | 130 +++++++++++++++++- .../Entities/ComputeCycle.cs | 8 +- .../NeoCortexApiSample/SequenceLearning.cs | 2 +- 3 files changed, 132 insertions(+), 8 deletions(-) diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs index d715f3720..dd787210a 100644 --- a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs +++ b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs @@ -9,6 +9,8 @@ using static NeoCortexApi.Entities.Connections; using System.Diagnostics; using System.IO; +using System.Threading.Tasks; +using System.Collections.Concurrent; namespace NeoCortexApi { @@ -127,6 +129,128 @@ protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices ActivColumnIndicies = activeColumnIndices }; + ConcurrentDictionary cycles = new ConcurrentDictionary(); + + ColumnData activeColumnData = new ColumnData(); + + ISet prevActiveCells = conn.ActiveCells; + ISet prevWinnerCells = conn.WinnerCells; + + // The list of active columns. + List activeColumns = new List(); + + foreach (var indx in activeColumnIndices.OrderBy(i => i)) + { + activeColumns.Add(conn.GetColumn(indx)); + } + + Func segToCol = (segment) => + { + var colIndx = ((DistalDendrite)segment).ParentCell.ParentColumnIndex; + var parentCol = this.connections.HtmConfig.Memory.GetColumn(colIndx); + return parentCol; + }; + + Func times1Fnc = x => (Column)x; + + var list = new Pair, Func>[3]; + list[0] = new Pair, Func>(Array.ConvertAll(activeColumns.ToArray(), item => (object)item).ToList(), times1Fnc); + list[1] = new Pair, Func>(Array.ConvertAll(conn.ActiveSegments.ToArray(), item => (object)item).ToList(), segToCol); + list[2] = new Pair, Func>(Array.ConvertAll(conn.MatchingSegments.ToArray(), item => (object)item).ToList(), segToCol); + + GroupBy2 grouper = GroupBy2.Of(list); + + double permanenceIncrement = conn.HtmConfig.PermanenceIncrement; + double permanenceDecrement = conn.HtmConfig.PermanenceDecrement; + + ParallelOptions opts = new ParallelOptions + { + MaxDegreeOfParallelism = Environment.ProcessorCount + }; + + // + // Grouping by columns, which have active and matching segments. + Parallel.ForEach(grouper, opts, (tuple) => + { + activeColumnData = activeColumnData.Set(tuple); + + if (activeColumnData.IsExistAnyActiveCol(cIndexofACTIVE_COLUMNS)) + { + // If there are some active segments on the column already... + if (activeColumnData.ActiveSegments != null && activeColumnData.ActiveSegments.Count > 0) + { + //Debug.Write("."); + + List cellsOwnersOfActSegs = ActivatePredictedColumn(conn, activeColumnData.ActiveSegments, + activeColumnData.MatchingSegments, prevActiveCells, prevWinnerCells, + permanenceIncrement, permanenceDecrement, learn, cycle.ActiveSynapses); + + ComputeCycle colCycle = new ComputeCycle(); + cycles[tuple.Key.Index] = colCycle; + + foreach (var item in cellsOwnersOfActSegs) + { + colCycle.ActiveCells.Add(item); + colCycle.WinnerCells.Add(item); + } + } + else + { + // + // If no active segments are detected (start of learning) then all cells are activated + // and a random single cell is chosen as a winner. + BurstingResult burstingResult = BurstColumn(conn, activeColumnData.Column(), activeColumnData.MatchingSegments, + prevActiveCells, prevWinnerCells, permanenceIncrement, permanenceDecrement, conn.HtmConfig.Random, + learn); + + // DRAFT. Removing this as unnecessary. + //cycle.ActiveCells.Add(burstingResult.BestCell); + + ComputeCycle colCycle = new ComputeCycle(); + cycles[tuple.Key.Index] = colCycle; + + // + // Here we activate all cells by putting them to list of active cells. + foreach (var item in burstingResult.Cells) + { + colCycle.ActiveCells.Add(item); + } + + //var actSyns = conn.getReceptorSynapses(burstingResult.BestCell).Where(s=>prevActiveCells.Contains(s.SourceCell)); + //foreach (var syn in actSyns) + //{ + // cycle.ActiveSynapses.Add(syn); + //} + + colCycle.WinnerCells.Add((Cell)burstingResult.BestCell); + } + } + else + { + if (learn) + { + PunishPredictedColumn(conn, activeColumnData.ActiveSegments, activeColumnData.MatchingSegments, + prevActiveCells, prevWinnerCells, conn.HtmConfig.PredictedSegmentDecrement); + } + } + }); + + foreach (var colCycle in cycles.Values) + { + cycle.ActiveCells.AddRange(colCycle.ActiveCells); + cycle.WinnerCells.AddRange(colCycle.WinnerCells); + } + + return cycle; + } + + protected ComputeCycle ActivateCellsOriginal(Connections conn, int[] activeColumnIndices, bool learn) + { + ComputeCycle cycle = new ComputeCycle + { + ActivColumnIndicies = activeColumnIndices + }; + ColumnData activeColumnData = new ColumnData(); ISet prevActiveCells = conn.ActiveCells; @@ -170,7 +294,7 @@ protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices // If there are some active segments on the column already... if (activeColumnData.ActiveSegments != null && activeColumnData.ActiveSegments.Count > 0) { - Debug.Write("."); + //Debug.Write("."); List cellsOwnersOfActSegs = ActivatePredictedColumn(conn, activeColumnData.ActiveSegments, activeColumnData.MatchingSegments, prevActiveCells, prevWinnerCells, @@ -475,7 +599,7 @@ public BurstingResult BurstColumn(Connections conn, Column column, List 0) { - Debug.Write($"B.({matchingSegments.Count})"); + // Debug.Write($"B.({matchingSegments.Count})"); DistalDendrite maxPotentialSeg = GetSegmentwithHighesPotential(conn, matchingSegments, prevActiveCells); @@ -496,7 +620,7 @@ public BurstingResult BurstColumn(Connections conn, Column column, List, NeoCortexApi.IModuleData /// if the number of active synapses (permanence higher than connectedPermanence) on that segment is higher than activationThreshold value. /// A Cell is by default in predictive state (depolarized state) if it owns the active dendrite segment. /// - private IList m_PredictiveCells = new List(); + private List m_PredictiveCells = new List(); /// /// Gets the list of active cells. /// - public IList ActiveCells { get; set; } = new List(); + public List ActiveCells { get; set; } = new List(); /// /// Gets the list of winner cells. /// - public IList WinnerCells { get; set; } = new List(); + public List WinnerCells { get; set; } = new List(); /// /// Synapses that create connections to currentlly active cells owners of active segments. /// - public IList ActiveSynapses { get; set; } = new List(); + public List ActiveSynapses { get; set; } = new List(); public int[] ActivColumnIndicies{ get; set; } diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs index 30bb08a7a..990af41fc 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs +++ b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs @@ -24,7 +24,7 @@ public void Run() Console.WriteLine($"Hello NeocortexApi! Experiment {nameof(SequenceLearning)}"); int inputBits = 100; - int numColumns = 1024; + int numColumns = 100000; HtmConfig cfg = new HtmConfig(new int[] { inputBits }, new int[] { numColumns }) { From 0b3f04669bac1a977a07acc3fc0c5e66950834ad Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Sun, 27 Dec 2020 15:28:05 +0100 Subject: [PATCH 06/24] Segments moved to cell --- NeoCortexApi/NeoCortexApi.xml | 2 +- NeoCortexApi/NeoCortexApi/TemporalMemory.cs | 4 +- .../NeoCortexEntities/Entities/Cell.cs | 12 ++- .../NeoCortexEntities/Entities/Column.cs | 4 +- .../NeoCortexEntities/Entities/Connections.cs | 95 ++++++++++--------- .../NeoCortexApiSample/SequenceLearning.cs | 2 +- .../UnitTestsProject/TemporalMemoryTests.cs | 50 +++++++--- 7 files changed, 105 insertions(+), 64 deletions(-) diff --git a/NeoCortexApi/NeoCortexApi.xml b/NeoCortexApi/NeoCortexApi.xml index 5fdde630f..3b38091ad 100644 --- a/NeoCortexApi/NeoCortexApi.xml +++ b/NeoCortexApi/NeoCortexApi.xml @@ -1887,7 +1887,7 @@ Note: PredictiveCells are not calculated here. They are calculated on demand from active segments. - + Calculate the active cells, using the current active columns and dendrite segments. Grow and reinforce synapses. diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs index dd787210a..07b2fc620 100644 --- a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs +++ b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs @@ -122,7 +122,7 @@ public ComputeCycle Compute(int[] activeColumns, bool learn) /// /// /// - protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices, bool learn) + protected ComputeCycle ActivateCellsParallel(Connections conn, int[] activeColumnIndices, bool learn) { ComputeCycle cycle = new ComputeCycle { @@ -244,7 +244,7 @@ protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices return cycle; } - protected ComputeCycle ActivateCellsOriginal(Connections conn, int[] activeColumnIndices, bool learn) + protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices, bool learn) { ComputeCycle cycle = new ComputeCycle { diff --git a/NeoCortexApi/NeoCortexEntities/Entities/Cell.cs b/NeoCortexApi/NeoCortexEntities/Entities/Cell.cs index b5c7e4ca2..46232b4e6 100644 --- a/NeoCortexApi/NeoCortexEntities/Entities/Cell.cs +++ b/NeoCortexApi/NeoCortexEntities/Entities/Cell.cs @@ -31,6 +31,8 @@ public class Cell : IEquatable, IComparable /// private readonly int m_Hashcode; + public List DistalDendrites { get; set; } = new List(); + /// /// Used for testing. /// @@ -75,10 +77,12 @@ public ISet GetReceptorSynapses(Connections c, bool doLazyCreate = fals /// the connections state of the temporal memory /// create a container for future use if true, if false return an orphaned empty set. /// a of this 's s - public List GetSegments(Connections c, bool doLazyCreate = false) - { - return c.GetSegments(this, doLazyCreate); - } + //public List GetSegments(Connections c, bool doLazyCreate = false) + //{ + // //DD + // //return c.GetSegments(this, doLazyCreate); + // return this.DistalDendrites; + //} /// /// Gets the hashcode of the cell. diff --git a/NeoCortexApi/NeoCortexEntities/Entities/Column.cs b/NeoCortexApi/NeoCortexEntities/Entities/Column.cs index b9b26b080..c4c25f2f4 100644 --- a/NeoCortexApi/NeoCortexEntities/Entities/Column.cs +++ b/NeoCortexApi/NeoCortexEntities/Entities/Column.cs @@ -108,7 +108,9 @@ public Cell GetLeastUsedCell(Connections c, Random random) foreach (var cell in Cells) { - int numSegments = cell.GetSegments(c).Count; + //DD + //int numSegments = cell.GetSegments(c).Count; + int numSegments = cell.DistalDendrites.Count; //int numSegments = cell.Segments.Count; if (numSegments < minNumSegments) diff --git a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs index dd83ef328..453039c50 100644 --- a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs +++ b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs @@ -20,7 +20,7 @@ public class Connections public static readonly double EPSILON = 0.00001; - //Internal state + //Internal state private double version = 1.0; /// @@ -38,7 +38,7 @@ public class Connections private double[] m_BoostedmOverlaps; private int[] m_Overlaps; - + /// /// Initialize a tiny random tie breaker. This is used to determine winning /// columns where the overlaps are identical. @@ -64,7 +64,7 @@ public class Connections /// One of all active column cells will be selected as the winner cell. /// public ISet WinnerCells { get => winnerCells; set => winnerCells = value; } - + /// /// All cells. Initialized during initialization of the TemporalMemory. /// @@ -72,7 +72,7 @@ public class Connections private double[] m_BoostFactors; - + private ISet m_ActiveCells = new LinkedHashSet(); private ISet winnerCells = new LinkedHashSet(); private ISet m_PredictiveCells = new LinkedHashSet(); @@ -154,12 +154,12 @@ private set /// /// Reverse mapping from source cell to /// - private Dictionary> m_ReceptorSynapses; + private Dictionary> m_ReceptorSynapses = new Dictionary>(); /// /// Distal segments of cells. /// - protected Dictionary> m_DistalSegments; + //protected Dictionary> m_DistalSegments = new Dictionary>(); /// We moved this as a poart of the segment. /// @@ -240,7 +240,7 @@ public Connections(HtmConfig prms) #endregion #region General Methods - + /// /// Returns the specified by the index passed in. /// @@ -882,7 +882,7 @@ public void StartNewIteration() ///////////////////////////////////////////////////////////////// // Segment (Specifically, Distal Dendrite) Operations // ///////////////////////////////////////////////////////////////// - + #region Segment (Specifically, Distal Dendrite) methods /// /// Adds a new segment on the specified , or reuses an existing one. @@ -917,7 +917,8 @@ public DistalDendrite CreateDistalSegment(Cell segmentParentCell) ++m_NextSegmentOrdinal; DistalDendrite segment = new DistalDendrite(segmentParentCell, flatIdx, m_TMIteration, ordinal, this.HtmConfig.SynPermConnected, this.HtmConfig.NumInputs); - GetSegments(segmentParentCell, true).Add(segment); + segmentParentCell.DistalDendrites.Add(segment); + //GetSegments(segmentParentCell, true).Add(segment); m_SegmentForFlatIdx[flatIdx] = segment; return segment; @@ -944,7 +945,9 @@ public void DestroySegment(DistalDendrite segment) m_NumSynapses -= len; // Remove the segment from the cell's list. - GetSegments(segment.ParentCell).Remove(segment); + //DD + //GetSegments(segment.ParentCell).Remove(segment); + segment.ParentCell.DistalDendrites.Remove(segment); // Remove the segment from the map //DD m_DistalSynapses.Remove(segment); @@ -962,7 +965,10 @@ public void DestroySegment(DistalDendrite segment) /// the least recently activated segment on the specified cell. private DistalDendrite LeastRecentlyUsedSegment(Cell cell) { - List segments = GetSegments(cell, false); + //DD + //List segments = GetSegments(cell, false); + List segments = cell.DistalDendrites; + DistalDendrite minSegment = null; long minIteration = long.MaxValue; @@ -1001,7 +1007,9 @@ public int NumSegments(Cell cell = null) { if (cell != null) { - return GetSegments(cell).Count; + //DD + //return GetSegments(cell).Count; + return cell.DistalDendrites.Count; } return m_NextFlatIdx - m_FreeFlatIdxs.Count; @@ -1017,33 +1025,34 @@ public int NumSegments(Cell cell = null) // return GetSegments(cell, false); //} + //DD /// /// Returns the mapping of s to their s. /// /// the used as a key. /// create a container for future use if true, if false return an orphaned empty set. /// the mapping of s to their s. - public List GetSegments(Cell cell, bool doLazyCreate = false) - { - if (cell == null) - { - throw new ArgumentException("Cell was null"); - } + //public List GetSegments(Cell cell, bool doLazyCreate = false) + //{ + // if (cell == null) + // { + // throw new ArgumentException("Cell was null"); + // } - if (m_DistalSegments == null) - { - m_DistalSegments = new Dictionary>(); - } + // //if (m_DistalSegments == null) + // //{ + // // m_DistalSegments = new Dictionary>(); + // //} - List retVal; - if ((m_DistalSegments.TryGetValue(cell, out retVal)) == false) - { - if (!doLazyCreate) return new List(); - m_DistalSegments.Add(cell, retVal = new List()); - } + // List retVal; + // if ((m_DistalSegments.TryGetValue(cell, out retVal)) == false) + // { + // if (!doLazyCreate) return new List(); + // m_DistalSegments.Add(cell, retVal = new List()); + // } - return retVal; - } + // return retVal; + //} /// /// Get the segment with the specified flatIdx. @@ -1070,10 +1079,10 @@ public int ColumnIndexForSegment(DistalDendrite segment) /// FOR TEST USE ONLY /// /// - public Dictionary> GetSegmentMapping() - { - return new Dictionary>(m_DistalSegments); - } + //public Dictionary> GetSegmentMapping() + //{ + // return new Dictionary>(m_DistalSegments); + //} /// /// Set/retrieved by the following a compute cycle. @@ -1106,9 +1115,9 @@ public Synapse CreateSynapse(DistalDendrite segment, Cell presynapticCell, doubl Synapse synapse = null; //DD GetSynapses(segment).Add( - segment.Synapses.Add( - synapse = new Synapse( - presynapticCell, segment.SegmentIndex, m_NextSynapseOrdinal, permanence)); + segment.Synapses.Add( + synapse = new Synapse( + presynapticCell, segment.SegmentIndex, m_NextSynapseOrdinal, permanence)); GetReceptorSynapses(presynapticCell, true).Add(synapse); @@ -1186,7 +1195,7 @@ private Synapse MinPermanenceSynapse(DistalDendrite dd) /// /// An optional Segment to specify the context of the synapse count. /// Either the total number of synapses or the number on a specified segment. - public long GetNumSynapses(DistalDendrite optionalSegmentArg ) + public long GetNumSynapses(DistalDendrite optionalSegmentArg) { if (optionalSegmentArg != null) { @@ -1213,10 +1222,10 @@ public LinkedHashSet GetReceptorSynapses(Cell cell, bool doLazyCreate = throw new ArgumentException("Cell was null"); } - if (m_ReceptorSynapses == null) - { - m_ReceptorSynapses = new Dictionary>(); - } + //if (m_ReceptorSynapses == null) + //{ + // m_ReceptorSynapses = new Dictionary>(); + //} LinkedHashSet retVal = null; if (m_ReceptorSynapses.TryGetValue(cell, out retVal) == false) @@ -1577,7 +1586,7 @@ public override int GetHashCode() result = prime * result + ((this.HtmConfig.Random == null) ? 0 : this.HtmConfig.Random.GetHashCode()); result = prime * result + ((m_ReceptorSynapses == null) ? 0 : m_ReceptorSynapses.GetHashCode()); result = prime * result + this.HtmConfig.RandomGenSeed; - result = prime * result + ((m_DistalSegments == null) ? 0 : m_DistalSegments.GetHashCode()); + //result = prime * result + ((m_DistalSegments == null) ? 0 : m_DistalSegments.GetHashCode()); temp = BitConverter.DoubleToInt64Bits(this.HtmConfig.StimulusThreshold); result = prime * result + (int)(temp ^ (temp >> 32)); temp = BitConverter.DoubleToInt64Bits(this.HtmConfig.SynPermActiveInc); diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs index 990af41fc..30bb08a7a 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs +++ b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs @@ -24,7 +24,7 @@ public void Run() Console.WriteLine($"Hello NeocortexApi! Experiment {nameof(SequenceLearning)}"); int inputBits = 100; - int numColumns = 100000; + int numColumns = 1024; HtmConfig cfg = new HtmConfig(new int[] { inputBits }, new int[] { numColumns }) { diff --git a/NeoCortexApi/UnitTestsProject/TemporalMemoryTests.cs b/NeoCortexApi/UnitTestsProject/TemporalMemoryTests.cs index 3f7d4ae76..c689f1559 100644 --- a/NeoCortexApi/UnitTestsProject/TemporalMemoryTests.cs +++ b/NeoCortexApi/UnitTestsProject/TemporalMemoryTests.cs @@ -415,7 +415,9 @@ public void TestNewSegmentAddSynapsesToSubsetOfWinnerCells() List winnerCells = new List(cc.WinnerCells); Assert.AreEqual(1, winnerCells.Count); - List segments = winnerCells[0].GetSegments(cn); + //DD + //List segments = winnerCells[0].GetSegments(cn); + List segments = winnerCells[0].DistalDendrites; //List segments = winnerCells[0].Segments; Assert.AreEqual(1, segments.Count); @@ -451,7 +453,11 @@ public void TestNewSegmentAddSynapsesToAllWinnerCells() List winnerCells = new List(cc.WinnerCells); Assert.AreEqual(1, winnerCells.Count); - List segments = winnerCells[0].GetSegments(cn); + + //DD + //List segments = winnerCells[0].GetSegments(cn); + List segments = winnerCells[0].DistalDendrites; + //List segments = winnerCells[0].Segments; Assert.AreEqual(1, segments.Count); List synapses = segments[0].GetAllSynapses(cn); @@ -725,13 +731,19 @@ public void TestRecycleLeastRecentlyActiveSegmentToMakeRoomForNewSegment() tm.Compute(prevActiveColumns1, true); tm.Compute(activeColumns, true); - Assert.AreEqual(1, cn.GetSegments(cell9).Count); - DistalDendrite oldestSegment = cn.GetSegments(cell9)[0]; + //DD + //Assert.AreEqual(1, cn.GetSegments(cell9).Count); + Assert.AreEqual(1, cell9.DistalDendrites.Count); + //DD + //DistalDendrite oldestSegment = cn.GetSegments(cell9)[0]; + DistalDendrite oldestSegment = cell9.DistalDendrites[0]; tm.Reset(cn); tm.Compute(prevActiveColumns2, true); tm.Compute(activeColumns, true); - Assert.AreEqual(2, cn.GetSegments(cell9).Count); + //DD + //Assert.AreEqual(2, cn.GetSegments(cell9).Count); + Assert.AreEqual(2, cell9.DistalDendrites.Count); //Set oldPresynaptic = cn.getSynapses(oldestSegment) // .stream() @@ -744,12 +756,17 @@ public void TestRecycleLeastRecentlyActiveSegmentToMakeRoomForNewSegment() tm.Reset(cn); tm.Compute(prevActiveColumns3, true); tm.Compute(activeColumns, true); - Assert.AreEqual(2, cn.GetSegments(cell9).Count); + + //DD + //Assert.AreEqual(2, cn.GetSegments(cell9).Count); + Assert.AreEqual(2, cell9.DistalDendrites.Count); // Verify none of the segments are connected to the cells the old // segment was connected to. - foreach (DistalDendrite segment in cn.GetSegments(cell9)) + //DD + //foreach (DistalDendrite segment in cn.GetSegments(cell9)) + foreach (DistalDendrite segment in cell9.DistalDendrites) { //Set newPresynaptic = cn.getSynapses(segment) // .stream() @@ -870,10 +887,14 @@ public void TestAddSegmentToCellWithFewestSegments() Assert.AreEqual(1, cn.GetNumSynapses(segment1)); Assert.AreEqual(1, cn.GetNumSynapses(segment2)); - List segments = new List(cn.GetSegments(cn.GetCell(1))); + //DD + //List segments = new List(cn.GetSegments(cn.GetCell(1))); + List segments = new List(cn.GetCell(1).DistalDendrites); if (segments.Count == 0) { - List segments2 = cn.GetSegments(cn.GetCell(2)); + //DD + //List segments2 = cn.GetSegments(cn.GetCell(2)); + List segments2 = cn.GetCell(2).DistalDendrites; Assert.IsFalse(segments2.Count == 0); grewOnCell2 = true; segments.AddRange(segments2); @@ -938,7 +959,9 @@ public void TestConnectionsNeverChangeWhenLearningDisabled() var r = deepCopyPlain(cn.GetReceptorSynapses().Values.First().First()); var synMapBefore = deepCopyPlain>>(cn.GetReceptorSynapses()); - var segMapBefore = deepCopyPlain>>(cn.GetSegmentMapping()); + //var segMapBefore = deepCopyPlain>>(cn.GetSegmentMapping()); + var actCellsBefore = cn.ActiveCells; + var winCellsBefore = cn.WinnerCells; tm.Compute(prevActiveColumns, false); tm.Compute(activeColumns, false); @@ -946,8 +969,11 @@ public void TestConnectionsNeverChangeWhenLearningDisabled() Assert.IsTrue(synMapBefore != cn.GetReceptorSynapses()); Assert.IsTrue(synMapBefore.Keys.SequenceEqual(cn.GetReceptorSynapses().Keys)); - Assert.IsTrue(segMapBefore != cn.GetSegmentMapping()); - Assert.IsTrue(segMapBefore.Keys.SequenceEqual(cn.GetSegmentMapping().Keys)); + cn.ActiveCells.SequenceEqual(actCellsBefore); + cn.WinnerCells.SequenceEqual(winCellsBefore); + //DD + //Assert.IsTrue(segMapBefore != cn.GetSegmentMapping()); + //Assert.IsTrue(segMapBefore.Keys.SequenceEqual(cn.GetSegmentMapping().Keys)); } public void TestLeastUsedCell() From d01d97a6e98a416370a24a10a7394df5a52a9013 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Sun, 27 Dec 2020 16:39:31 +0100 Subject: [PATCH 07/24] comment --- NeoCortexApi/NeoCortexEntities/Entities/Cell.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NeoCortexApi/NeoCortexEntities/Entities/Cell.cs b/NeoCortexApi/NeoCortexEntities/Entities/Cell.cs index 46232b4e6..0a2923c4a 100644 --- a/NeoCortexApi/NeoCortexEntities/Entities/Cell.cs +++ b/NeoCortexApi/NeoCortexEntities/Entities/Cell.cs @@ -31,6 +31,9 @@ public class Cell : IEquatable, IComparable /// private readonly int m_Hashcode; + /// + /// List of dendrites of the cell. + /// public List DistalDendrites { get; set; } = new List(); /// From 9f9bbb03d2352892eb05c847f09904a55b92210d Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Mon, 28 Dec 2020 10:00:07 +0100 Subject: [PATCH 08/24] m_ReceptorSynapses removed --- NeoCortexApi/NeoCortexApi/NeoCortexApi.xml | 2 +- NeoCortexApi/NeoCortexApi/TemporalMemory.cs | 4 +- .../NeoCortexEntities/Entities/Cell.cs | 17 ++-- .../NeoCortexEntities/Entities/Connections.cs | 77 ++++++++++--------- .../UnitTestsProject/TemporalMemoryTests.cs | 41 +++++++++- 5 files changed, 92 insertions(+), 49 deletions(-) diff --git a/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml b/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml index 5fdde630f..0297078a6 100644 --- a/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml +++ b/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml @@ -1887,7 +1887,7 @@ Note: PredictiveCells are not calculated here. They are calculated on demand from active segments. - + Calculate the active cells, using the current active columns and dendrite segments. Grow and reinforce synapses. diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs index 07b2fc620..eed318ed2 100644 --- a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs +++ b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs @@ -122,7 +122,7 @@ public ComputeCycle Compute(int[] activeColumns, bool learn) /// /// /// - protected ComputeCycle ActivateCellsParallel(Connections conn, int[] activeColumnIndices, bool learn) + protected ComputeCycle ActivateCellsPArallel(Connections conn, int[] activeColumnIndices, bool learn) { ComputeCycle cycle = new ComputeCycle { @@ -851,7 +851,7 @@ public void AdaptSegment(Connections conn, DistalDendrite segment, ICollection, IComparable private readonly int m_Hashcode; /// - /// List of dendrites of the cell. + /// List of dendrites of the cell. Every dendrite segment is owned bt the cell. /// public List DistalDendrites { get; set; } = new List(); + /// + /// List of receptor synapses that connect this cells as a source cell to the distal dendrit segment owned by some other cell. + /// + public List ReceptorSynapses { get; set; } = new List(); + /// /// Used for testing. /// @@ -63,15 +68,15 @@ public Cell(int parentColumnIndx, int colSeq, int numCellsPerColumn, int cellId, /// - /// Returns the Set of s which have this cell as their source cell. + /// DD Returns the Set of s which have this cell as their source cell. /// /// the connections state of the temporal memory /// create a container for future use if true, if false return an orphaned empty set. /// the Set of s which have this cell as their source cells. - public ISet GetReceptorSynapses(Connections c, bool doLazyCreate = false) - { - return c.GetReceptorSynapses(this, doLazyCreate); - } + //public ISet GetReceptorSynapses(Connections c, bool doLazyCreate = false) + //{ + // return c.GetReceptorSynapses(this, doLazyCreate); + //} /// diff --git a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs index 453039c50..d4d7ac16b 100644 --- a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs +++ b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs @@ -154,14 +154,14 @@ private set /// /// Reverse mapping from source cell to /// - private Dictionary> m_ReceptorSynapses = new Dictionary>(); + //private Dictionary> m_ReceptorSynapses = new Dictionary>(); /// /// Distal segments of cells. /// //protected Dictionary> m_DistalSegments = new Dictionary>(); - /// We moved this as a poart of the segment. + /// DD We moved this as a part of the segment. /// /// Synapses, which belong to some distal dentrite segment. /// @@ -833,7 +833,8 @@ public SegmentActivity ComputeActivity(ICollection activeCellsInCurrentCyc // Receptor synapses are synapses whose source cell (pre-synaptic cell) is the given cell. // Synapse processed here starts with the given 'cell' and points to some other cell that owns some segment in some other column. // The segment owner cell in other column pointed by synapse sourced by this 'cell' is depolirized (in predicting state). - foreach (Synapse synapse in GetReceptorSynapses(cell)) + //DD foreach (Synapse synapse in GetReceptorSynapses(cell)) + foreach (Synapse synapse in cell.ReceptorSynapses) { // Now, we get the segment of the synapse of the pre-synaptic cell. int segFlatIndx = synapse.SegmentIndex; @@ -896,7 +897,7 @@ public DistalDendrite CreateDistalSegment(Cell segmentParentCell) // least used segments will be destroyed. while (NumSegments(segmentParentCell) >= this.HtmConfig.MaxSegmentsPerCell) { - DestroySegment(LeastRecentlyUsedSegment(segmentParentCell)); + DestroyDistalDendrite(LeastRecentlyUsedSegment(segmentParentCell)); } int flatIdx; @@ -928,7 +929,7 @@ public DistalDendrite CreateDistalSegment(Cell segmentParentCell) /// Destroys a segment /// /// the segment to destroy - public void DestroySegment(DistalDendrite segment) + public void DestroyDistalDendrite(DistalDendrite segment) { // Remove the synapses from all data structures outside this Segment. //DD List synapses = GetSynapses(segment); @@ -1119,7 +1120,8 @@ public Synapse CreateSynapse(DistalDendrite segment, Cell presynapticCell, doubl synapse = new Synapse( presynapticCell, segment.SegmentIndex, m_NextSynapseOrdinal, permanence)); - GetReceptorSynapses(presynapticCell, true).Add(synapse); + presynapticCell.ReceptorSynapses.Add(synapse); + //DD GetReceptorSynapses(presynapticCell, true).Add(synapse); ++m_NextSynapseOrdinal; @@ -1152,14 +1154,17 @@ public void DestroySynapse(Synapse synapse, DistalDendrite segment) /// the synapse to remove public void RemoveSynapseFromPresynapticMap(Synapse synapse) { - LinkedHashSet presynapticSynapses; Cell cell = synapse.getPresynapticCell(); - (presynapticSynapses = GetReceptorSynapses(cell, false)).Remove(synapse); + cell.ReceptorSynapses.Remove(synapse); + //DD + //LinkedHashSet presynapticSynapses; + //Cell cell = synapse.getPresynapticCell(); + //(presynapticSynapses = GetReceptorSynapses(cell, false)).Remove(synapse); - if (presynapticSynapses.Count == 0) - { - m_ReceptorSynapses.Remove(cell); - } + //if (presynapticSynapses.Count == 0) + //{ + // m_ReceptorSynapses.Remove(cell); + //} } /// @@ -1215,27 +1220,27 @@ public long GetNumSynapses(DistalDendrite optionalSegmentArg) /// the used as a key. /// create a container for future use if true, if false return an orphaned empty set. /// the mapping of s to their reverse mapped - public LinkedHashSet GetReceptorSynapses(Cell cell, bool doLazyCreate = false) - { - if (cell == null) - { - throw new ArgumentException("Cell was null"); - } + //public LinkedHashSet GetReceptorSynapses(Cell cell, bool doLazyCreate = false) + //{ + // if (cell == null) + // { + // throw new ArgumentException("Cell was null"); + // } - //if (m_ReceptorSynapses == null) - //{ - // m_ReceptorSynapses = new Dictionary>(); - //} + // //if (m_ReceptorSynapses == null) + // //{ + // // m_ReceptorSynapses = new Dictionary>(); + // //} - LinkedHashSet retVal = null; - if (m_ReceptorSynapses.TryGetValue(cell, out retVal) == false) - { - if (!doLazyCreate) return new LinkedHashSet(); - m_ReceptorSynapses.Add(cell, retVal = new LinkedHashSet()); - } + // LinkedHashSet retVal = null; + // if (m_ReceptorSynapses.TryGetValue(cell, out retVal) == false) + // { + // if (!doLazyCreate) return new LinkedHashSet(); + // m_ReceptorSynapses.Add(cell, retVal = new LinkedHashSet()); + // } - return retVal; - } + // return retVal; + //} /// /// Returns synapeses of specified dentrite segment. @@ -1264,15 +1269,15 @@ public LinkedHashSet GetReceptorSynapses(Cell cell, bool doLazyCreate = //} - + //DD /// /// For testing only. /// /// Copy of dictionary. - public Dictionary> GetReceptorSynapses() - { - return new Dictionary>(m_ReceptorSynapses); - } + //public Dictionary> GetReceptorSynapses() + //{ + // return new Dictionary>(m_ReceptorSynapses); + //} /// /// Clears the sequence learning state. @@ -1584,7 +1589,7 @@ public override int GetHashCode() result = prime * result + (int)(temp ^ (temp >> 32)); result = prime * result + ((m_PredictiveCells == null) ? 0 : m_PredictiveCells.GetHashCode()); result = prime * result + ((this.HtmConfig.Random == null) ? 0 : this.HtmConfig.Random.GetHashCode()); - result = prime * result + ((m_ReceptorSynapses == null) ? 0 : m_ReceptorSynapses.GetHashCode()); + //result = prime * result + ((m_ReceptorSynapses == null) ? 0 : m_ReceptorSynapses.GetHashCode()); result = prime * result + this.HtmConfig.RandomGenSeed; //result = prime * result + ((m_DistalSegments == null) ? 0 : m_DistalSegments.GetHashCode()); temp = BitConverter.DoubleToInt64Bits(this.HtmConfig.StimulusThreshold); diff --git a/NeoCortexApi/UnitTestsProject/TemporalMemoryTests.cs b/NeoCortexApi/UnitTestsProject/TemporalMemoryTests.cs index c689f1559..c32057b05 100644 --- a/NeoCortexApi/UnitTestsProject/TemporalMemoryTests.cs +++ b/NeoCortexApi/UnitTestsProject/TemporalMemoryTests.cs @@ -957,17 +957,30 @@ public void TestConnectionsNeverChangeWhenLearningDisabled() cn.CreateSynapse(wrongMatchingSegment, prevActiveCells[1], 0.5); cn.CreateSynapse(wrongMatchingSegment, prevInactiveCell, 0.5); - var r = deepCopyPlain(cn.GetReceptorSynapses().Values.First().First()); - var synMapBefore = deepCopyPlain>>(cn.GetReceptorSynapses()); + //var r = deepCopyPlain(cn.GetReceptorSynapses().Values.First().First()); + //var synMapBefore = deepCopyPlain>>(cn.GetReceptorSynapses()); //var segMapBefore = deepCopyPlain>>(cn.GetSegmentMapping()); var actCellsBefore = cn.ActiveCells; var winCellsBefore = cn.WinnerCells; + int prevPresynSum = 0; + int segSynSum = 0; + + GetSynSums(cn, out prevPresynSum, out segSynSum); + tm.Compute(prevActiveColumns, false); tm.Compute(activeColumns, false); - Assert.IsTrue(synMapBefore != cn.GetReceptorSynapses()); - Assert.IsTrue(synMapBefore.Keys.SequenceEqual(cn.GetReceptorSynapses().Keys)); + int afterPresynSum = 0; + int afterSegSynSum = 0; + + GetSynSums(cn, out afterPresynSum, out afterSegSynSum); + + //DD + //Assert.IsTrue(synMapBefore != cn.GetReceptorSynapses()); + //Assert.IsTrue(synMapBefore.Keys.SequenceEqual(cn.GetReceptorSynapses().Keys)); + Assert.IsTrue(prevPresynSum == afterPresynSum); + Assert.IsTrue(segSynSum == afterSegSynSum); cn.ActiveCells.SequenceEqual(actCellsBefore); cn.WinnerCells.SequenceEqual(winCellsBefore); @@ -976,6 +989,26 @@ public void TestConnectionsNeverChangeWhenLearningDisabled() //Assert.IsTrue(segMapBefore.Keys.SequenceEqual(cn.GetSegmentMapping().Keys)); } + private void GetSynSums(Connections cn, out int prevPresynSum, out int segSynSum) + { + prevPresynSum = 0; + segSynSum = 0; + + for (int i = 0; i < cn.HtmConfig.NumColumns; i++) + { + var col = cn.GetColumn(i); + foreach (var cell in col.Cells) + { + prevPresynSum += cell.ReceptorSynapses.Count; + + foreach (var seg in cell.DistalDendrites) + { + segSynSum += seg.Synapses.Count; + } + } + } + } + public void TestLeastUsedCell() { TemporalMemory tm = new TemporalMemory(); From 58677b221de25c76b244566efb2e8420fb82022d Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Mon, 28 Dec 2020 11:31:45 +0100 Subject: [PATCH 09/24] function renamed --- NeoCortexApi/NeoCortexApi.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NeoCortexApi/NeoCortexApi.xml b/NeoCortexApi/NeoCortexApi.xml index 3b38091ad..0297078a6 100644 --- a/NeoCortexApi/NeoCortexApi.xml +++ b/NeoCortexApi/NeoCortexApi.xml @@ -1887,7 +1887,7 @@ Note: PredictiveCells are not calculated here. They are calculated on demand from active segments. - + Calculate the active cells, using the current active columns and dendrite segments. Grow and reinforce synapses. From a4194ecea405bdb35920df2523cbc0033aacf9b0 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Mon, 28 Dec 2020 12:48:51 +0100 Subject: [PATCH 10/24] m_SegmentForFlatIdx changed to concurrent dictionary --- NeoCortexApi/NeoCortexApi.xml | 2 +- NeoCortexApi/NeoCortexApi/TemporalMemory.cs | 4 +- .../NeoCortexEntities/Entities/Connections.cs | 19 ++++---- .../NeoCortexEntities.csproj | 1 + .../Example of none completed experiment.txt | 44 +++++++++++++++++++ 5 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 Results/SequenceLearning/Example of none completed experiment.txt diff --git a/NeoCortexApi/NeoCortexApi.xml b/NeoCortexApi/NeoCortexApi.xml index 0297078a6..5fdde630f 100644 --- a/NeoCortexApi/NeoCortexApi.xml +++ b/NeoCortexApi/NeoCortexApi.xml @@ -1887,7 +1887,7 @@ Note: PredictiveCells are not calculated here. They are calculated on demand from active segments. - + Calculate the active cells, using the current active columns and dendrite segments. Grow and reinforce synapses. diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs index eed318ed2..507479b72 100644 --- a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs +++ b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs @@ -122,7 +122,7 @@ public ComputeCycle Compute(int[] activeColumns, bool learn) /// /// /// - protected ComputeCycle ActivateCellsPArallel(Connections conn, int[] activeColumnIndices, bool learn) + protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices, bool learn) { ComputeCycle cycle = new ComputeCycle { @@ -244,7 +244,7 @@ protected ComputeCycle ActivateCellsPArallel(Connections conn, int[] activeColum return cycle; } - protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices, bool learn) + protected ComputeCycle ActivateCellsOriginal(Connections conn, int[] activeColumnIndices, bool learn) { ComputeCycle cycle = new ComputeCycle { diff --git a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs index d4d7ac16b..864b3b8f4 100644 --- a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs +++ b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs @@ -3,6 +3,7 @@ using NeoCortexApi.Types; using NeoCortexApi.Utility; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; @@ -202,7 +203,9 @@ private set /// Indexed segments by their global index (can contain nulls). /// Indexed list of distal segments. /// - protected List m_SegmentForFlatIdx = new List(); + //protected List m_SegmentForFlatIdx = new List(); + + protected ConcurrentDictionary m_SegmentForFlatIdx = new ConcurrentDictionary(); /// /// Stores each cycle's most recent activity @@ -224,6 +227,7 @@ private set /// public Connections() { + // TODO: Remove this when old way of parameter initialization is completely removed. this.m_HtmConfig = new HtmConfig(new int[100], new int[] { 2048 }); } @@ -814,12 +818,6 @@ public SegmentActivity ComputeActivity(ICollection activeCellsInCurrentCyc Dictionary numOfActiveSynapses = new Dictionary(); Dictionary numOfPotentialSynapses = new Dictionary(); - // Every receptor synapse on active cell, which has permanence over threshold is by default connected. - //int[] numActiveConnectedSynapsesForSegment = new int[nextFlatIdx]; // not needed - - // Every receptor synapse on active cell is active-potential one. - //int[] numActivePotentialSynapsesForSegment = new int[nextFlatIdx]; // not needed - double threshold = connectedPermanence - EPSILON; // @@ -843,15 +841,12 @@ public SegmentActivity ComputeActivity(ICollection activeCellsInCurrentCyc numOfPotentialSynapses[segFlatIndx] = numOfPotentialSynapses[segFlatIndx] + 1; - //++numActivePotentialSynapsesForSegment[segFlatIndx]; - if (synapse.Permanence > threshold) { if (numOfActiveSynapses.ContainsKey(segFlatIndx) == false) numOfActiveSynapses.Add(segFlatIndx, 0); numOfActiveSynapses[segFlatIndx] = numOfActiveSynapses[segFlatIndx] + 1; - //++numActiveConnectedSynapsesForSegment[segFlatIndx]; } } } @@ -910,7 +905,9 @@ public DistalDendrite CreateDistalSegment(Cell segmentParentCell) else { flatIdx = m_NextFlatIdx; - m_SegmentForFlatIdx.Add(null); + //m_SegmentForFlatIdx.TryAdd(flatIdx, null); + m_SegmentForFlatIdx[flatIdx] = null; + //m_SegmentForFlatIdx.Add(null); ++m_NextFlatIdx; } diff --git a/NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj b/NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj index 31606eed8..7be3b2bae 100644 --- a/NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj +++ b/NeoCortexApi/NeoCortexEntities/NeoCortexEntities.csproj @@ -19,6 +19,7 @@ + diff --git a/Results/SequenceLearning/Example of none completed experiment.txt b/Results/SequenceLearning/Example of none completed experiment.txt new file mode 100644 index 000000000..db1da8315 --- /dev/null +++ b/Results/SequenceLearning/Example of none completed experiment.txt @@ -0,0 +1,44 @@ +Some of cell SDRs generate more then 20 active cells. This is because such SDRs activate cells of more than one pattern. +Sometimes TM learns faster and long SDRs will be reduced to the expected lenght (In this case 2% of 1024 columns = 20) +--------------------------------------------------------------------------------------------------------------------------- + +Active segments: 36, Matching segments: 159 +Col SDR: 161, 175, 654, 666, 667, 668, 670, 674, 684, 688, 692, 693, 695, 697, 702, 708, 710, 717, 722, 736, +Cell SDR: 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048, 4049, 4375, 4376, 4377, 4378, 4379, 4380, 4381, 4382, 4383, 4384, 4385, 4386, 4387, 4388, 4389, 4390, 4391, 4392, 4393, 4394, 4395, 4396, 4397, 4398, 4399, 16350, 16351, 16352, 16353, 16354, 16355, 16356, 16357, 16358, 16359, 16360, 16361, 16362, 16363, 16364, 16365, 16366, 16367, 16368, 16369, 16370, 16371, 16372, 16373, 16374, 16650, 16651, 16652, 16653, 16654, 16655, 16656, 16657, 16658, 16659, 16660, 16661, 16662, 16663, 16664, 16665, 16666, 16667, 16668, 16669, 16670, 16671, 16672, 16673, 16674, 16675, 16676, 16677, 16678, 16679, 16680, 16681, 16682, 16683, 16684, 16685, 16686, 16687, 16688, 16689, 16690, 16691, 16692, 16693, 16694, 16695, 16696, 16697, 16698, 16699, 16700, 16701, 16702, 16703, 16704, 16705, 16706, 16707, 16708, 16709, 16710, 16711, 16712, 16713, 16714, 16715, 16716, 16717, 16718, 16719, 16720, 16721, 16722, 16723, 16724, 16750, 16751, 16752, 16753, 16754, 16755, 16756, 16757, 16758, 16759, 16760, 16761, 16762, 16763, 16764, 16765, 16766, 16767, 16768, 16769, 16770, 16771, 16772, 16773, 16774, 16850, 16851, 16852, 16853, 16854, 16855, 16856, 16857, 16858, 16859, 16860, 16861, 16862, 16863, 16864, 16865, 16866, 16867, 16868, 16869, 16870, 16871, 16872, 16873, 16874, 17100, 17101, 17102, 17103, 17104, 17105, 17106, 17107, 17108, 17109, 17110, 17111, 17112, 17113, 17114, 17115, 17116, 17117, 17118, 17119, 17120, 17121, 17122, 17123, 17124, 17200, 17201, 17202, 17203, 17204, 17205, 17206, 17207, 17208, 17209, 17210, 17211, 17212, 17213, 17214, 17215, 17216, 17217, 17218, 17219, 17220, 17221, 17222, 17223, 17224, 17300, 17301, 17302, 17303, 17304, 17305, 17306, 17307, 17308, 17309, 17310, 17311, 17312, 17313, 17314, 17315, 17316, 17317, 17318, 17319, 17320, 17321, 17322, 17323, 17324, 17325, 17326, 17327, 17328, 17329, 17330, 17331, 17332, 17333, 17334, 17335, 17336, 17337, 17338, 17339, 17340, 17341, 17342, 17343, 17344, 17345, 17346, 17347, 17348, 17349, 17375, 17376, 17377, 17378, 17379, 17380, 17381, 17382, 17383, 17384, 17385, 17386, 17387, 17388, 17389, 17390, 17391, 17392, 17393, 17394, 17395, 17396, 17397, 17398, 17399, 17425, 17426, 17427, 17428, 17429, 17430, 17431, 17432, 17433, 17434, 17435, 17436, 17437, 17438, 17439, 17440, 17441, 17442, 17443, 17444, 17445, 17446, 17447, 17448, 17449, 17550, 17551, 17552, 17553, 17554, 17555, 17556, 17557, 17558, 17559, 17560, 17561, 17562, 17563, 17564, 17565, 17566, 17567, 17568, 17569, 17570, 17571, 17572, 17573, 17574, 17700, 17701, 17702, 17703, 17704, 17705, 17706, 17707, 17708, 17709, 17710, 17711, 17712, 17713, 17714, 17715, 17716, 17717, 17718, 17719, 17720, 17721, 17722, 17723, 17724, 17750, 17751, 17752, 17753, 17754, 17755, 17756, 17757, 17758, 17759, 17760, 17761, 17762, 17763, 17764, 17765, 17766, 17767, 17768, 17769, 17770, 17771, 17772, 17773, 17774, 17925, 17926, 17927, 17928, 17929, 17930, 17931, 17932, 17933, 17934, 17935, 17936, 17937, 17938, 17939, 17940, 17941, 17942, 17943, 17944, 17945, 17946, 17947, 17948, 17949, 18050, 18051, 18052, 18053, 18054, 18055, 18056, 18057, 18058, 18059, 18060, 18061, 18062, 18063, 18064, 18065, 18066, 18067, 18068, 18069, 18070, 18071, 18072, 18073, 18074, 18400, 18401, 18402, 18403, 18404, 18405, 18406, 18407, 18408, 18409, 18410, 18411, 18412, 18413, 18414, 18415, 18416, 18417, 18418, 18419, 18420, 18421, 18422, 18423, 18424, +Missmatch! Actual value: 6-5-4-3-7-1-9-12-11-12-13-14-11-12-14-5-7-6-9-3-4-3-4-3-4-0-1-0-2-3-4-5 - Predicted value: +Item length: 35 Items: 32 +Predictive cells: 35 5826, 6040, 6246, 6629, 14742, 15904, 16132, 16482, 17562, 17936, 18185, 18201, 18410, 18415, 18421, 18513, 18703, 18706, 18711, 18868, 18955, 18960, 18967, 19180, 19188, 19340, 19389, 19504, 19510, 19513, 19658, 19677, 19679, 19689, 19703, +indx:0 inp/len: 6-5-4-3-7-1-9-12-11-12-13-14-11-12-14-5-7-6-9-3-4-3-4-3-4-0-1-0-2-3-4-5/500 = similarity 5 4025, 4026, 4027, 4028, 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036, 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048, 4049, 4375, 4376, 4377, 4378, 4379, 4380, 4381, 4382, 4383, 4384, 4385, 4386, 4387, 4388, 4389, 4390, 4391, 4392, 4393, 4394, 4395, 4396, 4397, 4398, 4399, 16350, 16351, 16352, 16353, 16354, 16355, 16356, 16357, 16358, 16359, 16360, 16361, 16362, 16363, 16364, 16365, 16366, 16367, 16368, 16369, 16370, 16371, 16372, 16373, 16374, 16650, 16651, 16652, 16653, 16654, 16655, 16656, 16657, 16658, 16659, 16660, 16661, 16662, 16663, 16664, 16665, 16666, 16667, 16668, 16669, 16670, 16671, 16672, 16673, 16674, 16675, 16676, 16677, 16678, 16679, 16680, 16681, 16682, 16683, 16684, 16685, 16686, 16687, 16688, 16689, 16690, 16691, 16692, 16693, 16694, 16695, 16696, 16697, 16698, 16699, 16700, 16701, 16702, 16703, 16704, 16705, 16706, 16707, 16708, 16709, 16710, 16711, 16712, 16713, 16714, 16715, 16716, 16717, 16718, 16719, 16720, 16721, 16722, 16723, 16724, 16750, 16751, 16752, 16753, 16754, 16755, 16756, 16757, 16758, 16759, 16760, 16761, 16762, 16763, 16764, 16765, 16766, 16767, 16768, 16769, 16770, 16771, 16772, 16773, 16774, 16850, 16851, 16852, 16853, 16854, 16855, 16856, 16857, 16858, 16859, 16860, 16861, 16862, 16863, 16864, 16865, 16866, 16867, 16868, 16869, 16870, 16871, 16872, 16873, 16874, 17100, 17101, 17102, 17103, 17104, 17105, 17106, 17107, 17108, 17109, 17110, 17111, 17112, 17113, 17114, 17115, 17116, 17117, 17118, 17119, 17120, 17121, 17122, 17123, 17124, 17200, 17201, 17202, 17203, 17204, 17205, 17206, 17207, 17208, 17209, 17210, 17211, 17212, 17213, 17214, 17215, 17216, 17217, 17218, 17219, 17220, 17221, 17222, 17223, 17224, 17300, 17301, 17302, 17303, 17304, 17305, 17306, 17307, 17308, 17309, 17310, 17311, 17312, 17313, 17314, 17315, 17316, 17317, 17318, 17319, 17320, 17321, 17322, 17323, 17324, 17325, 17326, 17327, 17328, 17329, 17330, 17331, 17332, 17333, 17334, 17335, 17336, 17337, 17338, 17339, 17340, 17341, 17342, 17343, 17344, 17345, 17346, 17347, 17348, 17349, 17375, 17376, 17377, 17378, 17379, 17380, 17381, 17382, 17383, 17384, 17385, 17386, 17387, 17388, 17389, 17390, 17391, 17392, 17393, 17394, 17395, 17396, 17397, 17398, 17399, 17425, 17426, 17427, 17428, 17429, 17430, 17431, 17432, 17433, 17434, 17435, 17436, 17437, 17438, 17439, 17440, 17441, 17442, 17443, 17444, 17445, 17446, 17447, 17448, 17449, 17550, 17551, 17552, 17553, 17554, 17555, 17556, 17557, 17558, 17559, 17560, 17561, 17562, 17563, 17564, 17565, 17566, 17567, 17568, 17569, 17570, 17571, 17572, 17573, 17574, 17700, 17701, 17702, 17703, 17704, 17705, 17706, 17707, 17708, 17709, 17710, 17711, 17712, 17713, 17714, 17715, 17716, 17717, 17718, 17719, 17720, 17721, 17722, 17723, 17724, 17750, 17751, 17752, 17753, 17754, 17755, 17756, 17757, 17758, 17759, 17760, 17761, 17762, 17763, 17764, 17765, 17766, 17767, 17768, 17769, 17770, 17771, 17772, 17773, 17774, 17925, 17926, 17927, 17928, 17929, 17930, 17931, 17932, 17933, 17934, 17935, 17936, 17937, 17938, 17939, 17940, 17941, 17942, 17943, 17944, 17945, 17946, 17947, 17948, 17949, 18050, 18051, 18052, 18053, 18054, 18055, 18056, 18057, 18058, 18059, 18060, 18061, 18062, 18063, 18064, 18065, 18066, 18067, 18068, 18069, 18070, 18071, 18072, 18073, 18074, 18400, 18401, 18402, 18403, 18404, 18405, 18406, 18407, 18408, 18409, 18410, 18411, 18412, 18413, 18414, 18415, 18416, 18417, 18418, 18419, 18420, 18421, 18422, 18423, 18424, +>indx:0 inp/len: 5-4-3-7-1-9-12-11-12-13-14-11-12-14-5-7-6-9-3-4-3-4-3-4-0-1-0-2-3-4-5-6/31 = similarity 31 5826, 6040, 6246, 6629, 17562, 17936, 18185, 18201, 18410, 18415, 18421, 18513, 18703, 18706, 18711, 18868, 18955, 18960, 18967, 19180, 19188, 19340, 19389, 19504, 19510, 19513, 19658, 19677, 19679, 19689, 19703, + Date: Mon, 28 Dec 2020 17:19:08 +0100 Subject: [PATCH 11/24] woeking on parallel version --- NeoCortexApi/NeoCortexApi.xml | 6 +- NeoCortexApi/NeoCortexApi/TemporalMemory.cs | 40 ++-- .../NeoCortexEntities/Entities/Connections.cs | 182 ++++++++++-------- .../UnitTestsProject/TemporalMemoryTests.cs | 8 +- 4 files changed, 128 insertions(+), 108 deletions(-) diff --git a/NeoCortexApi/NeoCortexApi.xml b/NeoCortexApi/NeoCortexApi.xml index 5fdde630f..0e2363c0b 100644 --- a/NeoCortexApi/NeoCortexApi.xml +++ b/NeoCortexApi/NeoCortexApi.xml @@ -1887,7 +1887,7 @@ Note: PredictiveCells are not calculated here. They are calculated on demand from active segments. - + Calculate the active cells, using the current active columns and dendrite segments. Grow and reinforce synapses. @@ -2067,10 +2067,8 @@ - Used in the {@link TemporalMemory#compute(Connections, int[], boolean)} method - to make pulling values out of the {@link GroupBy2} more readable and named. - Used in the method to make pulling values out of the more readable and named. + Used by Temporal memory algorithm. diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs index 507479b72..122361774 100644 --- a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs +++ b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs @@ -72,7 +72,7 @@ public void Init(Connections conn) this.connections.Cells = cells; } - //StreamWriter tmperf1 = new StreamWriter("tm-perf-100000-10cells.csv"); + StreamWriter tmperf1 = new StreamWriter("tm-perf-1024-25cells.p.csv"); /// @@ -89,17 +89,17 @@ public void Init(Connections conn) /// Note: PredictiveCells are not calculated here. They are calculated on demand from active segments. public ComputeCycle Compute(int[] activeColumns, bool learn) { - //Stopwatch sw = new Stopwatch(); - //sw.Start(); - ComputeCycle cycle = ActivateCells(this.connections, activeColumns, learn); + Stopwatch sw = new Stopwatch(); + sw.Start(); + ComputeCycle cycle = ActivateCellsParallel(this.connections, activeColumns, learn); ActivateDendrites(this.connections, cycle, learn); - //sw.Stop(); + sw.Stop(); - //tmperf1.WriteLine($"{sw.ElapsedMilliseconds}"); + tmperf1.WriteLine($"{sw.ElapsedMilliseconds}"); - //tmperf1.Flush(); + tmperf1.Flush(); return cycle; } @@ -122,7 +122,7 @@ public ComputeCycle Compute(int[] activeColumns, bool learn) /// /// /// - protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices, bool learn) + protected ComputeCycle ActivateCellsParallel(Connections conn, int[] activeColumnIndices, bool learn) { ComputeCycle cycle = new ComputeCycle { @@ -131,8 +131,6 @@ protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices ConcurrentDictionary cycles = new ConcurrentDictionary(); - ColumnData activeColumnData = new ColumnData(); - ISet prevActiveCells = conn.ActiveCells; ISet prevWinnerCells = conn.WinnerCells; @@ -172,7 +170,9 @@ protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices // Grouping by columns, which have active and matching segments. Parallel.ForEach(grouper, opts, (tuple) => { - activeColumnData = activeColumnData.Set(tuple); + ColumnData activeColumnData = new ColumnData(); + + activeColumnData.Set(tuple); if (activeColumnData.IsExistAnyActiveCol(cIndexofACTIVE_COLUMNS)) { @@ -244,7 +244,7 @@ protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices return cycle; } - protected ComputeCycle ActivateCellsOriginal(Connections conn, int[] activeColumnIndices, bool learn) + protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices, bool learn) { ComputeCycle cycle = new ComputeCycle { @@ -287,7 +287,7 @@ protected ComputeCycle ActivateCellsOriginal(Connections conn, int[] activeColum // Grouping by columns, which have active and matching segments. foreach (var tuple in grouper) { - activeColumnData = activeColumnData.Set(tuple); + activeColumnData.Set(tuple); if (activeColumnData.IsExistAnyActiveCol(cIndexofACTIVE_COLUMNS)) { @@ -849,20 +849,16 @@ public void AdaptSegment(Connections conn, DistalDendrite segment, ICollection - /// Used in the method to make pulling values out of the more readable and named. + /// Used by Temporal memory algorithm. /// public class ColumnData { @@ -871,11 +867,9 @@ public class ColumnData public ColumnData() { } - public ColumnData Set(Pair>> t) + public void Set(Pair>> t) { m_Pair = t; - - return this; } public Column Column() { return (Column)m_Pair.Key; } diff --git a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs index 864b3b8f4..20e3f103c 100644 --- a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs +++ b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs @@ -9,6 +9,7 @@ using System.Diagnostics; using System.Linq; using System.Text; +using System.Threading; namespace NeoCortexApi.Entities { @@ -215,8 +216,16 @@ private set /// /// The segment creation number. /// - public int NextSegmentOrdinal { get => m_NextSegmentOrdinal; } - + public int NextSegmentOrdinal + { + get + { + lock ("segmentindex") + { + return m_NextSegmentOrdinal; + } + } + } #region Constructors and Initialization @@ -227,7 +236,7 @@ private set /// public Connections() { - + // TODO: Remove this when old way of parameter initialization is completely removed. this.m_HtmConfig = new HtmConfig(new int[100], new int[] { 2048 }); } @@ -896,30 +905,38 @@ public DistalDendrite CreateDistalSegment(Cell segmentParentCell) } int flatIdx; - int len; - if ((len = m_FreeFlatIdxs.Count()) > 0) - { - flatIdx = m_FreeFlatIdxs[len - 1]; - m_FreeFlatIdxs.RemoveRange(len - 1, 1); - } - else + + lock ("segmentindex") { - flatIdx = m_NextFlatIdx; - //m_SegmentForFlatIdx.TryAdd(flatIdx, null); - m_SegmentForFlatIdx[flatIdx] = null; - //m_SegmentForFlatIdx.Add(null); - ++m_NextFlatIdx; - } + int len; + if ((len = m_FreeFlatIdxs.Count()) > 0) + { + flatIdx = m_FreeFlatIdxs[len - 1]; + m_FreeFlatIdxs.RemoveRange(len - 1, 1); + //if (!m_FreeFlatIdxs.TryRemove(len - 1, out flatIdx)) + // throw new Exception("Object cannot be removed!"); + } + else + { + flatIdx = m_NextFlatIdx; + //m_SegmentForFlatIdx.TryAdd(flatIdx, null); + m_SegmentForFlatIdx[flatIdx] = null; + //m_SegmentForFlatIdx.Add(null); + ++m_NextFlatIdx; + } - int ordinal = m_NextSegmentOrdinal; - ++m_NextSegmentOrdinal; + int ordinal = m_NextSegmentOrdinal; + ++m_NextSegmentOrdinal; - DistalDendrite segment = new DistalDendrite(segmentParentCell, flatIdx, m_TMIteration, ordinal, this.HtmConfig.SynPermConnected, this.HtmConfig.NumInputs); - segmentParentCell.DistalDendrites.Add(segment); - //GetSegments(segmentParentCell, true).Add(segment); - m_SegmentForFlatIdx[flatIdx] = segment; - return segment; + DistalDendrite segment = new DistalDendrite(segmentParentCell, flatIdx, m_TMIteration, ordinal, this.HtmConfig.SynPermConnected, this.HtmConfig.NumInputs); + segmentParentCell.DistalDendrites.Add(segment); + //GetSegments(segmentParentCell, true).Add(segment); + m_SegmentForFlatIdx[flatIdx] = segment; + + return segment; + + } } /// @@ -928,32 +945,39 @@ public DistalDendrite CreateDistalSegment(Cell segmentParentCell) /// the segment to destroy public void DestroyDistalDendrite(DistalDendrite segment) { - // Remove the synapses from all data structures outside this Segment. - //DD List synapses = GetSynapses(segment); - List synapses = segment.Synapses; - int len = synapses.Count; - - //getSynapses(segment).stream().forEach(s->removeSynapseFromPresynapticMap(s)); - //DD foreach (var s in GetSynapses(segment)) - foreach (var s in segment.Synapses) + lock ("segmentindex") { - RemoveSynapseFromPresynapticMap(s); - } + // Remove the synapses from all data structures outside this Segment. + //DD List synapses = GetSynapses(segment); + List synapses = segment.Synapses; + int len = synapses.Count; + + //getSynapses(segment).stream().forEach(s->removeSynapseFromPresynapticMap(s)); + //DD foreach (var s in GetSynapses(segment)) + foreach (var s in segment.Synapses) + { + RemoveSynapseFromPresynapticMap(s); + } - m_NumSynapses -= len; + lock ("synapses") + { + m_NumSynapses -= len; + } - // Remove the segment from the cell's list. - //DD - //GetSegments(segment.ParentCell).Remove(segment); - segment.ParentCell.DistalDendrites.Remove(segment); + // Remove the segment from the cell's list. + //DD + //GetSegments(segment.ParentCell).Remove(segment); + segment.ParentCell.DistalDendrites.Remove(segment); - // Remove the segment from the map - //DD m_DistalSynapses.Remove(segment); + // Remove the segment from the map + //DD m_DistalSynapses.Remove(segment); - // Free the flatIdx and remove the final reference so the Segment can be - // garbage-collected. - m_FreeFlatIdxs.Add(segment.SegmentIndex); - m_SegmentForFlatIdx[segment.SegmentIndex] = null; + // Free the flatIdx and remove the final reference so the Segment can be + // garbage-collected. + m_FreeFlatIdxs.Add(segment.SegmentIndex); + //m_FreeFlatIdxs[segment.SegmentIndex] = segment.SegmentIndex; + m_SegmentForFlatIdx[segment.SegmentIndex] = null; + } } /// @@ -1010,7 +1034,10 @@ public int NumSegments(Cell cell = null) return cell.DistalDendrites.Count; } - return m_NextFlatIdx - m_FreeFlatIdxs.Count; + lock ("segmentindex") + { + return m_NextFlatIdx - m_FreeFlatIdxs.Count; + } } ///// @@ -1106,25 +1133,28 @@ public int ColumnIndexForSegment(DistalDendrite segment) /// the created . public Synapse CreateSynapse(DistalDendrite segment, Cell presynapticCell, double permanence) { - while (GetNumSynapses(segment) >= this.HtmConfig.MaxSynapsesPerSegment) + while (segment.Synapses.Count >= this.HtmConfig.MaxSynapsesPerSegment) { DestroySynapse(MinPermanenceSynapse(segment), segment); } - Synapse synapse = null; - //DD GetSynapses(segment).Add( - segment.Synapses.Add( - synapse = new Synapse( - presynapticCell, segment.SegmentIndex, m_NextSynapseOrdinal, permanence)); + lock ("synapses") + { + Synapse synapse = null; + //DD GetSynapses(segment).Add( + segment.Synapses.Add( + synapse = new Synapse( + presynapticCell, segment.SegmentIndex, m_NextSynapseOrdinal, permanence)); - presynapticCell.ReceptorSynapses.Add(synapse); - //DD GetReceptorSynapses(presynapticCell, true).Add(synapse); + presynapticCell.ReceptorSynapses.Add(synapse); + //DD GetReceptorSynapses(presynapticCell, true).Add(synapse); - ++m_NextSynapseOrdinal; + ++m_NextSynapseOrdinal; - ++m_NumSynapses; + ++m_NumSynapses; - return synapse; + return synapse; + } } /// @@ -1134,13 +1164,16 @@ public Synapse CreateSynapse(DistalDendrite segment, Cell presynapticCell, doubl /// public void DestroySynapse(Synapse synapse, DistalDendrite segment) { - --m_NumSynapses; + lock ("synapses") + { + --m_NumSynapses; - RemoveSynapseFromPresynapticMap(synapse); + RemoveSynapseFromPresynapticMap(synapse); - //segment.Synapses.Remove(synapse); - //DD GetSynapses(segment).Remove(synapse); - segment.Synapses.Remove(synapse); + //segment.Synapses.Remove(synapse); + //DD GetSynapses(segment).Remove(synapse); + segment.Synapses.Remove(synapse); + } } /// @@ -1191,22 +1224,17 @@ private Synapse MinPermanenceSynapse(DistalDendrite dd) } - /// - /// Returns the number of s on a given - /// if specified, or the total number if the "optionalSegmentArg" is null. - /// - /// An optional Segment to specify the context of the synapse count. - /// Either the total number of synapses or the number on a specified segment. - public long GetNumSynapses(DistalDendrite optionalSegmentArg) - { - if (optionalSegmentArg != null) - { - // DD return GetSynapses(optionalSegmentArg).Count; - return optionalSegmentArg.Synapses.Count; - } - - return m_NumSynapses; - } + ///// + ///// Returns the number of s on a given + ///// if specified, or the total number if the "optionalSegmentArg" is null. + ///// + ///// An optional Segment to specify the context of the synapse count. + ///// Either the total number of synapses or the number on a specified segment. + //public long GetNumSynapses(DistalDendrite optionalSegmentArg) + //{ + // // DD return GetSynapses(optionalSegmentArg).Count; + // return optionalSegmentArg.Synapses.Count; + //} /// diff --git a/NeoCortexApi/UnitTestsProject/TemporalMemoryTests.cs b/NeoCortexApi/UnitTestsProject/TemporalMemoryTests.cs index c32057b05..8922e0302 100644 --- a/NeoCortexApi/UnitTestsProject/TemporalMemoryTests.cs +++ b/NeoCortexApi/UnitTestsProject/TemporalMemoryTests.cs @@ -627,7 +627,7 @@ public void TestDestroyWeakSynapseOnWrongPrediction() tm.Compute(previousActiveColumns, true); tm.Compute(activeColumns, true); - Assert.AreEqual(3, cn.GetNumSynapses(activeSegment)); + Assert.AreEqual(3, activeSegment.Synapses.Count); } [TestMethod] @@ -657,7 +657,7 @@ public void TestDestroyWeakSynapseOnActiveReinforce() tm.Compute(previousActiveColumns, true); tm.Compute(activeColumns, true); - Assert.AreEqual(3, cn.GetNumSynapses(activeSegment)); + Assert.AreEqual(3, activeSegment.Synapses.Count); } [TestMethod] @@ -884,8 +884,8 @@ public void TestAddSegmentToCellWithFewestSegments() Assert.AreEqual(3, cn.NumSegments()); Assert.AreEqual(1, cn.NumSegments(cn.GetCell(0))); Assert.AreEqual(1, cn.NumSegments(cn.GetCell(3))); - Assert.AreEqual(1, cn.GetNumSynapses(segment1)); - Assert.AreEqual(1, cn.GetNumSynapses(segment2)); + Assert.AreEqual(1, segment1.Synapses.Count); + Assert.AreEqual(1, segment2.Synapses.Count); //DD //List segments = new List(cn.GetSegments(cn.GetCell(1))); From 51723612dc965907257ab6c613296a696b7b8080 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Wed, 30 Dec 2020 12:33:56 +0100 Subject: [PATCH 12/24] comments --- NeoCortexApi/NeoCortexApi/NeoCortexApi.xml | 6 ++---- NeoCortexApi/NeoCortexApi/TemporalMemory.cs | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml b/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml index 0297078a6..0e2363c0b 100644 --- a/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml +++ b/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml @@ -1887,7 +1887,7 @@ Note: PredictiveCells are not calculated here. They are calculated on demand from active segments. - + Calculate the active cells, using the current active columns and dendrite segments. Grow and reinforce synapses. @@ -2067,10 +2067,8 @@ - Used in the {@link TemporalMemory#compute(Connections, int[], boolean)} method - to make pulling values out of the {@link GroupBy2} more readable and named. - Used in the method to make pulling values out of the more readable and named. + Used by Temporal memory algorithm. diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs index 122361774..e28adfe33 100644 --- a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs +++ b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs @@ -809,7 +809,7 @@ public void AdaptSegment(Connections conn, DistalDendrite segment, ICollection synapsesToDestroy = new List(); - //DD oreach (Synapse synapse in conn.GetSynapses(segment)) + //DD foreach (Synapse synapse in conn.GetSynapses(segment)) foreach (Synapse synapse in segment.Synapses) { double permanence = synapse.Permanence; From 61f89d5f8aeb636518fa2ab3f0dff8dd7807b1be Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Wed, 30 Dec 2020 17:19:28 +0100 Subject: [PATCH 13/24] Added WinnerCells approach to classifier --- NeoCortexApi/NeoCortexApi/NeoCortexApi.xml | 6 ++++-- NeoCortexApi/NeoCortexApi/TemporalMemory.cs | 2 +- .../NeoCortexApiSample/SequenceLearning.cs | 17 ++++++++++++++--- .../MuscNotesExperiment.cs | 19 +++++++++++++++---- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml b/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml index 0e2363c0b..0297078a6 100644 --- a/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml +++ b/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml @@ -1887,7 +1887,7 @@ Note: PredictiveCells are not calculated here. They are calculated on demand from active segments. - + Calculate the active cells, using the current active columns and dendrite segments. Grow and reinforce synapses. @@ -2067,8 +2067,10 @@ + Used in the {@link TemporalMemory#compute(Connections, int[], boolean)} method + to make pulling values out of the {@link GroupBy2} more readable and named. - Used by Temporal memory algorithm. + Used in the method to make pulling values out of the more readable and named. diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs index e28adfe33..122361774 100644 --- a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs +++ b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs @@ -809,7 +809,7 @@ public void AdaptSegment(Connections conn, DistalDendrite segment, ICollection synapsesToDestroy = new List(); - //DD foreach (Synapse synapse in conn.GetSynapses(segment)) + //DD oreach (Synapse synapse in conn.GetSynapses(segment)) foreach (Synapse synapse in segment.Synapses) { double permanence = synapse.Permanence; diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs index 30bb08a7a..a83ba3f52 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs +++ b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs @@ -175,14 +175,25 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li string key = GetKey(previousInputs, input); - //cls.Learn(GetKey(prevInput, input), lyrOut.ActiveCells.ToArray()); - cls.Learn(key, lyrOut.ActiveCells.ToArray()); + + List 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(lyrOut.ActiveCells.Select(c => c.Index).ToArray())}"); + Debug.WriteLine($"Cell SDR: {Helpers.StringifyVector(actCells.Select(c => c.Index).ToArray())}"); if (key == lastPredictedValue) { diff --git a/NeoCortexApi/UnitTestsProject/SequenceLearningExperiments/MuscNotesExperiment.cs b/NeoCortexApi/UnitTestsProject/SequenceLearningExperiments/MuscNotesExperiment.cs index 217d02803..e0ac657ec 100644 --- a/NeoCortexApi/UnitTestsProject/SequenceLearningExperiments/MuscNotesExperiment.cs +++ b/NeoCortexApi/UnitTestsProject/SequenceLearningExperiments/MuscNotesExperiment.cs @@ -163,7 +163,7 @@ private void RunExperiment(int inputBits, Parameters p, EncoderBase encoder, Lis p.apply(mem); - bool isInStableState; + bool isInStableState = false; //HtmClassifier cls = new HtmClassifier(); HtmClassifier cls = new HtmClassifier(); @@ -246,14 +246,25 @@ private void RunExperiment(int inputBits, Parameters p, EncoderBase encoder, Lis string key = GetKey(previousInputs, input); - //cls.Learn(GetKey(prevInput, input), lyrOut.ActiveCells.ToArray()); - cls.Learn(key, lyrOut.ActiveCells.ToArray()); + + List 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(lyrOut.ActiveCells.Select(c => c.Index).ToArray())}"); + Debug.WriteLine($"Cell SDR: {Helpers.StringifyVector(actCells.Select(c => c.Index).ToArray())}"); if (key == lastPredictedValue) { From 2bfd87fddde878b5e0625233ce6a3a59757edf35 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Wed, 30 Dec 2020 17:27:18 +0100 Subject: [PATCH 14/24] Added TM Multicore --- NeoCortexApi/NeoCortexApi.xml | 16 +- NeoCortexApi/NeoCortexApi/TemporalMemortMT.cs | 147 ++++++++++++++++++ NeoCortexApi/NeoCortexApi/TemporalMemory.cs | 133 +--------------- 3 files changed, 168 insertions(+), 128 deletions(-) create mode 100644 NeoCortexApi/NeoCortexApi/TemporalMemortMT.cs diff --git a/NeoCortexApi/NeoCortexApi.xml b/NeoCortexApi/NeoCortexApi.xml index 0e2363c0b..628b88f89 100644 --- a/NeoCortexApi/NeoCortexApi.xml +++ b/NeoCortexApi/NeoCortexApi.xml @@ -1854,6 +1854,20 @@ Overlap of every column. + + + Multicore implementation of the Temporal Memory algorithm + + + + + + + + + + + Implementation of Temporal Memory algorithm. @@ -1887,7 +1901,7 @@ Note: PredictiveCells are not calculated here. They are calculated on demand from active segments. - + Calculate the active cells, using the current active columns and dendrite segments. Grow and reinforce synapses. diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemortMT.cs b/NeoCortexApi/NeoCortexApi/TemporalMemortMT.cs new file mode 100644 index 000000000..1c3ee0b03 --- /dev/null +++ b/NeoCortexApi/NeoCortexApi/TemporalMemortMT.cs @@ -0,0 +1,147 @@ +using NeoCortexApi.Entities; +using NeoCortexApi.Utility; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NeoCortexApi +{ + /// + /// Multicore implementation of the Temporal Memory algorithm + /// + public class TemporalMemortMT : TemporalMemory + { + /// + /// + /// + /// + /// + /// + /// + protected override ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices, bool learn) + { + ComputeCycle cycle = new ComputeCycle + { + ActivColumnIndicies = activeColumnIndices + }; + + ConcurrentDictionary cycles = new ConcurrentDictionary(); + + ISet prevActiveCells = conn.ActiveCells; + ISet prevWinnerCells = conn.WinnerCells; + + // The list of active columns. + List activeColumns = new List(); + + foreach (var indx in activeColumnIndices.OrderBy(i => i)) + { + activeColumns.Add(conn.GetColumn(indx)); + } + + Func segToCol = (segment) => + { + var colIndx = ((DistalDendrite)segment).ParentCell.ParentColumnIndex; + var parentCol = this.connections.HtmConfig.Memory.GetColumn(colIndx); + return parentCol; + }; + + Func times1Fnc = x => (Column)x; + + var list = new Pair, Func>[3]; + list[0] = new Pair, Func>(Array.ConvertAll(activeColumns.ToArray(), item => (object)item).ToList(), times1Fnc); + list[1] = new Pair, Func>(Array.ConvertAll(conn.ActiveSegments.ToArray(), item => (object)item).ToList(), segToCol); + list[2] = new Pair, Func>(Array.ConvertAll(conn.MatchingSegments.ToArray(), item => (object)item).ToList(), segToCol); + + GroupBy2 grouper = GroupBy2.Of(list); + + double permanenceIncrement = conn.HtmConfig.PermanenceIncrement; + double permanenceDecrement = conn.HtmConfig.PermanenceDecrement; + + ParallelOptions opts = new ParallelOptions + { + MaxDegreeOfParallelism = Environment.ProcessorCount + }; + + // + // Grouping by columns, which have active and matching segments. + Parallel.ForEach(grouper, opts, (tuple) => + { + ColumnData activeColumnData = new ColumnData(); + + activeColumnData.Set(tuple); + + if (activeColumnData.IsExistAnyActiveCol(cIndexofACTIVE_COLUMNS)) + { + // If there are some active segments on the column already... + if (activeColumnData.ActiveSegments != null && activeColumnData.ActiveSegments.Count > 0) + { + //Debug.Write("."); + + List cellsOwnersOfActSegs = ActivatePredictedColumn(conn, activeColumnData.ActiveSegments, + activeColumnData.MatchingSegments, prevActiveCells, prevWinnerCells, + permanenceIncrement, permanenceDecrement, learn, cycle.ActiveSynapses); + + ComputeCycle colCycle = new ComputeCycle(); + cycles[tuple.Key.Index] = colCycle; + + foreach (var item in cellsOwnersOfActSegs) + { + colCycle.ActiveCells.Add(item); + colCycle.WinnerCells.Add(item); + } + } + else + { + // + // If no active segments are detected (start of learning) then all cells are activated + // and a random single cell is chosen as a winner. + BurstingResult burstingResult = BurstColumn(conn, activeColumnData.Column(), activeColumnData.MatchingSegments, + prevActiveCells, prevWinnerCells, permanenceIncrement, permanenceDecrement, conn.HtmConfig.Random, + learn); + + // DRAFT. Removing this as unnecessary. + //cycle.ActiveCells.Add(burstingResult.BestCell); + + ComputeCycle colCycle = new ComputeCycle(); + cycles[tuple.Key.Index] = colCycle; + + // + // Here we activate all cells by putting them to list of active cells. + foreach (var item in burstingResult.Cells) + { + colCycle.ActiveCells.Add(item); + } + + //var actSyns = conn.getReceptorSynapses(burstingResult.BestCell).Where(s=>prevActiveCells.Contains(s.SourceCell)); + //foreach (var syn in actSyns) + //{ + // cycle.ActiveSynapses.Add(syn); + //} + + colCycle.WinnerCells.Add((Cell)burstingResult.BestCell); + } + } + else + { + if (learn) + { + PunishPredictedColumn(conn, activeColumnData.ActiveSegments, activeColumnData.MatchingSegments, + prevActiveCells, prevWinnerCells, conn.HtmConfig.PredictedSegmentDecrement); + } + } + }); + + foreach (var colCycle in cycles.Values) + { + cycle.ActiveCells.AddRange(colCycle.ActiveCells); + cycle.WinnerCells.AddRange(colCycle.WinnerCells); + } + + return cycle; + } + + } +} diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs index 122361774..2d74cfce7 100644 --- a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs +++ b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs @@ -21,9 +21,9 @@ public class TemporalMemory : IHtmAlgorithm//: IComputeDeco { private static readonly double EPSILON = 0.00001; - private static readonly int cIndexofACTIVE_COLUMNS = 0; + protected static readonly int cIndexofACTIVE_COLUMNS = 0; - private Connections connections; + protected Connections connections; public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } @@ -91,7 +91,7 @@ public ComputeCycle Compute(int[] activeColumns, bool learn) { Stopwatch sw = new Stopwatch(); sw.Start(); - ComputeCycle cycle = ActivateCellsParallel(this.connections, activeColumns, learn); + ComputeCycle cycle = ActivateCells(this.connections, activeColumns, learn); ActivateDendrites(this.connections, cycle, learn); @@ -122,129 +122,8 @@ public ComputeCycle Compute(int[] activeColumns, bool learn) /// /// /// - protected ComputeCycle ActivateCellsParallel(Connections conn, int[] activeColumnIndices, bool learn) - { - ComputeCycle cycle = new ComputeCycle - { - ActivColumnIndicies = activeColumnIndices - }; - - ConcurrentDictionary cycles = new ConcurrentDictionary(); - - ISet prevActiveCells = conn.ActiveCells; - ISet prevWinnerCells = conn.WinnerCells; - - // The list of active columns. - List activeColumns = new List(); - - foreach (var indx in activeColumnIndices.OrderBy(i => i)) - { - activeColumns.Add(conn.GetColumn(indx)); - } - - Func segToCol = (segment) => - { - var colIndx = ((DistalDendrite)segment).ParentCell.ParentColumnIndex; - var parentCol = this.connections.HtmConfig.Memory.GetColumn(colIndx); - return parentCol; - }; - - Func times1Fnc = x => (Column)x; - - var list = new Pair, Func>[3]; - list[0] = new Pair, Func>(Array.ConvertAll(activeColumns.ToArray(), item => (object)item).ToList(), times1Fnc); - list[1] = new Pair, Func>(Array.ConvertAll(conn.ActiveSegments.ToArray(), item => (object)item).ToList(), segToCol); - list[2] = new Pair, Func>(Array.ConvertAll(conn.MatchingSegments.ToArray(), item => (object)item).ToList(), segToCol); - - GroupBy2 grouper = GroupBy2.Of(list); - - double permanenceIncrement = conn.HtmConfig.PermanenceIncrement; - double permanenceDecrement = conn.HtmConfig.PermanenceDecrement; - - ParallelOptions opts = new ParallelOptions - { - MaxDegreeOfParallelism = Environment.ProcessorCount - }; - - // - // Grouping by columns, which have active and matching segments. - Parallel.ForEach(grouper, opts, (tuple) => - { - ColumnData activeColumnData = new ColumnData(); - - activeColumnData.Set(tuple); - - if (activeColumnData.IsExistAnyActiveCol(cIndexofACTIVE_COLUMNS)) - { - // If there are some active segments on the column already... - if (activeColumnData.ActiveSegments != null && activeColumnData.ActiveSegments.Count > 0) - { - //Debug.Write("."); - - List cellsOwnersOfActSegs = ActivatePredictedColumn(conn, activeColumnData.ActiveSegments, - activeColumnData.MatchingSegments, prevActiveCells, prevWinnerCells, - permanenceIncrement, permanenceDecrement, learn, cycle.ActiveSynapses); - - ComputeCycle colCycle = new ComputeCycle(); - cycles[tuple.Key.Index] = colCycle; - - foreach (var item in cellsOwnersOfActSegs) - { - colCycle.ActiveCells.Add(item); - colCycle.WinnerCells.Add(item); - } - } - else - { - // - // If no active segments are detected (start of learning) then all cells are activated - // and a random single cell is chosen as a winner. - BurstingResult burstingResult = BurstColumn(conn, activeColumnData.Column(), activeColumnData.MatchingSegments, - prevActiveCells, prevWinnerCells, permanenceIncrement, permanenceDecrement, conn.HtmConfig.Random, - learn); - - // DRAFT. Removing this as unnecessary. - //cycle.ActiveCells.Add(burstingResult.BestCell); - - ComputeCycle colCycle = new ComputeCycle(); - cycles[tuple.Key.Index] = colCycle; - - // - // Here we activate all cells by putting them to list of active cells. - foreach (var item in burstingResult.Cells) - { - colCycle.ActiveCells.Add(item); - } - - //var actSyns = conn.getReceptorSynapses(burstingResult.BestCell).Where(s=>prevActiveCells.Contains(s.SourceCell)); - //foreach (var syn in actSyns) - //{ - // cycle.ActiveSynapses.Add(syn); - //} - - colCycle.WinnerCells.Add((Cell)burstingResult.BestCell); - } - } - else - { - if (learn) - { - PunishPredictedColumn(conn, activeColumnData.ActiveSegments, activeColumnData.MatchingSegments, - prevActiveCells, prevWinnerCells, conn.HtmConfig.PredictedSegmentDecrement); - } - } - }); - - foreach (var colCycle in cycles.Values) - { - cycle.ActiveCells.AddRange(colCycle.ActiveCells); - cycle.WinnerCells.AddRange(colCycle.WinnerCells); - } - - return cycle; - } - - protected ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices, bool learn) + + protected virtual ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices, bool learn) { ComputeCycle cycle = new ComputeCycle { @@ -477,7 +356,7 @@ public void Reset(Connections connections) /// /// /// Cells which own active column segments as calculated in the previous step. - private List ActivatePredictedColumn(Connections conn, List columnActiveSegments, + protected List ActivatePredictedColumn(Connections conn, List columnActiveSegments, List matchingSegments, ICollection prevActiveCells, ICollection prevWinnerCells, double permanenceIncrement, double permanenceDecrement, bool learn, IList activeSynapses) { From 6f8d7044ebbf64714092fee67df368c39e0fe5c9 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Wed, 30 Dec 2020 21:20:15 +0100 Subject: [PATCH 15/24] Rename TMMT and bugfix. --- NeoCortexApi/NeoCortexApi/NeoCortexApi.xml | 20 +++++++++++++++---- ...emporalMemortMT.cs => TemporalMemoryMT.cs} | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) rename NeoCortexApi/NeoCortexApi/{TemporalMemortMT.cs => TemporalMemoryMT.cs} (99%) diff --git a/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml b/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml index 0297078a6..9ab991ad3 100644 --- a/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml +++ b/NeoCortexApi/NeoCortexApi/NeoCortexApi.xml @@ -1887,7 +1887,7 @@ Note: PredictiveCells are not calculated here. They are calculated on demand from active segments. - + Calculate the active cells, using the current active columns and dendrite segments. Grow and reinforce synapses. @@ -2067,10 +2067,8 @@ - Used in the {@link TemporalMemory#compute(Connections, int[], boolean)} method - to make pulling values out of the {@link GroupBy2} more readable and named. - Used in the method to make pulling values out of the more readable and named. + Used by Temporal memory algorithm. @@ -2079,6 +2077,20 @@ indicator.Index of slot. + + + Multicore implementation of the Temporal Memory algorithm + + + + + + + + + + + add or update value to particular key diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemortMT.cs b/NeoCortexApi/NeoCortexApi/TemporalMemoryMT.cs similarity index 99% rename from NeoCortexApi/NeoCortexApi/TemporalMemortMT.cs rename to NeoCortexApi/NeoCortexApi/TemporalMemoryMT.cs index 1c3ee0b03..f05be9f3a 100644 --- a/NeoCortexApi/NeoCortexApi/TemporalMemortMT.cs +++ b/NeoCortexApi/NeoCortexApi/TemporalMemoryMT.cs @@ -12,7 +12,7 @@ namespace NeoCortexApi /// /// Multicore implementation of the Temporal Memory algorithm /// - public class TemporalMemortMT : TemporalMemory + public class TemporalMemoryMT : TemporalMemory { /// /// From 928a10335282bec84ab5ef13a4ecb09066e7df24 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Thu, 31 Dec 2020 11:45:02 +0100 Subject: [PATCH 16/24] Sample sequence learning changed to TM multicore --- .../NeoCortexApiSample/SequenceLearning.cs | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs index a83ba3f52..53efd5fbb 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs +++ b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs @@ -96,7 +96,7 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li var numInputs = inputValues.Distinct().ToList().Count; - TemporalMemory tm = new TemporalMemory(); + TemporalMemoryMT tm = new TemporalMemoryMT(); HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(mem, numInputs * 55, (isStable, numPatterns, actColAvg, seenInputs) => { @@ -175,25 +175,14 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li string key = GetKey(previousInputs, input); - - List actCells; - - if (lyrOut.ActiveCells.Count == lyrOut.WinnerCells.Count) - { - actCells = lyrOut.ActiveCells; - } - else - { - actCells = lyrOut.WinnerCells; - } - - cls.Learn(key, actCells.ToArray()); + //cls.Learn(GetKey(prevInput, input), lyrOut.ActiveCells.ToArray()); + 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(actCells.Select(c => c.Index).ToArray())}"); + Debug.WriteLine($"Cell SDR: {Helpers.StringifyVector(lyrOut.ActiveCells.Select(c => c.Index).ToArray())}"); if (key == lastPredictedValue) { From 83c5c0adb8b2644cd77181c5dacddbf6af4a1ff7 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Thu, 31 Dec 2020 11:55:54 +0100 Subject: [PATCH 17/24] merge issue fixed with winnercells --- NeoCortexApi/NeoCortexApi.xml | 28 +++++++++---------- .../NeoCortexApiSample/SequenceLearning.cs | 16 +++++++++-- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/NeoCortexApi/NeoCortexApi.xml b/NeoCortexApi/NeoCortexApi.xml index 628b88f89..9ab991ad3 100644 --- a/NeoCortexApi/NeoCortexApi.xml +++ b/NeoCortexApi/NeoCortexApi.xml @@ -1854,20 +1854,6 @@ Overlap of every column. - - - Multicore implementation of the Temporal Memory algorithm - - - - - - - - - - - Implementation of Temporal Memory algorithm. @@ -2091,6 +2077,20 @@ indicator.Index of slot. + + + Multicore implementation of the Temporal Memory algorithm + + + + + + + + + + + add or update value to particular key diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs index 53efd5fbb..ddeba9f3c 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs +++ b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs @@ -175,14 +175,24 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li string key = GetKey(previousInputs, input); - //cls.Learn(GetKey(prevInput, input), lyrOut.ActiveCells.ToArray()); - cls.Learn(key, lyrOut.ActiveCells.ToArray()); + List 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(lyrOut.ActiveCells.Select(c => c.Index).ToArray())}"); + Debug.WriteLine($"Cell SDR: {Helpers.StringifyVector(actCells.Select(c => c.Index).ToArray())}"); if (key == lastPredictedValue) { From 19394297a67644ea744ec9cdea662baa36fdfac4 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Sat, 2 Jan 2021 12:47:16 +0100 Subject: [PATCH 18/24] working on TM improvements --- .../NeoCortexApi/Network/CortexLayer.cs | 8 +- .../NeoCortexApi/Network/HtmClassifier.cs | 11 +- NeoCortexApi/NeoCortexApi/TemporalMemory.cs | 111 +++++++-------- .../NeoCortexApiSample/SequenceLearning.cs | 130 +++++++++++------- 4 files changed, 142 insertions(+), 118 deletions(-) diff --git a/NeoCortexApi/NeoCortexApi/Network/CortexLayer.cs b/NeoCortexApi/NeoCortexApi/Network/CortexLayer.cs index 63a324a77..edf44959b 100644 --- a/NeoCortexApi/NeoCortexApi/Network/CortexLayer.cs +++ b/NeoCortexApi/NeoCortexApi/Network/CortexLayer.cs @@ -84,15 +84,17 @@ public TOUT Compute(TIN input, bool learn) int i = 0; - foreach (var moduleKeyPair in this.HtmModules) + var keys = this.HtmModules.Keys; + + foreach (var key in new List(keys)) { - dynamic module = moduleKeyPair.Value; + dynamic module = this.HtmModules[key]; dynamic moduleInput = (i == 0) ? input : moduleOutput; moduleOutput = module.Compute(moduleInput, learn); - SetResult(moduleKeyPair.Key, moduleOutput); + SetResult(key, moduleOutput); i++; } diff --git a/NeoCortexApi/NeoCortexApi/Network/HtmClassifier.cs b/NeoCortexApi/NeoCortexApi/Network/HtmClassifier.cs index 7476992c9..c6643c3b0 100644 --- a/NeoCortexApi/NeoCortexApi/Network/HtmClassifier.cs +++ b/NeoCortexApi/NeoCortexApi/Network/HtmClassifier.cs @@ -96,12 +96,7 @@ public TIN GetPredictedInputValue(Cell[] predictiveCells) // bool x = false; double maxSameBits = 0; TIN predictedValue = default; - //int[] arr = new int[predictiveCells.Length]; - //for (int i = 0; i < predictiveCells.Length; i++) - //{ - // arr[i] = predictiveCells[i].Index; - //} - + if (predictiveCells.Length != 0) { int indxOfMatchingInp = 0; @@ -109,7 +104,7 @@ public TIN GetPredictedInputValue(Cell[] predictiveCells) int n = 0; List sortedMatches = new List(); - int indx = 0; + var celIndicies = GetCellIndicies(predictiveCells); Debug.WriteLine($"Predictive cells: {celIndicies.Length} \t {Helpers.StringifyVector(celIndicies)}"); @@ -136,7 +131,7 @@ public TIN GetPredictedInputValue(Cell[] predictiveCells) else Debug.WriteLine($" @@ -89,17 +89,17 @@ public void Init(Connections conn) /// Note: PredictiveCells are not calculated here. They are calculated on demand from active segments. public ComputeCycle Compute(int[] activeColumns, bool learn) { - Stopwatch sw = new Stopwatch(); - sw.Start(); + //Stopwatch sw = new Stopwatch(); + //sw.Start(); ComputeCycle cycle = ActivateCells(this.connections, activeColumns, learn); ActivateDendrites(this.connections, cycle, learn); - sw.Stop(); + //sw.Stop(); - tmperf1.WriteLine($"{sw.ElapsedMilliseconds}"); + // tmperf1.WriteLine($"{sw.ElapsedMilliseconds}"); - tmperf1.Flush(); + //tmperf1.Flush(); return cycle; } @@ -122,7 +122,7 @@ public ComputeCycle Compute(int[] activeColumns, bool learn) /// /// /// - + protected virtual ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices, bool learn) { ComputeCycle cycle = new ComputeCycle @@ -366,61 +366,56 @@ protected List ActivatePredictedColumn(Connections conn, List(conn.GetSynapses(segment))) - foreach (Synapse synapse in new List(segment.Synapses)) + if (!cellsOwnersOfActiveSegments.Contains(segment.ParentCell)) { - // WORKING DRAFT. TM algorithm change. - // The original algorithm adopt all synapses at the segment. - // The new (DRAFT) version adopts only synapses whose presynaptic cells - // are active cells in th eprevious cycle. - if (prevActiveCells.Contains(synapse.getPresynapticCell())) - { - // TODO - // Review this. not only previous cell should be consiered. - // We should rather consider all current list and look if the cell is already in. - segmOwnerCell = segment.ParentCell; - if (segmOwnerCell != previousCell) - { - //activeSynapses.Add(synapse); - cellsOwnersOfActiveSegments.Add(segmOwnerCell); - previousCell = segmOwnerCell; - } - else - { - // for debugging. - } + cellsOwnersOfActiveSegments.Add(segment.ParentCell); + ////DD foreach (Synapse synapse in new List(conn.GetSynapses(segment))) + //foreach (Synapse synapse in new List(segment.Synapses)) + //{ + // // WORKING DRAFT. TM algorithm change. + // // The original algorithm adopt all synapses at the segment. + // // The new (DRAFT) version adopts only synapses whose presynaptic cells + // // are active cells in th eprevious cycle. + // if (prevWinnerCells.Contains(synapse.getPresynapticCell())) + // { + // cellsOwnersOfActiveSegments.Add(segment.ParentCell); + // break; + // //// TODO + // //// Review this. not only previous cell should be consiered. + // //// We should rather consider all current list and look if the cell is already in. + // //segmOwnerCell = segment.ParentCell; + // //if (segmOwnerCell != previousCell) + // //{ + // // //activeSynapses.Add(synapse); + // // cellsOwnersOfActiveSegments.Add(segmOwnerCell); + // // previousCell = segmOwnerCell; + // //} + // //else + // //{ + // // // for debugging. + // //} + // } + //} + } - if (learn) - { - AdaptSegment(conn, segment, prevActiveCells, permanenceIncrement, permanenceDecrement); + if (learn) + { + AdaptSegment(conn, segment, prevActiveCells, permanenceIncrement, permanenceDecrement); - int numActive = conn.LastActivity.PotentialSynapses[segment.SegmentIndex]; - int nGrowDesired = conn.HtmConfig.MaxNewSynapseCount - numActive; + int numActive = conn.LastActivity.PotentialSynapses[segment.SegmentIndex]; + int nGrowDesired = conn.HtmConfig.MaxNewSynapseCount - numActive; - if (nGrowDesired > 0) - { - // Create new synapses on the segment from winner (pre-synaptic cells) cells. - GrowSynapses(conn, prevWinnerCells, segment, conn.HtmConfig.InitialPermanence, - nGrowDesired, conn.HtmConfig.Random); - } - } + if (nGrowDesired > 0) + { + // Create new synapses on the segment from winner (pre-synaptic cells) cells. + GrowSynapses(conn, prevWinnerCells, segment, conn.HtmConfig.InitialPermanence, + nGrowDesired, conn.HtmConfig.Random); + } + else + { + // for debugging. } } - - //if (learn) - //{ - // AdaptSegment(conn, segment, prevActiveCells, permanenceIncrement, permanenceDecrement); - - // int numActive = conn.getLastActivity().PotentialSynapses[segment.getIndex()]; - // int nGrowDesired = conn.HtmConfig.MaxNewSynapseCount - numActive; - - // if (nGrowDesired > 0) - // { - // // Create new synapses on the segment from winner (pre-synaptic cells) cells. - // growSynapses(conn, prevWinnerCells, segment, conn.getInitialPermanence(), - // nGrowDesired, conn.getRandom()); - // } - //} } return cellsOwnersOfActiveSegments; @@ -569,7 +564,7 @@ public void PunishPredictedColumn(Connections conn, List activeS List matchingSegments, ICollection prevActiveCells, ICollection prevWinnerCells, double predictedSegmentDecrement) { - + Debug.Write("P"); if (predictedSegmentDecrement > 0) { foreach (DistalDendrite segment in matchingSegments) @@ -735,7 +730,7 @@ public void AdaptSegment(Connections conn, DistalDendrite segment, ICollection /// Used by Temporal memory algorithm. /// diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs index ddeba9f3c..8fd549e36 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs +++ b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs @@ -52,7 +52,7 @@ public void Run() // Used by punishing of segments. PredictedSegmentDecrement = 0.1 }; - + double max = 20; Dictionary settings = new Dictionary() @@ -90,15 +90,17 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li var mem = new Connections(cfg); - bool isInStableState; + bool isInStableState = false; HtmClassifier cls = new HtmClassifier(); var numInputs = inputValues.Distinct().ToList().Count; - TemporalMemoryMT tm = new TemporalMemoryMT(); + CortexLayer layer1 = new CortexLayer("L1"); + + TemporalMemory tm = new TemporalMemory(); - HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(mem, numInputs * 55, (isStable, numPatterns, actColAvg, seenInputs) => + HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(mem, numInputs * 150, (isStable, numPatterns, actColAvg, seenInputs) => { if (isStable) // Event should be fired when entering the stable state. @@ -107,14 +109,16 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li // Ideal SP should never enter unstable state after stable state. Debug.WriteLine($"INSTABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); - isInStableState = true; + 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); - + //tm.Reset(mem); }, numOfCyclesToWaitOnChange: 25); @@ -122,11 +126,8 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li sp.Init(mem); tm.Init(mem); - CortexLayer layer1 = new CortexLayer("L1"); - layer1.HtmModules.Add("encoder", encoder); layer1.HtmModules.Add("sp", sp); - layer1.HtmModules.Add("tm", tm); double[] inputs = inputValues.ToArray(); int[] prevActiveCols = new int[0]; @@ -150,7 +151,35 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li previousInputs.Add("-1.0"); // - // Now training with SP+TM. SP is pretrained on the given input pattern. + // 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) as ComputeCycle; + + 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; @@ -165,57 +194,60 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li var lyrOut = layer1.Compute(input, learn) as ComputeCycle; - var activeColumns = layer1.GetResult("sp") as int[]; + // 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[]; - activeColumnsLst[input].Add(activeColumns.ToList()); + activeColumnsLst[input].Add(activeColumns.ToList()); - previousInputs.Add(input.ToString()); - if (previousInputs.Count > (maxPrevInputs + 1)) - previousInputs.RemoveAt(0); + previousInputs.Add(input.ToString()); + if (previousInputs.Count > (maxPrevInputs + 1)) + previousInputs.RemoveAt(0); - string key = GetKey(previousInputs, input); + string key = GetKey(previousInputs, input); - List actCells; + List actCells; - if (lyrOut.ActiveCells.Count == lyrOut.WinnerCells.Count) - { - actCells = lyrOut.ActiveCells; - } - else - { - actCells = lyrOut.WinnerCells; - } + if (lyrOut.ActiveCells.Count == lyrOut.WinnerCells.Count) + { + actCells = lyrOut.ActiveCells; + } + else + { + actCells = lyrOut.WinnerCells; + } - cls.Learn(key, actCells.ToArray()); + cls.Learn(key, actCells.ToArray()); - if (learn == false) - Debug.WriteLine($"Inference mode"); + 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())}"); + 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 (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()); + if (lyrOut.PredictiveCells.Count > 0) + { + var predictedInputValue = cls.GetPredictedInputValue(lyrOut.PredictiveCells.ToArray()); - Debug.WriteLine($"Current Input: {input} \t| Predicted Input: {predictedInputValue}"); + Debug.WriteLine($"Current Input: {input} \t| Predicted Input: {predictedInputValue}"); - lastPredictedValue = predictedInputValue; + lastPredictedValue = predictedInputValue; + } + else + { + Debug.WriteLine($"NO CELLS PREDICTED for next cycle."); + lastPredictedValue = String.Empty; + } } - 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. From f74efedaac847c014c12dec3984676a47a729ad5 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Sat, 2 Jan 2021 13:18:50 +0100 Subject: [PATCH 19/24] Merge with serialization branch --- .../DistributedComputeLib/DistributedComputeLib.csproj | 2 +- NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj | 3 +++ NeoCortexApi/NeoCortexEntities/Entities/Connections.cs | 7 +++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/NeoCortexApi/DistributedComputeLib/DistributedComputeLib.csproj b/NeoCortexApi/DistributedComputeLib/DistributedComputeLib.csproj index d1886a6ca..1257f2abf 100644 --- a/NeoCortexApi/DistributedComputeLib/DistributedComputeLib.csproj +++ b/NeoCortexApi/DistributedComputeLib/DistributedComputeLib.csproj @@ -6,7 +6,7 @@ - C:\dev\NeoCortexAPI\neocortexapi\NeoCortexApi\DistributedComputeLib\DistributedComputeLib.xml + diff --git a/NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj b/NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj index 49ba36dc3..39a777814 100644 --- a/NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj +++ b/NeoCortexApi/NeoCortexApi/NeoCortexApi.csproj @@ -68,6 +68,9 @@ + + all + all diff --git a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs index b281643d4..e7cb2af8a 100644 --- a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs +++ b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs @@ -1864,14 +1864,17 @@ public void Serialize(StreamWriter writer) this.m_HtmConfig.Serialize(writer); - ser.SerializeValue(this.m_DistalSegments, writer); + // Moved to Cell + //ser.SerializeValue(this.m_DistalSegments, writer); ser.SerializeValue(this.m_DistalSynapses, writer); ser.SerializeValue(this.m_NextFlatIdx, writer); ser.SerializeValue(this.m_NextSegmentOrdinal, writer); ser.SerializeValue(this.m_NextSynapseOrdinal, writer); ser.SerializeValue(this.m_NumSynapses, writer); ser.SerializeValue(this.m_FreeFlatIdxs, writer); - ser.SerializeValue(this.m_SegmentForFlatIdx, writer); + + // TODO!!! + //ser.SerializeValue(this.m_SegmentForFlatIdx, writer); this.LastActivity.Serialize(writer); From b0fd5a81da862dd94d005cae9302d67686e6af6c Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Sat, 2 Jan 2021 14:47:34 +0100 Subject: [PATCH 20/24] Sample Sequence Learning completes in 82 min. --- NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs index 8fd549e36..edb9c3338 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs +++ b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs @@ -109,7 +109,8 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li // Ideal SP should never enter unstable state after stable state. Debug.WriteLine($"INSTABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}"); - isInStableState = isStable; + // We are not learning in instable state. + learn = isInStableState = isStable; //if (isStable && layer1.HtmModules.ContainsKey("tm") == false) // layer1.HtmModules.Add("tm", tm); From 5ec761a60478a58a6435e3164cea19cc8e8db488 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Sun, 3 Jan 2021 10:10:42 +0100 Subject: [PATCH 21/24] number of stabley cycles iof HPC in SequenceSample increased from 25 to 50. --- .../NeoCortexApiSample/SequenceLearning.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs index edb9c3338..d551f6047 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs +++ b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs @@ -98,7 +98,7 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li CortexLayer layer1 = new CortexLayer("L1"); - TemporalMemory tm = new TemporalMemory(); + TemporalMemoryMT tm = new TemporalMemoryMT(); HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(mem, numInputs * 150, (isStable, numPatterns, actColAvg, seenInputs) => { @@ -120,7 +120,7 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li // Clear active and predictive cells. //tm.Reset(mem); - }, numOfCyclesToWaitOnChange: 25); + }, numOfCyclesToWaitOnChange: 50); SpatialPoolerMT sp = new SpatialPoolerMT(hpa); @@ -167,14 +167,14 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li { Debug.WriteLine($" -- {input} --"); - var lyrOut = layer1.Compute(input, learn) as ComputeCycle; + var lyrOut = layer1.Compute(input, learn) ; - if (isInStableState) - break; + // if (isInStableState) + // break; } - if (isInStableState) - break; + // if (isInStableState) + // break; } layer1.HtmModules.Add("tm", tm); @@ -206,8 +206,11 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li if (previousInputs.Count > (maxPrevInputs + 1)) previousInputs.RemoveAt(0); - string key = GetKey(previousInputs, input); + //if (previousInputs.Count < maxPrevInputs) + // continue; + string key = GetKey(previousInputs, input); + List actCells; if (lyrOut.ActiveCells.Count == lyrOut.WinnerCells.Count) From d185dd5cf59f21b8a24c328447c7f1a852fca8f2 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Sun, 3 Jan 2021 10:16:10 +0100 Subject: [PATCH 22/24] Added comment to HPC. --- .../NeoCortexApi/HomeostaticPlasticityController.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NeoCortexApi/NeoCortexApi/HomeostaticPlasticityController.cs b/NeoCortexApi/NeoCortexApi/HomeostaticPlasticityController.cs index d250b6292..54e632273 100644 --- a/NeoCortexApi/NeoCortexApi/HomeostaticPlasticityController.cs +++ b/NeoCortexApi/NeoCortexApi/HomeostaticPlasticityController.cs @@ -79,6 +79,14 @@ protected HomeostaticPlasticityController() } + /// + /// Creates the instance of HomeostaticPlasticityController. + /// + /// The HTM memory. + /// The minimum calls to the Learn method until HPC algorithm is activated. When this number is reached the HPC will disable boosting in SP. + /// Action invoked when the SP status is changed from stable t unstable and vise versa. + /// How many cycles all seen patterns must not change to declare SP as stable. Using smaller numbers might cause frequent status change. + /// Higher numbers ensure more stable SP, but it takes longer time to enter the stable stabe. public HomeostaticPlasticityController(Connections htmMemory, int minCycles, Action onStabilityStatusChanged, int numOfCyclesToWaitOnChange = 50) { this.m_OnStabilityStatusChanged = onStabilityStatusChanged; From bcdeacdca6deb56530b5403a3ea404da9114a5ab Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Mon, 4 Jan 2021 12:22:34 +0100 Subject: [PATCH 23/24] Sequence Compute corrections --- NeoCortexApi/NeoCortexApi/TemporalMemory.cs | 10 ++++---- NeoCortexApi/NeoCortexApi/TemporalMemoryMT.cs | 1 + .../NeoCortexEntities/Entities/Connections.cs | 1 - .../NeoCortexApiSample/SequenceLearning.cs | 23 +++++++++++-------- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs index 3e83a9d33..873ed1f24 100644 --- a/NeoCortexApi/NeoCortexApi/TemporalMemory.cs +++ b/NeoCortexApi/NeoCortexApi/TemporalMemory.cs @@ -256,8 +256,9 @@ protected void ActivateDendrites(Connections conn, ComputeCycle cycle, bool lear var activeSegments = new List(); foreach (var item in activity.ActiveSynapses) { - if (item.Value >= conn.HtmConfig.ActivationThreshold) - activeSegments.Add(conn.GetSegmentForFlatIdx(item.Key)); + var seg = conn.GetSegmentForFlatIdx(item.Key); + if(seg != null && item.Value >= conn.HtmConfig.ActivationThreshold) + activeSegments.Add(seg); } // @@ -265,8 +266,9 @@ protected void ActivateDendrites(Connections conn, ComputeCycle cycle, bool lear var matchingSegments = new List(); foreach (var item in activity.PotentialSynapses) { - if (item.Value >= conn.HtmConfig.MinThreshold) - matchingSegments.Add(conn.GetSegmentForFlatIdx(item.Key)); + var seg = conn.GetSegmentForFlatIdx(item.Key); + if (seg != null && item.Value >= conn.HtmConfig.MinThreshold) + matchingSegments.Add(seg); } // diff --git a/NeoCortexApi/NeoCortexApi/TemporalMemoryMT.cs b/NeoCortexApi/NeoCortexApi/TemporalMemoryMT.cs index f05be9f3a..49d1849a2 100644 --- a/NeoCortexApi/NeoCortexApi/TemporalMemoryMT.cs +++ b/NeoCortexApi/NeoCortexApi/TemporalMemoryMT.cs @@ -73,6 +73,7 @@ protected override ComputeCycle ActivateCells(Connections conn, int[] activeColu activeColumnData.Set(tuple); + if (activeColumnData.IsExistAnyActiveCol(cIndexofACTIVE_COLUMNS)) { // If there are some active segments on the column already... diff --git a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs index e7cb2af8a..da7d6f28a 100644 --- a/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs +++ b/NeoCortexApi/NeoCortexEntities/Entities/Connections.cs @@ -929,7 +929,6 @@ public DistalDendrite CreateDistalSegment(Cell segmentParentCell) int ordinal = m_NextSegmentOrdinal; ++m_NextSegmentOrdinal; - DistalDendrite segment = new DistalDendrite(segmentParentCell, flatIdx, m_TMIteration, ordinal, this.HtmConfig.SynPermConnected, this.HtmConfig.NumInputs); segmentParentCell.DistalDendrites.Add(segment); //GetSegments(segmentParentCell, true).Add(segment); diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs index d551f6047..1f646ad06 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs +++ b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs @@ -98,7 +98,7 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li CortexLayer layer1 = new CortexLayer("L1"); - TemporalMemoryMT tm = new TemporalMemoryMT(); + TemporalMemory tm = new TemporalMemory(); HomeostaticPlasticityController hpa = new HomeostaticPlasticityController(mem, numInputs * 150, (isStable, numPatterns, actColAvg, seenInputs) => { @@ -167,14 +167,14 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li { Debug.WriteLine($" -- {input} --"); - var lyrOut = layer1.Compute(input, learn) ; + var lyrOut = layer1.Compute(input, learn); - // if (isInStableState) - // break; + if (isInStableState) + break; } - // if (isInStableState) - // break; + if (isInStableState) + break; } layer1.HtmModules.Add("tm", tm); @@ -206,11 +206,16 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li if (previousInputs.Count > (maxPrevInputs + 1)) previousInputs.RemoveAt(0); - //if (previousInputs.Count < maxPrevInputs) - // continue; + // 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 actCells; if (lyrOut.ActiveCells.Count == lyrOut.WinnerCells.Count) From 3b3faf86962192a82bc47d9950ada417783ef740 Mon Sep 17 00:00:00 2001 From: Damir Dobric Date: Mon, 4 Jan 2021 17:30:31 +0100 Subject: [PATCH 24/24] Added comment in sequencesample experiment --- NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs index 1f646ad06..f5977c28c 100644 --- a/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs +++ b/NeoCortexApi/Samples/NeoCortexApiSample/SequenceLearning.cs @@ -200,6 +200,7 @@ private void RunExperiment(int inputBits, HtmConfig cfg, EncoderBase encoder, Li { var activeColumns = layer1.GetResult("sp") as int[]; + //layer2.Compute(lyrOut.WinnerCells, true); activeColumnsLst[input].Add(activeColumns.ToList()); previousInputs.Add(input.ToString());