/** * Uses the specified {@link Connections} object to Build the structural * anatomy needed by this {@code TemporalMemory} to implement its algorithms. * * The connections object holds the {@link Column} and {@link Cell} infrastructure, * and is used by both the {@link SpatialPooler} and {@link TemporalMemory}. Either of * these can be used separately, and therefore this Connections object may have its * Columns and Cells initialized by either the init method of the SpatialPooler or the * init method of the TemporalMemory. We check for this so that complete initialization * of both Columns and Cells occurs, without either being redundant (initialized more than * once). However, {@link Cell}s only get created when initializing a TemporalMemory, because * they are not used by the SpatialPooler. * * @param c {@link Connections} object */ public void init(Connections conn) { this.connections = conn; SparseObjectMatrix <Column> matrix = this.connections.getMemory() == null ? new SparseObjectMatrix <Column>(this.connections.getColumnDimensions()) : (SparseObjectMatrix <Column>) this.connections.getMemory(); this.connections.setMemory(matrix); int numColumns = matrix.getMaxIndex() + 1; this.connections.setNumColumns(numColumns); int cellsPerColumn = this.connections.getCellsPerColumn(); Cell[] cells = new Cell[numColumns * cellsPerColumn]; //Used as flag to determine if Column objects have been created. Column colZero = matrix.getObject(0); for (int i = 0; i < numColumns; i++) { Column column = colZero == null ? new Column(cellsPerColumn, i, this.connections.getSynPermConnected(), this.connections.NumInputs) : matrix.getObject(i); for (int j = 0; j < cellsPerColumn; j++) { cells[i * cellsPerColumn + j] = column.Cells[j]; } //If columns have not been previously configured if (colZero == null) { matrix.set(i, column); } } //Only the TemporalMemory initializes cells so no need to test for redundancy this.connections.setCells(cells); }
/// <summary> /// Implements muticore initialization of pooler. /// </summary> /// <param name="c"></param> protected override void ConnectAndConfigureInputs(Connections c) { List <KeyPair> colList = new List <KeyPair>(); ConcurrentDictionary <int, KeyPair> colList2 = new ConcurrentDictionary <int, KeyPair>(); int numColumns = c.HtmConfig.NumColumns; // Parallel implementation of initialization ParallelOptions opts = new ParallelOptions(); //int synapseCounter = 0; Parallel.For(0, numColumns, opts, (indx) => { Random rnd = new Random(42); int colIndex = (int)indx; var data = new ProcessingData { // Gets RF Potential = HtmCompute.MapPotential(c.HtmConfig, colIndex, rnd /*(c.getRandom()*/), Column = c.GetColumn(colIndex) }; // This line initializes all synases in the potential pool of synapses. // It creates the pool on proximal dendrite segment of the column. // After initialization permancences are set to zero. data.Column.CreatePotentialPool(c.HtmConfig, data.Potential, -1); //connectColumnToInputRF(c.HtmConfig, data.Potential, data.Column); //Interlocked.Add(ref synapseCounter, data.Column.ProximalDendrite.Synapses.Count); //colList.Add(new KeyPair() { Key = i, Value = column }); data.Perm = HtmCompute.InitSynapsePermanences(c.HtmConfig, data.Potential, c.HtmConfig.Random); data.AvgConnected = GetAvgSpanOfConnectedSynapses(c, colIndex); HtmCompute.UpdatePermanencesForColumn(c.HtmConfig, data.Perm, data.Column, data.Potential, true); if (!colList2.TryAdd(colIndex, new KeyPair() { Key = colIndex, Value = data })) { } }); //c.setProximalSynapseCount(synapseCounter); List <double> avgSynapsesConnected = new List <double>(); foreach (var item in colList2.Values) //for (int i = 0; i < numColumns; i++) { int i = (int)item.Key; ProcessingData data = (ProcessingData)item.Value; //ProcessingData data = new ProcessingData(); // Debug.WriteLine(i); //data.Potential = mapPotential(c, i, c.isWrapAround()); //var st = string.Join(",", data.Potential); //Debug.WriteLine($"{i} - [{st}]"); //var counts = c.getConnectedCounts(); //for (int h = 0; h < counts.getDimensions()[0]; h++) //{ // // Gets the synapse mapping between column-i with input vector. // int[] slice = (int[])counts.getSlice(h); // Debug.Write($"{slice.Count(y => y == 1)} - "); //} //Debug.WriteLine(" --- "); // Console.WriteLine($"{i} - [{String.Join(",", ((ProcessingData)item.Value).Potential)}]"); // This line initializes all synases in the potential pool of synapses. // It creates the pool on proximal dendrite segment of the column. // After initialization permancences are set to zero. //var potPool = data.Column.createPotentialPool(c, data.Potential); //connectColumnToInputRF(c, data.Potential, data.Column); //data.Perm = initPermanence(c.getSynPermConnected(), c.getSynPermMax(), // c.getRandom(), c.getSynPermTrimThreshold(), c, data.Potential, data.Column, c.getInitConnectedPct()); //updatePermanencesForColumn(c, data.Perm, data.Column, data.Potential, true); avgSynapsesConnected.Add(data.AvgConnected); colList.Add(new KeyPair() { Key = i, Value = data.Column }); } SparseObjectMatrix <Column> mem = (SparseObjectMatrix <Column>)c.HtmConfig.Memory; if (mem.IsRemotelyDistributed) { // Pool is created and attached to the local instance of Column. // Here we need to update the pool on remote Column instance. mem.set(colList); } // The inhibition radius determines the size of a column's local // neighborhood. A cortical column must overcome the overlap score of // columns in its neighborhood in order to become active. This radius is // updated every learning round. It grows and shrinks with the average // number of connected synapses per column. UpdateInhibitionRadius(c, avgSynapsesConnected); }