def getUnionEncodingFromTokens(self, tokens): """ Create a single, sparsified bitmap from a union of bitmaps for given tokens @param tokens (sequence) A sequence of tokens @return (sequence) Bitmap """ # Accumulate counts by inplace-adding sparse matrices counts = SparseMatrix() counts.resize(1, self.width * self.height) # Pre-allocate buffer sparse matrix sparseBitmap = SparseMatrix() sparseBitmap.resize(1, self.width * self.height) for t in tokens: bitmap = self._getWordBitmap(t) sparseBitmap.setRowFromSparse(0, bitmap, [1] * len(bitmap)) counts += sparseBitmap numNonZeros = counts.nNonZerosOnRow(0) # Add some jitter to aid in tie-breaking during sort jitterValues = tuple( (random.random() / 100) + 0.1 for _ in xrange(numNonZeros)) sparseBitmap.setRowFromSparse(0, counts.nonZeroCols(), jitterValues) counts += sparseBitmap maxSparsity = int(self.unionSparsity * self.n) w = min(numNonZeros, maxSparsity) # Return top w most popular positions return tuple(x[1] for x in counts.getNonZerosSorted())[:w]
def grow(self, rows, cols): """ Grows the histogram to have rows rows and cols columns. Must not have been initialized before, or already have the same number of columns. If rows is smaller than the current number of rows, does not shrink. Also updates the sizes of the row and column sums. :param rows: Integer number of rows. :param cols: Integer number of columns. """ if not self.hist_: self.hist_ = SparseMatrix(rows, cols) self.rowSums_ = numpy.zeros(rows, dtype=dtype) self.colSums_ = numpy.zeros(cols, dtype=dtype) self.hack_ = None else: oldRows = self.hist_.nRows() oldCols = self.hist_.nCols() nextRows = max(oldRows, rows) nextCols = max(oldCols, cols) if (oldRows < nextRows) or (oldCols < nextCols): self.hist_.resize(nextRows, nextCols) if oldRows < nextRows: oldSums = self.rowSums_ self.rowSums_ = numpy.zeros(nextRows, dtype=dtype) self.rowSums_[0:len(oldSums)] = oldSums self.hack_ = None if oldCols < nextCols: oldSums = self.colSums_ self.colSums_ = numpy.zeros(nextCols, dtype=dtype) self.colSums_[0:len(oldSums)] = oldSums self.hack_ = None
def countRandomBitFrequencies(numTerms=100000, percentSparsity=0.01): """Create a uniformly random counts matrix through sampling.""" # Accumulate counts by inplace-adding sparse matrices counts = SparseMatrix() size = 128 * 128 counts.resize(1, size) # Pre-allocate buffer sparse matrix sparseBitmap = SparseMatrix() sparseBitmap.resize(1, size) random.seed(42) # Accumulate counts for each bit for each word numWords = 0 for term in xrange(numTerms): bitmap = random.sample(xrange(size), int(size * percentSparsity)) bitmap.sort() sparseBitmap.setRowFromSparse(0, bitmap, [1] * len(bitmap)) counts += sparseBitmap numWords += 1 # Compute normalized version of counts as a separate matrix frequencies = SparseMatrix() frequencies.resize(1, size) frequencies.copy(counts) frequencies.divide(float(numWords)) # Wrap up by printing some statistics and then saving the normalized version printFrequencyStatistics(counts, frequencies, numWords, size) frequencyFilename = "bit_frequencies_random.pkl" print "Saving frequency matrix in", frequencyFilename with open(frequencyFilename, "wb") as frequencyPickleFile: pickle.dump(frequencies, frequencyPickleFile) return counts
def clean_outcpd(self): """Hack to act like clean_outcpd on zeta1.TopLevelNode. Take the max element in each to column, set it to 1, and set all the other elements to 0. Only called by inferRowMaxProd() and only needed if an updateRow() has been called since the last clean_outcpd(). """ m = self.hist_.toDense() for j in range(m.shape[1]): # For each column. cmax = m[:, j].max() if cmax: m[:, j] = numpy.array(m[:, j] == cmax, dtype=dtype) self.hack_ = SparseMatrix(0, self.hist_.nCols()) for i in range(m.shape[0]): self.hack_.addRow(m[i, :])
def __init__( self, name, numCorticalColumns=1, inputSize=1024, numInputBits=20, externalInputSize=1024, numExternalInputBits=20, L2Overrides=None, networkType="L4L2TMColumn", L4Overrides=None, seed=42, logCalls=False, objectNamesAreIndices=False, TMOverrides=None, ): """ Creates the network. Parameters: ---------------------------- @param TMOverrides (dict) Parameters to override in the TM region """ # Handle logging - this has to be done first self.logCalls = logCalls registerAllResearchRegions() self.name = name self.numLearningPoints = 1 self.numColumns = numCorticalColumns self.inputSize = inputSize self.externalInputSize = externalInputSize self.numInputBits = numInputBits self.objectNamesAreIndices = objectNamesAreIndices # seed self.seed = seed random.seed(seed) # update parameters with overrides self.config = { "networkType": networkType, "numCorticalColumns": numCorticalColumns, "externalInputSize": externalInputSize, "sensorInputSize": inputSize, "enableFeedback": False, "L4Params": self.getDefaultL4Params(inputSize, numExternalInputBits), "L2Params": self.getDefaultL2Params(inputSize, numInputBits), "TMParams": self.getDefaultTMParams(self.inputSize, self.numInputBits), } if L2Overrides is not None: self.config["L2Params"].update(L2Overrides) if L4Overrides is not None: self.config["L4Params"].update(L4Overrides) if TMOverrides is not None: self.config["TMParams"].update(TMOverrides) # Recreate network including TM parameters self.network = createNetwork(self.config) self.sensorInputs = [] self.externalInputs = [] self.L4Regions = [] self.L2Regions = [] self.TMRegions = [] for i in xrange(self.numColumns): self.sensorInputs.append(self.network.regions["sensorInput_" + str(i)].getSelf()) self.externalInputs.append(self.network.regions["externalInput_" + str(i)].getSelf()) self.L4Regions.append(self.network.regions["L4Column_" + str(i)]) self.L2Regions.append(self.network.regions["L2Column_" + str(i)]) self.TMRegions.append(self.network.regions["TMColumn_" + str(i)]) self.L4Columns = [region.getSelf() for region in self.L4Regions] self.L2Columns = [region.getSelf() for region in self.L2Regions] self.TMColumns = [region.getSelf() for region in self.TMRegions] # will be populated during training self.objectL2Representations = {} self.objectL2RepresentationsMatrices = [ SparseMatrix(0, self.config["L2Params"]["cellCount"]) for _ in xrange(self.numColumns) ] self.objectNameToIndex = {} self.statistics = [] # Create classifier to hold supposedly unique TM states self.classifier = KNNClassifier(distanceMethod="rawOverlap") self.numTMCells = (self.TMColumns[0].cellsPerColumn * self.TMColumns[0].columnCount)
def __init__(self, cellCount, inputSize, threshold): self.permanences = SparseMatrix(cellCount, inputSize) self.threshold = threshold self.activeCells = np.empty(0, dtype='uint32')
def __init__(self, inputWidth, lateralInputWidths=(), cellCount=4096, sdrSize=40, onlineLearning = False, maxSdrSize = None, minSdrSize = None, # Proximal synPermProximalInc=0.1, synPermProximalDec=0.001, initialProximalPermanence=0.6, sampleSizeProximal=20, minThresholdProximal=10, connectedPermanenceProximal=0.50, predictedInhibitionThreshold=20, # Distal synPermDistalInc=0.1, synPermDistalDec=0.001, initialDistalPermanence=0.6, sampleSizeDistal=20, activationThresholdDistal=13, connectedPermanenceDistal=0.50, inertiaFactor=1., seed=42): """ Parameters: ---------------------------- @param inputWidth (int) The number of bits in the feedforward input @param lateralInputWidths (list of ints) The number of bits in each lateral input @param sdrSize (int) The number of active cells in an object SDR @param onlineLearning (Bool) Whether or not the column pooler should learn in online mode. @param maxSdrSize (int) The maximum SDR size for learning. If the column pooler has more than this many cells active, it will refuse to learn. This serves to stop the pooler from learning when it is uncertain of what object it is sensing. @param minSdrSize (int) The minimum SDR size for learning. If the column pooler has fewer than this many active cells, it will create a new representation and learn that instead. This serves to create separate representations for different objects and sequences. If online learning is enabled, this parameter should be at least inertiaFactor*sdrSize. Otherwise, two different objects may be incorrectly inferred to be the same, as SDRs may still be active enough to learn even after inertial decay. @param synPermProximalInc (float) Permanence increment for proximal synapses @param synPermProximalDec (float) Permanence decrement for proximal synapses @param initialProximalPermanence (float) Initial permanence value for proximal synapses @param sampleSizeProximal (int) Number of proximal synapses a cell should grow to each feedforward pattern, or -1 to connect to every active bit @param minThresholdProximal (int) Number of active synapses required for a cell to have feedforward support @param connectedPermanenceProximal (float) Permanence required for a proximal synapse to be connected @param predictedInhibitionThreshold (int) How much predicted input must be present for inhibitory behavior to be triggered. Only has effects if onlineLearning is true. @param synPermDistalInc (float) Permanence increment for distal synapses @param synPermDistalDec (float) Permanence decrement for distal synapses @param sampleSizeDistal (int) Number of distal synapses a cell should grow to each lateral pattern, or -1 to connect to every active bit @param initialDistalPermanence (float) Initial permanence value for distal synapses @param activationThresholdDistal (int) Number of active synapses required to activate a distal segment @param connectedPermanenceDistal (float) Permanence required for a distal synapse to be connected @param inertiaFactor (float) The proportion of previously active cells that remain active in the next timestep due to inertia (in the absence of inhibition). If onlineLearning is enabled, should be at most 1 - learningTolerance, or representations may incorrectly become mixed. @param seed (int) Random number generator seed """ assert maxSdrSize is None or maxSdrSize >= sdrSize assert minSdrSize is None or minSdrSize <= sdrSize self.inputWidth = inputWidth self.cellCount = cellCount self.sdrSize = sdrSize self.onlineLearning = onlineLearning if maxSdrSize is None: self.maxSdrSize = sdrSize else: self.maxSdrSize = maxSdrSize if minSdrSize is None: self.minSdrSize = sdrSize else: self.minSdrSize = minSdrSize self.synPermProximalInc = synPermProximalInc self.synPermProximalDec = synPermProximalDec self.initialProximalPermanence = initialProximalPermanence self.connectedPermanenceProximal = connectedPermanenceProximal self.sampleSizeProximal = sampleSizeProximal self.minThresholdProximal = minThresholdProximal self.predictedInhibitionThreshold = predictedInhibitionThreshold self.synPermDistalInc = synPermDistalInc self.synPermDistalDec = synPermDistalDec self.initialDistalPermanence = initialDistalPermanence self.connectedPermanenceDistal = connectedPermanenceDistal self.sampleSizeDistal = sampleSizeDistal self.activationThresholdDistal = activationThresholdDistal self.inertiaFactor = inertiaFactor self.activeCells = numpy.empty(0, dtype="uint32") self._random = Random(seed) # These sparse matrices will hold the synapses for each segment. # Each row represents one segment on a cell, so each cell potentially has # 1 proximal segment and 1+len(lateralInputWidths) distal segments. self.proximalPermanences = SparseMatrix(cellCount, inputWidth) self.internalDistalPermanences = SparseMatrix(cellCount, cellCount) self.distalPermanences = tuple(SparseMatrix(cellCount, n) for n in lateralInputWidths) self.useInertia=True
def __init__( self, inputWidth, lateralInputWidths=(), cellCount=4096, sdrSize=40, # Proximal synPermProximalInc=0.1, synPermProximalDec=0.001, initialProximalPermanence=0.6, sampleSizeProximal=20, minThresholdProximal=10, connectedPermanenceProximal=0.50, # Distal synPermDistalInc=0.1, synPermDistalDec=0.001, initialDistalPermanence=0.6, sampleSizeDistal=20, activationThresholdDistal=13, connectedPermanenceDistal=0.50, distalSegmentInhibitionFactor=1.001, seed=42): """ Parameters: ---------------------------- @param inputWidth (int) The number of bits in the feedforward input @param lateralInputWidths (list of ints) The number of bits in each lateral input @param sdrSize (int) The number of active cells in an object SDR @param synPermProximalInc (float) Permanence increment for proximal synapses @param synPermProximalDec (float) Permanence decrement for proximal synapses @param initialProximalPermanence (float) Initial permanence value for proximal synapses @param sampleSizeProximal (int) Number of proximal synapses a cell should grow to each feedforward pattern, or -1 to connect to every active bit @param minThresholdProximal (int) Number of active synapses required for a cell to have feedforward support @param connectedPermanenceProximal (float) Permanence required for a proximal synapse to be connected @param synPermDistalInc (float) Permanence increment for distal synapses @param synPermDistalDec (float) Permanence decrement for distal synapses @param sampleSizeDistal (int) Number of distal synapses a cell should grow to each lateral pattern, or -1 to connect to every active bit @param initialDistalPermanence (float) Initial permanence value for distal synapses @param activationThresholdDistal (int) Number of active synapses required to activate a distal segment @param connectedPermanenceDistal (float) Permanence required for a distal synapse to be connected @param distalSegmentInhibitionFactor (float) The minimum ratio of active dendrite segment counts that will lead to inhibition. For example, with value 1.5, cells with 2 active segments will be inhibited by cells with 3 active segments, but cells with 3 active segments will not be inhibited by cells with 4. @param seed (int) Random number generator seed """ assert distalSegmentInhibitionFactor > 0.0 self.inputWidth = inputWidth self.cellCount = cellCount self.sdrSize = sdrSize self.synPermProximalInc = synPermProximalInc self.synPermProximalDec = synPermProximalDec self.initialProximalPermanence = initialProximalPermanence self.connectedPermanenceProximal = connectedPermanenceProximal self.sampleSizeProximal = sampleSizeProximal self.minThresholdProximal = minThresholdProximal self.synPermDistalInc = synPermDistalInc self.synPermDistalDec = synPermDistalDec self.initialDistalPermanence = initialDistalPermanence self.connectedPermanenceDistal = connectedPermanenceDistal self.sampleSizeDistal = sampleSizeDistal self.activationThresholdDistal = activationThresholdDistal self.distalSegmentInhibitionFactor = distalSegmentInhibitionFactor self.activeCells = numpy.empty(0, dtype="uint32") self._random = Random(seed) # These sparse matrices will hold the synapses for each segment. # Each row represents one segment on a cell, so each cell potentially has # 1 proximal segment and 1+len(lateralInputWidths) distal segments. self.proximalPermanences = SparseMatrix(cellCount, inputWidth) self.internalDistalPermanences = SparseMatrix(cellCount, cellCount) self.distalPermanences = tuple( SparseMatrix(cellCount, n) for n in lateralInputWidths)
def initializeConnections(self): """ Initialize connection matrix, including: _permanences : permanence of synaptic connections (sparse matrix) _potentialPools: potential pool of connections for each cell (sparse binary matrix) _connectedSynapses: connected synapses (binary sparse matrix) _connectedCounts: number of connections per cell (numpy array) """ numColumns = self._numColumns numInputs = self._numInputs # The SP should be setup so that stimulusThreshold is reasonably high, # similar to a TP's activation threshold. The pct of connected cells may # need to be low to avoid false positives given the monosynaptic rule initConnectedPct = self._initConnectedPct # Store the set of all inputs that are within each column's potential pool. # 'potentialPools' is a matrix, whose rows represent cortical columns, and # whose columns represent the input bits. if potentialPools[i][j] == 1, # then input bit 'j' is in column 'i's potential pool. A column can only be # connected to inputs in its potential pool. The indices refer to a # flattened version of both the inputs and columns. Namely, irrespective # of the topology of the inputs and columns, they are treated as being a # one dimensional array. Since a column is typically connected to only a # subset of the inputs, many of the entries in the matrix are 0. Therefore # the the potentialPool matrix is stored using the SparseBinaryMatrix # class, to reduce memory footprint and compuation time of algorithms that # require iterating over the data strcuture. self._potentialPools = SparseBinaryMatrix(numInputs) self._potentialPools.resize(numColumns, numInputs) # Initialize the permanences for each column. Similar to the # 'self._potentialPools', the permanences are stored in a matrix whose rows # represent the cortical columns, and whose columns represent the input # bits. if self._permanences[i][j] = 0.2, then the synapse connecting # cortical column 'i' to input bit 'j' has a permanence of 0.2. Here we # also use the SparseMatrix class to reduce the memory footprint and # computation time of algorithms that require iterating over the data # structure. This permanence matrix is only allowed to have non-zero # elements where the potential pool is non-zero. self._permanences = SparseMatrix(numColumns, numInputs) # 'self._connectedSynapses' is a similar matrix to 'self._permanences' # (rows represent cortical columns, columns represent input bits) whose # entries represent whether the cortial column is connected to the input # bit, i.e. its permanence value is greater than 'synPermConnected'. While # this information is readily available from the 'self._permanence' matrix, # it is stored separately for efficiency purposes. self._connectedSynapses = SparseBinaryMatrix(numInputs) self._connectedSynapses.resize(numColumns, numInputs) # Stores the number of connected synapses for each column. This is simply # a sum of each row of 'self._connectedSynapses'. again, while this # information is readily available from 'self._connectedSynapses', it is # stored separately for efficiency purposes. self._connectedCounts = numpy.zeros(numColumns, dtype=realDType) # Initialize the set of permanence values for each column. Ensure that # each column is connected to enough input bits to allow it to be # activated. for i in xrange(numColumns): potential = self._mapPotential(i, wrapAround=self._wrapAround) self._potentialPools.replaceSparseRow(i, potential.nonzero()[0]) perm = self._initPermanence(potential, initConnectedPct) self._updatePermanencesForColumn(perm, i, raisePerm=True)
def countBitFrequenciesForTerms(client, lines, acceptanceProbability=0.1, usePlaceholderEncoding=True, percentSparsity=0.0102): # Accumulate counts by inplace-adding sparse matrices skippedWords = {} counts = SparseMatrix() width = RETINA_SIZES[client.retina]["width"] height = RETINA_SIZES[client.retina]["height"] counts.resize(1, width * height) # Pre-allocate buffer sparse matrix sparseBitmap = SparseMatrix() sparseBitmap.resize(1, width * height) # Accumulate counts for each bit for each word numWords = 0 numLines = 0 for line in lines: tokens = TextPreprocess().tokenize(line) for term in tokens: p = random.uniform(0, 1) if p <= acceptanceProbability: if usePlaceholderEncoding: random.seed(term) bitmap = random.sample( xrange(width * height), int(width * height * percentSparsity)) bitmap.sort() random.seed(p) else: try: bitmap = client.getBitmap( term)["fingerprint"]["positions"] except Exception as err: print "Skipping '{}', reason: {}".format( term, str(err)) continue if not bitmap: skippedWords[term] = skippedWords.get(term, 0) + 1 # print "Skipping '{}', reason: empty".format(term) continue sparseBitmap.setRowFromSparse(0, bitmap, [1] * len(bitmap)) counts += sparseBitmap numWords += 1 numLines += 1 if numLines % 1000 == 0: print "...processed=", numLines, "lines and", numWords, "words" # Compute normalized version of counts as a separate matrix frequencies = SparseMatrix() frequencies.resize(1, width * height) frequencies.copy(counts) frequencies.divide(float(numWords)) # Wrap up by printing some statistics and then saving the normalized version print "Processed", numLines, "lines" printFrequencyStatistics(counts, frequencies, numWords, width * height) frequencyFilename = "bit_frequencies_" + client.retina + ".pkl" print "Saving frequency matrix in", frequencyFilename with open(frequencyFilename, "wb") as frequencyPickleFile: pickle.dump(frequencies, frequencyPickleFile) print "These words were skipped N times because of empty bitmap result" print skippedWords return counts
def __init__( self, name, numCorticalColumns=1, inputSize=1024, numInputBits=20, externalInputSize=1024, numExternalInputBits=20, L2Overrides=None, L2RegionType="py.ColumnPoolerRegion", L4RegionType="py.ApicalTMPairRegion", networkType="MultipleL4L2Columns", implementation=None, longDistanceConnections=0, maxConnectionDistance=1, columnPositions=None, L4Overrides=None, numLearningPoints=3, seed=42, logCalls=False, enableLateralSP=False, lateralSPOverrides=None, enableFeedForwardSP=False, feedForwardSPOverrides=None, objectNamesAreIndices=False, enableFeedback=True, maxSegmentsPerCell=10, ): """ Creates the network. Parameters: ---------------------------- @param name (str) Experiment name @param numCorticalColumns (int) Number of cortical columns in the network @param inputSize (int) Size of the sensory input @param numInputBits (int) Number of ON bits in the generated input patterns @param externalInputSize (int) Size of the lateral input to L4 regions @param numExternalInputBits (int) Number of ON bits in the external input patterns @param L2Overrides (dict) Parameters to override in the L2 region @param L2RegionType (string) The type of region to use for L2 @param L4RegionType (string) The type of region to use for L4 @param networkType (string) Which type of L2L4 network to create. If topology is being used, it should be specified here. Possible values for this parameter are "MultipleL4L2Columns", "MultipleL4L2ColumnsWithTopology" and "L4L2Column" @param longDistanceConnections (float) The probability that a column will randomly connect to a distant column. Should be in [0, 1). Only relevant when using multiple columns with topology. @param L4Overrides (dict) Parameters to override in the L4 region @param numLearningPoints (int) Number of times each pair should be seen to be learnt @param logCalls (bool) If true, calls to main functions will be logged internally. The log can then be saved with saveLogs(). This allows us to recreate the complete network behavior using rerunExperimentFromLogfile which is very useful for debugging. @param enableLateralSP (bool) If true, Spatial Pooler will be added between external input and L4 lateral input @param lateralSPOverrides Parameters to override in the lateral SP region @param enableFeedForwardSP (bool) If true, Spatial Pooler will be added between external input and L4 feed-forward input @param feedForwardSPOverrides Parameters to override in the feed-forward SP region @param objectNamesAreIndices (bool) If True, object names are used as indices in the getCurrentObjectOverlaps method. Object names must be positive integers. If False, object names can be strings, and indices will be assigned to each object name. @param enableFeedback (bool) If True, enable feedback between L2 and L4 """ # Handle logging - this has to be done first self.logCalls = logCalls registerAllResearchRegions() self.name = name self.numLearningPoints = numLearningPoints self.numColumns = numCorticalColumns self.inputSize = inputSize self.externalInputSize = externalInputSize self.numInputBits = numInputBits self.objectNamesAreIndices = objectNamesAreIndices # seed self.seed = seed random.seed(seed) # update parameters with overrides if implementation is None: self.config = { "networkType": networkType, "longDistanceConnections": longDistanceConnections, "enableFeedback": enableFeedback, "numCorticalColumns": numCorticalColumns, "externalInputSize": externalInputSize, "sensorInputSize": inputSize, "L2RegionType": L2RegionType, "L4RegionType": L4RegionType, "L4Params": self.getDefaultL4Params(inputSize, numExternalInputBits), "L2Params": self.getDefaultL2Params(inputSize, numInputBits), } else: if "Bayesian" in implementation: self.config = { "networkType": networkType, "longDistanceConnections": longDistanceConnections, "enableFeedback": enableFeedback, "numCorticalColumns": numCorticalColumns, "externalInputSize": externalInputSize, "sensorInputSize": inputSize, "L2RegionType": L2RegionType, "L4RegionType": L4RegionType, "L4Params": self.getBayesianL4Params(inputSize, numExternalInputBits), "L2Params": self.getBayesianL2Params(inputSize, numInputBits), } self.config["L4Params"][ "maxSegmentsPerCell"] = maxSegmentsPerCell self.config["L4Params"]["implementation"] = implementation self.config["L2Params"]["implementation"] = implementation if enableLateralSP: self.config["lateralSPParams"] = self.getDefaultLateralSPParams( inputSize) if lateralSPOverrides: self.config["lateralSPParams"].update(lateralSPOverrides) if enableFeedForwardSP: self.config[ "feedForwardSPParams"] = self.getDefaultFeedForwardSPParams( inputSize) if feedForwardSPOverrides: self.config["feedForwardSPParams"].update( feedForwardSPOverrides) if "Topology" in self.config["networkType"]: self.config["maxConnectionDistance"] = maxConnectionDistance # Generate a grid for cortical columns. Will attempt to generate a full # square grid, and cut out positions starting from the bottom-right if the # number of cortical columns is not a perfect square. if columnPositions is None: columnPositions = [] side_length = int(np.ceil(np.sqrt(numCorticalColumns))) for i in range(side_length): for j in range(side_length): columnPositions.append((i, j)) self.config[ "columnPositions"] = columnPositions[:numCorticalColumns] self.config["longDistanceConnections"] = longDistanceConnections if L2Overrides is not None: self.config["L2Params"].update(L2Overrides) if L4Overrides is not None: self.config["L4Params"].update(L4Overrides) # create network self.network = createNetwork(self.config) self.sensorInputs = [] self.externalInputs = [] self.L4Regions = [] self.L2Regions = [] for i in xrange(self.numColumns): self.sensorInputs.append(self.network.regions["sensorInput_" + str(i)].getSelf()) self.externalInputs.append(self.network.regions["externalInput_" + str(i)].getSelf()) self.L4Regions.append(self.network.regions["L4Column_" + str(i)]) self.L2Regions.append(self.network.regions["L2Column_" + str(i)]) self.L4Columns = [region.getSelf() for region in self.L4Regions] self.L2Columns = [region.getSelf() for region in self.L2Regions] # will be populated during training self.objectL2Representations = {} self.objectL2RepresentationsMatrices = [ SparseMatrix(0, self.config["L2Params"]["cellCount"]) for _ in xrange(self.numColumns) ] self.objectNameToIndex = {} self.statistics = []
def __init__(self, inputWidth, lateralInputWidth, numActiveColumnsPerInhArea=40, synPermProximalInc=0.1, synPermProximalDec=0.001, initialProximalPermanence=0.6, columnDimensions=(2048,), minThresholdProximal=10, activationThresholdDistal=13, minThresholdDistal=10, initialPermanence=0.41, connectedPermanence=0.50, maxNewProximalSynapseCount=20, maxNewDistalSynapseCount=20, permanenceIncrement=0.10, permanenceDecrement=0.10, predictedSegmentDecrement=0.0, maxSegmentsPerCell=255, maxSynapsesPerProximalSegment=255, maxSynapsesPerDistalSegment=255, seed=42): """ This classes uses an ExtendedTemporalMemory internally to keep track of distal segments. Please see ExtendedTemporalMemory for descriptions of constructor parameters not defined below. Parameters: ---------------------------- @param inputWidth (int) The number of proximal inputs into this layer @param lateralInputWidth (int) The number of lateral inputs into this layer @param numActiveColumnsPerInhArea (int) Target number of active cells @param synPermProximalInc (float) Permanence increment for proximal synapses @param synPermProximalDec (float) Permanence decrement for proximal synapses @param initialProximalPermanence (float) Initial permanence value for proximal segments """ self.inputWidth = inputWidth self.lateralInputWidth = lateralInputWidth self.numActiveColumnsPerInhArea = numActiveColumnsPerInhArea self.synPermProximalInc = synPermProximalInc self.synPermProximalDec = synPermProximalDec self.initialProximalPermanence = initialProximalPermanence self.connectedPermanence = connectedPermanence self.maxNewProximalSynapseCount = maxNewProximalSynapseCount self.maxNewDistalSynapseCount = maxNewDistalSynapseCount self.minThresholdProximal = minThresholdProximal self.minThresholdDistal = minThresholdDistal self.maxSynapsesPerProximalSegment = maxSynapsesPerProximalSegment self.activeCells = set() self._random = Random(seed) # Create our own instance of extended temporal memory to handle distal # segments. self.tm = createModel( modelName="etm_cpp", columnDimensions=columnDimensions, basalInputDimensions=(lateralInputWidth,), apicalInputDimensions=(), cellsPerColumn=1, activationThreshold=activationThresholdDistal, initialPermanence=initialPermanence, connectedPermanence=connectedPermanence, minThreshold=minThresholdDistal, maxNewSynapseCount=maxNewDistalSynapseCount, permanenceIncrement=permanenceIncrement, permanenceDecrement=permanenceDecrement, predictedSegmentDecrement=predictedSegmentDecrement, formInternalBasalConnections=False, learnOnOneCell=False, maxSegmentsPerCell=maxSegmentsPerCell, maxSynapsesPerSegment=maxSynapsesPerDistalSegment, seed=seed, ) # These sparse matrices will hold the synapses for each proximal segment. # # proximalPermanences - SparseMatrix with permanence values # proximalConnections - SparseBinaryMatrix of connected synapses self.proximalPermanences = SparseMatrix(self.numberOfColumns(), inputWidth) self.proximalConnections = SparseBinaryMatrix(inputWidth) self.proximalConnections.resize(self.numberOfColumns(), inputWidth)
def __init__( self, name, numCorticalColumns=1, inputSize=1024, numInputBits=20, externalInputSize=1024, numExternalInputBits=20, L2Overrides=None, L4Overrides=None, seed=42, logCalls=False, objectNamesAreIndices=False, ): """ Creates the network. Parameters: ---------------------------- @param TMOverrides (dict) Parameters to override in the TM region """ # Handle logging - this has to be done first self.logCalls = logCalls registerAllResearchRegions() self.name = name self.numLearningPoints = 1 self.numColumns = numCorticalColumns self.inputSize = inputSize self.externalInputSize = externalInputSize self.numInputBits = numInputBits self.objectNamesAreIndices = objectNamesAreIndices self.numExternalInputBits = numExternalInputBits # seed self.seed = seed random.seed(seed) # Create default parameters and then update with overrides self.config = { "networkType": "CombinedSequenceColumn", "numCorticalColumns": numCorticalColumns, "externalInputSize": externalInputSize, "sensorInputSize": inputSize, "enableFeedback": False, "L2Params": self.getDefaultL2Params(inputSize, numInputBits), } self.config["L4Params"] = self._getDefaultCombinedL4Params( self.numInputBits, self.inputSize, self.numExternalInputBits, self.externalInputSize, self.config["L2Params"]["cellCount"]) if L2Overrides is not None: self.config["L2Params"].update(L2Overrides) if L4Overrides is not None: self.config["L4Params"].update(L4Overrides) pprint.pprint(self.config) # Recreate network including TM parameters self.network = createNetwork(self.config) self.sensorInputs = [] self.externalInputs = [] self.L2Regions = [] self.L4Regions = [] for i in xrange(self.numColumns): self.sensorInputs.append(self.network.regions["sensorInput_" + str(i)].getSelf()) self.externalInputs.append(self.network.regions["externalInput_" + str(i)].getSelf()) self.L2Regions.append(self.network.regions["L2Column_" + str(i)]) self.L4Regions.append(self.network.regions["L4Column_" + str(i)]) self.L2Columns = [region.getSelf() for region in self.L2Regions] self.L4Columns = [region.getSelf() for region in self.L4Regions] # will be populated during training self.objectL2Representations = {} self.objectL2RepresentationsMatrices = [ SparseMatrix(0, self.config["L2Params"]["cellCount"]) for _ in xrange(self.numColumns) ] self.objectNameToIndex = {} self.statistics = []
def __init__(self, name, numCorticalColumns=1, inputSize=1024, numInputBits=20, externalInputSize=1024, numExternalInputBits=20, L2Overrides=None, L4RegionType="py.ExtendedTMRegion", L4Overrides=None, numLearningPoints=3, seed=42, logCalls=False, enableLateralSP=False, lateralSPOverrides=None, enableFeedForwardSP=False, feedForwardSPOverrides=None, objectNamesAreIndices=False ): """ Creates the network. Parameters: ---------------------------- @param name (str) Experiment name @param numCorticalColumns (int) Number of cortical columns in the network @param inputSize (int) Size of the sensory input @param numInputBits (int) Number of ON bits in the generated input patterns @param externalInputSize (int) Size of the lateral input to L4 regions @param numExternalInputBits (int) Number of ON bits in the external input patterns @param L2Overrides (dict) Parameters to override in the L2 region @param L4RegionType (string) The type of region to use for L4 @param L4Overrides (dict) Parameters to override in the L4 region @param numLearningPoints (int) Number of times each pair should be seen to be learnt @param logCalls (bool) If true, calls to main functions will be logged internally. The log can then be saved with saveLogs(). This allows us to recreate the complete network behavior using rerunExperimentFromLogfile which is very useful for debugging. @param enableLateralSP (bool) If true, Spatial Pooler will be added between external input and L4 lateral input @param lateralSPOverrides Parameters to override in the lateral SP region @param enableFeedForwardSP (bool) If true, Spatial Pooler will be added between external input and L4 feed-forward input @param feedForwardSPOverrides Parameters to override in the feed-forward SP region @param objectNamesAreIndices (bool) If True, object names are used as indices in the getCurrentObjectOverlaps method. Object names must be positive integers. If False, object names can be strings, and indices will be assigned to each object name. """ # Handle logging - this has to be done first self.logCalls = logCalls registerAllResearchRegions() self.name = name self.numLearningPoints = numLearningPoints self.numColumns = numCorticalColumns self.inputSize = inputSize self.externalInputSize = externalInputSize self.numInputBits = numInputBits self.objectNamesAreIndices = objectNamesAreIndices # seed self.seed = seed random.seed(seed) # update parameters with overrides self.config = { "networkType": "MultipleL4L2Columns", "numCorticalColumns": numCorticalColumns, "externalInputSize": externalInputSize, "sensorInputSize": inputSize, "L4RegionType": L4RegionType, "L4Params": self.getDefaultL4Params(L4RegionType, inputSize, numExternalInputBits), "L2Params": self.getDefaultL2Params(inputSize, numInputBits), } if enableLateralSP: self.config["lateralSPParams"] = self.getDefaultLateralSPParams(inputSize) if lateralSPOverrides: self.config["lateralSPParams"].update(lateralSPOverrides) if enableFeedForwardSP: self.config["feedForwardSPParams"] = self.getDefaultFeedForwardSPParams(inputSize) if feedForwardSPOverrides: self.config["feedForwardSPParams"].update(feedForwardSPOverrides) if L2Overrides is not None: self.config["L2Params"].update(L2Overrides) if L4Overrides is not None: self.config["L4Params"].update(L4Overrides) # create network self.network = createNetwork(self.config) self.sensorInputs = [] self.externalInputs = [] self.L4Regions = [] self.L2Regions = [] for i in xrange(self.numColumns): self.sensorInputs.append( self.network.regions["sensorInput_" + str(i)].getSelf() ) self.externalInputs.append( self.network.regions["externalInput_" + str(i)].getSelf() ) self.L4Regions.append( self.network.regions["L4Column_" + str(i)] ) self.L2Regions.append( self.network.regions["L2Column_" + str(i)] ) self.L4Columns = [region.getSelf() for region in self.L4Regions] self.L2Columns = [region.getSelf() for region in self.L2Regions] # will be populated during training self.objectL2Representations = {} self.objectL2RepresentationsMatrices = [ SparseMatrix(0, self.config["L2Params"]["cellCount"]) for _ in xrange(self.numColumns)] self.objectNameToIndex = {} self.statistics = []