Example #1
0
def testCount():
	rows = 5
	cols = 5
	coverage = 20
	numbits = 10
	numRounds = 500
	trainingRounds = numRounds/4
	originalInputVector = InputVector(numbits)
	inputVector = InputVector(0)

	predictions = dict()
	#repeat several times to increase activity:
	for i in range(3):
		inputVector.extendVector(originalInputVector)

	desiredLocalActivity = DESIRED_LOCAL_ACTIVITY

	newRegion = Region(rows,cols,inputVector,coverage,desiredLocalActivity)
	outputVector = newRegion.getOutputVector()
	correctBitPredictions = 0
 
	for round in range(numRounds): # This test executes the CLA for a set number of rounds. 
     
		#print("Round: " + str(round))
		# if (round % 2 == 0):
		# 	val = 682
		# else:
		# 	val = 341
		val = Ultrasonic(brick, PORT_1).get_sample()
		setInput(originalInputVector,val)
		inputString = inputVector.toString()
		outputString = outputVector.toString()
		#print(originalInputVector.toString())
           
		#for bit in originalInputVector.getVector():
		# 	print(bit.bit)
		# print('')
		# print(inputString)


		if outputString in predictions:
			currentPredictionString = predictions[outputString]
		else:
			currentPredictionString = "[New input]"
		pred[outputString] = inputString
		print("Round: %d" % round) # Prints the number of the round
		printStats(inputString, currentPredictionString)
		if (round > trainingRounds):
			correctBitPredictions += stringOverlap(currentPredictionString, predictions[outputString])
				 

		newRegion.doRound()
		printColumnStats(newRegion)
	for key in predictions:
		print("key: " + key + " predictions: " + predictions[key])

	print("Accuracy: " + str(float(correctBitPredictions)/float((30*(numRounds-trainingRounds)))))
Example #2
0
def testCount():
    rows = 5
    cols = 5
    coverage = 20
    numbits = 10
    numRounds = 500
    trainingRounds = numRounds / 4
    originalInputVector = InputVector(numbits)
    inputVector = InputVector(0)

    pred = dict()
    #repeat several times to increase activity:
    for i in range(3):
        inputVector.extendVector(originalInputVector)

    desiredLocalActivity = DESIRED_LOCAL_ACTIVITY

    r = Region(rows, cols, inputVector, coverage, desiredLocalActivity)
    outputVector = r.getOutputVector()
    correctBitPredctions = 0
    for round in range(numRounds):
        #print("Round: " + str(round))
        # if (round % 2 == 0):
        # 	val = 682
        # else:
        # 	val = 341
        val = round % 30
        setInput(originalInputVector, val)
        inputString = inputVector.toString()
        outputString = outputVector.toString()
        # for bit in inputVector.getVector():
        # 	printBit(bit)
        # print('')
        # print(inputString)

        if outputString in pred:
            curPredString = pred[outputString]
        else:
            curPredString = "[New input]"
        pred[outputString] = inputString

        printStats(inputString, curPredString)
        if (round > trainingRounds):
            correctBitPredctions += stringOverlap(curPredString,
                                                  pred[outputString])

        r.doRound()
        printColumnStats(r)
    for key in pred:
        print("key: " + key + " pred: " + pred[key])

    print("Accuracy: " + str(
        float(correctBitPredctions) / float((30 *
                                             (numRounds - trainingRounds)))))
Example #3
0
class Region:
	"""An HTM cortical region"""
	# Array of columns in 2D for inhibition. Not my prefered geomertry, 
        # but I'm working from a fork. I may make it a 1D geometry at some point.
	def __init__(self,rows,cols,inputVector,coverage,desiredLocalActivity):
			self.rows = rows
			self.cols = cols
			self.desiredLocalActivity=desiredLocalActivity
			self.columns = [Column() for i in range(self.rows*self.cols)]	
			self.mapRegionToInputVector(inputVector,coverage)
			self.mapRegionToOutputVector()
			self.inhibitionRadius = min(INITIAL_INHIBITION_RADIUS,self.rows,self.cols)
			self.updateColumnNeighbors()

	def mapRegionToOutputVector(self):
		self.outputVector = InputVector(0)
		for c in self.columns:
			self.outputVector.extendVector(c.getOutputBits())


	def mapRegionToInputVector(self,inputVector,coverage):
		# get the length of the input, and for each input bit assign
		# it to X columns randomly	
		self.inputVector = inputVector
		for bitIndex in range(self.inputVector.getLength()):
				columnIndices = random.sample(range(len(self.columns)),coverage)
				for ci in columnIndices:
					self.columns[ci].mapColumnToInput(inputVector.getBit(bitIndex))

	def getOutputVector(self):
		return self.outputVector


	def convert2Dindex(self,row,col,numCols):
		return row*(numCols) + col

	def computeNeighbors(self,cx,cy,radius):
		neighbors = []
		for dy in range(-radius,radius+1):
			for dx in range(-radius,radius+1):
				# enforce circular shape. optional
				if (dy*dy+dx*dx > radius*radius):
					continue 
				x = cx + dx
				y = cy + dy
				#wrap around: upper boundary check
				x = self.rows + x if (x < 0) else x
				y = self.cols + y if (y < 0) else y
				#wrap around: lower boundary check
				x = x - self.rows if (x >= self.rows) else x
				y = y - self.cols if (y >= self.cols) else y
				index = self.convert2Dindex(x,y,self.cols)
				#if (index < 0 or index >= len(self.columns)):
					#print('radius is' + str(radius))
					#print("bad: " + str(cx) + ", " + str(cy) + ", " + str(x) + ", " + str(y) + ", " + str(dx) + ", " + str(dy))
				n = self.columns[index]
				if (neighbors.count(n) == 0):
					neighbors.append(n)
		return neighbors

	def updateColumnNeighbors(self):
		for i in range(self.rows):
			for j in range(self.cols):
				index = self.convert2Dindex(i,j,self.cols)
				c = self.columns[index]
				c.setNeighbors(self.computeNeighbors(i,j,self.inhibitionRadius))

	def updateInhibitionRadius(self):
		r = 0.0
		for c in self.columns:
			r += c.getNumConnectedProximalSynapses()
		r /= len(self.columns)

		maxRadius = min(self.cols,self.rows)
		r = min(r,maxRadius)
		self.inhibitionRadius = int(r)
		self.updateColumnNeighbors()

	def getAllLearningCells(self,step):
		learningCellList = []
		for c in self.columns:
			learningCells = c.getLearningCells(step)
			learningCellList.extend(learningCells)
		return learningCellList


	def spatialPoolerRun(self):
		[c.updateOverlap() for c in self.columns]
		[c.updateActiveState(self.desiredLocalActivity) for c in self.columns]
		[c.updateBoost() for c in self.columns]
		[c.updateActiveDutyCycle() for c in self.columns]
		self.updateInhibitionRadius()

		#DEBUG THIS
		count = 0
		for c in self.columns:
			if c.active:
				count += 1
		count = 0
		for c in self.columns:
			for cell in c.cells:
				if cell.isActive(CURRENT_TIME_STEP):
					count += 1
		
	def temporalPoolerRun(self):
		[c.advanceTimeStep() for c in self.columns]
		allLearningCells = self.getAllLearningCells(PREVIOUS_TIME_STEP)
		[c.updateCellActivity(allLearningCells) for c in self.columns]
		[c.updateCellPrediction(allLearningCells) for c in self.columns]
		[c.updateCellLearning() for c in self.columns]

	def doRound(self):
		self.spatialPoolerRun()
		self.temporalPoolerRun()
Example #4
0
	def mapRegionToOutputVector(self):
		self.outputVector = InputVector(0)
		for c in self.columns:
			self.outputVector.extendVector(c.getOutputBits())
Example #5
0
class Region:
    """An HTM cortical region"""

    #array of columns or 2D for inhibition
    def __init__(self, rows, cols, inputVector, coverage,
                 desiredLocalActivity):
        self.rows = rows
        self.cols = cols
        self.desiredLocalActivity = desiredLocalActivity
        self.columns = [Column() for i in range(self.rows * self.cols)]
        self.mapRegionToInputVector(inputVector, coverage)
        self.mapRegionToOutputVector()
        self.inhibitionRadius = min(INITIAL_INHIBITION_RADIUS, self.rows,
                                    self.cols)
        self.updateColumnNeighbors()

    def mapRegionToOutputVector(self):
        self.outputVector = InputVector(0)
        for c in self.columns:
            self.outputVector.extendVector(c.getOutputBits())

    def mapRegionToInputVector(self, inputVector, coverage):
        # get the length of the input, and for each input bit assign
        # it to X columns randomly
        self.inputVector = inputVector
        for bitIndex in range(self.inputVector.getLength()):
            columnIndices = random.sample(range(len(self.columns)), coverage)
            for ci in columnIndices:
                self.columns[ci].mapColumnToInput(inputVector.getBit(bitIndex))

    def getOutputVector(self):
        return self.outputVector

    def convert2Dindex(self, row, col, numCols):
        return row * (numCols) + col

    def computeNeighbors(self, cx, cy, radius):
        neighbors = []
        for dy in range(-radius, radius + 1):
            for dx in range(-radius, radius + 1):
                # enforce circular shape. optional
                if (dy * dy + dx * dx > radius * radius):
                    continue
                x = cx + dx
                y = cy + dy
                #wrap around: upper boundary check
                x = self.rows + x if (x < 0) else x
                y = self.cols + y if (y < 0) else y
                #wrap around: lower boundary check
                x = x - self.rows if (x >= self.rows) else x
                y = y - self.cols if (y >= self.cols) else y
                index = self.convert2Dindex(x, y, self.cols)
                #if (index < 0 or index >= len(self.columns)):
                #print('radius is' + str(radius))
                #print("bad: " + str(cx) + ", " + str(cy) + ", " + str(x) + ", " + str(y) + ", " + str(dx) + ", " + str(dy))
                n = self.columns[index]
                if (neighbors.count(n) == 0):
                    neighbors.append(n)
        return neighbors

    def updateColumnNeighbors(self):
        for i in range(self.rows):
            for j in range(self.cols):
                index = self.convert2Dindex(i, j, self.cols)
                c = self.columns[index]
                c.setNeighbors(
                    self.computeNeighbors(i, j, self.inhibitionRadius))

    def updateInhibitionRadius(self):
        r = 0.0
        for c in self.columns:
            r += c.getNumConnectedProximalSynapses()
        r /= len(self.columns)

        maxRadius = min(self.cols, self.rows)
        r = min(r, maxRadius)
        self.inhibitionRadius = int(r)
        self.updateColumnNeighbors()

    def getAllLearningCells(self, step):
        learningCellList = []
        for c in self.columns:
            learningCells = c.getLearningCells(step)
            learningCellList.extend(learningCells)
        return learningCellList

    def spatialPoolerRun(self):
        [c.updateOverlap() for c in self.columns]
        [c.updateActiveState(self.desiredLocalActivity) for c in self.columns]
        [c.updateBoost() for c in self.columns]
        [c.updateActiveDutyCycle() for c in self.columns]
        self.updateInhibitionRadius()

        #DEBUG THIS
        count = 0
        for c in self.columns:
            if c.active:
                count += 1
        count = 0
        for c in self.columns:
            for cell in c.cells:
                if cell.isActive(CURRENT_TIME_STEP):
                    count += 1

    def temporalPoolerRun(self):
        [c.advanceTimeStep() for c in self.columns]
        allLearningCells = self.getAllLearningCells(PREVIOUS_TIME_STEP)
        [c.updateCellActivity(allLearningCells) for c in self.columns]
        [c.updateCellPrediction(allLearningCells) for c in self.columns]
        [c.updateCellLearning() for c in self.columns]

    def doRound(self):
        self.spatialPoolerRun()
        self.temporalPoolerRun()
Example #6
0
 def mapRegionToOutputVector(self):
     self.outputVector = InputVector(0)
     for c in self.columns:
         self.outputVector.extendVector(c.getOutputBits())
Example #7
0
 def getOutputBits(self):
     outputBits = InputVector(0)
     for cell in self.cells:
         outputBits.appendBit(cell.getOutputBit())
     return outputBits
Example #8
0
def testCount():
  rows = 5
	cols = 5
	coverage = 20
	numbits = 10 # I may need more bits for my readngs.
	numRounds = 500
	trainingRounds = numRounds/4
	originalInputVector = InputVector(numbits)
	inputVector = InputVector(0)
	predictions = dict()
 
     # Repeat several times to increase activity:
     # Seems to just extend the number of elements in inputVector by numbits (10) 3 times. 
     # Why not extend it by 3*numbits?
     # I think becuase rather than make it 3 times as long, it actually repeats the vector three times,
     # probably so as to, as said above, increase activity in those cells and aid learning. 
     # Good old repartition. In which case, I'm not sure I want to use this in my tests...
	for i in range(3): 
		inputVector.extendVector(originalInputVector)
     
     # Get a non-local variable and feed it to a local one for local manipulation.
	desiredLocalActivity = DESIRED_LOCAL_ACTIVITY
     
     # This sets up a new region, called newRegion,
     # a variable called ouputVector, which calls a method to find just that,
     # and a variable for the number of correct prodicitons, initialised as 0. 
	newRegion = Region(rows,cols,inputVector,coverage,desiredLocalActivity)
	outputVector = newRegion.getOutputVector()
	correctBitPredictions = 0
 
 
      # This is where the action starts. This loop forms the main body of the test.
      # For every time round, an input is given, the CLA updates spacial and temporal 
      # poolers with this new input and an output is found. 
	for round in range(numRounds): 
           # The old version gave two inputs alternatly. The aim was to get the CLA to 
           # predict one of two numbers. 
		#print("Round: " + str(round))
		# if (round % 2 == 0):
		# 	val = 682
		# else:
		# 	val = 341
		val = Ultrasonic(brick, PORT_1).get_sample() # Instead I'm now feeding in readings from the sonar. 
		setInput(originalInputVector,val) # These next few lines convert the inputs and outputs from integers to bitstrings,
		inputString = inputVector.toString() # so that the CLA can handle them. 
		outputString = outputVector.toString()
		#print(originalInputVector.toString())
           
		#for bit in originalInputVector.getVector():
		# 	print(bit.bit)
		# print('')
		# print(inputString)


		if outputString in predictions: # predictions was set up at the start, you might have missed it. 
			currentPredictionString = predictions[outputString]
		else:
			currentPredictionString = "[New input]"
			predictions[outputString] = inputString # I'm sure this line should be here. It's not indented in the origonal. 
   
		print("Round: %d" % round) # Prints the number of the round
		printStats(inputString, currentPredictionString)
  
		if (round > trainingRounds): 
			correctBitPredictions += stringOverlap(currentPredictionString, predictions[outputString])
				 

		newRegion.doRound() # The CLA bit!
		printColumnStats(newRegion) 
  
      
      # With the experiment now over, stat summaries are now printed. 
	for key in predictions:
		print("key: " + key + " predictions: " + predictions[key])
	print("Accuracy: " + str(float(correctBitPredictions)/float(30*(numRounds-trainingRounds))))
Example #9
0
def experiment():
    rows = 5
    cols = 5
    coverage = 20
    numbits = 10 # I may need more bits for my readngs.
    numRounds = 10
    numRuns = 1
    minimum_distance = 7
    #trainingRounds = numRounds/4
    accuracies = []
    sonarPositionResults = []
    originalInputVector = InputVector(numbits)
    inputVector = InputVector(0)
    predictions = dict()
    state = "Going Forwards"

 
    # Repeat several times to increase activity:
    # Seems to just extend the number of elements in inputVector by numbits (10) 3 times. 
    # Why not extend it by 3*numbits?
    # I think becuase rather than make it 3 times as long, it actually repeats the vector three times,
    # probably so as to, as said above, increase activity in those cells and aid learning. 
    # Good old repartition. In which case, I'm not sure I want to use this in my tests...
    for i in range(3): 
        inputVector.extendVector(originalInputVector)
    
    # Get a non-local variable and feed it to a local one for local manipulation.
    desiredLocalActivity = DESIRED_LOCAL_ACTIVITY
    
    # This sets up a new region, called newRegion,
    # a variable called ouputVector, which calls a method to find just that,
    # and a variable for the number of correct prodicitons, initialised as 0. 
    newRegion = Region(rows,cols,inputVector,coverage,desiredLocalActivity)
    outputVector = newRegion.getOutputVector()
    correctBitPredictions = 0
    
    robot = Robot()
    starting_position = robot.sonarReading()
    robot.move()
 

    # This is where the action starts. This loop forms the main body of the test.
    # For every time round, an input is given, the CLA updates spacial and temporal 
    # poolers with this new input and an output is found.    
    for round in range(numRounds): 
        if state == "Kill Switch: Engage!":
            break
        end_this_round = False
        stuck_counter = 0
        print state
        round_number = round+1
        print ("Round: %d" % round_number) # Prints the number of the round
            #printStats(inputString, currentPredictionString)
        robot.move()
        
        while end_this_round is False:            
            val = robot.sonarReading()
            print ("Sonar: %d cm" % val)
            sonarPositionResults.append(robot.currentSonarReading)
            setInput(originalInputVector,val) # These next few lines convert the inputs and outputs from integers to bitstrings,
            inputString = inputVector.toString() # so that the CLA can handle them.
            outputString = outputVector.toString()
             #print(originalInputVector.toString())
                  
       	  #for bit in originalInputVector.getVector():
       	  #print(bit.bit)
       	  #print('')
       	  #print(inputString)       
       
            if outputString in predictions: # If output string has been seen before, 
                currentPredictionString = predictions[outputString] 
                # summon the last input that caused that prediction and make it the "currentPredictionString"? That's confusing...
            else:
                currentPredictionString = "[New input]" # If not seen before, 
            predictions[outputString] = inputString # Update the i/o record with the new relationship 
                            
            #if (round > trainingRounds): 
            correctBitPredictions += stringOverlap(currentPredictionString, predictions[outputString]) 
            #    without training rounds, stringOverlap will be trying to compare binary stings with the string 'New input'. So correct BitPredictions is going to be 0 for a while,
            #    until inputs start repeating.
                
            newRegion.runCLA() # The CLA bit!
            numRuns += 1
            
            #printColumnStats(newRegion) 
            accuracy = float(correctBitPredictions)/float(30*numRuns) 
            # Times thirty becuase it's measuring the correct prediction of BITS not whole bit-strings, and there are 30 bits per input.
            # This makes sense as bits have semantic meaning where as bit-strings dont!
            accuracies.append(accuracy)
            
            if robot.killSwitch() == True: # This will terminate all loops and move to the end of the program
                end_this_round = True
                state = "Kill Switch: Engage!"
                print state
            if state == "Going Forwards":
                if robot.currentSonarReading <= minimum_distance: 
                    stuck_counter += 1
                if stuck_counter == 2:     # This routine confirms that a wall is hit, then sends the robot back to the start position
                    robot.stop()             
                    print "Stuck Reflex"
                    state = "Reversing"
                    print state
                    stuck_counter = 0
                    robot.move(-75)
            if state == "Reversing":                   
                if (starting_position-3) < robot.currentSonarReading < (starting_position+3): # Clean this up
                    state = "Going Forwards"                    
                    end_this_round = True
                    
                
                
           
 
     
     # With the experiment now over, stat summaries are now printed. 
#    for key in predictions:
#        print("key: " + key + " predictions: " + predictions[key])
    robot.stop()    
    #print("Accuracy: " + str(float(correctBitPredictions)/float(30*(numRounds-trainingRounds))))
    
    #code below prints a graph of runs against accuracies
    runs = np.arange(1, numRuns, 1)
    plt.figure(1)
    plt.subplot(211)
    plt.grid(True)
    plt.plot(runs, accuracies)
    plt.plot(runs, accuracies, 'bo')
    plt.ylabel('Accuracy (correct preditions/predictions)')
    plt.title('Change in CLA accuracy of sonar position prediction')
    plt.subplot(212)
    plt.grid(True)
    plt.plot(runs, sonarPositionResults, 'r-')
    plt.plot(runs, sonarPositionResults, 'ro')
    plt.ylabel('Sonar Readings (cm)')
    plt.xlabel('Number of CLA runs')
    plt.show()
Example #10
0
	def getOutputBits(self):
		outputBits = InputVector(0)
		for cell in self.cells:
			outputBits.appendBit(cell.getOutputBit())
		return outputBits