🧠 MNIST Neural Network

Projekt für Handschriftenerkennung mit Python und NumPy

🔍 Ziel

Implementierung eines einfachen neuronalen Netzwerks zur Erkennung handgeschriebener Ziffern mit Trainings- und Testdaten aus dem MNIST-Datensatz.

📦 Setup & Training Code

import numpy as np
import scipy.special

class neuralNetwork:
    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
        self.inodes = inputnodes
        self.hnodes = hiddennodes
        self.onodes = outputnodes
        self.lr = learningrate
        self.wih = np.random.normal(0.0, pow(self.inodes, -0.5), (self.hnodes, self.inodes))
        self.who = np.random.normal(0.0, pow(self.hnodes, -0.5), (self.onodes, self.hnodes))
        self.activation_function = lambda x: scipy.special.expit(x)

    def train(self, inputs_list, targets_list):
        inputs = np.array(inputs_list, ndmin=2).T
        targets = np.array(targets_list, ndmin=2).T
        hidden_inputs = np.dot(self.wih, inputs)
        hidden_outputs = self.activation_function(hidden_inputs)
        final_inputs = np.dot(self.who, hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        output_errors = targets - final_outputs
        hidden_errors = np.dot(self.who.T, output_errors)
        self.who += self.lr * np.dot((output_errors * final_outputs * (1.0 - final_outputs)), hidden_outputs.T)
        self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), inputs.T)

    def query(self, inputs_list):
        inputs = np.array(inputs_list, ndmin=2).T
        hidden_inputs = np.dot(self.wih, inputs)
        hidden_outputs = self.activation_function(hidden_inputs)
        final_inputs = np.dot(self.who, hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        return final_outputs

n = neuralNetwork(784, 200, 10, 0.1)

with open("mnist_train.csv", 'r') as file:
    training_data_list = file.readlines()

for epoch in range(5):
    for record in training_data_list:
        all_values = record.split(',')
        inputs = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
        targets = np.zeros(10) + 0.01
        targets[int(all_values[0])] = 0.99
        n.train(inputs, targets)

🧪 Testcode

with open("mnist_test.csv", 'r') as file:
    test_data_list = file.readlines()

test_indexes = [0, 100, 500]
for index in test_indexes:
    record = test_data_list[index]
    all_values = record.split(',')
    label = int(all_values[0])
    inputs = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
    outputs = n.query(inputs)
    predicted_label = np.argmax(outputs)
    print(f"Testbild {index}: Erwartet {label}, erkannt {predicted_label}")
    for i, val in enumerate(outputs):
        print(f"{i}: {val[0]:.4f}")
    print("-" * 40)

📈 Genauigkeit berechnen

scorecard = []
for record in test_data_list:
    all_values = record.split(',')
    correct_label = int(all_values[0])
    inputs = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
    outputs = n.query(inputs)
    label = np.argmax(outputs)
    scorecard.append(1 if label == correct_label else 0)

performance = np.asarray(scorecard).sum() / len(scorecard)
print("Genauigkeit:", round(performance * 100, 2), "%")
Beispielausgabe:
Genauigkeit: 94.56 %