4
votes

Keras + mnist + tester ses propres images. Mauvaise prédiction

Cela fonctionne bien en testant les propres images de test de mnist, mais dès que j'utilise des images provenant de l'extérieur de mnist, il prédit mal. J'ai même essayé de copier l'une des images de l'ensemble de données mnist, et il ne pouvait toujours pas prédire le bon chiffre (même si la même image était correcte (prédite) à l'intérieur de l'ensemble de données mnist).

Quelqu'un pourrait-il voir quoi je fais mal? Je suppose qu'il y a quelque chose avec les dimensions ou la forme de l'image.

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense, Conv2D, Dropout, Flatten, MaxPooling2D
import cv2 as cv

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
input_shape = (28, 28, 1)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
# Normalizing the RGB codes by dividing it to the max RGB value.
x_train /= 255
x_test /= 255

# -------------------------- CREATE MODEL ------------------------------
'''
model = Sequential()
model.add(Conv2D(28, kernel_size=(3,3), input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten()) # Flattening the 2D arrays for fully connected layers
model.add(Dense(128, activation=tf.nn.relu))
model.add(Dropout(0.2))
model.add(Dense(10,activation=tf.nn.softmax))

# ----------------------------------------------------------------------

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
model.fit(x=x_train,y=y_train, epochs=1)

# ----------------------------------------------------------------------
'''
model = tf.keras.models.load_model("C:/Users/A551110/PycharmProjects/keras_mnist/venv/mnistv2.model")
file = "C:/Users/A551110/Documents/images/7.png"
model.evaluate(x_test, y_test)

image = cv.imread(file, cv.IMREAD_GRAYSCALE)
image = cv.resize(image, (28,28))
image = 255-image          #inverts image. Always gets read inverted.

plt.imshow(image.reshape(28, 28),cmap='Greys')
plt.show()
pred = model.predict(image.reshape(1, 28, 28, 1), batch_size=1)

print(pred.argmax())

J'ai essayé pred = model.predict (image.reshape (1, 28 , 28, 1)) ,

ainsi que pred = model.predict_classes (image.reshape (1, 28, 28, 1)) p >

Les chiffres que je prédisais. Un supérieur de l'ensemble de données mnist (prédit correctement) et un inférieur copié et inséré (prédit à tort)


0 commentaires

3 Réponses :


0
votes

Quelques suppositions

1) Vous avez normalisé vos données de train et de test. Je suppose que vous avez peut-être oublié de normaliser vos données d'entrée avant de faire la prédiction?

x_train /= 255
x_test /= 255

2) Avez-vous vérifié que le modèle est chargé correctement? Après l'enregistrement et le chargement, vérifiez qu'il fonctionne toujours de la même manière sur l'ensemble de test. Si les résultats ne sont pas bons, cela vous indique que les poids ne sont pas chargés correctement.

3) Y a-t-il eu un prétraitement (en dehors de votre propre normalisation) de l'ensemble de données fourni par tf.keras.datasets.mnist.load_data () ? Si tel est le cas, vous devrez prétraiter vos propres données d'entrée avec les mêmes transformations avant l'inférence


2 commentaires

2) Le modèle est chargé exactement de la même manière lorsqu'il est testé sur l'ensemble de données mnist (lors de l'obtention d'une prédiction correcte), donc je ne pense pas que les poids sont mal chargés. 3) Pas vraiment sûr. Selon ce fil la taille diffère de celle du train pour tester les échantillons. Je ne sais pas si cela en dit long sur le prétraitement.


Si vous deviez imprimer certains poids à la fin de la formation et après le chargement, sont-ils les mêmes?



6
votes

Je l'ai compris. Je n'ai pas obtenu les bonnes valeurs normalisées avec ce bloc de code.

image = cv.imread(file, cv.IMREAD_GRAYSCALE)
image = cv.resize(file, (28, 28))
image = image.astype('float32')
image = image.reshape(1, 28, 28, 1)
image = 255-image
image /= 255

Au lieu de cela, j'ai dû le corriger avec la division en bas (ici en bas), ce que j'ai par erreur avait mis avant l ' image = 255-image lors d'une tentative antérieure. C'était l'un des défauts, ainsi que l'absence de conversion du type en float32 qui permettait de normaliser, ainsi que le remodelage entre les deux.

image = cv.imread(file, cv.IMREAD_GRAYSCALE)
image = cv.resize(image, (28,28))
image = 255-image     


0 commentaires

0
votes
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np

y=cv2.imread("/content/download.png")   #image outside mnist data
y1=cv2.resize(y,(28,28))                #you need to resize it on the bsis pf your  modeL's image shape
plt.imshow(y1)

temp = cv2.cvtColor(y1,cv2.COLOR_BGR2YCrCb)  #since its a three channel image i hav econverted into this so rbg are represented in the luminance one 
temp=255-temp                                #negative image
plt.imshow(temp)

print(temp.shape)

Y = np.zeros((temp.shape[0], temp.shape[1],1), dtype=float)    #array of (28,28,1)
Y[:,:,0] = temp[:, :,0].astype(float) / 255           #fitting the data of temp image in that zeros and normalizing it
yh= model.predict_classes(Y.reshape(1,28,28,1))       #finally the value of image
yh

0 commentaires