Creating Convolutional Neural Network From Scratch | by Himanshu Sharma | Towards Data Science

Image classification basically helps us in classifying images into different labels. It is like bucketing different images into the bucket they belong to. For, e.g. a model trained to identify the image of a cat and a dog will help in segregating different images of cats and dogs respectively. There are multiple deep learning frameworks like Tensorflow, Keras, Theano, etc that can be used to create image classification models. Today we will create an image classification model from scratch using Keras and Tensorflow.
For creating image-related modeling can be done using CNN. Convolutional Neural Networks are mainly used for image-related modeling. It is one of the easiest ways to perform image classification, image detection, image segmentation, etc. It contains different types of convolutional layers that help in filtering out the most important features of the image using kernels of different sizes. Some of the most important layers are:
Conv2D
Conv2D
It is used to create a Convolutional kernel that is convolved with the input layer to produce the output tensor.
2. MaxPooling2D
It is a downsampling technique that takes the maximum value by pool size.
3. Flatten
It flattens the input and creates an1-D output.
There are multiple hyper-parameters that can be used accordingly to improve the model performance. These hyper-parameters may include a number of neurons, kernel size, pool size, activation function, etc.
In this article, we will create a network using CNN from scratch. I will show you how you can load data from online sources, preprocess that data and make it ready for modeling, and finally design the model architecture.
Let’s get started...
We will start by installing all required libraries. We will install Keras, TensorFlow and will also install TensorBay(SDK on Graviti data platform) that we will use for loading the dataset. The command given below will do that.
!pip install tensorflow!pip install tensorbay!pip install keras
In this step, we will import all the required libraries and functions to load the data, preprocess it and create the model.
# Library importsfrom tensorbay import GASfrom PIL import Imageimport matplotlib.pyplot as pltfrom tensorbay.dataset import Data, Datasetimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom matplotlib.image import imreadimport cv2import randomfrom os import listdirfrom sklearn.preprocessing import LabelBinarizerfrom keras.preprocessing import imagefrom keras.preprocessing.image import img_to_array, array_to_imgfrom tensorflow.keras.optimizers import Adamfrom keras.models import Sequentialfrom keras.layers import Conv2D, MaxPooling2D, Activation, Flatten, Dropout, Densefrom sklearn.model_selection import train_test_split
This is the initial step, where we will load the data from TensorBay. In order to download a dataset from TensorBay, we need to create an account and fork a dataset on which we want to work, it contains a large variety of image datasets. For loading the dataset in our Jupyter notebook we need to have the access key to TensorBay that we can download from developer tools in our account.
gas = GAS("<Your Key>")dataset = Dataset("Flower17–1", gas)segment = dataset[1]
For this article, I am using the Flower 17 Dataset, as you can see I have loaded it above using TensorBay.
In this step, we will preprocess the data and make it ready for modelling. We will start by creating the image and labels list and loading data into it.
image_list, label_list = [], []for data in segment:with data.open() as fp:image_list.append(img_to_array(Image.open(fp).resize((500, 500))))label_list.append(data.label.classification.category)
Next, let us visualize the number of classes that we have in this dataset.
# Visualize the number of classes countlabel_counts = pd.DataFrame(label_list).value_counts()label_counts
Next, we will split the dataset, normalize it and also binarize the labels.
# Splitting datasetx_train, x_test, y_train, y_test = train_test_split(image_list, label_list, test_size=0.2, random_state = 10)# Normalize and reshape datax_train = np.array(x_train, dtype=np.float16) / 225.0x_train = x_train.reshape( -1,500,500,3)x_test = np.array(x_test, dtype=np.float16) / 225.0x_test = x_test.reshape( -1,500,500,3)# Label binarizinglb = LabelBinarizer()y_train = lb.fit_transform(y_train)y_test = lb.fit_transform(y_test)print(lb.classes_)
This is the final step, where we will create the model architecture, compile the model and train it. Before creating the model architecture, let’s split the training data into train and validation.
# Splitting the training data set into training and validation data setsx_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size = 0.2)# Building model architecturemodel = Sequential()model.add(Conv2D(8, (3, 3), padding="same",input_shape=(500,500,3), activation="relu"))model.add(MaxPooling2D(pool_size=(3, 3)))model.add(Conv2D(16, (3, 3), padding="same", 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(Flatten())model.add(Dense(32, activation="relu"))model.add(Dense(num_classes, activation="softmax"))model.summary()
# Compiling modelmodel.compile(loss = 'categorical_crossentropy', optimizer = Adam(0.0005),metrics=['accuracy'])# Training the modelepochs = 20batch_size = 128history = model.fit(x_train, y_train, batch_size = batch_size, epochs = epochs, validation_data = (x_val, y_val))
As you can see above we have created and trained the model using some hyper-parameters, model accuracy is not that good but you can always tune the hyper-parameters to increase the performance. We can also save the model by using the command given below.
# Saving modelmodel.save("/content/flower_species.h5")Let's visualize the model training and loss history.#Plot the training historyplt.figure(figsize=(12, 5))plt.plot(history.history['accuracy'], color='r')plt.plot(history.history['val_accuracy'], color='b')plt.title('Model Accuracy')plt.ylabel('Accuracy')plt.xlabel('Epochs')plt.legend(['train', 'val'])plt.show()
#Plot the loss historyplt.figure(figsize=(12, 5))plt.plot(history.history['loss'], color='r')plt.plot(history.history['val_loss'], color='b')plt.title('Model Loss')plt.ylabel('Loss')plt.xlabel('Epochs')plt.legend(['train', 'val'])plt.show()
In the end, let us also create some predictions using the model.
# Storing predictionsy_pred = model.predict(x_test)Let's verify one of the predictions.# Plotting image to compareimg = array_to_img(x_test[4])img
# Finding max value from prediction list and comparing original value vs predictedlabels = lb.classes_print(labels)print("Originally : ",labels[np.argmax(y_test[4])])print("Predicted : ",labels[np.argmax(y_pred[4])])
Go ahead, try this with different datasets and create CNN models easily by following this article. In case you find any difficulty please let me know in the response section.
Thanks for reading! If you want to get in touch with me, feel free to reach me at hmix13@gmail.com or my LinkedIn Profile. You can view my Github profile for different data science projects and packages tutorials. Also, feel free to explore my profile and read different articles I have written related to Data Science.