Skip to content
This repository has been archived by the owner on Sep 1, 2023. It is now read-only.

Commit

Permalink
Merge pull request #3153 from hernandezurbina/RES217
Browse files Browse the repository at this point in the history
Added overlap accessors to spatial_pooler.py
  • Loading branch information
rhyolight committed Jun 2, 2016
2 parents 9c698bb + 92aa1d2 commit f4d1fe2
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 8 deletions.
33 changes: 25 additions & 8 deletions src/nupic/research/spatial_pooler.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
realDType = GetNTAReal()
uintType = "uint32"

VERSION = 2
VERSION = 3



Expand Down Expand Up @@ -285,6 +285,8 @@ def __init__(self,
self._synPermMin = 0.0
self._synPermMax = 1.0
self._synPermTrimThreshold = synPermActiveInc / 2.0
self._overlaps = numpy.zeros(self._numColumns, dtype=realDType)
self._boostedOverlaps = numpy.zeros(self._numColumns, dtype=realDType)

if self._synPermTrimThreshold >= self._synPermConnected:
raise InvalidSPParamValueError(
Expand Down Expand Up @@ -718,6 +720,16 @@ def getConnectedCounts(self, connectedCounts):
connectedCounts[:] = self._connectedCounts[:]


def getOverlaps(self):
"""Returns the overlap score for each column."""
return self._overlaps


def getBoostedOverlaps(self):
"""Returns the boosted overlap score for each column."""
return self._boostedOverlaps


def compute(self, inputVector, learn, activeArray):
"""
This is the primary public method of the SpatialPooler class. This
Expand Down Expand Up @@ -754,20 +766,20 @@ def compute(self, inputVector, learn, activeArray):
self._updateBookeepingVars(learn)
inputVector = numpy.array(inputVector, dtype=realDType)
inputVector.reshape(-1)
overlaps = self._calculateOverlap(inputVector)
self._overlaps = self._calculateOverlap(inputVector)

# Apply boosting when learning is on
if learn:
boostedOverlaps = self._boostFactors * overlaps
self._boostedOverlaps = self._boostFactors * self._overlaps
else:
boostedOverlaps = overlaps
self._boostedOverlaps = self._overlaps

# Apply inhibition to determine the winning columns
activeColumns = self._inhibitColumns(boostedOverlaps)
activeColumns = self._inhibitColumns(self._boostedOverlaps)

if learn:
self._adaptSynapses(inputVector, activeColumns)
self._updateDutyCycles(overlaps, activeColumns)
self._updateDutyCycles(self._overlaps, activeColumns)
self._bumpUpWeakColumns()
self._updateBoostFactors()
if self._isUpdateRound():
Expand Down Expand Up @@ -1645,6 +1657,11 @@ def __setstate__(self, state):
# the wrapAround property was added in version 2,
# in version 1 the wrapAround parameter was True for SP initialization
state['_wrapAround'] = True
if state['_version'] < 3:
# the overlaps and boostedOverlaps properties were added in version 3,
state['_overlaps'] = numpy.zeros(self._numColumns, dtype=realDType)
state['_boostedOverlaps'] = numpy.zeros(self._numColumns, dtype=realDType)

# update version property to current SP version
state['_version'] = VERSION
self.__dict__.update(state)
Expand Down Expand Up @@ -1716,7 +1733,7 @@ def write(self, proto):

boostFactorsProto = proto.init("boostFactors", len(self._boostFactors))
for i, v in enumerate(self._boostFactors):
boostFactorsProto[i] = float(v)
boostFactorsProto[i] = float(v)


@classmethod
Expand Down Expand Up @@ -1781,7 +1798,7 @@ def read(cls, proto):
instance._minActiveDutyCycles = numpy.array(proto.minActiveDutyCycles,
dtype=realDType)
instance._boostFactors = numpy.array(proto.boostFactors, dtype=realDType)

return instance


Expand Down
33 changes: 33 additions & 0 deletions tests/unit/nupic/research/spatial_pooler_unit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,35 @@ def testCompute2(self):
potential = sp._potentialPools[columnIndex]
perm = sp._permanences.getRow(columnIndex)
self.assertEqual(list(perm), list(potential))


def testOverlapsOutput(self):
"""Checks that overlaps and boostedOverlaps are correctly returned"""

sp = SpatialPooler(inputDimensions=[5],
columnDimensions=[3],
potentialRadius=5,
numActiveColumnsPerInhArea=5,
globalInhibition=True,
seed=1,
synPermActiveInc=0.1,
synPermInactiveDec=0.1)

inputVector = numpy.ones(5)
activeArray = numpy.zeros(3)

expOutput = numpy.array([2, 0, 0], dtype=realDType)
boostFactors = 2.0 * numpy.ones(3)
sp.setBoostFactors(boostFactors)
sp.compute(inputVector, True, activeArray)
overlaps = sp.getOverlaps()
boostedOverlaps = sp.getBoostedOverlaps()

for i in range(sp._numColumns):
self.assertEqual(overlaps[i], expOutput[i])

for i in range(sp._numColumns):
self.assertEqual(boostedOverlaps[i], (2 * expOutput[i]))


def testExactOutput(self):
Expand Down Expand Up @@ -1743,11 +1772,15 @@ def testWriteRead(self):

# Load the deserialized proto
sp2 = SpatialPooler.read(proto2)

ephemeral = set(["_boostedOverlaps", "_overlaps"])

# Check that the two spatial poolers have the same attributes
self.assertSetEqual(set(sp1.__dict__.keys()), set(sp2.__dict__.keys()))
for k, v1 in sp1.__dict__.iteritems():
v2 = getattr(sp2, k)
if k in ephemeral:
continue
if isinstance(v1, numpy.ndarray):
self.assertEqual(v1.dtype, v2.dtype,
"Key %s has differing dtypes: %s vs %s" % (
Expand Down

0 comments on commit f4d1fe2

Please sign in to comment.