Seite 1 von 2
Handgeschriebene Zahlen erkennen
Verfasst: Mittwoch 29. März 2023, 20:58
von Andreas Schneider
Hallo, ich versuche ein neuronales Netzwerk in Python zu programmieren, in das ich Bilder von handgeschriebenen Zahlen hochladen kann und das diese erkennt. Kann mir jemand dabei helfen?
Re: Handgeschriebene Zahlen erkennen
Verfasst: Mittwoch 29. März 2023, 21:38
von __deets__
Das ist doch ein absolutes Standardthema. Wahrscheinlich auch genau aus dem Grund deine Hausaufgabe.. es gibt viel dazu im Netz, empfehlen kann ich Adrian von pyimagesearch. Wenn du konkrete fragen hast, bekommst du hier auch gerne Hilfe. Aber so das grundlegende an Eigeninitiative darfs dann doch sein.
Re: Handgeschriebene Zahlen erkennen
Verfasst: Donnerstag 30. März 2023, 16:27
von Andreas Schneider
Ich habe den folgenden Code geschrieben:
#Importieren der Bibliothek tensorflow und numpy
import tensorflow as tf
import numpy as np
#Definieren des Datensets
#Anlegen der Variablen mnist und zuweisen des datensets fasion_mnist welches in der Bibliothek tensorflow im Package datasets aus dem Package keras enthalten ist
mnist = tf.keras.datasets.mnist
#Definieren von 4 weiteren Variablen zum Einladen der Daten
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
#Nun bringen wir die Daten in eine Form mit der das neuronale Netzwerk gut arbeiten kann
#Wir haben 60000 Trainingsbilder mit je 28 mal 28 Pixeln, da wir mit Schwarz-weiß-bildern arbeiten möchten brauchen wir nur einen Farbbereich
#Währen die Bilder welche in das Neuronale Netz eingelesen werden sollen Bunt bräuchten wir (60000, 28, 28, 3) - Je ine Farbwert zwischen 0 und 255 für R,G und B
training_images = training_images.reshape(60000, 28, 28, 1)
#Normalisieren der Daten - Die Farbwerte sollen nun in Gleitkommazahlen zwischen 0 und eins umgerechnet werden
training_images = training_images / 255.0
#Analog verfahren wir mit unseren 10000 test_images
test_images = test_images.reshape(10000, 28, 28, 1)
test_images = test_images / 255.0
#Definieren des Modells von unserem neuronalen Netz
model = tf.keras.models.Sequential([
#Wandele die Daten in eine eindimensionale Zahlenreihe um
tf.keras.layers.Flatten(),
#Einsetzen einer Schicht von 128 Neuronen in Dense sowie festlegen einer relu-funktion als Aktivierungsfunktion
#rectified-linear-activation-function: Eliminiert alle Werte kleiner 0 für Werte größer 0
#wird versucht einen Wert so zuzuordnen, dass ein linearer Zusammenhang zwischen den Daten entsteht ->
#Optimal für Neuronale Netze - Analogie zu Linearen funktionen basierend auf Gewichtung in den Neuronen
tf.keras.layers.Dense(128, activation='relu'),
#Anlegen von 10 Neuronen für die Ausgabe; softmax wandelt die Werte der Ausgabeschicht so um, dass deren Summe 1 ergibt ->
#Jedes Neuron also die Wahrscheinlichkeit ausgibt, dass es sich bei dem Bild um das Kleidungsstück handelt, welches jenem Ausgabeneuron zugewiesen ist
tf.keras.layers.Dense(10, activation='softmax')
])
#in diesem Abschnitt trainieren wir unser neuronales Netz
#Was definieren/bedeuten die Variablen aus der compile-Funktion?
#loss: Größe des Fehlers nach jeder Epoche; optimizer: Funktion zur Optimierung des neuronalen Netzwerks nach jeder Epoche
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
#Trainiere das neuronale Netz 4 Epochen lang auf diese Weise mit allen training_images und den zugehörigen bekannten training_labels
model.fit(training_images,training_labels, epochs=4)
#in diesem Abschnitt testen wir unser neuronales Netz mit den Testbildern des Datensets, welche unser neuronales Netz noch nie gesehen hat
classes = model.predict(test_images)
predicted_classes = np.argmax(classes, axis=1)
print(classes[0])
print(test_labels[0])
#in diesem Abschnitt schauen wir uns das Bild an, welches wir vorher zum Testen genutzt haben
mnist = tf.keras.datasets.mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
import matplotlib.pyplot as plt
plt.imshow(test_images[0], cmap='Greys_r')
#in diesem Abschnitt laden wir die Libraries ein
import numpy as np
from google.colab import files
import keras.utils as image
import cv2
import matplotlib.pyplot as plt
uploaded = files.upload()
for fn in uploaded.keys():
#in diesem Abschnitt laden wir die Bilder rein; wir nutzen eine for Schleife, um mehrere Daten gleichzeitig einladen zu können
path = '/content/' + fn
img = cv2.imread(path)
#in diesem Abschnitt formartieren wir unsere Bilder, sodass sie zu unserem neuronalen Netz passen
img = cv2.resize(img,(28,28))
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
x = image.img_to_array(img, dtype=np.float32)
print("top left pixel value:", x[0,0])
if x[0,0] > 250:
# white background
print("needs to be inverted!")
x -= 255
x *= -1
x = x / 255.0
# x = np.expand_dims(x, axis=0) # das brauchst du nicht weil du danach ja reshapest
x = x.reshape(1, 28, 28, 1)
plt.imshow(img, cmap='Greys_r')
plt.show()
#in diesem Abschnitt lassen wir unser neuronales Netz einschätzen, um welches Kleidungsstück es sich handelt; Bedenkt, dass Python ab 0 zählt, somit müsst ihr bei der ausgegebenen Zahl +1 rechnen
classes = model.predict(x)
plt.bar(range(10), classes[0])
plt.show()
print("prediction: class", np.argmax(classes[0]))
Leider wird ein Bild von einer 1, welches ich in das Programm geladen habe fälschlicherweise als 6 klassifiziert. Den Code habe ich ausgehend von einem Programm welches bereits Kleidungsstücke wie T-Shirts richtig klassifiziert hat so abgeändert, dass es eigentlich mit handgeschriebenen Zahlen arbeiten sollte. Kann mir jemand sagen wo mein Fehler liegt?
Re: Handgeschriebene Zahlen erkennen
Verfasst: Donnerstag 30. März 2023, 16:56
von grubenfox
bei den Trainingsdaten?
Re: Handgeschriebene Zahlen erkennen
Verfasst: Donnerstag 30. März 2023, 17:30
von Andreas Schneider
Danke für deine Antwort.
Ich bin leider blutiger Anfänger und brauche noch weitere Erklärungen.
Aber tf.keras.datasets.mnist sollte eigentlich handgeschriebene Zahlen beinhalten. Jedenfalls habe ich ein anderes Programm geschrieben welches bereits Handgeschriebene Zahlen aus dem Testset richtig klassifiziert. Leider gelingt es mir dort nicht ein eigenes Bild so rein zu laden, dass das Programm läuft. Beide Programme habe ich aus Tutorials kopiert.
Re: Handgeschriebene Zahlen erkennen
Verfasst: Donnerstag 30. März 2023, 18:19
von grubenfox
Hhmm, stimmt... das sind wohl handgeschriebene Zahlen bzw. Bilder davon. Schade, war so schön einfach die Antwort. Da muss dann wohl mal jemand ran, der sich damit auskennt....
Re: Handgeschriebene Zahlen erkennen
Verfasst: Donnerstag 30. März 2023, 20:25
von Andreas Schneider
Ja ich hoffe es findet sich noch jemand der mir helfen kann. Sonst komme ich leider nicht weiter.
Re: Handgeschriebene Zahlen erkennen
Verfasst: Donnerstag 30. März 2023, 21:02
von ThomasL
Nabend Andreas,
dein model ist halt nicht gut genug um deine Bilder zu erkennen.
Ich habe mal dieses Model hier gegoogelt:
Code: Alles auswählen
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Activation, Dense, Dropout
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten
from tensorflow.keras.utils import to_categorical, plot_model
from tensorflow.keras.datasets import mnist
# load mnist dataset
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# compute the number of labels
num_labels = len(np.unique(y_train))
# convert to one-hot vector
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
# input image dimensions
image_size = x_train.shape[1]
# resize and normalize
x_train = np.reshape(x_train,[-1, image_size, image_size, 1])
x_test = np.reshape(x_test,[-1, image_size, image_size, 1])
x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255
# network parameters
# image is processed as is (square grayscale)
input_shape = (image_size, image_size, 1)
batch_size = 128
kernel_size = 3
pool_size = 2
filters = 64
dropout = 0.2
# model is a stack of CNN-ReLU-MaxPooling
model = Sequential()
model.add(Conv2D(filters=filters,
kernel_size=kernel_size,
activation='relu',
input_shape=input_shape))
model.add(MaxPooling2D(pool_size))
model.add(Conv2D(filters=filters,
kernel_size=kernel_size,
activation='relu'))
model.add(MaxPooling2D(pool_size))
model.add(Conv2D(filters=filters,
kernel_size=kernel_size,
activation='relu'))
model.add(Flatten())
model.add(Dropout(dropout))
model.add(Dense(num_labels))
model.add(Activation('softmax'))
model.summary()
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=10, batch_size=batch_size)
_, acc = model.evaluate(x_test,
y_test,
batch_size=batch_size,
verbose=0)
print("\nTest accuracy: %.1f%%" % (100.0 * acc))
Das liefert auf dem Testdatensatz eine Accuracy von 99,4 %
Habe dann mal ein paar Zahlen per paint.net gemalt und erkennen lassen. 100%
Code: Alles auswählen
from google.colab import files
import keras.utils as image
import cv2
uploaded = files.upload()
for filename in uploaded.keys():
path = '/content/' + filename
img = cv2.imread(path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.resize(img,(28,28))
x = image.img_to_array(img, dtype=np.float32)
x = x / 255
x = x.reshape(1, 28, 28, 1)
plt.imshow(img, cmap='Greys_r')
plt.show()
classes = model.predict(x)
plt.bar(range(10), classes[0])
plt.show()
print("prediction: class", np.argmax(classes[0]))
Re: Handgeschriebene Zahlen erkennen
Verfasst: Freitag 31. März 2023, 21:16
von Andreas Schneider
Danke
Re: Handgeschriebene Zahlen erkennen
Verfasst: Freitag 31. März 2023, 21:25
von Andreas Schneider
Sorry ich bin leider blutiger Anfänger. Wenn ich den Code ausführen möchte erhalte ich die Fehlermeldung: NameError: name 'np' is not defined. Wo bei handelt es sich bei diesem np? Was muss ich tun um deinen Code zum laufen zu bringen? Ich programmiere in Google Colab.
Re: Handgeschriebene Zahlen erkennen
Verfasst: Freitag 31. März 2023, 21:40
von Dennis89
Hallo,
'np' ist üblicherweise die Abkürzung für
NumPy.
Das musst du installieren und im Programm importieren:
Grüße
Dennis
Re: Handgeschriebene Zahlen erkennen
Verfasst: Samstag 1. April 2023, 08:07
von ThomasL
Ah sorry, die imports sind bei copy & paste irgendwie verschütt gegangen.
Aber schau doch mal in deinen zweiten Beitrag in Zeile 4 deines Codes, da steht die Zeile.
Hätte dir also bekannt vorkommen können.
Re: Handgeschriebene Zahlen erkennen
Verfasst: Samstag 1. April 2023, 19:46
von Andreas Schneider
Jetzt funktioniert der Code. Vielen Dank

Re: Handgeschriebene Zahlen erkennen
Verfasst: Samstag 1. April 2023, 20:18
von Andreas Schneider
Ich habe ebenfalls einige Zahlen mit Paint gemalt aber es wurde nur eine von 5 Zahlen richtig erkannt. Als ich Bilder aus dem Trainingsset kopiere und in das Netzwerk hochladen habe hatte ich 4 von 5 richtige Klassifizierungen.
Re: Handgeschriebene Zahlen erkennen
Verfasst: Samstag 1. April 2023, 21:15
von ThomasL
Hast du denn weiß auf schwarz (wie die Trainingsdaten) oder schwarz auf weiß gemalt?
Und welche Maße haben deine Bilder und wie dick ist der Pinsel mit dem du die Zahlen gemalt hast?
Die Bilder werden ja auf 28x28 Pixel herunter skaliert, wenn du vorher 1920x1080 hast und mit einem Pinsel mit 1 Pixel Dicke gemalt hast
dann wird es für das Model schwierig, da was zu erkennen.
Re: Handgeschriebene Zahlen erkennen
Verfasst: Samstag 1. April 2023, 21:40
von ThomasL
Hier mal Links zu von mir erstellen Bildern mit Zahlen.
Alle ausser einer werden korrekt erkannt.
Code: Alles auswählen
https://ibb.co/h700kyT
https://ibb.co/CP9jpkr
https://ibb.co/5R5jW48
https://ibb.co/z63r1nJ
https://ibb.co/L8LgR65
https://ibb.co/stXm4Kf
https://ibb.co/BcRqfvh
https://ibb.co/FhLrnVX
Re: Handgeschriebene Zahlen erkennen
Verfasst: Mittwoch 5. April 2023, 18:47
von Andreas Schneider
Danke,
Meine Zahlen waren zwar dick genug geschrieben um auch verkleinert noch erkannt zu werden, jedoch waren sie schwarz auf weißem Hintergrund und auch nicht so dick wie deine. Ich bin mal gespannt ob es mit deinen Zahlen besser funktioniert.
Re: Handgeschriebene Zahlen erkennen
Verfasst: Mittwoch 5. April 2023, 19:08
von Andreas Schneider
Vielen Dank, mit deinen Ziffern haben jetzt 3 von 3 Tests perfekt funktioniert.
Re: Handgeschriebene Zahlen erkennen
Verfasst: Freitag 21. April 2023, 21:37
von Andreas Schneider
Rein aus Interesse: Wäre es auch möglich ein Neuronales Netz zu programmieren, das sowohl schwarz auf weiß geschriebene Zahlen als auch weiß auf schwarz geschriebene Zahlen erkennt?
Re: Handgeschriebene Zahlen erkennen
Verfasst: Freitag 21. April 2023, 22:30
von __deets__
Ja. Hast du’s mal probiert? Der MINST Datensatz ist doch verfügbar und invertieren einfach.