Coders Packet

Dogs vs Cats classifier in Python using TensorFlow

By Mirza Yusuf

A classifier that identifies dogs and cats in Python using TensorFlow, making layers from scratch

In this project we will make a dogs and cat identifier. Using TensorFlow which is a library in Python.

Since the dataset is moderately big we don't need to use transfer learning. We will be building models from scratch .

DATASET

The dataset we looking at already has divided the data into training and testing data so we don't need to worry about splitting it. Furthermore it around 5,000 images which is a moderate number when it comes to making a classifier. You can find the kaggle dataset here dogs & cats.

INSTALLING DEPENDENCIES

Before importing libraries we need to install the dependencies. 

pip install tensorflow
pip install numpy 
pip install pandas
pip install cv2

IMPORTING LIBRARIES

import tensorflow as tf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
from os import getcwd
from os import listdir
from matplotlib.image import imread
import cv2
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, MaxPooling2D, Dropout, Flatten
import random

SET PATH

Set path and along with that check if the path is working by printing out one image.

path = '../input/dogs-cats-images/dataset/training_set/cats/cat.1.jpg'
cath = cv2.imread(path)
plt.imshow(cath, cmap='binary', interpolation='nearest')

DATA PREPROCESSING 

Let's define a function that will preprocess the data as in resize the images and convert them to lists for easier conversion. Here we also convert the coloured images to grayscale so that identifying features becomes easier.

def preproces(path,path_test, label):
    train_image = []
    train_label = []
    test_image = []
    test_label = []
    for i in os.listdir(path):
        img = cv2.imread(path + '/' + i)
        res = cv2.resize(img, dsize=(128,128),interpolation=cv2.INTER_CUBIC) 
        gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY) # Converting to grayscale
        train_image.append(gray)
        train_label.append(label)
    for j in os.listdir(path_test):
        img2 = cv2.imread(path_test + '/' + j)
        res2 = cv2.resize(img, dsize = (128,128), interpolation = cv2.INTER_CUBIC)
        gray2 = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)
        test_image.append(gray2)
        test_label.append(label)
    return train_image, train_label, test_image, test_label

Now let's use the function to get both the images in a list and converge those lists together, keeping all training data for dogs and cats together and all test data along with both of their labels together. After that we need to convert it into a numpy array so that the data fits in the compiler.

train = []
test = []
trainlabel = []
testlabel = []
train_image, train_label, test_image, test_label = preproces('../input/dogs-cats-images/dataset/training_set/cats','../input/dogs-cats-images/dataset/test_set/cats', 0)
train.extend(train_image)
trainlabel.extend(train_label)
test.extend(test_image)
testlabel.extend(test_label)

#dogs 
train_image, train_label, test_image, test_label = preproces('../input/dogs-cats-images/dataset/training_set/dogs','../input/dogs-cats-images/dataset/test_set/dogs', 1)
train.extend(train_image)
trainlabel.extend(train_label)
test.extend(test_image)
testlabel.extend(test_label)

train = np.array(train)
trainlabel = np.array(trainlabel)
test = np.array(test)
testlabel = np.array(testlabel)

Reshaping and shuffling the data for better accuracy 

train = train.reshape(train.shape[0], 128,128,1).astype('float32')
test = test.reshape(test.shape[0], 128, 128, 1).astype('float32')
train = train/255.0
test = test/255.0

temp = list(zip(train,trainlabel))
random.shuffle(temp)
train_x,train_l = zip(*temp)
train_x = np.array(train_x)
train_l = np.array(train_l)

MODEL

Now we define the neural nets for this, in this model we will be using a series of Conv2D layers along with MaxPooling along with dropouts occasionaly to determine the proper features as both of them resemble each other closely.

model = Sequential()

model.add(Conv2D(16, (3,3), padding = 'same', activation = 'relu', input_shape = (128,128,1)))
model.add(Conv2D(16, (3,3), activation = 'relu'))
model.add(MaxPooling2D(pool_size= (2,2)))

model.add(Conv2D(32, (3,3), padding = 'same', activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Dropout(0.2))

model.add(Conv2D(64, (3,3), padding = 'same', activation = 'relu'))
model.add(Conv2D(64, (3,3), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(1024, activation = 'relu'))
model.add(Dense(512, activation = 'relu'))
model.add(Dropout(0.5))
model.add(Dense(128, activation = 'relu'))
model.add(Dense(64, activation = 'relu'))
model.add(Dense(1, activation = 'sigmoid'))

COMPILING AND FITTING

We will be using Adam optimizer for the code along with the binary crossentropy for loss as there are only 2 classifications to be done.

model.compile(optimizer = 'adam', loss ='binary_crossentropy', metrics =['accuracy'] )

Fit the model on the shuffled data

history = model.fit(train_x, train_l, epochs = 30, validation_data = (test, testlabel), verbose =1)

In 30 epochs we reach an accuracy of around 98% on training and 95% on testing which is a pretty good classification.

Download Complete Code

Comments

No comments yet