Skip to content

Instantly share code, notes, and snippets.

@thisiscetin
Last active November 21, 2017 21:55
Show Gist options
  • Save thisiscetin/ab5b54b97444f1a35d3b2d7e1b1f0f7c to your computer and use it in GitHub Desktop.
Save thisiscetin/ab5b54b97444f1a35d3b2d7e1b1f0f7c to your computer and use it in GitHub Desktop.
Genetic Neural Network
import numpy as np
from timeit import default_timer as timer
from math import log
def sigmoid(x):
return 1 / (1 + np.exp(-x))
class Person(object):
def __init__(self, input, hidden, output):
self.fitness = 0
self.input = input
self.hidden = hidden
self.output = output
self.error = 0
self.feeds = 0
self.ai = [1.0] * self.input
self.ah0 = [1.0] * self.hidden
self.ah1 = [1.0] * self.hidden
self.ao = [1.0] * self.output
self.wi = np.random.randn(self.hidden, self.input)
self.wh = np.random.randn(self.hidden, self.hidden)
self.wo = np.random.randn(self.output, self.hidden)
def feed_forward(self, inputs):
if len(inputs) != self.input:
raise ValueError('Wrong number of inputs')
self.ai = inputs
for i in range(self.hidden):
sum0 = sum(np.multiply(self.ai, self.wi[i]))
self.ah0[i] = sigmoid(sum0)
for i in range(self.hidden):
sum0 = sum(np.multiply(self.ah0, self.wh[i]))
self.ah1[i] = sigmoid(sum0)
for i in range(self.output):
sum0 = sum(np.multiply(self.ah1, self.wo[i]))
self.ao[i] = sigmoid(sum0)
return self.ao[:]
def test_fitness(self, data):
err = 0.0
for i in range(len(data)):
dif = np.subtract(data[i][1], self.feed_forward(data[i][0]))
err += np.sum(dif ** 2)
self.fitness = 1 / log(err+1) + 1
return self.fitness
class CrossOver(object):
def __init__(self, person0, person1, mutation_prob = 0.05):
self.p0 = person0
self.p1 = person1
self.mutation_prob = mutation_prob
def breed(self):
child = Person(self.p0.input, self.p0.hidden, self.p0.output)
for i in range(len(child.wi)):
if np.random.rand() > self.mutation_prob:
child.wi[i] = self.p0.wi[i] if np.random.rand() < 0.5 else self.p1.wi[i]
for i in range(len(child.wh)):
if np.random.rand() > self.mutation_prob:
child.wh[i] = self.p0.wh[i] if np.random.rand() < 0.5 else self.p1.wh[i]
for i in range(len(child.wo)):
if np.random.rand() > self.mutation_prob:
child.wo[i] = self.p0.wo[i] if np.random.rand() < 0.5 else self.p1.wo[i]
return child
class Population(object):
def __init__(self, input, hidden, output, pop_size = 25, min_survival_rate = 0.1):
self.generation = 0
self.people = []
self.pop_size = pop_size
self.min_survival_rate = min_survival_rate
self.fittest_person = None
self.fittest_score = 0
self.fitness_data = []
self.fittest_found_in = 0
for i in range(pop_size):
self.people.append(Person(input, hidden, output))
def rank_people(self):
self.people.sort(key = lambda x: x.fitness, reverse = True)
def asses_people(self, data):
for i in range(len(self.people)):
score = self.people[i].test_fitness(data)
if score > self.fittest_score:
self.fittest_score = score
self.fittest_person = self.people[i]
self.fittest_found_in = self.generation
self.fitness_data.append(score)
def evolve(self, data):
self.generation += 1
self.asses_people(data)
self.rank_people()
survivors = max(self.min_survival_rate, np.random.rand()) * 10
next_generation = self.people[:int(survivors)]
for i in range(len(self.people)):
for j in range(len(self.people)):
if len(next_generation) < self.pop_size:
c = CrossOver(self.people[i], self.people[j])
next_generation.append(c.breed())
else:
break
self.people = next_generation
def stats(self):
return [self.generation, len(self.people), np.max(self.fitness_data), np.mean(self.fitness_data),
np.min(self.fitness_data), self.fittest_found_in]
DATASET = [
[[0, 0, 1], [0]],
[[0, 1, 1], [0]],
[[1, 0, 1], [1]],
[[1, 1, 1], [1]]
]
pop = Population(3, 5, 1, 20)
start = timer()
for i in range(10001):
pop.evolve(DATASET)
if i % 1000 == 0:
end = timer()
if i > 999:
print("%.2f secs for 1000 generations" % (end - start))
print(pop.stats())
for j in range(len(DATASET)):
input = DATASET[j][0]
output = DATASET[j][1]
res = pop.fittest_person.feed_forward(DATASET[j][0])
print(input, output, res)
print("----")
start = timer()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment