def __executeOne(self, learning): from numenta.htm import pool_spatial, pool_temporal for cell in self.cells: cell.clockTick() pool_spatial(self) self._updateSegments = pool_temporal(self, self._updateSegments, learning=learning) #non-Numenta optimization: #track whether cell is predicted next #penalize near segments for failing immediately if EXTENSION_NEXT_STEP_PENALTY: for cell in self.cells: #mark prediction of immediate next step cell.predictingNext = False for segment in cell.segmentsNear: if segment.active: cell.predictingNext = True if cell.predictedNext and not cell.active: #penalize only active near segments otherSynapseStates = [] for synapses in self._updateSegments[cell]: if len(synapses) and synapses[0].segment == segment: Segment.adapt_down(synapses) else: otherSynapseStates.append(synapses) self._updateSegments.reset(cell) self._updateSegments.addAll(cell, otherSynapseStates)
def testAggregation(self): seg = Segment() self.assertFalse(seg.active) firing = Mock({'is_firing': True}) off = Mock({'is_firing': False}) seg.add_synapse(off) self.assertFalse(seg.active) onRequired = int(FRACTION_SEGMENT_ACTIVATION_THRESHOLD * 100) offRequired = 99 - onRequired #this isn't a hard requirement, just a limitation of the test assert (onRequired >= 2) for _ in xrange(offRequired): seg.add_synapse(off) self.assertFalse(seg.active) for _ in xrange(onRequired - 1): seg.add_synapse(firing) self.assertFalse(seg.active) seg.add_synapse(firing) self.assert_(seg.active)
def testAggregation(self): seg = Segment() self.assertFalse(seg.active) firing = Mock({'is_firing':True}) off = Mock({'is_firing':False}) seg.add_synapse(off) self.assertFalse(seg.active) onRequired = int(FRACTION_SEGMENT_ACTIVATION_THRESHOLD*100) offRequired = 99-onRequired #this isn't a hard requirement, just a limitation of the test assert(onRequired >= 2) for _ in xrange(offRequired): seg.add_synapse(off) self.assertFalse(seg.active) for _ in xrange(onRequired-1): seg.add_synapse(firing) self.assertFalse(seg.active) seg.add_synapse(firing) self.assert_(seg.active)
def _temporal_phase3(htm, updateSegments): 'Phase 3, p42' for cell in htm.cells: if cell.learning: for synapseStates in updateSegments[cell]: Segment.adapt_up(synapseStates) updateSegments.reset(cell) elif not cell.predicting and cell.predicted: for synapseStates in updateSegments[cell]: Segment.adapt_down(synapseStates) updateSegments.reset(cell) return updateSegments
def __init__(self, htm, x, y, cellsPerColumn): ''' ''' self.htm = htm self.cells = [Cell(self, i) for i in xrange(cellsPerColumn)] self.overlap = 0 #synapses on input/proximal dendrites, forced equal for whole column, in equivalent of single segment self.segment = Segment(distal=False) self.boost = 1 self.x = x self.y = y self.dutyCycleMin = 0 self.dutyCycleActive = 0 self.dutyCycleOverlap = 0 self.active = False
def testAggregation(self): seg = Segment() firing = Mock({'is_firing':True}) off = Mock({'is_firing':False}) for i in xrange(SEGMENT_ACTIVATION_THRESHOLD-1): #@UnusedVariable seg.add_synapse(firing) self.assertFalse(seg.active) seg.add_synapse(off) self.assertFalse(seg.active) seg.add_synapse(firing) self.assert_(seg.active)
def __init__(self, htm, x, y, cellsPerColumn): ''' ''' self.htm = htm self.cells = [Cell() for i in xrange(cellsPerColumn)] #@UnusedVariable self.overlap = 0 #synapses on input/proximal dendrites, forced equal for whole column, in equivalent of single segment self.segment = Segment(distal=False) self.boost = 1 self.x = x self.y = y self.dutyCycleMin = 0 self.dutyCycleActive = 0 self.dutyCycleOverlap = 0 self.active = False
def __init__(self, column=None, layer=None): ''' @param layer the inner layer of the cell, so an HTM with 3 cells per column would have cells with layers 0, 1 and 2 ''' self.column = column self.layer = layer self.active = False self.__wasActive = False #read-only self.predicting = False self.__predicted = False #read-only self.learning = False self.__wasLearning = False #read-only self.predictingNext = None #cached-val self.__predictedNext = False #read-only self.segments = [Segment() for i in xrange(SEGMENTS_PER_CELL)]
def create_segment(self, htm, nextStep): ''' @param htm: the htm network that contains the cell @param nextStep: boolean for whether this segment indicates predicted firing in the very next time step ''' seg = Segment(nextStep=nextStep) #randomly choose input cells, from active non-self cells synapseLen = self.__createSynapses(seg, htm.cells, SYNAPSES_PER_SEGMENT, lambda c: c.wasLearning) if not nextStep and synapseLen < SYNAPSES_PER_SEGMENT: addSynapseLen = SYNAPSES_PER_SEGMENT - synapseLen activeSynapseLen = self.__createSynapses(seg, htm.cells, addSynapseLen, lambda c: c.wasActive) self.segments.append(seg) return seg
class Column(object): ''' Represents a column in an HTM network ''' MIN_OVERLAP = 5 #TODO: choose a reasonable number def __init__(self, htm, x, y, cellsPerColumn): ''' ''' self.htm = htm self.cells = [Cell() for i in xrange(cellsPerColumn)] #@UnusedVariable self.overlap = 0 #synapses on input/proximal dendrites, forced equal for whole column, in equivalent of single segment self.segment = Segment(distal=False) self.boost = 1 self.x = x self.y = y self.dutyCycleMin = 0 self.dutyCycleActive = 0 self.dutyCycleOverlap = 0 self.active = False def synapses_firing(self): return self.segment.synapses_firing() def increase_permanences(self, byAmount): return self.segment.increase_permanences(byAmount) def get_duty_cycle_active(self): newDutyCycle = AVG_SCALE*self.dutyCycleActive if self.active: newDutyCycle += (1-AVG_SCALE) return newDutyCycle def get_duty_cycle_overlap(self): newDutyCycle = AVG_SCALE*self.dutyCycleOverlap if self.overlap > self.MIN_OVERLAP: newDutyCycle += (1-AVG_SCALE) return newDutyCycle def next_boost(self): if self.dutyCycleActive >= self.dutyCycleMin: return 1 elif self.dutyCycleActive == 0: return self.boost * 1.05 #5% growth until you hit something... else: return self.dutyCycleMin / self.dutyCycleActive @property def synapses(self): return self.segment.synapses @property def synapsesConnected(self): return self.segment.synapsesConnected @property def neighbors(self): return self.htm.neighbors(self) def bestCell(self): '#see htm doc 0.1.1 pg 45: getBestMatchingCell' bestCell = None bestCellFiringSynapseCount = 0 #find cell with best best matching segment for cell in self.cells: seg = cell.bestMatchingSegment() if seg and len(seg.synapses_firing()) > bestCellFiringSynapseCount: bestCellFiringSynapseCount = len(seg.synapses_firing()) bestCell = cell #if none, pick the one with the fewest segments if bestCell is None: fewestSegments = len(self.cells[0].segments) bestCell = self.cells[0] for cell in self.cells[1:]: if len(cell.segments) < fewestSegments: bestCell = cell fewestSegments = len(cell.segments) return bestCell def distance_to(self, x, y): #map column's x,y values to input space: inputx = self.htm.inputCompression * self.x inputy = self.htm.inputCompression * self.y #assume 2d distances for now return math.sqrt((x-inputx)**2 + (y-inputy)**2) def __str__(self): #TODO: much more return "pos %s,%s; active? %s\n\t%s" % (self.x, self.y, self.active, self.segment) def neighbor_duty_cycle_max(self): ''' (Adapted from maxDutyCycle) Numenta docs: Returns the maximum active duty cycle of the columns in the neighborhood ''' return max((c.dutyCycleActive for c in self.neighbors)) def kth_neighbor(self, k): ''' Numenta docs: Given the list of columns, return the kth highest overlap value ''' allNeighbors = sorted(self.neighbors, key=lambda col: col.overlap) index = min(k-1,len(allNeighbors)-1) return allNeighbors[index] def __eq__(self, another): if not hasattr(another, 'htm') or not hasattr(another, 'x') or \ not hasattr(another, 'y') or not hasattr(another, 'boost'): return False return self.htm == another.htm and self.x == another.x and self.y == another.y
class Column(object): ''' Represents a column in an HTM network ''' MIN_OVERLAP = 5 #TODO: choose a reasonable number def __init__(self, htm, x, y, cellsPerColumn): ''' ''' self.htm = htm self.cells = [Cell(self, i) for i in xrange(cellsPerColumn)] self.overlap = 0 #synapses on input/proximal dendrites, forced equal for whole column, in equivalent of single segment self.segment = Segment(distal=False) self.boost = 1 self.x = x self.y = y self.dutyCycleMin = 0 self.dutyCycleActive = 0 self.dutyCycleOverlap = 0 self.active = False def old_firing_synapses(self): return self.segment.old_firing_synapses() def increase_permanences(self, byAmount): return self.segment.increase_permanences(byAmount) def get_duty_cycle_active(self): newDutyCycle = AVG_SCALE * self.dutyCycleActive if self.active: newDutyCycle += (1 - AVG_SCALE) return newDutyCycle def get_duty_cycle_overlap(self): newDutyCycle = AVG_SCALE * self.dutyCycleOverlap if self.overlap > self.MIN_OVERLAP: newDutyCycle += (1 - AVG_SCALE) return newDutyCycle def next_boost(self): if self.dutyCycleActive >= self.dutyCycleMin: return 1 elif self.dutyCycleActive == 0: return self.boost * 1.05 #5% growth until you hit something... else: return self.dutyCycleMin / self.dutyCycleActive @property def synapses(self): return self.segment.synapses @property def synapsesConnected(self): return self.segment.synapsesConnected @property def neighbors(self): return self.htm.neighbors(self) def bestCell(self, nextStep=True): '#see htm doc 0.2 pg 45: getBestMatchingCell' bestCell = None bestCellFiringSynapseCount = 0 bestSeg = None #find cell with best best matching segment for cell in self.cells: seg = cell.bestMatchingSegment(nextStep) numSynapses = len(seg.old_firing_synapses( requireConnection=False)) if seg else 0 if numSynapses > bestCellFiringSynapseCount: bestCellFiringSynapseCount = numSynapses bestCell = cell bestSeg = seg #if none, pick the one with the fewest segments if bestCell is None: bestSeg = None fewestSegments = len(self.cells[0].segments) bestCell = self.cells[0] for cell in self.cells[1:]: if len(cell.segments) < fewestSegments: bestCell = cell fewestSegments = len(cell.segments) bestSeg = cell.bestMatchingSegment(nextStep) return (bestCell, bestSeg) def distance_to(self, x, y): #map column's x,y values to input space: inputx = self.htm.inputCompression * self.x inputy = self.htm.inputCompression * self.y #assume 2d distances for now return math.sqrt((x - inputx)**2 + (y - inputy)**2) def __str__(self): #TODO: much more return "pos %s,%s; active? %s\n\t%s" % (self.x, self.y, self.active, self.segment) def neighbor_duty_cycle_max(self): ''' (Adapted from maxDutyCycle) Numenta docs: Returns the maximum active duty cycle of the columns in the neighborhood ''' return max((c.dutyCycleActive for c in self.neighbors)) def kth_neighbor(self, k): ''' Numenta docs: Given the list of columns, return the kth highest overlap value ''' allNeighbors = sorted(self.neighbors, reverse=True, key=lambda col: col.overlap) index = min(k - 1, len(allNeighbors) - 1) return allNeighbors[index] @property def predicting(self): for cell in self.cells: if cell.predicting: return True return False @property def predictedNext(self): 'is this column expected to get excited next?' for cell in self.cells: if cell.predictedNext: return True return False def __hash__(self): return self.x * self.y * hash(self.htm) def __eq__(self, another): if not hasattr(another, 'htm') or not hasattr(another, 'x') or \ not hasattr(another, 'y') or not hasattr(another, 'boost'): return False return self.htm == another.htm and self.x == another.x and self.y == another.y
def testAdaptation(self): seg = Segment() #for now, just don't crash seg.adapt_up([]) seg.adapt_down([])