So, habe etwas Zeit investiert und folgendes festgestellt.
Die Bilddaten in den Dateien sind nach Klassen sortiert, d.h. zuerst kommen x Bilder von Klasse 0, dann x Bilder von Klasse 1, etc.
Das ist extrem schlecht. Die Reihenfolge sollte immer gut durchmischt sein.
Die Trainings-, Validierungs- und Test-Bilddaten haben Werte von 0 bis 255, die sollten durch 255 geteilt werden, damit wir Werte zwischen 0 und 1 erhalten.
In deinem Code machst du das nur bei deinen eigenen Bildern, jedoch ist es da nicht nötig, da cv2.imread() bereits entsprechende Werte liefert.
Und du teilst die dann nochmal durch 255, dadurch werden die Werte viel zu klein.
cv2.imread() liefert auch float64 Werte, die du dann in float32 reduzierst, warum nicht alle Daten nach float64 wandeln, erhöht die Genauigkeit.
Nachfolgend etwas Code, ich habe da die Trainings- und Validierungsdaten zusammengefügt und erzeuge in der fit()-Funktion einen Split durch den Parameter validation_split.
Habe das in Google Colab laufen lassen, durch den Link im Header kannst du dir das da lesend anschauen wenn du ein Google Account hast.
Du müsstest nur die Daten in deinem Google Drive unter "Colab Notebooks/traffic_signs/data" abspeichern.
Das DNN hat über 16.8 Mio Parameter und nur eine Testaccuracy von 0.7355
Das CNN hat nur knapp 500k Parameter und eine Testaccuracy von 0.9564
Das CNN predicted das Stopschild als Predicted Class: 33 Accuracy: 0.999985933303833 und das 60-Schild als Predicted Class: 1 Accuracy: 0.9496980905532837
Das DNN predicted das Stopschild als Predicted Class: 34 Accuracy: 0.9946086406707764 und das 60-Schild als Predicted Class: 15 Accuracy: 0.9466899037361145
Leider hat das Datenset gar keine Dokumentation welche Klasse denn welche traffic signs sein sollen.
Ich habe mir jetzt auch nicht die Bilder der 43 Klassen anzeigen lassen.
Viel Spass mit dem Code.
Code: Alles auswählen
# -*- coding: utf-8 -*-
"""traffic_signs.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1z7ejGKCNWLnxAuV3qrtTHPynZ6ZwIP3T
"""
import numpy as np
import pickle
import cv2
import tensorflow as tf
from tensorflow.keras.models import Sequential, load_model
from tensorflow.keras.layers import Dense, Conv2D, MaxPooling2D, Flatten, Dropout
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.preprocessing.image import img_to_array
from skimage import transform
from google.colab import drive
drive.mount('/content/gdrive')
root_path = 'gdrive/My Drive/Colab Notebooks/traffic_signs/'
testing_image_path = f"{root_path}data/test.p"
training_image_path = f"{root_path}data/train.p"
validation_image_path = f"{root_path}data/valid.p"
with open(training_image_path, mode='rb') as file:
train_data = pickle.load(file)
with open(testing_image_path, mode='rb') as file:
test_data = pickle.load(file)
with open(validation_image_path, mode='rb') as file:
validation_data = pickle.load(file)
Features = np.append(train_data['features'], validation_data['features'], axis=0)
Labels = np.append(train_data['labels'], validation_data['labels'], axis=0)
print(Features.shape, Labels.shape)
n_classes = len(np.unique(Labels))
print("Anzahl der Klassen:", n_classes)
#X_train = Features.reshape(len(Features), 32, 32, 3).astype('float32') / 255.
X_train = Features.astype('float64') / 255.
y_train = tf.keras.utils.to_categorical(Labels, n_classes)
print("Trainingsdaten:", X_train.shape, y_train.shape)
X_test, y_test = test_data['features'], test_data['labels']
#X_test = X_test.reshape(len(X_test), 32, 32, 3).astype('float32') / 255.
X_test = X_test.astype('float64') / 255.
y_test = tf.keras.utils.to_categorical(y_test, n_classes)
print("Testdaten:", X_test.shape, y_test.shape)
print("Bilddimensionen:", np.shape(X_train[1]))
def create_cnn_model():
model = Sequential()
model.add(Conv2D(64, (3, 3), input_shape=(32, 32, 3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=None, padding='valid'))
model.add(Dropout(0.2))
model.add(Conv2D(128, (3, 3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=None, padding='valid'))
model.add(Dropout(0.2))
model.add(Conv2D(128, (3, 3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=None, padding='valid'))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(n_classes, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
cnn = create_cnn_model()
history = cnn.fit(X_train, y_train, batch_size=32, epochs=10, verbose=1, validation_split=0.1)
test_loss, test_acc = cnn.evaluate(X_test, y_test, verbose=0)
print(f"Test Loss: {test_loss} Test Accuracy: {test_acc}")
cnn.save(f'{root_path}traffic_signs.h5', save_format='h5')
model = load_model(f'{root_path}traffic_signs.h5')
def load_own_image(filepath):
image = cv2.imread(filepath)
image = transform.resize(image, (32, 32))
image = np.expand_dims(image, axis=0)
return image
image = load_own_image(f'{root_path}data/stop_sign.jpg')
predictions = model.predict(image)[0]
pred_class = np.argmax(predictions)
print(f"Predicted Class: {pred_class} Accuracy: {predictions[pred_class]}")
image = load_own_image(f'{root_path}data/60_sign.jpg')
predictions = model.predict(image)[0]
pred_class = np.argmax(predictions)
print(f"Predicted Class: {pred_class} Accuracy: {predictions[pred_class]}")
def create_dnn():
model = Sequential()
model.add(Dense(64, activation='relu', input_shape=(32, 32, 3,)))
model.add(BatchNormalization())
model.add(Dense(128, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(128, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(BatchNormalization())
model.add(Dense(n_classes, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
dnn = create_dnn()
history = dnn.fit(X_train, y_train, batch_size=32, epochs=10, verbose=1, validation_split=0.1)
test_loss, test_acc = dnn.evaluate(X_test, y_test, verbose=0)
print(f"Test Loss: {test_loss} Test Accuracy: {test_acc}")
image = load_own_image(f'{root_path}data/stop_sign.jpg')
predictions = dnn.predict(image)[0]
pred_class = np.argmax(predictions)
print(f"Predicted Class: {pred_class} Accuracy: {predictions[pred_class]}")
image = load_own_image(f'{root_path}data/60_sign.jpg')
predictions = dnn.predict(image)[0]
pred_class = np.argmax(predictions)
print(f"Predicted Class: {pred_class} Accuracy: {predictions[pred_class]}")