
Introduction to CNN
Convolutional neural networks (CNN) are primarily used to classify images or identify pattern similarities between them.
So a convolutional network receives a normal color image as a rectangular box whose width and height are measured by the number of pixels along those dimensions, and whose depth is three layers deep, one for each letter in RGB.
Also, read – Understanding a Neural Network
As images move through a convolutional network, different patterns are recognised just like a normal neural network.
But here rather than focussing on one pixel at a time, a convolutional net takes in square patches of pixels and passes them through a filter.
That filter is also a square matrix smaller than the image itself, and equal in size to the patch. It is also called a kernel.
Now lets start with importing the libraries
import numpy as np # linear algebra import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv) import cv2 import matplotlib.pyplot as plt import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Flatten, Dropout, Activation, Conv2D, MaxPooling2D
We need to train a model first so we will check training data In the below code we are iterating through all images in train folder and then we will split image name with deliminiter “.”
We have names like dog.0, dog.1, cat.2 etc.. Hence after splitting we are gonna get results like “dog’, “cat” as category value of the image. To make this example more easy we will consider dog as “1” and cat as “0”.
Now every image is actually a set of pixels so how to get our computer know that. Its simple convert all those pixels into an array.
So we are going to use here a cv2 library to read our image into an array and also it will read as a gray scale image.
train_dir = # your path to train dataset path = os.path.join(main_dir,train_dir) for p in os.listdir(path): category = p.split(".")[0] img_array = cv2.imread(os.path.join(path,p),cv2.IMREAD_GRAYSCALE) new_img_array = cv2.resize(img_array, dsize=(80, 80)) plt.imshow(new_img_array,cmap="gray") break
Okay so the above code was more for understanding purpose. Nowe we will get to the real part of coding here.
Declare your training array X and your target array y. Here X will be the array of pixels and y will be value 0 or 1 indicating its a dog or cat Write convert function to map category “dog” or “cat” into 1 and 0
Create a function create_test_data which takes all training images into a loop. Converts into image array. Resize image into 80 X80. Append image into X array. Append category value into y array.
X = [] y = [] convert = lambda category : int(category == 'dog') def create_test_data(path): for p in os.listdir(path): category = p.split(".")[0] category = convert(category) img_array = cv2.imread(os.path.join(path,p),cv2.IMREAD_GRAYSCALE) new_img_array = cv2.resize(img_array, dsize=(80, 80)) X.append(new_img_array) y.append(category)
Now call the function, but also later convert X and y into numpy array We also have to reshape X with the below code
create_test_data(path) X = np.array(X).reshape(-1, 80,80,1) y = np.array(y)
If you see the values of X you can see a variety of values between 0- 255 . Its because every pixel has different density of black and white. But with the wide range of values it becomes difficult for a training model to learn ( sometimes memorize ).
How to resolve this And you guessed it right . You can normalize the data. We can use Keras normalize here also . But well we already know all values are having range between 0-255 so we can just divide it by 255 and get all values scaled between 0 -1
That’s what we have done below. You can skip this step to see the difference between accuracy. Don’t believe everything I say. Experiment and see for yourself
#Normalize data X = X/255.0
Now Lets train our model
model = Sequential() # Adds a densely-connected layer with 64 units to the model: model.add(Conv2D(64,(3,3), activation = 'relu', input_shape = X.shape[1:])) model.add(MaxPooling2D(pool_size = (2,2))) # Add another: model.add(Conv2D(64,(3,3), activation = 'relu')) model.add(MaxPooling2D(pool_size = (2,2))) model.add(Flatten()) model.add(Dense(64, activation='relu')) # Add a softmax layer with 10 output units: model.add(Dense(1, activation='sigmoid')) model.compile(optimizer="adam", loss='binary_crossentropy', metrics=['accuracy'])
Now we will fit our model with training data.
Epochs :- How many times our model will go through data
Batch size :- How much amount of data at once you wanna pass through the model
validation_split :- How much amount of data (in this case its 20 %) you will need to check cross validation error
model.fit(X, y, epochs=10, batch_size=32, validation_split=0.2)
Train on 20000 samples, validate on 5000 samples Epoch 1/10 20000/20000 [==============================] - 16s 790us/step - loss: 0.6109 - acc: 0.6558 - val_loss: 0.5383 - val_acc: 0.7308 Epoch 2/10 20000/20000 [==============================] - 14s 679us/step - loss: 0.4989 - acc: 0.7557 - val_loss: 0.4989 - val_acc: 0.7564 Epoch 3/10 20000/20000 [==============================] - 14s 679us/step - loss: 0.4502 - acc: 0.7916 - val_loss: 0.4728 - val_acc: 0.7796 Epoch 4/10 20000/20000 [==============================] - 14s 680us/step - loss: 0.4059 - acc: 0.8143 - val_loss: 0.5290 - val_acc: 0.7644 Epoch 5/10 20000/20000 [==============================] - 14s 679us/step - loss: 0.3675 - acc: 0.8334 - val_loss: 0.4572 - val_acc: 0.7938 Epoch 6/10 20000/20000 [==============================] - 14s 679us/step - loss: 0.3181 - acc: 0.8610 - val_loss: 0.4744 - val_acc: 0.7958 Epoch 7/10 20000/20000 [==============================] - 14s 680us/step - loss: 0.2704 - acc: 0.8841 - val_loss: 0.4575 - val_acc: 0.7976 Epoch 8/10 20000/20000 [==============================] - 14s 681us/step - loss: 0.2155 - acc: 0.9104 - val_loss: 0.5198 - val_acc: 0.7878 Epoch 9/10 20000/20000 [==============================] - 14s 679us/step - loss: 0.1646 - acc: 0.9357 - val_loss: 0.6021 - val_acc: 0.7928 Epoch 10/10 20000/20000 [==============================] - 14s 680us/step - loss: 0.1227 - acc: 0.9532 - val_loss: 0.6653 - val_acc: 0.7874
Now the time has come to finally PREDICT, so feed your CNN model with test data to predict.
predictions = model.predict(X_test)
We are rounding the result here as we used sigmoid function and we got the probability values in our predicted data set
predicted_val = [int(round(p[0])) for p in predictions]
Now you have to make submission data frame to submit your result set.
submission_df = pd.DataFrame({'id':id_line, 'label':predicted_val})
Write your data frame to a csv file
submission_df.to_csv("submission.csv", index=False)
Also, read – 10 Machine Learning Projects to Boost your Portfolio
I hope this CNN model will help you, mention in comments on what topic you want the next article.