Mon réseau de neurone se trompe à chaque prédiction

Keras

Le problème exposé dans ce sujet a été résolu.

Bonjour, J’essaye de reconnaitre des pièces d’échecs à l’aide d’un réseau de neurone. J’ai pris pour label de chaque pièce un numéro compris entre 0 et 11, malheureusement mon réseau me prédit à chaque fois 1.0, alors que je devrais avoir une prédiction du type 0,0,0…,1,1,1…,2,2,2…etc Je ne sais pas si le problème vient du design de mon réseau ou si il vient simplement d’une erreur dans mon code comme par exemple des dimensions de mes arrays. Voici ce que j’ai fait:

import cv2
import os
import numpy as np
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.utils import to_categorical

def model(x_train):
    model = Sequential()
    model.add(Flatten(input_shape=x_train.shape[1:]))
    model.add(Dense(256, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(1, activation='sigmoid'))
    return model

def preprocessing(x_train,rep_img,label,path):  #Passe les images en noir et blanc puis les ajoute a la liste train avec leur label
    for i in rep_img:
        img=cv2.imread(path+"//"+i)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        img=np.array(img)
        img=img.astype('float32')
        img/=255
        x_train.append([label,cv2.resize(img,(taille_image,taille_image))])
    return x_train

taille_image=150
x_train=[]
x_test=[]
rep_liste=[]
rep_test=[]

#Dossier des images
.....
#Chargement des fichiers
#fin des chargements des fichiers

#Ajout des images traités dans le dossier de train
for rep in rep_liste:
    x_train=preprocessing(x_train,rep[1],rep[0],rep[2])
for rep in rep_test:
    x_test=preprocessing(x_test,rep[1],rep[0],rep[2])
X_train=[]
Y_train=[]
X_test=[]
Y_test=[]
for i in range(len(x_train)):
    X_train.append(x_train[i][1])#Creation de liste avec images pour train
    Y_train.append(x_train[i][0])#Creation de liste avec labels pour train
for i in range(len(x_test)):
    X_test.append(x_test[i][1])#Creation de liste avec images pour test
    Y_test.append(x_test[i][0])#Creation de liste avec labels pour test
#cv2.imshow('img', X_train[0])
X_train=np.array(X_train)
Y_train=np.array(Y_train)
model=model(X_train)
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])
model.fit(X_train, Y_train, epochs=50, batch_size=256)
print(model.predict(np.array(X_test)))

Auriez vous une idée de comment résoudre mon problème ?

Merci d’avance pour votre aide :)

+0 -0

Le code n’est pas extrèmement long, peut-être que tu auras des réponses sur le code lui-même.

Quoi qu’il en soit, voici une suggestion qui peut t’aider à avancer.

En principe, tu as fait une première phase, pour alimenter la base de connaissance de ton programme. Tu lui as dit que telle série d’images, c’était des cavaliers (code 1), telle autre série, c’était des fous (code 2) , etc etc

Refait complètement cette phase d’apprentissage, en permutant les pièces. Les cavaliers ne correspondent plus au code 1 mais au code 2.

Et tu refais tes tests. Si maintenant, ton programme te répond systématiquement 2, tu as une piste, et s’il te répond toujours systématiquement 1, tu as une autre piste.

Je pense en tout cas qu’il y a au moins une erreur dans l’architecture de ton réseau :

def model(x_train):
    model = Sequential()
    model.add(Flatten(input_shape=x_train.shape[1:]))
    model.add(Dense(256, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(1, activation='sigmoid'))
    return model

Indépendamment des premières couches, si tu regardes ta dernière couche, tu as un unique neurone en sortie dont la fonction d’activation est une sigmoïde, qui va donc avoir une sortie comprise entre 00 et 11, avec une transition de phase entre 00 et 11 normalement assez marquée (c’est à dire ne passant pas par des paliers intermédiaires). Je pense que l’on comprend assez vite pourquoi ça peut coincer pour ton problème où tu veux classer des entrées parmi 12 classes distinctes ! ^^ L’expérience proposée par elegance devrait confirmer ce problème.

Je pense que tu n’es pas très loin de pouvoir corriger ce soucis, je t’invite peut-être à jeter un œil à des références sur des problèmes de «multi-class classification», par exemple ici (si tu es à l’aise avec l’anglais), peut-être les schémas pourront-ils t’aiguiller un peu mieux sur des idées à suivre.

Bonsoir,

Merci beaucoup pour vos réponses :) Effectivement le problème venait bien de mon modèle et de la fonction sigmoïde. J’ai lue certains passages du livre Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow d’Aurélien Geron, et j’ai utilisé un de ses modèles.

Voici mon nouveau code pour ceux qui souhaiteraient le voir:

import cv2
import os
import numpy as np
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.utils import to_categorical

def model(x_train):
    model = Sequential()
    model.add(Flatten( input_shape =x_train[0].shape))
    model.add(Dense(300, activation='relu'))
    model.add(Dense(100, activation='relu'))
    model.add(Dense(12, activation="softmax"))
    return model

def preprocessing(x_train,rep_img,label,path):  #Passe les images en noir et blanc puis les ajoute a la liste train avec leur label
    for i in rep_img:
        img=cv2.imread(path+"//"+i)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        img=np.array(img)
        img=img.astype('float32')
        img/=255
        x_train.append([label,cv2.resize(img,(taille_image,taille_image))])
    return x_train

taille_image=150
x_train=[]
x_test=[]
rep_liste=[]
rep_test=[]

#Dossier des images
...
#fin des images


#Ajout des images traités dans le dossier de train
for rep in rep_liste:
    x_train=preprocessing(x_train,rep[1],rep[0],rep[2])
for rep in rep_test:
    x_test=preprocessing(x_test,rep[1],rep[0],rep[2])
X_train=[]
Y_train=[]
X_test=[]
Y_test=[]
for i in range(len(x_train)):
    X_train.append(x_train[i][1])#Creation de liste avec images pour train
    Y_train.append(x_train[i][0])#Creation de liste avec labels pour train
for i in range(len(x_test)):
    X_test.append(x_test[i][1])#Creation de liste avec images pour test
    Y_test.append(x_test[i][0])#Creation de liste avec labels pour test
#cv2.imshow('img', X_train[0])
X_train=np.array(X_train)
Y_train=np.array(Y_train)
model=model(X_train)
model.compile( loss ="sparse_categorical_crossentropy", optimizer ="sgd", metrics =["accuracy"])
model.fit(X_train, Y_train, epochs=5)
#print(model.predict(np.array(X_test)))

J’ai aussi changé les paramètres de la fonction compile comme vous pouvez le voir. Maintenant les prédictions ont des valeurs différentes mais elles sont toujours erronés, voici ce que j’obtiens:

array([[4.2631317e-02, 3.8927935e-02, 8.0633563e-01, ..., 3.0603724e-11,
        7.8799927e-09, 2.1536446e-10],
       [2.1030279e-01, 1.0317818e-01, 3.2497022e-01, ..., 2.2019420e-04,
        1.2553144e-03, 4.6314142e-04],
       [2.2856282e-02, 1.9324407e-01, 6.1313701e-01, ..., 7.9186678e-11,
        2.6644882e-08, 2.4350819e-10],
       ...,
       [5.0731137e-04, 3.8499318e-04, 5.8921760e-05, ..., 4.8456818e-01,
        1.1028121e-01, 8.6966529e-02],
       [6.5148342e-04, 5.7989303e-03, 2.7776934e-04, ..., 7.2158533e-01,
        3.3845440e-02, 3.9254509e-02],
       [1.6761942e-04, 1.0153319e-04, 6.3506432e-06, ..., 1.9193715e-01,
        1.4250539e-01, 9.1972582e-02]], dtype=float32)

Alors que mon Y_train n’est composé que d’entiers compris entre 0 et 11. Je vais essayer de comprendre pourquoi, je reviens vers vous dès que j’ai trouvé :)

Bonjour,

J’ai trouvé pourquoi mon résultat est le suivant:

En fait la variable retourné par la fonction fit fourni pour chaque prédiction un tableau avec le pourcentage de chance pour chaque labels. Si l’on veut obtenir seulement le label avec la plus grande chance qu’il soit correct il faut utiliser la fonction model.predict_classes.

Si quelqu’un souhaite utiliser mon code, je lui conseille d’augmenter le paramètre epochs dans model.fit parceque je l’avais baissé pour pouvoir débugger plus vite.

Je conseille aussi de mélanger les jeux de données d’entrainement et de test afin d’améliorer la précision du modèle. J’ai réussi à obtenir une précision de 75% avec ce code mais je pense que le résultat variera beaucoup en fonction du jeu de donné.

Merci encore à tous pour votre aide, je me permet de mettre le sujet en résolu en espérant qu’il pourra aider quelqu’un dans le futur :)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte