First, some code. Scroll down.


In [1]:
import itertools
import random

from htmresearch.algorithms.column_pooler import ColumnPooler

In [2]:
INPUT_SIZE = 10000

def createFeatureLocationPool(size=10):
    duplicateFound = False
    for _ in xrange(5):
        candidateFeatureLocations = [frozenset(random.sample(xrange(INPUT_SIZE), 40))
                                     for featureNumber in xrange(size)]

        # Sanity check that they're pretty unique.
        duplicateFound = False
        for pattern1, pattern2 in itertools.combinations(candidateFeatureLocations, 2):
            if len(pattern1 & pattern2) >= 5:
                duplicateFound = True
                break
                
        if not duplicateFound:
            break
        
    if duplicateFound:
        raise ValueError("Failed to generate unique feature-locations")
      
    featureLocationPool = {}
    for i, featureLocation in enumerate(candidateFeatureLocations):
        if i < 26:
            name = chr(ord('A') + i)
        else:
            name = "Feature-location %d" % i
        featureLocationPool[name] = featureLocation
        
    return featureLocationPool


def getLateralInputs(columnPoolers):
    cellsPerColumnPooler = columnPoolers[0].numberOfCells()
    assert all(column.numberOfCells() == cellsPerColumnPooler
               for column in columnPoolers)

    inputsByColumn = []
    for recipientColumnIndex in xrange(len(columnPoolers)):
        columnInput = []
        for inputColumnIndex, column in enumerate(columnPoolers):
            if inputColumnIndex == recipientColumnIndex:
                continue
            elif inputColumnIndex < recipientColumnIndex:
                relativeIndex = inputColumnIndex
            elif inputColumnIndex > recipientColumnIndex:
                relativeIndex = inputColumnIndex - 1
                                       
            offset = relativeIndex * cellsPerColumnPooler
            
            columnInput.extend(cell + offset 
                               for cell in column.getActiveCells())
        inputsByColumn.append(columnInput)
        
    return inputsByColumn


def getColumnPoolerParams(inputWidth, numColumns):
    cellCount = 2048
    
    return {
        "inputWidth": inputWidth,
        "lateralInputWidth": cellCount * (numColumns - 1),
        "columnDimensions": (cellCount,),
        "activationThresholdDistal": 13,
        "initialPermanence": 0.41,
        "connectedPermanence": 0.50,
        "minThresholdProximal": 10,
        "minThresholdDistal": 10,
        "maxNewProximalSynapseCount": 20,
        "maxNewDistalSynapseCount": 20,
        "permanenceIncrement": 0.10,
        "permanenceDecrement": 0.10,
        "predictedSegmentDecrement": 0.0,
        "synPermProximalInc": 0.1,
        "synPermProximalDec": 0.001,
        "initialProximalPermanence": 0.6,
        "seed": 42,
        "numActiveColumnsPerInhArea": 40,
        "maxSynapsesPerProximalSegment": inputWidth,
    }

def experiment(objects, numColumns):
    #
    # Initialize
    #
    params = getColumnPoolerParams(INPUT_SIZE, numColumns)
    columnPoolers = [ColumnPooler(**params) for _ in xrange(numColumns)]

    #
    # Learn
    #
    columnObjectRepresentations = [{} for _ in xrange(numColumns)]

    for objectName, objectFeatureLocations in objects.iteritems():
        for featureLocationName in objectFeatureLocations:
            pattern = featureLocationPool[featureLocationName]
            for _ in xrange(10):
                lateralInputs = getLateralInputs(columnPoolers)

                for i, column in enumerate(columnPoolers):
                    column.compute(feedforwardInput=pattern,
                                   lateralInput = lateralInputs[i],
                                   learn=True)

        for i, column in enumerate(columnPoolers):
            columnObjectRepresentations[i][objectName] = frozenset(column.getActiveCells())
            column.reset()
            
    objectName = "Object 1"
    objectFeatureLocations = objects[objectName]

    success = False
    featureLocationLog = []
    activeCellsLog = []
    for attempt in xrange(60):
        featureLocations = random.sample(objectFeatureLocations, numColumns)
        featureLocationLog.append(featureLocations)
        
        # Give the feedforward input 3 times so that the lateral inputs have time to spread.
        for _ in xrange(3):
            lateralInputs = getLateralInputs(columnPoolers)

            for i, column in enumerate(columnPoolers):
                pattern = featureLocationPool[featureLocations[i]]
                column.compute(feedforwardInput=pattern,
                               lateralInput=lateralInputs[i],
                               learn=False)

        allActiveCells = [set(column.getActiveCells()) for column in columnPoolers]
        activeCellsLog.append(allActiveCells)

        if all(set(column.getActiveCells()) == columnObjectRepresentations[i][objectName]
               for i, column in enumerate(columnPoolers)):
            success = True
            print "Converged after %d steps" % (attempt + 1)
            break

    if not success:
        print "Failed to converge after %d steps" % (attempt + 1)
        
    return (objectName, columnPoolers, featureLocationLog, activeCellsLog, columnObjectRepresentations)

Initialize some feature-locations


In [3]:
featureLocationPool = createFeatureLocationPool(size=8)

Issue: One column spots a difference, but its voice is drowned out

Create 8 objects, each with 7 feature-locations. Each object is 1 different from each other object.


In [4]:
objects = {"Object 1": set(["A", "B", "C", "D", "E", "F", "G"]),
           "Object 2": set(["A", "B", "C", "D", "E", "F", "H"]),
           "Object 3": set(["A", "B", "C", "D", "E", "G", "H"]),
           "Object 4": set(["A", "B", "C", "D", "F", "G", "H"]),
           "Object 5": set(["A", "B", "C", "E", "F", "G", "H"]),
           "Object 6": set(["A", "B", "D", "E", "F", "G", "H"]),
           "Object 7": set(["A", "C", "D", "E", "F", "G", "H"]),
           "Object 8": set(["B", "C", "D", "E", "F", "G", "H"])}

We're testing L2 in isolation, so these "A", "B", etc. patterns are L4 representations, i.e. "feature-locations".

Train an array of 5 columns to recognize these objects, then show it Object 1. It will randomly move its sensors to different feature-locations on the object. It will never put two sensors on the same feature-location at the same time.


In [5]:
(testObject,
 columnPoolers,
 featureLocationLog,
 activeCellsLog,
 columnObjectRepresentations) = experiment(objects, numColumns=5)


Failed to converge after 60 steps

In [6]:
columnContentsLog = []
for timestep, allActiveCells in enumerate(activeCellsLog):
    columnContents = []
    for columnIndex, activeCells in enumerate(allActiveCells):
        contents = {}
        for objectName, objectCells in columnObjectRepresentations[columnIndex].iteritems():
            containsRatio = len(activeCells & objectCells) / float(len(objectCells))
            if containsRatio >= 0.20:
                contents[objectName] = containsRatio
        columnContents.append(contents)
    columnContentsLog.append(columnContents)

In [7]:
for timestep in xrange(len(featureLocationLog)):
    allFeedforwardInputs = featureLocationLog[timestep]
    allActiveCells = activeCellsLog[timestep]
    allColumnContents = columnContentsLog[timestep]
    
    print "Step %d" % timestep
    
    for columnIndex in xrange(len(allFeedforwardInputs)):
        feedforwardInput = allFeedforwardInputs[columnIndex]
        activeCells = allActiveCells[columnIndex]
        columnContents = allColumnContents[columnIndex]
        
        print "Column %d: Input: %s, Active cells: %d %s" % (columnIndex,
                                                             allFeedforwardInputs[columnIndex],
                                                             len(activeCells),
                                                             columnContents)
        
    print


Step 0
Column 0: Input: E, Active cells: 252 {'Object 8': 1.0, 'Object 5': 1.0, 'Object 7': 1.0, 'Object 6': 0.9, 'Object 1': 1.0, 'Object 3': 0.9, 'Object 2': 1.0}
Column 1: Input: C, Active cells: 256 {'Object 8': 1.0, 'Object 5': 1.0, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 1': 1.0, 'Object 3': 0.9, 'Object 2': 1.0}
Column 2: Input: G, Active cells: 256 {'Object 8': 1.0, 'Object 5': 1.0, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 6': 0.925, 'Object 1': 1.0, 'Object 3': 0.9, 'Object 2': 0.2}
Column 3: Input: D, Active cells: 254 {'Object 8': 1.0, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 6': 0.925, 'Object 1': 1.0, 'Object 3': 0.9, 'Object 2': 1.0}
Column 4: Input: F, Active cells: 256 {'Object 8': 1.0, 'Object 5': 0.925, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 6': 0.925, 'Object 1': 1.0, 'Object 2': 1.0}

Step 1
Column 0: Input: E, Active cells: 219 {'Object 8': 1.0, 'Object 5': 1.0, 'Object 7': 1.0, 'Object 6': 0.55, 'Object 1': 1.0, 'Object 3': 0.4, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 227 {'Object 8': 1.0, 'Object 5': 1.0, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 6': 0.65, 'Object 1': 1.0, 'Object 3': 0.425, 'Object 2': 0.2}
Column 2: Input: C, Active cells: 237 {'Object 8': 1.0, 'Object 5': 1.0, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 1': 1.0, 'Object 3': 0.425, 'Object 2': 1.0}
Column 3: Input: D, Active cells: 226 {'Object 8': 1.0, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 6': 0.7, 'Object 1': 1.0, 'Object 3': 0.425, 'Object 2': 1.0}
Column 4: Input: F, Active cells: 245 {'Object 8': 1.0, 'Object 5': 0.925, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 6': 0.65, 'Object 1': 1.0, 'Object 2': 1.0}

Step 2
Column 0: Input: B, Active cells: 186 {'Object 5': 1.0, 'Object 4': 1.0, 'Object 1': 1.0, 'Object 8': 0.85, 'Object 2': 1.0}
Column 1: Input: A, Active cells: 189 {'Object 5': 1.0, 'Object 4': 1.0, 'Object 7': 0.925, 'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: G, Active cells: 189 {'Object 8': 0.95, 'Object 5': 1.0, 'Object 4': 1.0, 'Object 7': 0.925, 'Object 1': 1.0, 'Object 2': 0.2}
Column 3: Input: D, Active cells: 187 {'Object 4': 1.0, 'Object 7': 0.925, 'Object 1': 1.0, 'Object 8': 0.95, 'Object 2': 1.0}
Column 4: Input: C, Active cells: 218 {'Object 8': 0.95, 'Object 5': 0.925, 'Object 4': 1.0, 'Object 7': 0.925, 'Object 1': 1.0, 'Object 2': 1.0}

Step 3
Column 0: Input: G, Active cells: 193 {'Object 8': 1.0, 'Object 5': 1.0, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 1': 1.0, 'Object 2': 0.2}
Column 1: Input: F, Active cells: 225 {'Object 8': 1.0, 'Object 5': 1.0, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: D, Active cells: 191 {'Object 4': 0.975, 'Object 7': 1.0, 'Object 1': 1.0, 'Object 8': 1.0, 'Object 2': 1.0}
Column 3: Input: C, Active cells: 225 {'Object 8': 1.0, 'Object 5': 1.0, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: E, Active cells: 190 {'Object 5': 1.0, 'Object 7': 1.0, 'Object 1': 1.0, 'Object 8': 1.0, 'Object 2': 1.0}

Step 4
Column 0: Input: D, Active cells: 181 {'Object 4': 0.875, 'Object 7': 0.9, 'Object 1': 1.0, 'Object 8': 0.95, 'Object 2': 1.0}
Column 1: Input: C, Active cells: 215 {'Object 8': 0.95, 'Object 5': 1.0, 'Object 4': 0.875, 'Object 7': 0.9, 'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: E, Active cells: 184 {'Object 5': 1.0, 'Object 7': 0.9, 'Object 1': 1.0, 'Object 8': 0.95, 'Object 2': 1.0}
Column 3: Input: A, Active cells: 183 {'Object 5': 1.0, 'Object 4': 0.875, 'Object 7': 0.9, 'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: B, Active cells: 188 {'Object 5': 1.0, 'Object 4': 0.925, 'Object 1': 1.0, 'Object 8': 0.975, 'Object 2': 1.0}

Step 5
Column 0: Input: B, Active cells: 188 {'Object 5': 0.9, 'Object 4': 1.0, 'Object 1': 1.0, 'Object 8': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 186 {'Object 8': 1.0, 'Object 5': 0.9, 'Object 4': 1.0, 'Object 7': 0.9, 'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: C, Active cells: 218 {'Object 8': 1.0, 'Object 5': 0.9, 'Object 4': 1.0, 'Object 7': 0.9, 'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: F, Active cells: 218 {'Object 8': 1.0, 'Object 5': 0.9, 'Object 4': 1.0, 'Object 7': 0.9, 'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: D, Active cells: 189 {'Object 4': 1.0, 'Object 7': 0.925, 'Object 1': 1.0, 'Object 8': 1.0, 'Object 2': 1.0}

Step 6
Column 0: Input: E, Active cells: 178 {'Object 5': 0.7, 'Object 7': 1.0, 'Object 1': 1.0, 'Object 8': 1.0, 'Object 2': 1.0}
Column 1: Input: D, Active cells: 191 {'Object 4': 0.975, 'Object 7': 1.0, 'Object 1': 1.0, 'Object 8': 1.0, 'Object 2': 1.0}
Column 2: Input: G, Active cells: 181 {'Object 8': 1.0, 'Object 5': 0.7, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 1': 1.0, 'Object 2': 0.2}
Column 3: Input: F, Active cells: 213 {'Object 8': 1.0, 'Object 5': 0.7, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: A, Active cells: 180 {'Object 5': 0.725, 'Object 4': 0.975, 'Object 7': 1.0, 'Object 1': 1.0, 'Object 2': 1.0}

Step 7
Column 0: Input: A, Active cells: 151 {'Object 4': 1.0, 'Object 7': 0.9, 'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: C, Active cells: 180 {'Object 4': 1.0, 'Object 7': 0.9, 'Object 1': 1.0, 'Object 8': 0.875, 'Object 2': 1.0}
Column 2: Input: G, Active cells: 148 {'Object 4': 1.0, 'Object 7': 0.9, 'Object 1': 1.0, 'Object 8': 0.875, 'Object 2': 0.2}
Column 3: Input: D, Active cells: 180 {'Object 4': 1.0, 'Object 7': 0.9, 'Object 1': 1.0, 'Object 8': 0.875, 'Object 2': 1.0}
Column 4: Input: B, Active cells: 150 {'Object 4': 1.0, 'Object 1': 1.0, 'Object 8': 0.875, 'Object 2': 1.0}

Step 8
Column 0: Input: A, Active cells: 138 {'Object 4': 0.95, 'Object 7': 0.7, 'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: E, Active cells: 104 {'Object 7': 0.7, 'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: B, Active cells: 117 {'Object 4': 0.975, 'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: C, Active cells: 140 {'Object 4': 0.975, 'Object 7': 0.725, 'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: G, Active cells: 114 {'Object 4': 0.975, 'Object 7': 0.875, 'Object 1': 1.0, 'Object 2': 0.2}

Step 9
Column 0: Input: B, Active cells: 114 {'Object 4': 0.95, 'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: D, Active cells: 114 {'Object 4': 0.95, 'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: C, Active cells: 114 {'Object 4': 0.95, 'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: A, Active cells: 114 {'Object 4': 0.95, 'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: E, Active cells: 80 {'Object 1': 1.0, 'Object 2': 1.0}

Step 10
Column 0: Input: F, Active cells: 110 {'Object 4': 0.85, 'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: E, Active cells: 80 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: G, Active cells: 77 {'Object 4': 0.825, 'Object 1': 1.0, 'Object 2': 0.2}
Column 3: Input: B, Active cells: 109 {'Object 4': 0.825, 'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: D, Active cells: 111 {'Object 4': 0.875, 'Object 1': 1.0, 'Object 2': 1.0}

Step 11
Column 0: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}

Step 12
Column 0: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 13
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 14
Column 0: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 1: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 15
Column 0: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 1: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 16
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}

Step 17
Column 0: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 1: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 18
Column 0: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}

Step 19
Column 0: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 20
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 4: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 21
Column 0: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 1: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 22
Column 0: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 23
Column 0: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 24
Column 0: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 25
Column 0: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 26
Column 0: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 3: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 27
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 4: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 28
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 29
Column 0: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 1: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 30
Column 0: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 4: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 31
Column 0: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 4: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 32
Column 0: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 4: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 33
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 34
Column 0: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 1: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 35
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 36
Column 0: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 1: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 37
Column 0: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 38
Column 0: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 1: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 39
Column 0: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}

Step 40
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 3: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 41
Column 0: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 42
Column 0: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 1: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 43
Column 0: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 44
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 4: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 45
Column 0: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 46
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 47
Column 0: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 48
Column 0: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 49
Column 0: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 50
Column 0: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 3: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 51
Column 0: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 4: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 52
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}

Step 53
Column 0: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}

Step 54
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 55
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 56
Column 0: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 57
Column 0: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 4: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 58
Column 0: Input: B, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 2: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 3: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: D, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Step 59
Column 0: Input: C, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 1: Input: E, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 2: Input: G, Active cells: 46 {'Object 1': 1.0, 'Object 2': 0.2}
Column 3: Input: A, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}
Column 4: Input: F, Active cells: 78 {'Object 1': 1.0, 'Object 2': 1.0}

Each column is activating a union of cells. Column 2 sees input G, so it knows this isn't "Object 2", but multiple other columns are including "Object 2" in their unions, so Column 2's voice gets drowned out.

How does this vary with number of columns?


In [8]:
for numColumns in xrange(2, 8):
    print "With %d columns:" % numColumns
    experiment(objects, numColumns)
    print


With 2 columns:
Converged after 9 steps

With 3 columns:
Converged after 6 steps

With 4 columns:
Converged after 5 steps

With 5 columns:
Failed to converge after 60 steps

With 6 columns:
Failed to converge after 60 steps

With 7 columns:
Failed to converge after 60 steps