CNN - falsche Vorhersagen trotz 99% acc -Fehler ?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Huhu und zwar habe ich ein CNN auf dem Kaggle-Datensatz:
https://www.kaggle.com/tomerel/traffic- ... ed-dataset
trainiert.

Das hat auch alles super funktionert ... allerdings bekomme ich jetzt wenn ich es auf eigene Bilder anwende immer die 31 vorhergesagt, was natürlich nicht korrekt ist.
Ich stehe gerade etwas auf dem Schlauch und weiß nicht so recht wo mein Fehler liegt vlt. könnte mir ja hier jmd helfen :)

Das sind die Bilder die ich getestet habe:

Bild
Bild

trafficnet.py

Code: Alles auswählen

import pickle
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, MaxPooling2D, Flatten, Dropout
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.utils import to_categorical
import numpy as np
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'  # dont show warnings from Tensorflow

testing_image_path = "data/test.p"
training_image_path = "data/train.p"
validation_image_path = "data/valid.p"

with open(training_image_path, mode='rb') as file:
    train = pickle.load(file)
with open(testing_image_path, mode='rb') as file:
    test = pickle.load(file)
with open(validation_image_path, mode='rb') as file:
    valid = pickle.load(file)

X_train, y_train = train['features'], train['labels']
X_test, y_test = test['features'], test['labels']
X_valid, y_valid = valid['features'], valid['labels']

print("Trainingsdaten:", len(X_train))
print("Testdaten:", len(y_test))
print("Validierungsdaten:", len(X_valid))
print("Bilddimensionen:", np.shape(X_train[1]))
print("Anzahl der Klassen:", len(np.unique(y_train)))

n_classes = 43

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'])

X_train_baseline = X_train.reshape(len(X_train), 32, 32, 3).astype('float32')
X_valid_baseline = X_valid.reshape(len(X_valid), 32, 32, 3).astype('float32')
y_train_baseline = tf.keras.utils.to_categorical(y_train, n_classes)
y_valid_baseline = tf.keras.utils.to_categorical(y_valid, n_classes)

model.fit(X_train_baseline, y_train_baseline, batch_size=128, epochs=10, verbose=1, validation_data=(X_valid_baseline, y_valid_baseline))

X_test_baseline = X_test.reshape(len(X_test), 32, 32, 3).astype('float32')
y_test_baseline = tf.keras.utils.to_categorical(y_test, n_classes)

model.evaluate(X_test_baseline, y_test_baseline, verbose=0)

model.save('traffic_signs_100epochs.h5', save_format='h5')
test.py

Code: Alles auswählen

import cv2
import numpy as np
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.image import img_to_array
from skimage import transform

model = load_model('./data/traffic_signs_10epochs.h5')

image = cv2.imread('4.jpg')
image = transform.resize(image,(32,32))

image = image.astype("float32") / 255.0
image = img_to_array(image)
image = np.expand_dims(image, axis=0)
pred = model.predict(image)[0]


print(pred)
Benutzeravatar
ThomasL
User
Beiträge: 1378
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Da du keine Convolutional Layer verwendest ist es kein CNN, eher ein DNN. ;-)
Deine Trainingsdaten haben shape (32, 32, 3) also RGB Channel, dein Testbild wird in (32x32) resized. Hat das dann auch 3 Channel?
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

@ThomasL ja hat es hab es gerade mit image.shape nochmal überprüft :)
Benutzeravatar
ThomasL
User
Beiträge: 1378
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Ich trainiere morgen mal ein Model mit deinem Code und schaue was bei mir da rum kommt.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Das wäre super danke :) :mrgreen:
Github-projektname: traffic_helper

PS: ich habe noch ein "richtiges" CNN :D trainiert (96%) bekomme aber auch dort wenn ich meine Bilder vorhersagen will falsche Ergebnisse .. :cry:
Benutzeravatar
ThomasL
User
Beiträge: 1378
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

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]}")
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Wow vielen Dank für deine Mühe :D
Eine Frage hätte ich da noch und zwar bist du der Meinung es lohnt sich (auch Performance technisch) dieses Netz zur Erkennung von Verkehrszeichen auf ein "Live-Video" anzuwenden ?
Oder sollte ich eher versuchen YOLOv3 entsprechend anzupassen und mit meinen Daten das Darknet zu trainieren ?

PS: Ich habe jetzt noch ein CNN (also wirklich CNN ^^) auf den Daten https://www.kaggle.com/meowmeowmeowmeow ... affic-sign trainiert ich werde das die Tage mal testen und hoffe das läuft besser/sicherer

Kurz zum Ziel: Ich möchte halt ein Netz eigentlich selbst trainieren mit welchem ich dann Verkehrszeichen in einem Live-Video möglichst genau identifizieren kann um dann je nach Vorhersage halt noch Features einzubauen
MfG Felix
Benutzeravatar
ThomasL
User
Beiträge: 1378
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Bilderkennung in Videos wie YOLO kenne ich, habe mich damit aber noch nicht intensiv beschäftigt.
Welche Maße haben die Trainingsdaten bzgl. width and height, hier waren es 32x32.
Welche Maße hat das Videomaterial? Bei 1920x1080 müsste man bei einem Stride von (1, 1) 1889x1049 Bilder a 32x32 Bilder = 1.981.561 durch die Erkennung schicken.
Wie schnell ist die Hardware auf der das NN-Model dabei läuft? Schafft es das bei 60FPS oder 30FPS?
Man kann den Stride natürlich vergrößern, (2,2) oder (5,5) oder (10,10) und die Anzahl der Bilder verringern aber wie sieht es dann mit der Erkennung aus?
Oder nimmt man größere Maße bei den Subpictures z.b. 64x64 und resized die auf 32x32?
Fragen Fragen Fragen bei denen man die Antworten sich selbst durch experimentieren erarbeiten muss oder man recherchiert was andere bereits gemacht haben.
Ist ein sehr interessanten Gebiet und ich wünsche dir viel Erfolg.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Also ich habe jetzt mal etwas rumexperimentiert auf Bildern klappt es einwandfrei (zumindest wenn das Verkehrsschild direkt im Vordergrund ist) das ganze Spiel habe ich jetzt versucht auf die Cam zu übertragen was erst garnicht funktioniert hat ... mittlerweile geht es wenn man ein Verkehrsschildbild direkt vor die Cam hält.
Mein größtes Problem ist das einfach viel zu viele Vorhersagen gemacht werden ohne das überhaupt ein Verkehrschild im Bild ist ... daher habe ich das Frame erstmal in ein Grid aufgeteilt um das ganze etwas runterzubrechen ..
hat hier vlt. jmd eine Idee was ich noch tuen könnte um das Ganze einzugrenzen ?
Eine Idee wäre noch erstmal eine Formerkennung ( Dreieck, Quadrat, Kreis) über die einzelnen "Kacheln" zu jagen diese dann in eine Region of Interest zu begrenzen und darauf zu predicten. Allerdings vermute ich ohne es schon probiert zu haben das es zu Fehlern kommt wenn eine Form zwischen 2 "Kacheln" des Grids liegt.
Ideen oder Erfahrungen ?? :D
(PS: ich möchte das Ding selber bauen daher kein fertiges Modell vorschlagen danke :) )
Code mach ich noch schick wenn ich nen Durchbruch erzielt habe bisher ist alles noch reines testen :roll:

Hub: https://github.com/felixdittrich92/traffic_helper

Hier mal etwas Testcode:

Code: Alles auswählen

import cv2
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import load_model
from skimage import transform
from os import listdir
from pathlib import Path
from PIL import Image

classes = ['Tempo: 20', 'Tempo: 30', 'Tempo: 50', 'Tempo: 60', 'Tempo: 70',
            'Tempo: 80', 'Auflösung 80', 'Tempo: 100', 'Tempo: 120', 'Überholverbot',
            'LKW Überholverbot', 'Vorfahrt nächste Kreuzung', 'Vorfahrtsstraße',
            'Vorfahrt gewehren', 'Stop', 'Einfahrt verboten', 'LKW Einfahrt verboten',
            'Einfahrt verboten Einbahnstraße', 'Achtung', 'Achtung Kurve Links', 'Achtung Kurve Rechts',
            'Achtung Kurvenkombination', 'Achtung unebene Fahrbahn', 'Achtung Schleudergefahr',
            'einseitig verengte Fahrbahn', 'Achtung Baustelle', 'Achtung Ampel', 'Achtung Fußgänger',
            'Achtung Kinder', 'Achtung Fahrrad', 'Achtung Glätte', 'Achtung Wildwechsel', 'Auflösung',
            'Zwangspfeil Rechts', 'Zwangspfeil Links', 'Zwangspfeil Geradeaus', 'Zwangspfeil Geradeaus und Rechts',
            'Zwangspfeil Geradeaus und Links', 'Vorbeifahrt Rechts', 'Vorbeifahrt Links', 'Kreisverkehr', 'Auflösung Überholverbot',
            'Auflösung LKW Überholverbot']

model = load_model('./data/traffic_signs_20_epochs.h5')

""" Image tests
def load_own_image(filepath):
    image = cv2.imread(filepath)
    image = transform.resize(image, (30, 30))
    image = np.expand_dims(image, axis=0)
    return image

folder = './test_bilder/'
for file in listdir(folder):
    path = Path(folder, file)
    path = "./" + str(path)
    image = load_own_image(path)
    print(path)
    predictions = model.predict(image)[0]
    pred_class = np.argmax(predictions)
    class_name = classes[pred_class]
    if predictions[pred_class] < 0.5:
        print(f"Prediction Fail: {path}")
    else:
        print(f"Class Name: {class_name} Predicted Class: {pred_class} Accuracy: {predictions[pred_class]}")

"""

def load_frame(frame):
    frame = transform.resize(frame, (30, 30))
    frame = np.array(frame)
    frame = np.expand_dims(frame, axis=0)
    return frame

cap = cv2.VideoCapture(0)
index = 0


while(True):
    if index % 200 == 0:
        print(index)
        ret, frame = cap.read()

        #split frame in grid
        height = frame.shape[0]
        width = frame.shape[1]

        y1 = 0
        M = height//3
        N = width//3

        for y in range(0,height,M):
            for x in range(0, width, N):
                y1 = y + M
                x1 = x + N
                tiles = frame[y:y+M,x:x+N]  

                cv2.rectangle(frame, (x, y), (x1, y1), (0, 255, 0))
                image = load_frame(tiles)
                predictions = model.predict(image)[0]
                pred_class = np.argmax(predictions)
                class_name = classes[pred_class]
                if predictions[pred_class] < 0.99:
                    pass
                else:
                    print(f"Class Name: {class_name} Predicted Class: {pred_class} Accuracy: {predictions[pred_class]}")
                    index += 1

    else:
        index += 1
    
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
Und zur Ergänzung das Netz:

Code: Alles auswählen

import os
import cv2
from PIL import Image
import pandas as pd
import numpy as np
import random
import tensorflow as tf
import tensorflow.keras as keras
import matplotlib.pyplot as plt
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Flatten, Conv2D, MaxPooling2D, Dropout, Dense
from tensorflow.keras.utils import to_categorical
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score


data = []
labels = []

height = 30
width = 30
channels = 3
num_classes = 43
n_inputs = height * width * channels # (30, 30, 3)

# alle Images anpassen
for i in range(num_classes) :
    path = "./data/train/{0}/".format(i)
    print(path)
    Class = os.listdir(path)
    for a in Class:
        try:
            image=cv2.imread(path+a)
            image_from_array = Image.fromarray(image, 'RGB')
            size_image = image_from_array.resize((height, width))
            data.append(np.array(size_image))
            labels.append(i)
        except AttributeError:
            print(" ")
            
x_train = np.array(data)
x_train = x_train/255.0

y_train = np.array(labels)
y_train = to_categorical(y_train, num_classes) # One Hot Encoding

# Daten splitten
X_train,X_valid,Y_train,Y_valid = train_test_split(x_train,y_train,test_size = 0.3,random_state=0)
print("Train :", X_train.shape)
print("Valid :", X_valid.shape)

# CNN-Modell erstellen

model = Sequential()

model.add(Conv2D(64, (3, 3), input_shape=(30, 30, 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(num_classes, activation='softmax'))

model.summary()

# Modell kompilieren
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# Modell trainieren 20 Epochen
epochs = 20
history = model.fit(X_train, Y_train, validation_data=(X_valid, Y_valid), batch_size=64, epochs=epochs,verbose=1)


# Testdaten vorhersagen
y_test=pd.read_csv("./data/Test.csv")
labels=y_test['Path'].values
y_test=y_test['ClassId'].values

data=[]

for f in labels:
    image=cv2.imread('./data/test/'+f.replace('Test/', ''))
    image_from_array = Image.fromarray(image, 'RGB')
    size_image = image_from_array.resize((height, width))
    data.append(np.array(size_image))

X_test=np.array(data)
X_test = X_test.astype('float32')/255  
pred = model.predict_classes(X_test)
print(pred)

print(accuracy_score(y_test, pred))

# Modellgewichte speichern
model.save('./data/traffic_signs_20_epochs.h5', save_format='h5')
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der Grund, warum man dir immer wieder zu etablierten Netzen raten wird: deren Erfolg liegt nicht in ihrer Struktur, oder einer "neuen" Technologie, die das alle deutlich besser machen wuerde. Das sind (meistenteils) 20-30 Jahre alte Algorithmen. Sondern in der *unfassbaren* Datenmenge, die man denen vorgeworfen hat. Ein Ordner mit einem Beispiel fuer jede Klasse ist da um diverse Groessenordungen - im Zweifel millionenfach - zu wenig. Du solltest also mindestens mal deutlich mehr Beispiele verwenden, und im Zweifel auf transfer-learning setzen, wenn es denn schon nicht "einfach" etwas fertiges sein darf.

Der Ansatz wiederum, analytische Verfahren mit dem CNN zu kombinieren, ist zum scheitern verurteilt. Ein solches prae-processing negiert genau die Vorteile der CNNs, direkt im Pixel-Raum arbeiten zu koennen. Und ist - ich spreche da aus eigener Erfahrung - auch nicht robust zu kriegen unter all den auftretenden Beleuchtungssituationen, mit denen du in der echten Welt zu kaempfen hast. Wenn das anders waere, wuerde man auf CNNs komplett verzichten (gerade bei so simpel und farblich/geometrisch gut klassifizierbaren Dingen wie Schildern), was einen guten Freund der an selbstfahrenden Autos arbeitet gluecklich machen wuerde. Denn dann braucht er weniger ML-Verfahren, deren Verhalten leider nicht klar definiert ist unter allen auftretenden Eingaben. Stichwort adversarial examples zB.
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

Also das CNN ist mit knapp 30k Bildern trainiert aus 43 Klassen wo die Anzahl der Bilder pro Klasse leider ziemlich krass schwankt... :/
Danke aufjedenfall für die Antwort :)
Dieses "Beleuchtungsproblem" hatte ich in einem anderen Kontext schonmal , mal schauen ob meine Lösung von dort mir hier dann weiter hilft.
Ich werde es trotzdem mal so probieren kostet ja nix und bringt Erfahrungen :D
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Man findet Aussagen wie "You need 1,000 representative images for each class". Ggf. kannst du durch Techniken wie spiegeln, rotieren, scheren, skalieren deine Trainingsdaten vergroessern und den Klassifikator robuster machen.
Benutzeravatar
ThomasL
User
Beiträge: 1378
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Bei Straßenschildern würde ich jetzt die Bilder nicht spiegeln. :-)
Aber durch Data Augmenting kann man schon die Trainingsdatenmenge erheblich vergrößern. Aus 30k kann man da 300k oder 3000k machen.
Dann aber wird die Trainingsdauer ein Problem, ausser man hat eine gute GPU lokal oder kann in the Cloud trainieren.

Guter Artikel hier: https://medium.com/ymedialabs-innovatio ... 1ae43d5be9
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich will, dass mein selbstfahrender Androide auch Stopschilder im Rueckspiegel erkennt!!!1!!!!!!!!11!
Benutzeravatar
Felix92
User
Beiträge: 133
Registriert: Mittwoch 7. November 2018, 17:57

@__deets__ muss ich gerade nicht nachvollziehen können oder ? ^^ (son kleiner Prank zur Spiegelung)
@ThomasL also lokal GTX1060 6gb reicht vermutlich nicht nach bisherigen Erfahrungen ....
Naja ich probiere erstmal noch und falls es Probleme gibt melde ich mich nochmal sowie wenn ich ein guten Durchbruch erzielen sollte ... Weihnachten steht ja auch bald aus dort hagelt es für mich wieder Fachbücher vlt. kann ich dort einen Ansatz erarbeiten der sinnvoll und hardwaremäßig realisierbar ist :)
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das war ein Scherz, ja.
Antworten