4

It works fine by testing mnist's own test images, but as soon as i use images from outside mnist, it predicts wrong. I even tried to copy one of the images from the mnist dataset, and it still could'nt predict the right digit (even though the exact same image was OK (predicted) when inside the mnist dataset).

Could someone see what i do wrong? I'm guessing there's something with the dimensions or shape of the 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())

I've tried pred = model.predict(image.reshape(1, 28, 28, 1)),

as well as pred = model.predict_classes(image.reshape(1, 28, 28, 1))

The digits i was predicting. Upper one from mnist dataset (predicted correctly) and one lower one copied and put in (predicted wrongly)

Filip Mellqvist
  • 113
  • 1
  • 6

3 Answers3

7

I figured it out. I didn't get the right normalized values out with this block of code.

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

Instead, I had to correct it with the division at the bottom (here at the bottom), which i mistakenly had put before the image = 255-image in earlier attempt. This was one of the fault, together with missing casting the type to float32 which made it possible to normalize, as well as the reshape there in between.

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
Filip Mellqvist
  • 113
  • 1
  • 6
0

Some guesses

1) You normalized your train and test data. I'm assuming you might have forgotten to normalize your input data before doing the prediction?

x_train /= 255
x_test /= 255

2) Have you verified that the model is loaded correctly? After saving and loading, verify that it still performs the same on the test set. If the results aren't good that tells you that the weights aren't being loaded properly.

3) Was there any pre-processing (outside your own normalization) to the dataset as provided by tf.keras.datasets.mnist.load_data()? If so, you'll have to pre-process your own input data with the same transformations prior to inference

IanQ
  • 1,831
  • 5
  • 20
  • 29
  • 2) The model is loaded the exact same way when tested on the mnist dataset (when getting correct prediction), so I don't think that the weights are loaded wrongly. 3) Not really sure. According to [this thread](https://stackoverflow.com/questions/46846502/how-to-change-the-format-of-the-return-value-of-mnist-load-data-to-mnist-tr?rq=1) the size is differing from the train to test samples. I don't know if it says something about being pre-processed in some way. – Filip Mellqvist Feb 04 '19 at 17:26
  • If you were to print some of the weights at the end of training, and after loading are they the same? – IanQ Feb 05 '19 at 21:30
0
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
David Buck
  • 3,752
  • 35
  • 31
  • 35