Building a Deep Face Detection Model with Python and TensorFlow (Part 3)

Rmag Breaking News

Check out Part 1

Check out Part 2

Welcome back to the continuation of our tutorial on building a deep face detection model using Python and TensorFlow. In this part, we’ll pick up where we left off and cover steps 5 through 11, including data augmentation, model building, training, and making predictions.

5. Build and Run Augmentation Pipeline

5.1 Run Augmentation Pipeline

for partition in [train, test, val]:
for image in os.listdir(os.path.join(data, partition, images)):
img = cv2.imread(os.path.join(data, partition, images, image))

coords = [0, 0, 0.00001, 0.00001]
label_path = os.path.join(data, partition, labels, f{image.split(.)[0]}.json)
if os.path.exists(label_path):
with open(label_path, r) as f:
label = json.load(f)

coords[0] = label[shapes][0][points][0][0]
coords[1] = label[shapes][0][points][0][1]
coords[2] = label[shapes][0][points][1][0]
coords[3] = label[shapes][0][points][1][1]
coords = list(np.divide(coords, [640, 480, 640, 480]))

try:
for x in range(60):
augmented = augmentor(image=img, bboxes=[coords], class_labels=[face])
cv2.imwrite(os.path.join(aug_data, partition, images, f{image.split(.)[0]}.{x}.jpg), augmented[image])

annotation = {}
annotation[image] = image

if os.path.exists(label_path):
if len(augmented[bboxes]) == 0:
annotation[bbox] = [0, 0, 0, 0]
annotation[class] = 0
else:
annotation[bbox] = augmented[bboxes][0]
annotation[class] = 1
else:
annotation[bbox] = [0, 0, 0, 0]
annotation[class] = 0

with open(os.path.join(aug_data, partition, labels, f{image.split(.)[0]}.{x}.json), w) as f:
json.dump(annotation, f)

except Exception as e:
print(e)

5.2 Load Augmented Images to TensorFlow Dataset

train_images = tf.data.Dataset.list_files(‘aug_data\train\images\*.jpg’, shuffle=False)
train_images = train_images.map(load_image)
train_images = train_images.map(lambda x: tf.image.resize(x, (120, 120)))
train_images = train_images.map(lambda x: x/255)

test_images = tf.data.Dataset.list_files(‘aug_data\test\images\*.jpg’, shuffle=False)
test_images = test_images.map(load_image)
test_images = test_images.map(lambda x: tf.image.resize(x, (120, 120)))
test_images = test_images.map(lambda x: x/255)

val_images = tf.data.Dataset.list_files(‘aug_data\val\images\*.jpg’, shuffle=False)
val_images = val_images.map(load_image)
val_images = val_images.map(lambda x: tf.image.resize(x, (120, 120)))
val_images = val_images.map(lambda x: x/255)

train_images.as_numpy_iterator().next()

6. Prepare Labels

6.1 Build Label Loading Function

def load_labels(label_path):
with open(label_path.numpy(), r, encoding=utf-8) as f:
label = json.load(f)

return [label[class]], label[bbox]

6.2 Load Labels to TensorFlow Dataset

train_labels = tf.data.Dataset.list_files(aug_data\train\labels\*.json, shuffle=False)
train_labels = train_labels.map(lambda x: tf.py_function(load_labels, [x], [tf.uint8, tf.float16]))

test_labels = tf.data.Dataset.list_files(aug_data\test\labels\*.json, shuffle=False)
test_labels = test_labels.map(lambda x: tf.py_function(load_labels, [x], [tf.uint8, tf.float16]))

val_labels = tf.data.Dataset.list_files(aug_data\val\labels\*.json, shuffle=False)
val_labels = val_labels.map(lambda x: tf.py_function(load_labels, [x], [tf.uint8, tf.float16]))

train_labels.as_numpy_iterator().next()

7. Combine Label and Image Samples

7.1 Check Partition Lengths

len(train_images), len(train_labels), len(test_images), len(test_labels), len(val_images), len(val_labels)

7.2 Create Final Datasets (Images/Labels)

train = tf.data.Dataset.zip((train_images, train_labels))
train = train.shuffle(5000)
train = train.batch(8)
train = train.prefetch(4)

test = tf.data.Dataset.zip((test_images, test_labels))
test = test.shuffle(1300)
test = test.batch(8)
test = test.prefetch(4)

val = tf.data.Dataset.zip((val_images, val_labels))
val = val.shuffle(1000)
val = val.batch(8)
val = val.prefetch(4)

train.as_numpy_iterator().next()[1]

7.3 View Images and Annotations

data_samples = train.as_numpy_iterator()
res = data_samples.next()

fig, ax = plt.subplots(ncols=4, figsize=(20,20))
for idx in range(4):
sample_image = res[0][idx]
sample_coords = res[1][1][idx]

cv2.rectangle(sample_image,
tuple(np.multiply(sample_coords[:2], [120, 120]).astype(int)),
tuple(np.multiply(sample_coords[2:], [120, 120]).astype(int)),
(255, 0, 0), 2)

ax[idx].imshow(sample_image)

8. Build Deep Learning Model using the Functional API

8.1 Import Layers and Base Network

from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv2D, Dense, GlobalMaxPooling2D
from tensorflow.keras.applications import VGG16

8.2 Download VGG16

vgg = VGG16(include_top=False)
vgg.summary()

8.3 Build instance of Network

def build_model():
input_layer = Input(shape=(120, 120, 3))

vgg = VGG16(include_top=False)(input_layer)

# Classification Model
f1 = GlobalMaxPooling2D()(vgg)
class1 = Dense(2048, activation=relu)(f1)
class2 = Dense(1, activation=sigmoid)(class1)

# Bounding box model
f2 = GlobalMaxPooling2D()(vgg)
regress1 = Dense(2048, activation=relu)(f2)
regress2 = Dense(4, activation=sigmoid)(regress1)

facetracker = Model(inputs=input_layer, outputs=[class2, regress2])
return facetracker

8.4 Test out Neural Network

facetracker = build_model()
facetracker.summary()

X, y = train.as_numpy_iterator().next()
X.shape

classes, coords = facetracker.predict(X)
classes, coords

This concludes part 2 of our tutorial. In the next part, we’ll define losses, optimizers, and train our deep learning model.

Stay tuned for the next installment!

Leave a Reply

Your email address will not be published. Required fields are marked *