User:Ping/Python Perceptron: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
Line 10: | Line 10: | ||
class Perceptron: | class Perceptron: | ||
def __init__(self, size): | def __init__(self, size): | ||
"""The 'size' parameter sets the number of inputs to this Perceptron.""" | |||
self.weights = [0.0]*size + [0.0] | self.weights = [0.0]*size + [0.0] | ||
self.threshold = 0.0 | self.threshold = 0.0 | ||
def __repr__(self): | def __repr__(self): | ||
"""Display the weights and threshold of this Perceptron.""" | |||
weights = '[%s]' % (', '.join('%.3g' % w for w in self.weights)) | weights = '[%s]' % (', '.join('%.3g' % w for w in self.weights)) | ||
return '<weights=%s, threshold=%r>' % (weights, self.threshold) | return '<weights=%s, threshold=%r>' % (weights, self.threshold) | ||
def evaluate(self, inputs): | def evaluate(self, inputs): | ||
"""Evaluate this Perceptron with the given inputs, giving 0 or 1. | |||
'inputs' should be a list of numbers, and the length of the list | |||
should equal the 'size' used to construct this Perceptron.""" | |||
return int(dot_product(self.weights, inputs + [1]) > self.threshold) | return int(dot_product(self.weights, inputs + [1]) > self.threshold) | ||
def adjust(self, inputs, | def adjust(self, inputs, rate): | ||
"""Adjust the weights of this Perceptron for the given inputs, using | |||
the given training rate.""" | |||
for i, input in enumerate(inputs + [1]): | for i, input in enumerate(inputs + [1]): | ||
self.weights[i] += | self.weights[i] += rate*input | ||
def train( | def train(self, inputs, expected_output, rate): | ||
"""Train this Perceptron for a single test case.""" | |||
output = self.evaluate(inputs) | |||
self.adjust(inputs, rate*(expected_output - output)) | |||
def | def train_all(self, training_set, rate): | ||
"""Train this Perceptron for all cases in the given training set.""" | |||
for inputs, expected_output in training_set: | |||
self.train(inputs, expected_output, rate) | |||
def | def check_all(self, training_set): | ||
"""Check whether this Perceptron produces all the correct outputs.""" | |||
print self | |||
failures = 0 | |||
for inputs, expected_output in training_set: | |||
output = self.evaluate(inputs) | |||
print ' %r -> %r (want %r)' % (inputs, output, expected_output) | |||
if output != expected_output: | |||
failures += 1 | |||
return not failures | |||
training_set = [ | training_set = [ | ||
Line 54: | Line 64: | ||
perceptron = Perceptron(3) | perceptron = Perceptron(3) | ||
rate = 0.1 | |||
while | while rate > 1e-9: | ||
if | if perceptron.check_all(training_set): | ||
print | print | ||
print 'Success:', perceptron | print 'Success:', perceptron | ||
break | break | ||
perceptron.train_all(training_set, rate) | |||
rate *= 0.99 | |||
</pre> | </pre> |
Revision as of 20:23, 18 March 2009
This Perceptron builds in a bias input (by internally appending an extra 1 to the inputs).
#!/usr/bin/env python __author__ = 'Ka-Ping Yee <ping@zesty.ca>' def dot_product(inputs, weights): return sum(input*weight for input, weight in zip(inputs, weights)) class Perceptron: def __init__(self, size): """The 'size' parameter sets the number of inputs to this Perceptron.""" self.weights = [0.0]*size + [0.0] self.threshold = 0.0 def __repr__(self): """Display the weights and threshold of this Perceptron.""" weights = '[%s]' % (', '.join('%.3g' % w for w in self.weights)) return '<weights=%s, threshold=%r>' % (weights, self.threshold) def evaluate(self, inputs): """Evaluate this Perceptron with the given inputs, giving 0 or 1. 'inputs' should be a list of numbers, and the length of the list should equal the 'size' used to construct this Perceptron.""" return int(dot_product(self.weights, inputs + [1]) > self.threshold) def adjust(self, inputs, rate): """Adjust the weights of this Perceptron for the given inputs, using the given training rate.""" for i, input in enumerate(inputs + [1]): self.weights[i] += rate*input def train(self, inputs, expected_output, rate): """Train this Perceptron for a single test case.""" output = self.evaluate(inputs) self.adjust(inputs, rate*(expected_output - output)) def train_all(self, training_set, rate): """Train this Perceptron for all cases in the given training set.""" for inputs, expected_output in training_set: self.train(inputs, expected_output, rate) def check_all(self, training_set): """Check whether this Perceptron produces all the correct outputs.""" print self failures = 0 for inputs, expected_output in training_set: output = self.evaluate(inputs) print ' %r -> %r (want %r)' % (inputs, output, expected_output) if output != expected_output: failures += 1 return not failures training_set = [ ([1, 0, 0], 1), ([1, 0, 1], 1), ([1, 1, 0], 1), ([1, 1, 1], 0), ([0, 1, 0], 1), ([0, 0, 1], 1), ([0, 1, 1], 1), ([0, 0, 0], 1), ] perceptron = Perceptron(3) rate = 0.1 while rate > 1e-9: if perceptron.check_all(training_set): print print 'Success:', perceptron break perceptron.train_all(training_set, rate) rate *= 0.99