Cat or Dog — Image Classification with Convolutional Neural Network | by Andrej Baranovskij | Towards Data Science

The goal of this post is to show how convnet (CNN — Convolutional Neural Network) works. I will be using classical cat/dog classification example described in François Chollet book — Deep Learning with Python. Source code for this example is available on François Chollet GitHub. I’m using this source code to run my experiment.
Convnet works by abstracting image features from the detail to higher level elements. An analogy can be described with the way how humans think. Each of us knows how airplane looks, but most likely when thinking about airplane we are not thinking about every little bit of airplane structure. In a similar way, convnet learns to recognize higher level elements in the image and this helps to classify new images when they look similar to the ones used for the training.
Image classification model should be trained using this notebook (you will find a description there from where to download image dataset with cats and dogs images). Model is being used and classification prediction is invoked in this notebook. For the convenience, I uploaded my own notebooks (based on the code from Deep Learning with Python book) to GitHub.
I was running notebook in Jupyter Docker image, a path to image dataset should be updated (refer to code example in my GitHub repo), you should use Docker configured path as the root to fetch dataset images from the disk:
# The path to the directory where the original# dataset was uncompressedoriginal_dataset_dir = '/home/jovyan/work/study/python/dogs_vs_cats/train'# The directory where we will# store our smaller datasetbase_dir = '/home/jovyan/work/study/python/dogs_vs_cats_small'os.mkdir(base_dir)
Model is built using a subset of data:
1000 cats and 1000 dogs images for training500 cats and 500 dogs images for validation500 cats and 500 dogs images for testing
1000 cats and 1000 dogs images for training
500 cats and 500 dogs images for validation
500 cats and 500 dogs images for testing
First model training attempt is done directly using available images from the dataset. Convnet trains to identify cats vs dogs using Keras and TensorFlow backend. But overfitting happens during early iterations. This is the result of training executed by me — validation performance doesn’t improve, when training performance improves — Convnet adjusting according to training data and doesn’t perform as good with validation data:
To fight with overfitting, more training data is supplied by applying a data augmentation technique. Augmentation process allows generating more training data from existing data, by altering existing data. Random transformations are applied to adjust the existing image and create multiple images out of one (refer to the source from Deep Learning with Python book).
After data augmentation convnet trains better by far — validation quality stays very close to the training quality:
Image classification based on convnet model is done in endpoint notebook. A good practice is save trained model and later re-open it for classification task:
from keras.models import load_modelmodel = load_model('cats_and_dogs_small_2.h5')
I will be testing model with our dog images. Let’s see based on the model classification results how close our dog looks to be a dog :) (well, at least based on those 1000 dog pictures used for convnet training).
I will be using 11 pictures, all are uploaded to the GitHub repo along with Python notebooks. First picture:
Using the code from Deep Learning with Python book to transform the image into the format to be sent to model.predict function:
img_path = '/home/jovyan/work/study/python/dogs_vs_cats_small/test/dogs/dog.2000.jpg'# We preprocess the image into a 4D tensorfrom keras.preprocessing import imageimport numpy as npimg = image.load_img(img_path, target_size=(150, 150))img_tensor = image.img_to_array(img)img_tensor = np.expand_dims(img_tensor, axis=0)# Remember that the model was trained on inputs# that were preprocessed in the following way:img_tensor /= 255.# Its shape is (1, 150, 150, 3)print(img_tensor.shape)
It might be useful to display a transformed image of 150x150 pixels:
import matplotlib.pyplot as pltplt.imshow(img_tensor[0])plt.show()
Classification result: 58% a dog. I think this is a good result, anything more than 50% is good for a dog, less than 50% => a cat look.
prediction = model.predict(img_tensor)print(prediction)[[ 0.5823279]]
We repeat the same steps (calling model.predict function) with more pictures.
Dog: 53% (GOOD)
Dog: 53% (GOOD)
Cat: 43% (BAD). From this picture, convnet wasn’t able to tell this is a dog. Well — makes sense, maybe it really looks more like a cat in that pic.
Dog: 88% (VERY GOOD). Besides various distracting colors, convnet was able to clearly identify the dog here. It seems like if dog face is displayed more clear — for convnet is easier to identify a dog.
Dog: 55% (GOOD)
Dog: 100% (EXCELLENT).
Dog: 89% (VERY GOOD). Even there is a black background, classification works very well.
Cat: 19% (VERY BAD). In this picture, it seems like our dog looks more like a cat.
Dog: 51% (GOOD)
Dog: 74% (VERY GOOD). Slightly different angle (face is more clear) from the previous picture makes the result way better.
Summary: convnet was trained on a small dataset and still it can offer fantastic classification results (verified with my dog pictures :)