Skip to content

Instantly share code, notes, and snippets.

@lesguillemets
Created September 30, 2013 17:03
Show Gist options
  • Save lesguillemets/6766833 to your computer and use it in GitHub Desktop.
Save lesguillemets/6766833 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
# encoding:utf-8
import random
class Neuron(object):
# 神経細胞体 class.
# i) synapse からの入力を受けることができ,
# ii) ある間にうけた入力の総和が threshold を超えれば
# iii) 発火し,本人から出ていく synapse に伝達される.
# Neuron 同士の結合情報は Synapse class, NSystem class に任せ,
# Neuron class から能動的に特定のシナプスに情報を与えることはない.
# ... はずだったが,
# postsnapses に PostNeuron を '持つ' ことに.
def __init__(self, threshold = 1):
self.threshold = threshold
self.inputstack = 0
self.isfiring = False
self.wasfiring = False
self.isalive = True
self.postsynapses = []
def getinput(self, x):
# 大きさ x の入力を受ける.
# 入力は self.inputstack に蓄えられ,'1 世代' の入力となる
self.inputstack += x
def update(self):
self.wasfiring = self.isfiring
self.isfiring = self.doesfire()
self.clear()
def add_synapse(postneuron, x):
self.postsnapses.append(Synapse(postneuron, x))
def clear(self):
# inputstack を空に.次の'世代'の入力を受けられる
self.inputstack = 0
def doesfire(self):
# 発火するか
return self.inputstack >= self.threshold
def __repr__(self):
return int(self.isfiring)
def __str__(self):
return str(int(self.isfiring))
class Synapse(object):
# シナプス class.
# 結合元 neuron に保持され, 結合先 neuron を保持する.
# pre-synaptic cell の fire に対し,
# {x <- R | -limit <= x <= limit } を満たす出力を
# post-synaptic cell に与える.
# 両端が active になるとき LTPratio を x に乗じる形での学習を行う.
# active な入力を受けても出力先が active にならなかった場合は逆を行う.
def __init__(self, postn, x,
limit = 2, LTPratio = 1.1, forgetratio = 0.95, isactive = True):
self.postn = postn
self.x = x
self.limit = 2
self.isactive = True
self.LTPratio = LTPratio
self.forgetratio = forgetratio
def givefire(self):
if self.isactive:
self.postn.getinput(self.x)
def LTP(self):
# this function doesn't check if LTP can occur or not.
# because Synapse class doesn't know whether
# its postneuron fires or not.
self.x *= self.LTPratio
if not -self.limit > self.x:
self.x = -self.limit
elif self.x < self.limit:
self.x = self.limit
def reverseLTP(self):
self.x /= self.LTPratio
def forgetalittle(self):
self.x *= self.forgetratio
class NSystem(object):
def __init__(self, number_of_neurons, inneurons, outneurons):
# number_of_neurons :: Int, inneurons :: [Int], outneurons :: [Int]
self.neurons = [] # neurons in the system
self.inneurons = [] # neurons to (conveniently) receive input from us.
self.outneurons = [] # neurons from which we get output.
self.n_of_neurons = number_of_neurons
for i in xrange(number_of_neurons):
self.neurons.append(Neuron())
for n in inneurons:
self.inneurons.append( self.neurons[n] )
for n in outneurons:
self.outneurons.append( self.neurons[n] )
def init_perfect(self):
# good luck memory
self.synapses = []
for (i, preneuron) in enumerate(self.neurons):
self.synapses.append([])
for (j, postneuron) in enumerate(self.neurons):
self.synapses[i].append(
Synapse(preneuron, postneuron, random.random()))
for i in xrange(self.n_of_neurons):
self.synapses[i][i].isactive = False
def step(self):
# if a neuron is firing, its postsynapses gives fire.
for neuron in self.neurons:
if neuron.isfiring:
for synapse in neuron.postsynapses:
synapse.givefire()
# updates the states of the neurons.
for neuron in self.neurons:
neuron.update()
# LTP: for each synapse,
# if the two neurons at its ends is/was firing,
# let its LTP occur.
# preneuron.wasfiring and not postneuron.isfiring
# -> reversed LTP (LTD).
for neuron in self.neurons:
if neuron.wasfiring:
for synapse in neuron.postsynapses:
if synapse.postn.isfiring:
synapse.LTP()
else:
synapse.reverseLTP()
def give_stimulus(self, xs):
for (x,n) in zip(xs, self.inneurons):
n.getinput(x)
def get_output(self):
output = []
for (i,n) in enumerate(self.outneurons):
output.append((i, str(n)))
return output
def example1():
"""
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment