Basics of image classification with Keras | by John Olafenwa | Towards Data Science

In my previous post, I delved into some of the theoretical concepts underlying artificial neural networks. In this post, I would be explaining some common operations that you would frequently need in keras. First, how to save models and use them for prediction later, displaying images from the dataset and loading images from our system and predicting their class.
Fire up your IDE if you haven’t done so and read on.
SAVING MODELS
Training models is a very slow process, nobody want’s to do that every time, fortunately, we only need to train our model once, save it and then we can load it anytime and use it to predict new images.
Keras saves models in the .h5 format, so in case you skipped installing h5py in the first tutorial I posted, pleas run
pip3 install h5py
We would also need matplotlib to visualize our image, hence, run
pip3 install matplotlib
Here is the code for the first tutorial
import kerasfrom keras.datasets import mnistfrom keras.layers import Densefrom keras.models import Sequentialfrom keras.optimizers import SGD(train_x, train_y) , (test_x, test_y) = mnist.load_data()#train_x = train_x.astype('float32') / 255#test_x = test_x.astype('float32') / 255print(train_x.shape)print(train_y.shape)print(test_x.shape)print(test_y.shape)train_x = train_x.reshape(60000,784)test_x = test_x.reshape(10000,784)train_y = keras.utils.to_categorical(train_y,10)test_y = keras.utils.to_categorical(test_y,10)model = Sequential()model.add(Dense(units=128,activation="relu",input_shape=(784,)))model.add(Dense(units=128,activation="relu"))model.add(Dense(units=128,activation="relu"))model.add(Dense(units=10,activation="softmax"))model.compile(optimizer=SGD(0.001),loss="categorical_crossentropy",metrics=["accuracy"])model.fit(train_x,train_y,batch_size=32,epochs=10,verbose=1)accuracy = model.evaluate(x=test_x,y=test_y,batch_size=32)print("Accuracy: ",accuracy[1])
To save the model, simply add below after model.fit()
model.save("mnist-model.h5")
INFERENCE
Inference refers to the process of predicting new images using our model.
In your code, comment out the
model.fit
and instead replace with the following
model.load_weights("mnistmodel.h5")
Our code now looks like this
import kerasfrom keras.datasets import mnistfrom keras.layers import Densefrom keras.models import Sequentialfrom keras.optimizers import SGD(train_x, train_y) , (test_x, test_y) = mnist.load_data()#train_x = train_x.astype('float32') / 255#test_x = test_x.astype('float32') / 255print(train_x.shape)print(train_y.shape)print(test_x.shape)print(test_y.shape)train_x = train_x.reshape(60000,784)test_x = test_x.reshape(10000,784)train_y = keras.utils.to_categorical(train_y,10)test_y = keras.utils.to_categorical(test_y,10)model = Sequential()model.add(Dense(units=128,activation="relu",input_shape=(784,)))model.add(Dense(units=128,activation="relu"))model.add(Dense(units=128,activation="relu"))model.add(Dense(units=10,activation="softmax"))model.compile(optimizer=SGD(0.001),loss="categorical_crossentropy",metrics=["accuracy"])model.load_weights("mnist-model.h5")#model.fit(train_x,train_y,batch_size=32,epochs=10,verbose=1)#model.save("mnistmodel.h5")accuracy = model.evaluate(x=test_x,y=test_y,batch_size=32)print("Accuracy: ",accuracy[1])
What we did here is to load the parameters of the model from the saved model file and the evaluate function runs predictions over the test dataset and returns the accuracy of our prediction.
So far, I have demonstrated how to save models and use them later for prediction, however, this is all boring stuff, the real deal is being able to load a specific image and determine what class it belongs to.
The first step is to add the code below to get the prediction for a specific image from the test
img = test_x[130]test_img = img.reshape((1,784))img_class = model.predict_classes(test_img)prediction = img_class[0]classname = img_class[0]print("Class: ",classname)
Here we just pick a random image, in this case at index 130 from the test set, we create a flatten copy that is reshaped to
(1,784)
and we feed this copy into our model, next we obtain the prediction and print it out.
Comment out the model.evaluate in the code, add the above and run it.
Your output should be this:
Class: 6
Now that we have the prediction, we use matplotlib to display the image and its predicted class
img = img.reshape((28,28))plt.imshow(img)plt.title(classname)plt.show()
The reshape operation here is necessary to enable matplotlib display the image
Your updated code should all be like this
import kerasfrom keras.datasets import mnistfrom keras.layers import Densefrom keras.models import Sequentialfrom keras.optimizers import SGDimport matplotlib.pyplot as plt(train_x, train_y) , (test_x, test_y) = mnist.load_data()train_x = train_x.reshape(60000,784)test_x = test_x.reshape(10000,784)train_y = keras.utils.to_categorical(train_y,10)test_y = keras.utils.to_categorical(test_y,10)model = Sequential()model.add(Dense(units=128,activation="relu",input_shape=(784,)))model.add(Dense(units=128,activation="relu"))model.add(Dense(units=128,activation="relu"))model.add(Dense(units=10,activation="softmax"))model.compile(optimizer=SGD(0.001),loss="categorical_crossentropy",metrics=["accuracy"])model.load_weights("mnistmodel.h5")img = test_x[130]test_img = img.reshape((1,784))img_class = model.predict_classes(test_img)prediction = img_class[0]classname = img_class[0]print("Class: ",classname)img = img.reshape((28,28))plt.imshow(img)plt.title(classname)plt.show()
Run this and your output should be this
AND THAT’S IT! Absolutely simple, we have built a basic digit recognition system.
I encourage you to try different indexes of the test images and see for yourself, what the result would be.
But, what if we wanted to bring in an image not included in the test set, for this test, please save the image below to your system and copy it into the directory where your python file resides.
Run the code below
import kerasfrom keras.datasets import mnistfrom keras.layers import Densefrom keras.models import Sequentialfrom keras.optimizers import SGDimport matplotlib.pyplot as pltfrom keras.preprocessing import image(train_x, train_y) , (test_x, test_y) = mnist.load_data()train_x = train_x.reshape(60000,784)test_x = test_x.reshape(10000,784)train_y = keras.utils.to_categorical(train_y,10)test_y = keras.utils.to_categorical(test_y,10)model = Sequential()model.add(Dense(units=128,activation="relu",input_shape=(784,)))model.add(Dense(units=128,activation="relu"))model.add(Dense(units=128,activation="relu"))model.add(Dense(units=10,activation="softmax"))model.compile(optimizer=SGD(0.001),loss="categorical_crossentropy",metrics=["accuracy"])model.load_weights("mnistmodel.h5")img = image.load_img(path="testimage.png",grayscale=True,target_size=(28,28,1))img = image.img_to_array(img)test_img = img.reshape((1,784))img_class = model.predict_classes(test_img)prediction = img_class[0]classname = img_class[0]print("Class: ",classname)img = img.reshape((28,28))plt.imshow(img)plt.title(classname)plt.show()
You might notice a few new things here, first we imported image from keras.preprocessing
Next we added
img = image.load_img(path="testimage.png",grayscale=True,target_size=(28,28,1))img = image.img_to_array(img)
In the first line, we loaded the image from disk and specified that it should be resized to 28 x 28 x 1, remember that this is the dimension of the original mnist images, so its good we keep things constant.
Next we converted the image into an array of pixels, that’s all.
Run it and Check the result yourself, if the prediction would be 3 or not.
Any questions or comments should be left in the comment box below, you can also reach me on twitter via @johnolafenwa
If you love this tutorial, give some claps.
The next post would be on using Convolutional Neural Networks, which would push our accuracy to over 99%!!! Just keep in touch.