In this article, you learn how to build your deep learning model to predict whether someone Covid-19 patient or not.
Keep reading 🔥
What Is Covid-19
Covid-19 is a Third World War-💥type disease anybody knows our world.
First identified this virus in Wuhan China has been named coronavirus disease 19 (Covid-19).
Covid-19 is the disease cause by SARS-Conv-2. Why does this Disease care about me? Because it’s one of the diseases that come from the earth huge of people die every day. also fastly decreases every country’s economy. At this time no one to move outside of the home. That is a very turf moment to see everyone.😭
What Problem Solves This Deep Learning Model
In this notebook, you build a neural network model, to see a person’s heart x-ray image and predict to these three classes Covid-19, Viral Pneumonia, and normal. These three classes define what condition of the person.
Note 🔥: If you follow this article make sure you can use GPU.
!nividia-smi
Above see I am using Tesla T4 GPU. And now download my halper function.
Download My Halper Function File To Your NoteBook
# download halper function file and import some function
!wget https://raw.githubusercontent.com/hi-sushanta/course_project/main/halper_function.py
Download Dataset
Now see what dataset to use in this notebook. This dataset is available on the Kaggle website and for everyone to use. The data set under a total of 317 images have and two categories one is training images and another is testing images. Each of these categories also has 3 categories names is Covid, Normal, and Viral Pneumonia.
Download Process : 🔥
Go to the actual data set page, link here!
Click the Download Button.
(Optional) if you using Google Colab then upload this data set to Google drive.
After you download the dataset now move on to writing a code. 👩💻
Import Important Libary
# import the most important library required in this notebook
import tensorflow as tf
from tensorflow.keras import layers , Sequential
from tensorflow import keras
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.layers import Dense,GlobalAveragePooling2D, Conv2D, MaxPooling2D, Flatten, Dense,Input,Dropout
import pathlib
import numpy as np
from halper_function import walk_through_dir
import cv2
import os
import re
from sklearn.preprocessing import OneHotEncoder
import matplotlib.pyplot as plt
Load Data And Preprocess
If you complete the above step then go on to see how to load images and preprocess them.
Set up training and testing dataset path. 🤖
Store training and testing directory path in a different variable.
# set up directory path
train_covid_19_dir = "drive/MyDrive/Covid19-dataset/train/"
test_covid_19_dir = "drive/MyDrive/Covid19-dataset/test/"
See How Many Images Have Each Directory
In that step to complete my halper function name is walk_through_dir( )
. This function input a path of the dataset and display how many directories, image, and path of the directory.
# let's see how many image have each directory
walk_through_dir("drive/MyDrive/Covid19-dataset")
Get The Class Name Programmatically
What is mean to Get class programmatically?
It means writing code and that code act to get all class names automatically in the file manager.
# Get the class names programmatically, this is much more helpful with a longer list of classes
# Convert training path to Python path
train_data_dir = pathlib.Path(train_covid_19_dir)
# Convert testing path to python path
test_data_dir = pathlib.Path(test_covid_19_dir)
# created a list of class_names from the subdirectories
class_names = np.array(sorted([item.name for item in train_data_dir.glob('*')]))
print(class_names)
# OUTPUT >>> ['Covid' 'Normal' 'Viral Pneumonia']
Create A Function To Return All Image And Label
In this section, you write one function and then preprocessing part is complete! Such as resizing all images and reading BGR color space.
img_size = 244
def get_image_from_directory(data_dir):
"""
data_dir: input a path of the dataset
return : image and label list format
"""
# two empty list create
image_bgr = []
label = []
for file in data_dir.glob("*"):
for image in file.glob("*"):
if re.search(r"(Normal)",str(image)):
_image = cv2.imread(str(image))
if not _image is None: # check to see image is not empty
label.append("Noraml")
resize_image = cv2.resize(_image, (img_size, img_size),interpolation = cv2.INTER_NEAREST)
image_bgr.append(resize_image)
elif re.search(r"Viral Pneumonia",str(image)):
_image = cv2.imread(str(image))
if not _image is None: # check to see image is not empty
label.append("Viral Pneumonia")
resize_image = cv2.resize(_image, (img_size, img_size),interpolation = cv2.INTER_NEAREST)
image_bgr.append(resize_image)
elif re.search(r"Covid",str(image)):
_image = cv2.imread(str(image))
if not _image is None: # check to see image is not empty
label.append("Covid")
resize_image = cv2.resize(_image, (img_size, img_size),interpolation = cv2.INTER_NEAREST)
image_bgr.append(resize_image)
return image_bgr,label
Above function is ready, now input the path of the dataset and get the image and label.
train_image_bgr,train_label = get_image_from_directory(train_data_dir)
test_image_bgr,test_label = get_image_from_directory(test_data_dir)
Check the shape of the images!
print(np.array(train_image_bgr[0]).shape)
print(np.array(test_image_bgr[0]).shape)
# OUTPUT >>> (244, 244, 3)
# (244, 244, 3)
Also check how many unique labels have.
print(np.unique(train_label))
print(np.unique(test_label))
# OUPUT >>> ['Covid' 'Noraml' 'Viral Pneumonia']
# ['Covid' 'Noraml' 'Viral Pneumonia']
Convert Vector to Matrix
The One-Hot-Encoding method accepts a matrix-type array, not a vector. But my label is stored as a vector array. So first, convert the vector to a matrix just simply using the TensorFlow expand_dims( )
function to complete this task.
train_label = tf.expand_dims(train_label,axis=1)
test_label = tf.expand_dims(test_label,axis=1)
print(train_label.shape)
print(test_label.shape)
# OUTPUT >>> (251, 1)
# (66, 1)
Convert String To One-Hot-Encoding Label
Everything working perfectly, and now convert the object type label to one-hot-encoding format. Why because the machine doesn’t understand object-type data they only understand 0 and 1.
At this time I am using Scikit-Learn One_Hot_Encoding( )
function to complete this task.
from sklearn.preprocessing import OneHotEncoder
def one_hot_label(label):
label_one_hot = OneHotEncoder(sparse=False)
train_label_one_hot = label_one_hot.fit_transform(label)
return train_label_one_hot
train_label_one_hot = one_hot_label(train_label)
test_label_one_hot = one_hot_label(test_label)
See what data look like after converting One-Hot-Encoding.
train_label_one_hot[:10]
Convert Image Dataset Label To TensorFlow Prefetch Dataset
At this time image and label are ready, now convert to TensorFlow data. Why using it this dataset? because it can perform the shuffling and batching of samples efficiently. It’s most useful for large data and small datasets. It’s also model train fast as possible.
train_dataset = tf.data.Dataset.from_tensor_slices((np.array(train_image_bgr),train_label_one_hot)).batch(32).shuffle(100).prefetch(tf.data.AUTOTUNE)
test_dataset = tf.data.Dataset.from_tensor_slices((test_image_bgr,test_label_one_hot)).batch(32).prefetch(tf.data.AUTOTUNE)
train_dataset
# OUTPUT >>> <PrefetchDataset element_spec=(TensorSpec(shape=(None, 244, 244, 3), dtype=tf.uint8, name=None),
# TensorSpec(shape=(None, 3), dtype=tf.float64, name=None))>
Build Deep Learning Model
In this section, I am building a deep neural network to solve this problem. This time I am using functional programming way to build the TensorFlow model. See down below code.
# Create a model
model = Sequential()
model.add(Input(shape=[img_size,img_size,3]))
model.add(Conv2D(128, kernel_size =(3, 3), strides =(1, 1),
activation ='relu'))
model.add(MaxPooling2D(pool_size =(2, 2), strides =(2, 2)))
model.add(Conv2D(64, (5, 5), activation ='relu'))
model.add(MaxPooling2D(pool_size =(2, 2)))
model.add(Flatten())
model.add(Dense(1000, activation ='relu'))
model.add(Dropout(0.2))
model.add(Dense(len(class_names), activation ='softmax'))
Model is ready now compile them and display the summary.🤗
model.compile(loss=tf.keras.losses.CategoricalCrossentropy(),
optimizer=tf.keras.optimizers.Adam(),
metrics=['accuracy'])
model.summary()
My model is complete and now training our model.
Keep reading 🔥
tf.random.set_seed(42)
history = model.fit(train_dataset,
epochs = 10,
validation_data=test_dataset,
verbose = 1,
callbacks=[tf.keras.callbacks.ModelCheckpoint(filepath="Deep_Neural_Network",save_best_only=True)])
Evaluate Model Performance.
Training is complete, it’s time to see how much accuracy is returned only testing dataset.
model.evaluate(test_dataset)
# OUTPUT >>> [1.387477993965149, 0.7878788113594055]
If you see my model accuracy up to 70% that is not bad. Now move on to Transfer Learning a simple way to extend model accuracy.
Use Transfer-Learning Improve Model Accuracy
In this section, I use a pre-trained model and also add some layers.
base_model = VGG16(weights='imagenet', include_top=False,
input_shape=(img_size, img_size,3))
# freeze extraction layers
base_model.trainable = False
# add custom top layers
x = base_model.output
# x = GlobalAveragePooling2D()(x)
x = Conv2D(128, kernel_size =(3, 3), strides =(1, 1),
activation ='relu',input_shape=[img_size,img_size,3])(x)
x = MaxPooling2D(pool_size =(2, 2), strides =(2, 2))(x)
x = Conv2D(64, (5, 5), activation ='relu',padding='same')(x)
x = MaxPooling2D(pool_size =(2, 2))(x)
x = Flatten()(x)
x = Dense(1000, activation ='relu')(x)
x = Dropout(0.2)(x)
predictions = Dense(len(class_names), activation='softmax')(x)
model = keras.Model(inputs=base_model.input, outputs=predictions)
# confirm unfrozen layers
for layer in model.layers:
if layer.trainable==True:
print(layer)
The model is ready and now compile them.
$$🤖$$
opt = keras.optimizers.Adam(learning_rate=0.001)
model.compile(
loss='categorical_crossentropy',
optimizer=opt,
metrics=['accuracy']
)
After compile is done now it’s time to train the model.
tf.random.set_seed(42)
history = model.fit(train_dataset,
epochs = 10,
validation_data=test_dataset,
verbose = 1,
callbacks=[tf.keras.callbacks.ModelCheckpoint(filepath="Transfer_Learning",save_best_only=True)])
Load The Best Model And Evaluate Them
If you notice training time some overfitting shows but our model accuracy improves. Now it’s time to evaluate the best model save ModelCheckpoint callback.
# load best model
model = tf.keras.models.load_model("Transfer_Learning_Model")
model.evaluate(test_dataset)
''' OUTPUT >>> 3/3 [==============================] - 1s 96ms/step
- loss: 0.2298 - accuracy: 0.9242
[0.22979137301445007, 0.9242424368858337]
'''
Model accuracy shows up to 90%. That is a very exciting moment. 😀
Create A Function To Predict And Display the Image
In this section, I create one helper function to work on Reading images, Resize_image, Model prediction, Getting prediction labels, and Displaying images with labels!
# Make a function to predict on images and plot them (works with multi-class)
def pred_and_plot(model, filename, class_names):
"""
model : input as actual neural network model.
filename : It's a input as image path but list under.
class_names : It's a input as class names type of list
"""
for i in range(len(filename)):
img = cv2.imread(filename[i])
img = cv2.resize(img, (img_size, img_size),interpolation = cv2.INTER_NEAREST)
# Make a prediction
pred = model.predict(tf.expand_dims(img, axis=0),verbose=False)
# Get the predicted class
if len(pred[0]) > 1: # check for multi-class
pred_class = class_names[pred.argmax()] # if more than one output, take the max
else:
pred_class = class_names[int(tf.round(pred)[0][0])] # if only one output, round
# Plot the image and predicted class
fig = plt.figure(figsize=(8,8))
fig.add_subplot(2,2,1);plt.imshow(img);plt.title(f"Prediction: {pred_class}");plt.axis(False);
See Our Model Prediction
It’s time I use 3 images as an example and see what our model prediction is.
img_path = ["/content/drive/MyDrive/Covid19-dataset/test/Covid/0105.png",
"/content/drive/MyDrive/Covid19-dataset/test/Viral Pneumonia/0119.jpeg",
"/content/drive/MyDrive/Covid19-dataset/test/Normal/0120.jpeg"]
pred_and_plot(model,filename=img_path,class_names=class_names,)
Above all the image model predict the right label. Now check out how to save the model in the file manager.
Save And Load .h5 Model
# This input as path include file extension
model.save("/content/drive/MyDrive/Covid_19_Predict_model-master/covid_detect/Covid_Predict.h5")
Load the best model in previously saved.
# It's input as a model file path
load_model = tf.keras.models.load_model("/content/drive/MyDrive/Covid_19_Predict_model-master/covid_detect/Covid_Predict.h5")
Once more time to see some prediction examples.
$$🤖$$
pred_and_plot(load_model,filename=img_path,class_names=class_names)