Using python AI mnist to recognize my picture, trained accuracy is 97.99%, but accuracy to my img is less than 20%
I'm hoping can use MNIST doing 0~9 number recognition, and trainning accuracy rate reach up to 97% , I thought it will be fine to reconize my pic
but predict/recognize my 2 picture as number 7
predict/recognize my 3 picture as number 6
predict/recognize my 5 picture as number 2
here is the share pic link : https://imgur.com/a/yDJ8ujc
import keras
from keras.datasets import mnist
import matplotlib.pyplot as plt
import PIL
from PIL import Image
(train_images,train_labels),(test_images,test_labels) = mnist.load_data()
train_images.shape
len(train_labels)
train_labels
test_images.shape
len(test_labels)
test_labels
from keras import models
from keras import layers
network = models.Sequential()
network.add(layers.Dense(512,activation='relu',input_shape=(28*28,)))
network.add(layers.Dense(10,activation='softmax'))
network.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
train_images = train_images.reshape((60000,28*28))
train_images = train_images.astype('float32')/255
test_images = test_images.reshape((10000,28*28))
test_images = test_images.astype('float32')/255
from keras.utils import to_categorical
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
network.fit(train_images,train_labels,epochs= 3 ,batch_size=128)
test_loss , test_acc = network.evaluate(test_images,test_labels)
print('test_acc:',test_acc)
network.save('m_lenet.h5')
#########
import numpy as np
from keras.models import load_model
import matplotlib.pyplot as plt
from PIL import Image
model = load_model('/content/m_lenet.h5')
picPath = '/content/02_a.png'
img = Image.open(picPath)
reIm = img.resize((28,28),Image.ANTIALIAS)
plt.imshow(reIm)
plt.savefig('/content/result.png')
im1 = np.array(reIm.convert("L"))
im1 = im1.reshape((1,28*28))
im1 = im1.astype('float32')/255
# predict = model.predict_classes(im1)
predict_x=model.predict(im1)
classes_x=np.argmax(predict_x,axis=1)
print ("---------------------------------")
print ('predict as:')
print (predict_x)
print ("")
print ("")
print ('predict number as:')
print (classes_x)
print ("---------------------------------")
print ("Original img : ")
what should I do for this?
- should I also import my img with ans for AI to trainning?
- add more layers?
that all the idea I came up, if there is more, just let me know? If that the only two idea to slove, also tell me how to implement (ex:import my img with ans for AI to trainning)
tried code suggested by expert:
use data augmentation in dataset in Keras with ImageDataGenerator
import keras
from keras.datasets import mnist
import matplotlib.pyplot as plt
import PIL
from PIL import Image
(train_images,train_labels),(test_images,test_labels) = mnist.load_data()
train_images.shape
len(train_labels)
train_labels
test_images.shape
len(test_labels)
test_labels
from keras import models
from keras import layers
network = models.Sequential()
network.add(layers.Dense(512,activation='relu',input_shape=(28*28,)))
network.add(layers.Dense(10,activation='softmax'))
network.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
train_images = train_images.reshape((60000,28*28))
train_images = train_images.astype('float32')/255
test_images = test_images.reshape((10000,28*28))
test_images = test_images.astype('float32')/255
from keras.utils import to_categorical
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
network.fit(train_images,train_labels,epochs= 3 ,batch_size=128)
# Here is image data augmentation example:
from tensorflow.keras.preprocessing.image import ImageDataGenerator
data_generator = ImageDataGenerator(rotation_range=10,
width_shift_range=8,
height_shift_range=8,
brightness_range=[0.6,1.1],
zoom_range=.15,
validation_split=.2,
rescale=1./255)
train_dataset = data_generator.flow(train_images, train_labels, batch_size=32, subset='training')
validation_dataset = data_generator.flow(train_images, train_labels, batch_size=32, subset='validation')
# Now it's time to train model with augmented dataset
network.fit(train_dataset, validation_data=validation_dataset, epochs=30)
test_loss , test_acc = network.evaluate(test_images,test_labels)
print('test_acc:',test_acc)
network.save('m_lenet.h5')
#########
import numpy as np
from keras.models import load_model
import matplotlib.pyplot as plt
from PIL import Image
model = load_model('/content/m_lenet.h5')
picPath = '/content/02_a.png'
img = Image.open(picPath)
reIm = img.resize((28,28),Image.ANTIALIAS)
plt.imshow(reIm)
plt.savefig('/content/result.png')
im1 = np.array(reIm.convert("L"))
im1 = im1.reshape((1,28*28))
im1 = im1.astype('float32')/255
# predict = model.predict_classes(im1)
predict_x=model.predict(im1)
classes_x=np.argmax(predict_x,axis=1)
print ("---------------------------------")
print ('predict as:')
print (predict_x)
print ("")
print ("")
print ('predict number as:')
print (classes_x)
print ("---------------------------------")
print ("Original img : ")
output:
Epoch 1/3
469/469 [==============================] - 10s 15ms/step - loss: 0.2555 - accuracy: 0.9268
Epoch 2/3
469/469 [==============================] - 5s 10ms/step - loss: 0.1023 - accuracy: 0.9695
Epoch 3/3
469/469 [==============================] - 5s 10ms/step - loss: 0.0678 - accuracy: 0.9796
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-11-476f532516e9> in <module>
51 rescale=1./255)
52
---> 53 train_dataset = data_generator.flow(train_images, train_labels, batch_size=32, subset='training')
54 validation_dataset = data_generator.flow(train_images, train_labels, batch_size=32, subset='validation')
55
1 frames
/usr/local/lib/python3.7/dist-packages/keras/preprocessing/image.py in __init__(self, x, y, image_data_generator, batch_size, shuffle, sample_weight, seed, data_format, save_to_dir, save_prefix, save_format, subset, ignore_class_split, dtype)
675 'Input data in `NumpyArrayIterator` '
676 'should have rank 4. You passed an array '
--> 677 'with shape', self.x.shape)
678 channels_axis = 3 if data_format == 'channels_last' else 1
679 if self.x.shape[channels_axis] not in {1, 3, 4}:
ValueError: ('Input data in `NumpyArrayIterator` should have rank 4. You passed an array with shape', (48000, 784))
CodePudding user response:
As Dr. Snoopy mentioned, MNIST is an academic dataset, the handwritten numbers are in the same size, and all of them are in the center of the image, but we know in the real world this rarely happens. I think the best thing you should do is use data augmentation
.
With data augmentation, you can train the model with images with different zooms, different brightness and move numbers in different directions, in this situation the model does not get used to a specific zoom, brightness, and location of numbers, and it has more chance to work properly in the real world.
You can simply use data augmentation in your image dataset in Keras with ImageDataGenerator
. Here is a very simple code that might help you:
# Here is image data augmentation example:
from tensorflow.keras.preprocessing.image import ImageDataGenerator
data_generator = ImageDataGenerator(rotation_range=10,
width_shift_range=8,
height_shift_range=8,
brightness_range=[0.6,1.1],
zoom_range=.15,
validation_split=.2,
rescale=1./255)
train_dataset = data_generator.flow(train_images, train_labels, batch_size=32, subset='training')
validation_dataset = data_generator.flow(train_images, train_labels, batch_size=32, subset='validation')
# Now it's time to train model with augmented dataset
network.fit(train_dataset, validation_data=validation_dataset, epochs=10)
CodePudding user response:
The MNIST dataset is white digit on black background whereas you have provided a black digit on a white background which inverts everything.