Showing posts with label Neural Networks. Show all posts
Showing posts with label Neural Networks. Show all posts

Sunday, December 30, 2012

A Python Hopfield Network

Quick Background

Hopfield networks are general purpose neural networks that take a set of input values (boolean) and produce an output of same length. They are particularly useful in signal processing and cleaning up images where noise is an issue, (think smudged characters).

I imagine they would be particularly useful in normalizing inputs from different hardware (e.g. creating color profiles, removing static or echos from some microphones, etc.)

This Implementation

This implementation is a tanslation of the algorithm found in the Clever Algorithms book from Ruby to Python.
#!/usr/bin/env python3
# A translation of http://www.cleveralgorithms.com/nature-inspired/neural/hopfield_network.html
import random

def random_vector(minmax):
return [row[0] + ((row[1] - row[0]) * random.random()) for row in minmax]

def initialize_weights(problem_size):
return random_vector([[-0.5,0.5] for i in range(problem_size)])

def create_neuron(num_inputs):
return {'weights' : initialize_weights(num_inputs)}

def propagate_was_change(neurons):
i = random.randrange(len(neurons))
activation = 0

for j, other in enumerate(neurons):
activation += other['weights'][i] * other['output'] if i != j else 0

output = 1 if activation >= 0 else -1
change = output != neurons[i]['output']
neurons[i]['output'] = output
return change

def flatten(nested):
try:
return [item for sublist in nested for item in sublist]
except TypeError:
return nested

def get_output(neurons, pattern, evals=100):
vector = flatten(pattern)

for i, neuron in enumerate(neurons):
neuron['output'] = vector[i]

for j in range(evals):
propagate_was_change(neurons)

return [neuron['output'] for neuron in neurons]

def train_network(neurons, patters):
for i, neuron in enumerate(neurons):
for j in range((i+1), len(neurons)):
if i == j:
continue

wij = 0.0

for pattern in patters:
vector = flatten(pattern)
wij += vector[i] * vector[j]

neurons[i]['weights'][j] = wij
neurons[j]['weights'][i] = wij

def to_binary(vector):
return [0 if i == -1 else 1 for i in vector]

def print_patterns(provided, expected, actual):
p, e, a = to_binary(provided), to_binary(expected), to_binary(actual)
p1, p2, p3 = ', '.join(map(str, p[0:2])), ', '.join(map(str, p[3:5])), ', '.join(map(str, p[6:8]))
e1, e2, e3 = ', '.join(map(str, e[0:2])), ', '.join(map(str, e[3:5])), ', '.join(map(str, e[6:8]))
a1, a2, a3 = ', '.join(map(str, a[0:2])), ', '.join(map(str, a[3:5])), ', '.join(map(str, a[6:8]))
print( "Provided\tExpected\tGot")
print( "%s\t\t%s\t\t%s" % (p1, e1, a1))
print( "%s\t\t%s\t\t%s" % (p2, e2, a2))
print( "%s\t\t%s\t\t%s" % (p3, e3, a3))


def calculate_error(expected, actual):
return sum([1 for i in range(len(expected)) if expected[i] != actual[i]])

def perturb_pattern(vector, num_errors=1):
perturbed = [v for v in vector]
indicies = [0 for i in range(random.randrange(len(perturbed)))]

while len(indicies) < num_errors:
index = random.randrange(len(perturbed))
if not index in indicies:
indicies.append(index)

for i in indicies:
perturbed[i] = -1 if perturbed[i] == 1 else 1

return perturbed


def test_network(neurons, patterns):
error = 0.0

for pattern in patterns:
vector = flatten(pattern)
perturbed = perturb_pattern(vector)
output = get_output(neurons, perturbed)
error += calculate_error(vector, output)
print_patterns(perturbed, vector, output)

error = error / float(len(patterns))
print("Final Result: avg pattern error=%s" % (error))

return error

def execute(patters, num_inputs):
neurons = [create_neuron(num_inputs) for i in range(num_inputs)]
train_network(neurons, patters)
test_network(neurons, patters)
return neurons

if __name__ == "__main__":
# problem configuration
num_inputs = 9
p1 = [[1,1,1],[-1,1,-1],[-1,1,-1]] # T
p2 = [[1,-1,1],[1,-1,1],[1,1,1]] # U
patters = [p1, p2]
# execute the algorithm
execute(patters, num_inputs)

Friday, December 21, 2012

Open Source Laptops, Rebuilding Pong, Free Neural Networking Course: Friday Link List

Operating Systems

  • Syllalbe OS should benefit now that REBOL 3 has been released under the Apache License. What does this mean for the world? Nothing. Syllable is a mostly pedantic project and REBOL is a difficult language that suffers the same flaws as smalltalk and has a severely limited scope compared to JavaScript (that already runs everywhere and is not encumbered by strange programming paradigms.)

Curiosities

Algorithms

Making

  • Andrew “bunnie” Huang has designed an open-source laptop motherboard with some great features, including built-in FPGA, touch-screen ports, and lots of UART /GPIO ports.
  • Pong Reborn Rebuilding the original arcade version of Atari's Pong.