Face mask detection using AI (model creation)

Jerry John
Analytics Vidhya
Published in
6 min readJul 29, 2020

Reference from https://www.pyimagesearch.com/faqs/single-faq/how-do-i-reference-or-cite-one-of-your-blog-posts-books-or-courses

1. Introduction

As confirmed cases of COVID-19 continue to rise, the use of facial mask has become one of the most important safety measure that everyone should take these days. Wearing a face mask will help prevent the spread of virus to a large extent . The CDC is recommending everyone to wear a cloth mask when they go out in public.

Very soon the mask will become a part of our life. Public places, offices etc. will make mask mandatory. It is very difficult to manually check each person who is entering to public places or offices whether they are wearing a mask or not. To solve this problem we are creating a Deep Learning model that can detect whether a people who are entering without mask.

2. Datasets

For creating a face mask classification model, we want two type of images- face with mask and without mask. We can find many datasets for this purpose. Some of them are given below.

  1. Kaggle : https://www.kaggle.com/andrewmvd/face-mask-detection?select=images
  2. https://arxiv.org/abs/2003.09093
Our datasets images with mask
Our datasets images without mask

3. Importing necessary libraries

Now let’s import the libraries we want. We may use keras, tensorflow, matplotlib, umpy etc..

# import the necessary packages
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.layers import AveragePooling2D
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Input
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.preprocessing.image import load_img
from tensorflow.keras.utils import to_categorical
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import os

4. Getting the datasets

Download the datasets mentioned above and provide the directory so that we can use them in our program. There are mainly two categories one with mask and the other without mask. We need to first convert the image into arrays. Each image is converted into a uniform size 224,224. Each of these array is stored as data (list) and the labels are stored under labels(list)

DIRECTORY = r"C:\Users\jerry\project works ML\article to publish\face mask detetcion\dataset"
CATEGORIES = ["with_mask", "without_mask"]
# grab the list of images in our dataset directory, then initialize
# the list of data (i.e., images) and class images
print("[INFO] loading images...")
data = []
labels = []
for category in CATEGORIES:
path = os.path.join(DIRECTORY, category)
for img in os.listdir(path):
img_path = os.path.join(path, img)
image = load_img(img_path, target_size=(224, 224))
image = img_to_array(image)
image = preprocess_input(image)
data.append(image)
labels.append(category)

5. Perform one-hot encoding on the labels

As we can see above the labels are in string format, we need to convert that to integer format, as our models do not accept string format. For this purpose we use one hot encoder (for example if we are having two labels YES and NO it can be converted as 0 and 1).

# perform one-hot encoding on the labels
lb = LabelBinarizer()
labels = lb.fit_transform(labels)
labels = to_categorical(labels)
data = np.array(data, dtype="float32")
labels = np.array(labels)

6. Train Test Split

Now we need to split our datasets so that we can have a fresh datasets that can be used to test our model performance. Here we are taking 80% of our data for the training purpose and the other 20% for the testing purpose.

(trainX, testX, trainY, testY) = train_test_split(data, labels,
test_size=0.20, stratify=labels, random_state=5)

We also use ‘ImageDataGenerator’. Image Data Generator is a function provided by keras to increase the number of data we have to train. In many cases the data used to be trained very less. As the amount of data increases the accuracy level also increases . It creates many images from a single image by adding various properties like flipping, rotating etc.. There are many properties that can be changed as given below in the code. Most of them are set to default.

# construct the training image generator for data augmentation
aug = ImageDataGenerator(
rotation_range=20,
zoom_range=0.15,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.15,
horizontal_flip=True,
fill_mode="nearest")

7. Model Creation

There are some pre trained models for images, so when we use ‘imagenet’ those weights will be initialized which will give a better result. Input tensor is the shape of the image that goes through.

We also initialize the initial learning rate, number of epochs to train for and batch size.

We take our output model as Dense(2, activation=”softmax”). The 2 is because we are having two classes with mask and without mask. The activation function used in the output layer is softmax (binary classification).

# initialize the initial learning rate, number of epochs to train for,
# and batch size
INIT_LR = 1e-4
EPOCHS = 20
BS = 32

# load the MobileNetV2 network, ensuring the head FC layer sets are
# left off
baseModel = MobileNetV2(weights="imagenet", include_top=False,
input_tensor=Input(shape=(224, 224, 3)))
# construct the head of the model that will be placed on top of the
# the base model
headModel = baseModel.output
headModel = AveragePooling2D(pool_size=(7, 7))(headModel)
headModel = Flatten(name="flatten")(headModel)
headModel = Dense(128, activation="relu")(headModel)
headModel = Dropout(0.5)(headModel)
headModel = Dense(2, activation="softmax")(headModel)
# place the head FC model on top of the base model (this will become
# the actual model we will train)
model = Model(inputs=baseModel.input, outputs=headModel)
# loop over all layers in the base model and freeze them so they will
# *not* be updated during the first training process
for layer in baseModel.layers:
layer.trainable = False
# compile our model
print("[INFO] compiling model...")
opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
model.compile(loss="binary_crossentropy", optimizer=opt,
metrics=["accuracy"])
# train the head of the network
print("[INFO] training head...")
H = model.fit(
aug.flow(trainX, trainY, batch_size=BS),
steps_per_epoch=len(trainX) // BS,
validation_data=(testX, testY),
validation_steps=len(testX) // BS,
epochs=EPOCHS)
# make predictions on the testing set
print("[INFO] evaluating network...")
predIdxs = model.predict(testX, batch_size=BS)
# for each image in the testing set we need to find the index of the
# label with corresponding largest predicted probability
predIdxs = np.argmax(predIdxs, axis=1)
# show a nicely formatted classification report
print(classification_report(testY.argmax(axis=1), predIdxs,
target_names=lb.classes_))
# serialize the model to disk
print("[INFO] saving mask detector model...")
model.save("mask_detector.model", save_format="h5")

Finally save our model as mask_detector.model, save it in h5 format. We will use this model for later use.

8. Training loss and accuracy

We use matplotlib for plotting training loss, val_loss, train_acc, val_accuracy.

# plot the training loss and accuracy
N = EPOCHS
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, N), H.history["loss"], label="train_loss")
plt.plot(np.arange(0, N), H.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, N), H.history["accuracy"], label="train_acc")
plt.plot(np.arange(0, N), H.history["val_accuracy"], label="val_acc")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="lower left")
plt.savefig("plot.png")

9. Conclusion

In this article we learned how to build a face mask detection model. Now we can use this model in a real time application. Here we are implementing this model in our web cam using OpenCV, This project can be integrated with embedded systems for application in schools,airports, railway stations, offices and public places to ensure that public safety guidelines are followed.

The program to implement this model is here.

As NO one is perfect, if anyone find any errors or suggestion please feel free to comment below.

Email Id : jerryjohn1995@gmail.com

Instagram : https://www.instagram.com/jerry_john_7/?hl=en

Linkedin : linkedin.com/in/jerryjohn1995

Face Book : https://www.facebook.com/jerry.john.583234/

--

--