In [1]:
from urllib import urlretrieve
import csv
import datetime
from io import BytesIO
import numpy as np
import json
import copy
import random

import uuid
from IPython.display import HTML

from nupic.encoders import MultiEncoder
import nupic.research.temporal_memory 
import nupic.bindings.algorithms
In [2]:
%%javascript
require.config({
        paths: {
            d3: '//d3js.org/d3.v3.min',
            hello: "//mrcslws.com/stuff/segment-stories.2016.04.28"
  }
});
In [3]:
def drawEverything(columnStatesChartBuilder, segmentLifetimesChartBuilder):
    elementId = str(uuid.uuid1())
    addChart = """
    <div id="%s" style="-webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;"></div>
    <script>
    require(['hello', 'd3'], function() {
        var myContainer = zoomableTimeSeries(document.getElementById('%s'));
        insertColumnStatesAndSegmentLifetimes(myContainer, '%s', '%s');
    });
    </script>
    """ % (elementId, elementId,
           columnStatesChartBuilder.output.getvalue().replace('\r', '\\r').replace('\n', '\\n'),
           segmentLifetimesChartBuilder.getOutput().replace('\r', '\\r').replace('\n', '\\n'))
    
    return HTML(addChart)
In [4]:
def parseHotgym(hotgymRaw):
    parsed = []

    csvReader = csv.reader(hotgymRaw)
    csvReader.next()
    csvReader.next()
    csvReader.next()
    
    for row in csvReader:
        timestampStr, consumptionStr = row
        parsed.append({
                'timestamp': datetime.datetime.strptime(timestampStr,
                                                        "%m/%d/%y %H:%M"),
                'consumption': float(consumptionStr)
            })
        
    return parsed

def encodeHotgym(hotgym):
    encoder = MultiEncoder({
        'consumption': {
            'fieldname': 'consumption',
            'name': 'consumption',
            'type': 'ScalarEncoder',
            'minval': 5.0,
            'maxval': 55.0,
            'clipInput': True,
            'n': 478,
            'w': 31,
        },
        'timestamp_timeOfDay': {
            'fieldname': 'timestamp',
            'name': 'timestamp_timeOfDay',
            'timeOfDay': (21, 1),
            'type': 'DateEncoder'
        },
        'timestamp_weekend': {
            'fieldname': 'timestamp',
            'name': 'timestamp_weekend',
            'type': 'DateEncoder',
            'weekend': 21
        },
    })
    
    return map(lambda row : encoder.encode(row), hotgym)
In [5]:
with open(urlretrieve("http://mrcslws.com/stuff/rec-center-hourly.csv")[0],
          'r') as hotgym:
    HOTGYM_ENCODED_ALL = encodeHotgym(parseHotgym(hotgym))
    HOTGYM_INDICES_ALL = map(lambda encoding : set(encoding.nonzero()[0]),
                             HOTGYM_ENCODED_ALL)
    
    HOTGYM_ENCODED = HOTGYM_ENCODED_ALL[:1000]
    HOTGYM_INDICES = HOTGYM_INDICES_ALL[:1000]

Here I've tuned the encoders to produce sparse outputs and to use every bit.

In [6]:
len(HOTGYM_ENCODED[0].nonzero()[0])
Out[6]:
73
In [7]:
# Sparsity
len(HOTGYM_ENCODED[0].nonzero()[0]) / float(len(HOTGYM_ENCODED[0]))
Out[7]:
0.0712890625
In [8]:
# Number of columns
len(HOTGYM_ENCODED[0])
Out[8]:
1024
In [9]:
# Show how often each bit is used
np.set_printoptions(threshold=1024)
reduce(lambda accum, encoding: accum + encoding,
       HOTGYM_ENCODED,
       np.zeros(1024, dtype='uint32'))
Out[9]:
array([140, 157, 186, 208, 225, 228, 228, 228, 229, 230, 231, 231, 231,
       231, 232, 232, 233, 234, 235, 235, 235, 235, 236, 236, 237, 238,
       239, 239, 239, 240, 242, 102,  86,  57,  35,  18,  15,  16,  20,
        21,  21,  22,  24,  24,  25,  24,  24,  23,  23,  22,  22,  25,
        25,  24,  24,  24,  25,  24,  25,  26,  26,  25,  26,  26,  26,
        26,  26,  26,  26,  23,  22,  22,  21,  19,  20,  19,  22,  23,
        24,  24,  25,  29,  27,  27,  28,  28,  28,  27,  28,  30,  29,
        29,  28,  28,  28,  30,  33,  35,  36,  37,  39,  39,  39,  38,
        38,  39,  41,  39,  40,  39,  39,  38,  35,  37,  39,  40,  40,
        39,  40,  39,  36,  36,  38,  40,  40,  39,  37,  35,  33,  32,
        32,  30,  30,  31,  32,  33,  31,  30,  31,  33,  33,  33,  34,
        34,  32,  33,  32,  36,  39,  41,  41,  42,  47,  46,  53,  56,
        63,  66,  66,  67,  71,  69,  68,  67,  67,  69,  68,  69,  68,
        66,  62,  62,  62,  61,  61,  60,  57,  56,  52,  50,  46,  47,
        47,  42,  40,  31,  27,  20,  17,  17,  17,  13,  13,  13,  13,
        11,   8,   8,   7,   7,   7,   7,   7,   6,   6,   5,   6,   6,
         6,   7,   6,   7,   6,   5,   6,   7,   7,   7,   7,   7,   6,
         5,   6,   6,   6,   8,   9,   9,   9,  11,  11,  11,  11,  11,
        12,  12,  15,  15,  15,  15,  17,  18,  17,  18,  18,  17,  17,
        17,  17,  17,  17,  17,  17,  16,  18,  18,  16,  15,  15,  15,
        13,  13,  13,  14,  14,  14,  14,  12,  11,  11,  12,  10,   9,
        10,  10,  13,  14,  13,  13,  15,  17,  18,  23,  28,  32,  35,
        39,  44,  53,  56,  62,  74,  76,  79,  83,  87,  92, 101, 105,
       117, 125, 133, 138, 145, 155, 162, 162, 165, 174, 182, 188, 198,
       204, 207, 212, 215, 218, 216, 218, 217, 220, 220, 217, 219, 222,
       229, 231, 232, 228, 226, 217, 217, 210, 216, 212, 203, 196, 198,
       198, 195, 191, 185, 183, 179, 177, 174, 173, 169, 173, 169, 169,
       166, 163, 156, 156, 155, 148, 142, 139, 138, 138, 139, 135, 134,
       124, 126, 128, 132, 128, 126, 120, 120, 121, 113, 114, 111, 106,
       102,  99,  94,  94,  88,  85,  82,  82,  78,  74,  71,  72,  69,
        66,  64,  62,  58,  57,  56,  52,  49,  46,  45,  43,  44,  41,
        39,  37,  35,  32,  31,  29,  31,  30,  27,  25,  25,  25,  23,
        23,  22,  20,  19,  19,  18,  17,  15,  15,  15,  14,  13,  12,
        10,  10,  10,   9,   8,   7,   7,   5,   5,   4,   4,   1,   1,
         1,   1,   1,   1,   1,   3,   3,   3,   3,   2,   2,   2,   2,
         2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,
         2,   2,   2,   2,   2,   2,   2,   2,   2,   2,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  42,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  41,
        41,  41,  41,  41,  41,  41,  41,  41,  41,  41,  42,  42,  42,
        42,  42,  42,  42,  42,  42,  42, 682, 682, 682, 682, 682, 682,
       682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, 682,
       682, 682, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
       318, 318, 318, 318, 318, 318, 318, 318, 318, 318], dtype=uint32)

Experiment 1: temporal_memory.py

In [10]:
class ColumnStatesPatcher(object):
    def __init__(self):
        self.output = BytesIO()

    def patchTM(self, tm):
        csvOutput = csv.writer(self.output)

        headerRow = [
            'n-unpredicted-active-columns',
            'n-predicted-inactive-columns',
            'n-predicted-active-columns',
        ]
        csvOutput.writerow(headerRow)

        computeMethod = tm.compute
        def myCompute(activeColumns, **kwargs):
            predictedCells = tm.predictiveCells
            predictedColumns = set([cell / tm.cellsPerColumn for cell in predictedCells])

            computeResult = computeMethod(activeColumns, **kwargs)

            row = (
                len(activeColumns - predictedColumns),
                len(predictedColumns - activeColumns),
                len(activeColumns & predictedColumns),
            )
            csvOutput.writerow(row)

            return computeResult

        tm.compute = myCompute
In [11]:
class SegmentLifetimeChartBuilder(object):
    def __init__(self):
        # (cell, segment) => {}
        self.segments = {}
        # (cell, segment, {}) because a segment might get destroyed multiple times
        self.destroyedSegments = []
        self.timestep = 0
        
    def getOutput(self):
        outputSegments = []
        for cell, segment, data in self.destroyedSegments:
            out = {
                'birthstep': data['birthstep'],
                'deathstep': data['deathstep'],
            }
            
            if len(data['correctMatches']) > 0:
                out['correctMatches'] = data['correctMatches']
                
            if len(data['incorrectMatches']) > 0:
                out['incorrectMatches'] = data['incorrectMatches']
                
            if len(data['correctActivations']) > 0:
                out['correctActivations'] = data['correctActivations']
                
            if len(data['incorrectActivations']) > 0:
                out['incorrectActivations'] = data['incorrectActivations']
                
            outputSegments.append(out)
        for k, data in self.segments.items():
            out = {
                'birthstep': data['birthstep'],
            }
            
            if len(data['correctMatches']) > 0:
                out['correctMatches'] = data['correctMatches']
                
            if len(data['incorrectMatches']) > 0:
                out['incorrectMatches'] = data['incorrectMatches']
                
            if len(data['correctActivations']) > 0:
                out['correctActivations'] = data['correctActivations']
                
            if len(data['incorrectActivations']) > 0:
                out['incorrectActivations'] = data['incorrectActivations']
                
            outputSegments.append(out)
        outputSegments = sorted(outputSegments, key = lambda x : x['birthstep'])
        output = {
            'nTimesteps': self.timestep,
            'segments': outputSegments
        }
        return json.dumps(output)
    
    def patchTM(self, tm):
        # patch connections createSegment and destroySegment
        
        createSegment = tm.connections.createSegment
        def myCreateSegment(cell):
            segment = createSegment(cell)
            
            k = (cell, segment)
            assert k not in self.segments
            
            self.segments[k] = {
                'birthstep': self.timestep,
                'correctMatches': [],
                'incorrectMatches': [],
                'correctActivations': [],
                'incorrectActivations': []
            }
            
            return segment
        tm.connections.createSegment = myCreateSegment

        destroySegment = tm.connections.destroySegment
        def myDestroySegment(segment):            
            cell = tm.connections.cellForSegment(segment)

            destroySegment(segment)

            k = (cell, segment)            
            data = self.segments[k]
            del self.segments[k]
            
            data['deathstep'] = self.timestep
            v = (cell, segment, data)
            self.destroyedSegments.append(v)
        tm.connections.destroySegment = myDestroySegment            

        compute = tm.compute
        def myCompute(activeColumns, **kwargs):
            self.beforeCompute(tm, activeColumns)
            compute(activeColumns, **kwargs)
            self.afterCompute(tm, activeColumns)
        tm.compute = myCompute

    
    def beforeCompute(self, tm, activeColumns):
        # for every active segment, use its previous timestep.
        # use current timestep info to choose how to classify them.
        self.active = []
        for segment in tm.activeSegments:
            cell = tm.connections.cellForSegment(segment)
            k = (cell, segment)
            self.active.append(k)

        self.matching = []
        for segment in tm.matchingSegments:
            cell = tm.connections.cellForSegment(segment)
            k = (cell, segment)
            self.matching.append(k)
    
    def afterCompute(self, tm, activeColumns):
        for k in self.active:
            cell, segment = k
            segmentData = None
            if k in self.segments:
                segmentData = self.segments[k]
            else:
                for cell2, segment2, data in reversed(self.destroyedSegments):
                    if cell2 == cell and segment2 == segment:
                        segmentData = data
                        break


            if cell in tm.activeCells:
                segmentData['correctActivations'].append(self.timestep)
            else:
                segmentData['incorrectActivations'].append(self.timestep)

        for k in self.matching:
            cell, segment = k
            segmentData = None
            if k in self.segments:
                segmentData = self.segments[k]
            else:
                for cell2, segment2, data in reversed(self.destroyedSegments):
                    if cell2 == cell and segment2 == segment:
                        segmentData = data
                        break


            if cell in tm.activeCells:
                segmentData['correctMatches'].append(self.timestep)
            else:
                segmentData['incorrectMatches'].append(self.timestep)

        self.timestep += 1
In [12]:
experiment1_column_states = ColumnStatesPatcher()
experiment1_segment_lifetimes = SegmentLifetimeChartBuilder()

def experiment1(tm=None):
    if tm is None:
        tm = nupic.research.temporal_memory.TemporalMemory(
                columnDimensions=(1024,),
                cellsPerColumn=4,
                activationThreshold=13,
                initialPermanence=0.21,
                connectedPermanence=0.50,
                minThreshold=10,
                maxNewSynapseCount=20,
                permanenceIncrement=0.10,
                permanenceDecrement=0.10,
                predictedSegmentDecrement=0.07*0.10,
                maxSegmentsPerCell=4,
                maxSynapsesPerSegment=255,
                seed=42)

        experiment1_column_states.patchTM(tm)
        experiment1_segment_lifetimes.patchTM(tm)

    i = 0
    for activeColumns in HOTGYM_INDICES:
        i += 1
        if i % 100 == 0:
            print "timestep %d" % i
        tm.compute(activeColumns)
        
    return tm
In [13]:
e1_tm = experiment1()
timestep 100
timestep 200
timestep 300
timestep 400
timestep 500
timestep 600
timestep 700
timestep 800
timestep 900
timestep 1000
In [14]:
drawEverything(experiment1_column_states, experiment1_segment_lifetimes)
Out[14]:
In [15]:
for i in xrange(1000):
    if i % 100 == 0:
        print "timestep %d" % i

    activeColumns = set(random.sample(xrange(1024), 73))
    e1_tm.compute(activeColumns)
timestep 0
timestep 100
timestep 200
timestep 300
timestep 400
timestep 500
timestep 600
timestep 700
timestep 800
timestep 900
In [16]:
drawEverything(experiment1_column_states, experiment1_segment_lifetimes)
Out[16]:
In [17]:
experiment1(e1_tm)
timestep 100
timestep 200
timestep 300
timestep 400
timestep 500
timestep 600
timestep 700
timestep 800
timestep 900
timestep 1000
Out[17]:
<nupic.research.temporal_memory.TemporalMemory at 0x106eb6050>
In [18]:
drawEverything(experiment1_column_states, experiment1_segment_lifetimes)
Out[18]:

Experiment 2: TemporalMemory.cpp

In [19]:
class ColumnStatesPatcherCpp(object):
    def __init__(self):
        self.output = BytesIO()
        self.csvOutput = csv.writer(self.output)

        headerRow = [
            'n-unpredicted-active-columns',
            'n-predicted-inactive-columns',
            'n-predicted-active-columns',
        ]
        self.csvOutput.writerow(headerRow)
        
    def beforeCompute(self, tm, activeColumns):
        predictedCells = tm.getPredictiveCells()
        predictedColumns = set([cell / tm.getCellsPerColumn()
                                for cell in predictedCells])
        row = (
            len(activeColumns - predictedColumns),
            len(predictedColumns - activeColumns),
            len(activeColumns & predictedColumns),
        )
        self.csvOutput.writerow(row)
    
    def afterCompute(self, tm, activeColumns):
        pass

class SegmentLifetimeChartBuilderCpp(object):
    def __init__(self):
        # (cell, segment) => {}
        self.segments = {}
        # (cell, segment, {}) because a segment might get destroyed multiple times
        self.destroyedSegments = []
        self.timestep = 0
        
    def getOutput(self):
        outputSegments = []
        for cell, segment, data in self.destroyedSegments:
            out = {
                'birthstep': data['birthstep'],
                'deathstep': data['deathstep'],
            }
            
            if len(data['correctMatches']) > 0:
                out['correctMatches'] = data['correctMatches']
                
            if len(data['incorrectMatches']) > 0:
                out['incorrectMatches'] = data['incorrectMatches']
                
            if len(data['correctActivations']) > 0:
                out['correctActivations'] = data['correctActivations']
                
            if len(data['incorrectActivations']) > 0:
                out['incorrectActivations'] = data['incorrectActivations']
                
            outputSegments.append(out)

        for k, data in self.segments.items():
            out = {
                'birthstep': data['birthstep'],
            }
            
            if len(data['correctMatches']) > 0:
                out['correctMatches'] = data['correctMatches']
                
            if len(data['incorrectMatches']) > 0:
                out['incorrectMatches'] = data['incorrectMatches']
                
            if len(data['correctActivations']) > 0:
                out['correctActivations'] = data['correctActivations']
                
            if len(data['incorrectActivations']) > 0:
                out['incorrectActivations'] = data['incorrectActivations']
                
            outputSegments.append(out)
        outputSegments = sorted(outputSegments, key = lambda x : x['birthstep'])
        output = {
            'nTimesteps': self.timestep,
            'segments': outputSegments
        }
        return json.dumps(output)
    
    def subscribe(self, tm):
        class eventHandler(nupic.bindings.algorithms.ConnectionsEventHandler):
            @staticmethod
            def onCreateSegment(segment):
                k = (int(segment.cell.idx), int(segment.idx))
                assert k not in self.segments

                self.segments[k] = {
                    'birthstep': self.timestep,
                    'correctMatches': [],
                    'incorrectMatches': [],
                    'correctActivations': [],
                    'incorrectActivations': []
                }

            @staticmethod
            def onDestroySegment(segment):
                k = (int(segment.cell.idx), int(segment.idx))

                data = self.segments[k]
                del self.segments[k]

                data['deathstep'] = self.timestep

                v = (k[0], k[1], data)
                self.destroyedSegments.append(v)
            
        tm.connections.subscribe(eventHandler().__disown__())
    
    def beforeCompute(self, tm, activeColumns):
        # for every active segment, use its previous timestep.
        # use current timestep info to choose how to classify them.
        self.active = []
        for segment in tm.getActiveSegments():
            k = (int(segment.cell.idx), int(segment.idx))
            self.active.append(k)

        self.matching = []
        for segment in tm.getMatchingSegments():
            k = (int(segment.cell.idx), int(segment.idx))
            self.matching.append(k)
    
    def afterCompute(self, tm, activeColumns):
        activeCells = set([int(cell.idx) for cell in tm.activeCells])
        for k in self.active:
            cell, segment = k
            segmentData = None
            if k in self.segments:
                segmentData = self.segments[k]
            else:
                for cell2, segment2, data in reversed(self.destroyedSegments):
                    if cell2 == cell and segment2 == segment:
                        segmentData = data
                        break


            if cell in activeCells:
                segmentData['correctActivations'].append(self.timestep)
            else:
                segmentData['incorrectActivations'].append(self.timestep)

        for k in self.matching:
            cell, segment = k
            segmentData = None
            if k in self.segments:
                segmentData = self.segments[k]
            else:
                for cell2, segment2, data in reversed(self.destroyedSegments):
                    if cell2 == cell and segment2 == segment:
                        segmentData = data
                        break


            if cell in activeCells:
                segmentData['correctMatches'].append(self.timestep)
            else:
                segmentData['incorrectMatches'].append(self.timestep)

        self.timestep += 1
In [20]:
experiment2_column_states = ColumnStatesPatcherCpp()
experiment2_segment_lifetimes = SegmentLifetimeChartBuilderCpp()

def experiment2(tm=None):
    if tm is None:
        tm = nupic.bindings.algorithms.TemporalMemory(
            columnDimensions=(1024,),
            cellsPerColumn=4,
            activationThreshold=13,
            initialPermanence=0.21,
            connectedPermanence=0.50,
            minThreshold=10,
            maxNewSynapseCount=20,
            permanenceIncrement=0.10,
            permanenceDecrement=0.10,
            predictedSegmentDecrement=0.07*0.10,
            maxSegmentsPerCell=4,
            maxSynapsesPerSegment=255,
            seed=42)
        
        experiment2_segment_lifetimes.subscribe(tm)    

    i = 0
    for activeColumns in HOTGYM_INDICES:
        i += 1
        if i % 100 == 0:
            print "timestep %d" % i
        experiment2_column_states.beforeCompute(tm, activeColumns)
        experiment2_segment_lifetimes.beforeCompute(tm, activeColumns)
        tm.compute(activeColumns)
        experiment2_column_states.afterCompute(tm, activeColumns)
        experiment2_segment_lifetimes.afterCompute(tm, activeColumns)
        
    return tm
In [21]:
e2_tm = experiment2()
timestep 100
timestep 200
timestep 300
timestep 400
timestep 500
timestep 600
timestep 700
timestep 800
timestep 900
timestep 1000
In [22]:
drawEverything(experiment2_column_states, experiment2_segment_lifetimes)
Out[22]:
In [23]:
for i in xrange(1000):
    if i % 100 == 0:
        print "timestep %d" % i
        
    activeColumns = set(random.sample(xrange(1024), 73))
    experiment2_column_states.beforeCompute(e2_tm, activeColumns)
    experiment2_segment_lifetimes.beforeCompute(e2_tm, activeColumns)
    e2_tm.compute(activeColumns)
    experiment2_column_states.afterCompute(e2_tm, activeColumns)
    experiment2_segment_lifetimes.afterCompute(e2_tm, activeColumns)
timestep 0
timestep 100
timestep 200
timestep 300
timestep 400
timestep 500
timestep 600
timestep 700
timestep 800
timestep 900
In [24]:
drawEverything(experiment2_column_states, experiment2_segment_lifetimes)
Out[24]:
In [25]:
experiment2(e2_tm)
timestep 100
timestep 200
timestep 300
timestep 400
timestep 500
timestep 600
timestep 700
timestep 800
timestep 900
timestep 1000
Out[25]:
<nupic.bindings.algorithms.TemporalMemory; proxy of <Swig Object of type 'nupic::algorithms::temporal_memory::TemporalMemory *' at 0x120c5ba20> >
In [26]:
drawEverything(experiment2_column_states, experiment2_segment_lifetimes)
Out[26]:
In [27]:
with open('2016.04.28.experiment1_column_states.csv', 'w') as f:
    f.write(experiment1_column_states.output.getvalue())
In [28]:
with open('2016.04.28.experiment1_segment_lifetimes.json', 'w') as f:
    f.write(experiment1_segment_lifetimes.getOutput())
In [29]:
with open('2016.04.28.experiment2_column_states.csv', 'w') as f:
    f.write(experiment2_column_states.output.getvalue())
In [30]:
with open('2016.04.28.experiment2_segment_lifetimes.json', 'w') as f:
    f.write(experiment2_segment_lifetimes.getOutput())

Another demo

In [41]:
experiment3_column_states = ColumnStatesPatcherCpp()
experiment3_segment_lifetimes = SegmentLifetimeChartBuilderCpp()

def experiment3(tm=None):
    if tm is None:
        tm = nupic.bindings.algorithms.TemporalMemory(
            columnDimensions=(1024,),
            cellsPerColumn=4,
            activationThreshold=13,
            initialPermanence=0.21,
            connectedPermanence=0.50,
            minThreshold=10,
            maxNewSynapseCount=20,
            permanenceIncrement=0.10,
            permanenceDecrement=0.10,
            predictedSegmentDecrement=0.07*0.10,
            maxSegmentsPerCell=4,
            maxSynapsesPerSegment=255,
            seed=42)
        
        experiment3_segment_lifetimes.subscribe(tm)    

    i = 0
    for activeColumns in HOTGYM_INDICES_ALL[:2800]:
        i += 1
        if i % 100 == 0:
            print "timestep %d" % i
        experiment3_column_states.beforeCompute(tm, activeColumns)
        experiment3_segment_lifetimes.beforeCompute(tm, activeColumns)
        tm.compute(activeColumns)
        experiment3_column_states.afterCompute(tm, activeColumns)
        experiment3_segment_lifetimes.afterCompute(tm, activeColumns)
        
    return tm
In [42]:
e3_tm = experiment3()
timestep 100
timestep 200
timestep 300
timestep 400
timestep 500
timestep 600
timestep 700
timestep 800
timestep 900
timestep 1000
timestep 1100
timestep 1200
timestep 1300
timestep 1400
timestep 1500
timestep 1600
timestep 1700
timestep 1800
timestep 1900
timestep 2000
timestep 2100
timestep 2200
timestep 2300
timestep 2400
timestep 2500
timestep 2600
timestep 2700
timestep 2800
In [43]:
drawEverything(experiment3_column_states, experiment3_segment_lifetimes)
Out[43]:
In [44]:
with open('2016.04.28.experiment3_column_states.csv', 'w') as f:
    f.write(experiment3_column_states.output.getvalue())
In [45]:
with open('2016.04.28.experiment3_segment_lifetimes.json', 'w') as f:
    f.write(experiment3_segment_lifetimes.getOutput())
In [ ]: