Skip to content

Instantly share code, notes, and snippets.

@iandanforth
Last active December 16, 2015 20:29
Show Gist options
  • Save iandanforth/5493031 to your computer and use it in GitHub Desktop.
Save iandanforth/5493031 to your computer and use it in GitHub Desktop.
Learning Loop - A simple bit of python code that illustrates biological style learning.
#!/usr/bin/python
import time
from random import randint
"""
#############################
Learning Loop
Our scenario is that of a simple creature in a very simple world.
The creature can look left, or it can look right. That's all it can do.
When it looks left, it sees blackness. When it looks right, it sees light.
Our creature likes light.
It learns, quite quickly, that looking right is better than looking left. Soon
it will look right all the time.
This script illustrates some of the basic components that go into biological
learning. In one configuration or another, all animal learning takes place
between *at least* this set of components. Even creatures that don't have brains
use neurons with specific rolls to fulfil these functions.
##############################
Important Concepts to Consider
What controls how quickly the creature learns?
What controls what the creature prefers? Do you think this is realistic?
What would happen if the judgement of internal and external state were at odds?
For example, if it hurt to turn your head right, but you really wanted to
see what was in that direction?
Does the program always take the same number of loops to eliminate one of the
behaviors? Do you think this is realistic?
##############################
Code Caveats
Biology is intrinsicly parallel and event driven. This code is written in an
imperative style to be easy to follow and introspect.
The 'bias' would be better implemented as a skew on a normal distribution.
"""
def main():
# Create the world
world = World()
# Build up a body
senses = Senses()
senseCenter = SenseCenter()
motorCenter = MotorCenter()
critic = Critic()
brain = Brain(motorCenter, senseCenter, critic)
body = Body(senses, brain)
# Start time
counter = 0
while True:
# The body changes based on a command from the motor center
body.setState(motorCenter.getAction())
print "Action: ", motorCenter.action
# The senses register this change in internal state
senses.setInternalState(body.getState())
# The world (from the body's perspective) is also changed
world.setState(body.getState())
# The senses register this change in external state
senses.setExternalState(world.getState())
print "Perception: ", world.state
# The brain perceives the senses
senseCenter.setStates(*senses.getStates())
# The critic (judgement center) perceives the sense representation
critic.setJudgement(*senseCenter.getStates())
print "Judgement: ", critic.judgement
# The motor center learns if what it did was good or bad
motorCenter.setBias(critic.getJudgement())
######################################################################
# This simulation runs quickly to completion.
time.sleep(.01)
counter += 1
if counter >= 100:
print "Done"
quit()
class World(object):
'''
The whole world
'''
def __init__(self):
self.state = "White"
def setState(self, bodyState):
if bodyState == "Left":
self.state = "Black"
elif bodyState == "Right":
self.state = "White"
else:
raise Exception("Invalid body state")
def getState(self):
return self.state
class Body(object):
'''
A very simple creatures body. It can look left, and look right.
'''
def __init__(self, senses, brain):
self.senses = senses
self.brain = brain
self.state = None
def setState(self, action):
if action == "LookLeft":
self.state = "Left"
elif action == "LookRight":
self.state = "Right"
else:
raise Exception("Invalid action %s" % action)
def getState(self):
return self.state
class Senses(object):
'''
The internal and external senses of a body
'''
def __init__(self):
self.internalState = None
self.externalState = None
def setInternalState(self, bodyState):
self.internalState = bodyState
def setExternalState(self, worldState):
self.externalState = worldState
def getStates(self):
return self.internalState, self.externalState
class Brain(object):
'''
A very simple brain made up of three centers
'''
def __init__(self, motorCenter, senseCenter, critic):
self.motorCenter = motorCenter
self.senseCenter = senseCenter
self.critic = critic
class BrainCenter(object):
'''
The parent class for all our brain centers. Exists only to illustrate the
connection between classes.
'''
def __init__(self):
pass
class SenseCenter(BrainCenter):
'''
The brain center that percieves the output of the body's senses
'''
def __init__(self):
self.internalState = None
self.externalState = None
def setStates(self, internalState, externalState):
self.internalState = internalState
self.externalState = externalState
def getStates(self):
return self.internalState, self.externalState
class MotorCenter(BrainCenter):
'''
The brain center that generates actions and learns
'''
def __init__(self):
self.bias = 0
self.min = 0
self.max = 100
self.action = None
def getAction(self):
rangeMin = self.min
rangeMax = self.max + self.bias
try:
choice = randint(rangeMin, rangeMax)
except ValueError:
print "Foo"
choice = 0
if choice >= 50:
self.action = "LookLeft"
else:
self.action = "LookRight"
return self.action
def setBias(self, judgement):
if self.action == "LookLeft":
# More likely to go left
if judgement == "Good":
self.bias += 1
# Less likely to go left
elif judgement == "Bad":
self.bias -= 1
elif self.action == "LookRight":
# More likely to go right
if judgement == "Good":
self.bias -= 1 # Note the swapped sign here.
# Less likely to go right
elif judgement == "Bad":
self.bias += 1
class Critic(BrainCenter):
'''
The innate judgement of good and bad.
'''
def __init__(self):
self.judgement = "Good"
def setJudgement(self, internalState, externalState):
if externalState == "Black":
self.judgement = "Bad"
elif externalState == "White":
self.judgement = "Good"
else:
raise Exception("Invalid external state: %s" % externalState)
def getJudgement(self):
return self.judgement
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment