public
Last active

The idea behind this project is that the functionality of a neuron is really simple (as far as my knowledge goes). There are inputs and an output. If there are enough inputs firing at a time, then the neuron will output 1. Otherwise 0. And also there can be "negative" inputs - inputs which decrement the count when turned on rather than increment it. So something like: if(positive inputs - negative inputs >= threshhold): output 1 else: output 0 The goal is to be able to simulate how a collection of these neurons would react when connected to each other. Specificially, designate "input" and "output" neurons for the system so the 'brain' can be fed input information, perform some computation, then send it to output. The mechanism by which these would be designed is by evolution. evolve.py provides the functions to take a template brain and mutate it by tweaking some of the parameters. evaluate.py then can take those mutated brains together with intended input/output pairs, and score how closely the brain performs what we want it to do. So the thought was that we could make a trivial brain as is made in inEqualsOut.py, then iteratively make batches of mutated brains, pick the best performing one(s), and repeat until desired. neuron,py provides the object code for individual neurons brain.py provides the object code for collections of neurons, with so-called 'input neurons', those which hold the input value, 'output neurons' which are read for output, and 'middle neurons', which are subject to the mutations in evolve.py, and which are responsible for the computation of the brain. inEqualsOut.py constructs and saves the trivial case brain, where input = output. Simply change inString to whichever string, and the brain will output that string. To run, save the python files, and in powershell or whichever, simply enter "python inEqualsOut.py". This will save the trivial brain, then run "python evolve.py". This takes the trivial brain and each time you press enter, the program will do a random amount of mutations, outputing the number of neurons at each mutation, then the resulting output string the brain computed, then finally

  • Download Gist
brain.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
from neuron import *
import sys
 
class Brain:
def __init__(self, ins, middles, outs):
 
input_string = "0" * ins
input_bits = self.get_input(input_string)
#print input_string
 
 
self.input_neurons = []
self.middle_neurons = []
self.output_neurons = []
 
for i in range(0,ins):
dummy = Neuron(not input_bits[i] + 0)
self.input_neurons.append(dummy)
 
for i in range(0, middles):
dummy = Neuron(1)
self.middle_neurons.append(dummy)
 
for i in range(0,outs):
dummy = Neuron(1)
self.output_neurons.append(dummy)
 
def destroy(self):
for neuron in self.input_neurons:
neuron.destroy()
del(neuron)
for neuron in self.middle_neurons:
neuron.destroy()
del(neuron)
for neuron in self.output_neurons:
neuron.destroy()
del(neuron)
 
def add_neuron(self, neuron ):
self.middle_neurons.append(neuron)
 
def cycle(self, num_cycles):
for neuron in self.input_neurons:
neuron.update_count()
neuron.update_signal()
 
for i in range(0, num_cycles):
for neuron in self.middle_neurons:
neuron.update_count()
for neuron in self.middle_neurons:
neuron.update_signal()
 
for neuron in self.output_neurons:
neuron.update_count()
for neuron in self.output_neurons:
neuron.update_signal()
 
def set_input(self, input_string):
length = len(input_string)
maxLen = len(self.input_neurons)
if (length > maxLen):
input_string = input_string[-1 * length:]
while(len(input_string) < maxLen):
input_string = "0" + input_string
 
input_bits = self.get_input(input_string)
 
for i in range(0, maxLen):
self.input_neurons[i].threshhold = (not input_bits[i] + 0)
 
def get_input(self, input_string):
input_bits = []
for i in range(0, len(input_string)):
input_bits.insert(0, ord(input_string[i]) - 48)
 
return input_bits
 
def get_output(self):
string = ''
for i in range(len(self.output_neurons) - 1, -1, -1):
string += chr(48 + self.output_neurons[i].signal)
return string
 
def print_output(self):
for i in range(len(self.output_neurons) - 1, -1, -1):
sys.stdout.write(chr(48 + self.output_neurons[i].signal))
 
print
 
def print_brain(self):
print "Input Neurons:"
i = 0
for neuron in self.input_neurons:
print "\tinput_neurons[%d]\tsignal: %d\tcount%d" % (i, neuron.signal, neuron.count)
i += 1
 
print "Middle Neurons:"
i=0
for neuron in self.middle_neurons:
print "\tmiddle_neurons[%d]\tsignal: %d\tcount%d" % (i, neuron.signal, neuron.count)
i+=1
 
print "Output Neurons:"
i=0
for neuron in self.middle_neurons:
print "\toutput_neurons[%d]\tsignal: %d\tcount%d" % (i, neuron.signal, neuron.count)
i+=1
description.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
The idea behind this project is that the functionality of a neuron is really simple (as far as my knowledge goes). There are inputs and an output. If there are enough inputs firing at a time, then the neuron will output 1. Otherwise 0. And also there can be "negative" inputs - inputs which decrement the count when turned on rather than increment it. So something like:
 
 
if(positive inputs - negative inputs >= threshhold):
output 1
else:
output 0
 
The goal is to be able to simulate how a collection of these neurons would react when connected to each other. Specificially, designate "input" and "output" neurons for the system so the 'brain' can be fed input information, perform some computation, then send it to output.
 
The mechanism by which these would be designed is by evolution. evolve.py provides the functions to take a template brain and mutate it by tweaking some of the parameters. evaluate.py then can take those mutated brains together with intended input/output pairs, and score how closely the brain performs what we want it to do. So the thought was that we could make a trivial brain as is made in inEqualsOut.py, then iteratively make batches of mutated brains, pick the best performing one(s), and repeat until desired.
 
neuron,py provides the object code for individual neurons
brain.py provides the object code for collections of neurons, with so-called 'input neurons', those which hold the input value, 'output neurons' which are read for output, and 'middle neurons', which are subject to the mutations in evolve.py, and which are responsible for the computation of the brain.
 
inEqualsOut.py constructs and saves the trivial case brain, where input = output. Simply change inString to whichever string, and the brain will output that string.
 
To run, save the python files, and in powershell or whichever, simply enter "python inEqualsOut.py". This will save the trivial brain, then run "python evolve.py". This takes the trivial brain and each time you press enter, the program will do a random amount of mutations, outputing the number of neurons at each mutation, then the resulting output string the brain computed, then finally
evaluate.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
from brain import *
from neuron import *
import pickle, copy
 
class test:
class entry:
def __init__ (self, input_str, target):
self.input_str = input_str
self.target = target
self.score = 0.0
self.observed = None
def calc_score(self):
if(self.observed != None):
score = 0.0
inc = 0.5 / len(self.target)
for i in range(0, len(self.target)):
if (self.target[i] == self.observed[i]):
score += inc
 
if (score == 0.5):
score = 1
self.score = score
else:
self.score = 0.0
 
return score
 
def __init__(self):
self.entries = []
self.recent_score = -1.0
 
def calc_score(self):
score = 0.0
for entry in self.entries:
score += entry.calc_score()
 
score = score / len(self.entries)
return score
def perform_test(self, the_brain, cycles):
for entry in self.entries:
new_brain = copy.deepcopy(the_brain)
new_brain.set_input(entry.input_str)
new_brain.cycle(cycles)
entry.observed = new_brain.get_output()
entry.calc_score()
 
 
self.recent_score = self.calc_score()
def add_entry(self, input_str, target):
self.entries.append(self.entry(input_str, target))
evolve.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
from evaluate import *
import random
 
def get_mutants(the_brain, num_brains):
new_brains = []
random.seed(None)
 
for i in range(0,num_brains):
new_brains.append(mutate(the_brain))
return new_brains
 
def mutate(the_brain):
mutations = 1
while(random.randint(0,1)):
mutations += 1
 
new_brain = copy.deepcopy(the_brain)
mute_strats = [duplicate,adjust_threshhold,add_outputs,remove_rand_neuron]
 
for i in range(0,mutations):
randy = random.randint(0,len(mute_strats) - 1)
mute_strats[randy](new_brain)
 
return new_brain
 
def rand_neuron(the_brain):
print len(the_brain.middle_neurons)
randy = random.randint(0, len(the_brain.middle_neurons) - 1)
return the_brain.middle_neurons[randy]
 
def duplicate(the_brain):
the_brain.add_neuron(copy.deepcopy(rand_neuron(the_brain)))
 
def adjust_threshhold(the_brain):
nums = [-1,1]
rand_neuron(the_brain).threshhold += random.randrange(-1,2,2)
 
def add_outputs(the_brain):
rand_neuron(the_brain).add_output(rand_neuron(the_brain), random.randrange(-1,2,2))
 
def remove_rand_neuron(the_brain):
if(len(the_brain.middle_neurons) > 10):
randy = rand_neuron(the_brain)
for neuron in the_brain.middle_neurons:
while(randy in neuron.pos_inputs):
neuron.pos_inputs.remove(randy)
while(randy in neuron.neg_inputs):
neuron.neg_inputs.remove(randy)
while(randy in the_brain.middle_neurons):
the_brain.middle_neurons.remove(randy)
del(randy)
 
old = pickle.load(open("save.p", "rb"))
 
old.set_input("0000000000000011")
new = mutate(old)
 
while(raw_input("") != '0'):
new = mutate(old)
new.cycle(10)
new.print_output()
print len(new.middle_neurons)
old.destroy()
del(old)
old = new
inEqualsOut.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
from brain import *
from evolve import *
import pickle
 
inString = "0000000000000000"
a = Brain(len(inString), len(inString), len(inString))
 
a.set_input(inString)
for i in range(0, len(inString)):
a.input_neurons[i].add_output(a.middle_neurons[i], 1)
a.middle_neurons[i].add_output(a.output_neurons[i], 1)
 
a.cycle(100)
 
a.print_output()
 
pickle.dump(a, open("save.p", "wb"))
neuron.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
class Neuron:
def __init__(self, threshhold):
self.threshhold = threshhold
self.pos_inputs = []
self.neg_inputs = []
self.outputs = []
self.count = 0
self.signal = 0
 
def destroy(self):
del (self.threshhold)
del(self.pos_inputs)
del(self.neg_inputs)
del(self.outputs)
del(self.count)
del(self.signal)
def add_output(self, new_output, sign):
self.outputs.append(new_output)
new_output.add_input(self, sign)
 
def add_input(self, new_input, sign):
if (sign == 1):
self.pos_inputs.append(new_input)
else:
self.neg_inputs.append(new_input)
 
def remove_output(self, rem_out):
if(rem_out in self.outputs):
self.outputs.remove(rem_out)
 
def remove_input(self, rem_in):
removed = self.remove_input_sign(rem_in, 1)
if (not removed):
self.remove_input_sign(rem_in, -1)
 
def remove_input_sign(self, rem_in, sign):
if(sign == 1 and rem_in in self.pos_inputs):
self.pos_inputs.remove(rem_in)
else:
self.neg_inputs.remove(rem_in)
 
def update_count(self):
self.count = 0
for x in self.pos_inputs:
if(x.signal == 1):
self.count += 1
for x in self.neg_inputs:
if(x.signal == 1):
self.count += -1
 
def update_signal(self):
if(self.count >= self.threshhold):
self.signal = 1
else:
self.signal = 0

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.