First commit

This commit is contained in:
2020-06-23 22:53:47 +02:00
commit 368d134228
17 changed files with 308 additions and 0 deletions

71
multiclass_perceptron.py Normal file
View File

@@ -0,0 +1,71 @@
from typing import Tuple, List, Callable, Generator
from import_data import test_x_y, train_x_y, IMAGE_SIZE, print_img_to_console, show_picture
import numpy as np
class MulticlassPerceptron:
class Perceptron:
def __init__(self, input_size, learn_rate: float = 0.0001):
self.weights = np.random.rand(input_size + 1) * 2 - 1
self.learn_rate = learn_rate
def train(self, data_lbl_pairs: Callable[[], Generator], positive_label: int, iterations: int = 10):
for num_iter in range(iterations):
print(f"Iteration number: {num_iter + 1}")
for i, (x, y) in enumerate(data_lbl_pairs()):
prediction = self.output(x)
label = 1 if y == positive_label else -1
correct = prediction >= 0 and label >= 0 or prediction < 0 and label < 0
if not correct:
self.weights = self.weights + self.learn_rate * label * np.array([1.0] + x)
def output(self, datum):
return np.dot(self.weights, np.array([1.0] + datum))
def get_normalised_weight_array(self):
return [int(x) for x in (((self.weights / np.max(self.weights) + 1) / 2) * 255)]
def __init__(self, input_size: int, num_classes: int, learn_rate: float = 0.001):
self.classifiers = [self.Perceptron(input_size, learn_rate) for _ in range(num_classes)]
def train(self, data_lbl_pairs: Callable[[], Generator], iterations: int = 10):
for i, classifier in enumerate(self.classifiers):
print(f"Training classifier for class {i}...")
classifier.train(data_lbl_pairs, i, iterations)
print()
def output(self, datum: List[int]):
return list(map(lambda x: x.output(datum), self.classifiers))
def prediction(self, datum):
return max(list(range(10)), key=lambda x: self.output(datum)[x])
def view_for_classifier(self, classifier_index: int):
return self.classifiers[classifier_index].get_normalised_weight_array()
def train_and_test_multiclass_perceptron(iterations: int = 5, training_inputs: int = 5000, test_inputs: int = 1000):
print("Loading data")
training_data_gen = train_x_y(training_inputs)
print("Begin training model!")
model = MulticlassPerceptron(IMAGE_SIZE, 10)
model.train(training_data_gen, iterations)
print("Model successfully trained.")
print("Testing model...")
test_data = list(test_x_y(test_inputs)())
n_correct = sum(model.prediction(x) == y for x, y in test_data)
accuracy = n_correct / len(test_data)
print(f"Accuracy: {accuracy} ({n_correct} correctly classified out of {len(test_data)} total test inputs.)")
for i in range(10):
print_img_to_console(model.view_for_classifier(i))
def get_trained_digit_model(iterations: int = 5, training_inputs: int = 5000, test_inputs: int = 1000):
training_data_gen = train_x_y(training_inputs)
model = MulticlassPerceptron(IMAGE_SIZE, 10)
model.train(training_data_gen, iterations)
return model
if __name__ == "__main__":
train_and_test_multiclass_perceptron()