Basics of image classification with Keras

John Olafenwa
Towards Data Science
5 min readJan 19, 2018

--

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 keras
from keras.datasets import mnist
from keras.layers import Dense
from keras.models import Sequential
from 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') / 255
print(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 keras
from keras.datasets import mnist
from keras.layers import Dense
from keras.models import Sequential
from 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') / 255
print(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 keras
from keras.datasets import mnist
from keras.layers import Dense
from keras.models import Sequential
from keras.optimizers import SGD
import 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 keras
from keras.datasets import mnist
from keras.layers import Dense
from keras.models import Sequential
from keras.optimizers import SGD
import matplotlib.pyplot as plt
from 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.

--

--