# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     name: python3
# ---

# + [markdown] id="WzfdUE-RDKZe" colab_type="text"
# #Face Recognition using Deep Learning (IoT project)

# + id="y6_UOrhYOyHX" colab_type="code" outputId="f82f10ed-4d28-4e08-beb7-ed75a073deae" colab={"base_uri": "https://localhost:8080/", "height": 638}
# !pip install tensorflow==1.8

# + id="weuAoWzzAu_w" colab_type="code" outputId="55a882e1-b6b0-4df2-d262-a3b635f2049e" colab={"base_uri": "https://localhost:8080/", "height": 54}
import matplotlib.pyplot as plt
import numpy as np
import os

import tensorflow as tf
import zipfile
import keras
from keras.applications import MobileNet
from keras.layers import Conv2D, Dense, Dropout, Flatten, MaxPooling2D
from keras.models import Sequential
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
print(keras.__version__)

# + [markdown] id="6Jvxio08wbUG" colab_type="text"
# ##Build dataset 
#
# We have taken photos of our group members mixed with  public face dataset . I took a video of the landmarks and used FFmpeg to extract 4 images(frames) per second. Finally I shuffle the dataset and split them into train, validation and test dataset.

# + id="gZHxl2dESMpg" colab_type="code" outputId="b7543693-4dea-4fc4-b722-d51ca8f1b910" colab={"base_uri": "https://localhost:8080/", "height": 35}
# !ls 

# + id="LKqy9HGQBQIj" colab_type="code" colab={}
local_zip = 'face.zip'
zip_ref = zipfile.ZipFile(local_zip, 'r')
zip_ref.extractall('face')
zip_ref.close()
base_dir = 'face'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'val')
test_dir = os.path.join(base_dir, 'test')

train_owner_dir = os.path.join(train_dir, 'owner')
train_breaker_dir = os.path.join(train_dir, 'breaker')

validation_owner_dir = os.path.join(validation_dir, 'owner')
validation_breaker_dir = os.path.join(validation_dir, 'breaker')


test_owner_dir = os.path.join(test_dir, 'owner')
test_breaker_dir = os.path.join(test_dir, 'breaker')

# + id="maha4K_3BQLK" colab_type="code" colab={}
num_owner_tr = len(os.listdir(train_owner_dir))
num_breaker_tr = len(os.listdir(train_breaker_dir))

num_owner_val = len(os.listdir(validation_owner_dir))
num_breaker_val = len(os.listdir(validation_breaker_dir))

num_owner_test = len(os.listdir(test_owner_dir))
num_breaker_test = len(os.listdir(test_breaker_dir))

total_train = num_owner_tr + num_breaker_tr
total_val = num_owner_val + num_breaker_val
total_test = num_owner_test + num_breaker_test

# + id="MQ65ATMiBQNy" colab_type="code" outputId="bdf37960-d5ff-4648-f178-b3ba682086e6" colab={"base_uri": "https://localhost:8080/", "height": 199}
print('Training owner images:', num_owner_tr)
print('Training breaker images:', num_breaker_tr)

print('Validation owner images:', num_owner_val)
print('Validation breaker images:', num_breaker_val)


print('Test owner images:', num_owner_test)
print('Test breaker images:', num_breaker_test)

print("--")

print("Total training images:", total_train)
print("Total validation images:", total_val)
print("Total test images:", total_test)

# + [markdown] id="ZTmsWSd27dx6" colab_type="text"
# ##Data augmentation

# + id="3fUE42H1aqvE" colab_type="code" outputId="9699bd1b-acef-4344-c05e-f9c2f814d5f8" colab={"base_uri": "https://localhost:8080/", "height": 72}
TARGET_SHAPE = 160 
BATCH_SIZE = 32


image_gen_train = ImageDataGenerator(
      rescale=1./255,
      rotation_range=40,
      width_shift_range=0.2,
      height_shift_range=0.2,
      shear_range=0.2,
      zoom_range=0.2,
      horizontal_flip=True,
      fill_mode='nearest')


train_data_gen = image_gen_train.flow_from_directory(
    batch_size=BATCH_SIZE, 
    directory=train_dir, 
    shuffle=True, 
    target_size=(TARGET_SHAPE,TARGET_SHAPE),
    class_mode='binary')


image_gen_val = ImageDataGenerator(rescale=1./255)
val_data_gen = image_gen_val.flow_from_directory(
    batch_size=BATCH_SIZE, 
    directory=validation_dir, 
    target_size=(TARGET_SHAPE, TARGET_SHAPE),
    class_mode='binary')


image_gen_test = ImageDataGenerator(rescale=1./255)
test_data_gen = image_gen_val.flow_from_directory(
    batch_size=BATCH_SIZE, 
    directory=test_dir, 
    target_size=(TARGET_SHAPE, TARGET_SHAPE),
    class_mode='binary')

# + [markdown] id="-p_mE4Gmya_c" colab_type="text"
# ## Display Sample Training Images

# + id="nWeQxPmryba0" colab_type="code" colab={}
sample_training_images, sample_training_labels = next(train_data_gen)


# + id="w2T5e-x_ysN3" colab_type="code" colab={}

def plotImages(images_arr):
    fig, axes = plt.subplots(1, 5, figsize=(20,20))
    axes = axes.flatten()
    for img, ax in zip( images_arr, axes):
        ax.grid(False)
        ax.imshow(img)
    plt.tight_layout()
    plt.show()


# + id="WrAYXQvwysQn" colab_type="code" outputId="8366b06f-a764-42c8-897f-acab4a57c08a" colab={"base_uri": "https://localhost:8080/", "height": 317}

plotImages(sample_training_images[:5])

# + [markdown] id="ridXwziwyb3c" colab_type="text"
# # Part2 transfer learning
# First I chosen MobileNet as the model, and I apply the transfer learning onto the Mobilenet model trained on my own Dataset.

# + id="Mtp9BqPZ0BSC" colab_type="code" colab={}

vgg16_conv_base = MobileNet(weights='imagenet',include_top=False, input_shape=(160, 160, 3))


# + id="DCoyxHb90BsD" colab_type="code" outputId="e258f1ee-141b-431a-9667-e4636ccbae7d" colab={"base_uri": "https://localhost:8080/", "height": 3308}
vgg16_conv_base.summary()

# + id="E2jde6qb0By4" colab_type="code" colab={}

vgg16_conv_base.trainable = False
vgg16_model = Sequential()
vgg16_model.add(vgg16_conv_base)
vgg16_model.add(Flatten())
vgg16_model.add(Dense(512, activation='relu'))
vgg16_model.add(Dense(1, activation='sigmoid'))

# + id="XA6mKtoLz9Bq" colab_type="code" outputId="abfb73b2-94a1-469d-9503-e44119fdfa40" colab={"base_uri": "https://localhost:8080/", "height": 290}
vgg16_model.summary()


# + id="ZkKVaCtZb-C5" colab_type="code" colab={}
EPOCHS = 5


# + id="PeaLKrspaqxr" colab_type="code" outputId="0ff1693c-3558-497e-9e02-b392abd30085" colab={"base_uri": "https://localhost:8080/", "height": 219}

vgg16_model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['acc'])


vgg16_history = vgg16_model.fit_generator(
      train_data_gen,
      steps_per_epoch=int(np.ceil(total_train / float(BATCH_SIZE))),
      epochs=EPOCHS,
      validation_data=val_data_gen,
      validation_steps=int(np.ceil(total_val / float(BATCH_SIZE))),
      verbose=1)

# + [markdown] id="FIhThbSJ4XH6" colab_type="text"
# ## Plot Training and Validation Loss and Accuracy

# + id="1BjJ4R_uaq0r" colab_type="code" outputId="f226a5f5-407e-4874-efc6-03ae05055684" colab={"base_uri": "https://localhost:8080/", "height": 791}
acc = vgg16_history.history['acc']
val_acc = vgg16_history.history['val_acc']

loss = vgg16_history.history['loss']                                              
val_loss = vgg16_history.history['val_loss']

epochs_range = range(1, EPOCHS+1)

plt.figure(figsize=(13,13))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy from Transfer Learning on VGG16')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss from Transfer Learning on VGG16')
plt.show()

# + [markdown] id="LFZun68z4b2z" colab_type="text"
# ## Show Testing Loss and Accuracy

# + id="GYItoZm-aq3L" colab_type="code" outputId="0edfa5ce-42ff-4747-cc8a-4f2ff4b3a1fc" colab={"base_uri": "https://localhost:8080/", "height": 345}
vgg16_test_loss, vgg16_test_accuracy = vgg16_model.evaluate(test_data_gen, verbose=1)

# + id="u-kw_jFLaq6E" colab_type="code" colab={}
print('The test loss is '+ str(round(vgg16_test_loss,2))+' and the test accracy is '+ str(round(vgg16_test_accuracy,2)))

# + id="oZb16Wj5oBSx" colab_type="code" colab={}
vgg16_model.save("model1.h5")

# + [markdown] id="NWwX6iL-dUeg" colab_type="text"
# #part3: self-defined CNN

# + id="04UFK-TcK00x" colab_type="code" outputId="91b08510-6807-477f-8555-f6fe4639a59c" colab={"base_uri": "https://localhost:8080/", "height": 72}
TARGET_SHAPE = 150 
BATCH_SIZE = 32


image_gen_train = ImageDataGenerator(
      rescale=1./255,
      rotation_range=40,
      width_shift_range=0.2,
      height_shift_range=0.2,
      shear_range=0.2,
      zoom_range=0.2,
      horizontal_flip=True,
      fill_mode='nearest')


train_data_gen = image_gen_train.flow_from_directory(
    batch_size=BATCH_SIZE, 
    directory=train_dir, 
    shuffle=True, 
    target_size=(TARGET_SHAPE,TARGET_SHAPE),
    class_mode='binary')


image_gen_val = ImageDataGenerator(rescale=1./255)
val_data_gen = image_gen_val.flow_from_directory(
    batch_size=BATCH_SIZE, 
    directory=validation_dir, 
    target_size=(TARGET_SHAPE, TARGET_SHAPE),
    class_mode='binary')


image_gen_test = ImageDataGenerator(rescale=1./255)
test_data_gen = image_gen_val.flow_from_directory(
    batch_size=BATCH_SIZE, 
    directory=test_dir, 
    target_size=(TARGET_SHAPE, TARGET_SHAPE),
    class_mode='binary')

# + id="AvXjmqjVfshF" colab_type="code" colab={}
inc_model = Sequential()
inc_model.add(Conv2D(32, (3, 3), activation='relu',
                        input_shape=(480, 480, 3)))
inc_model.add(MaxPooling2D((2, 2)))
inc_model.add(Conv2D(64, (3, 3), activation='relu'))
inc_model.add(MaxPooling2D((2, 2)))
inc_model.add(Conv2D(128, (3, 3), activation='relu'))
inc_model.add(MaxPooling2D((2, 2)))
inc_model.add(Conv2D(128, (3, 3), activation='relu'))
inc_model.add(MaxPooling2D((2, 2)))
inc_model.add(Flatten())
inc_model.add(Dense(512, activation='relu'))
inc_model.add(Dense(1, activation='sigmoid'))

# + id="9AsfAdiSi-cL" colab_type="code" outputId="cfa03d4c-34da-4755-8983-528a7a75fd06" colab={"base_uri": "https://localhost:8080/", "height": 401}
EPOCHS = 10
inc_model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['acc'])

# Train Transfer Learning
inc_history = inc_model.fit_generator(
      train_data_gen,
      steps_per_epoch=int(np.ceil(total_train / float(BATCH_SIZE))),
      epochs=EPOCHS,
      validation_data=val_data_gen,
      validation_steps=int(np.ceil(total_val / float(BATCH_SIZE))),
      verbose=1)

# + id="2C3GwvfFlpgT" colab_type="code" outputId="728d3db5-728d-482e-e815-9081e399e6d8" colab={"base_uri": "https://localhost:8080/", "height": 499}
acc = inc_history.history['acc']
val_acc = inc_history.history['val_acc']

loss = inc_history.history['loss']
val_loss = inc_history.history['val_loss']

epochs_range = range(1, EPOCHS+1)

plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

# + id="fauEIos5l2FG" colab_type="code" outputId="1de2e583-a8b0-4b32-855e-3d000eb008f6" colab={"base_uri": "https://localhost:8080/", "height": 363}
inc_test_loss, inc_test_accuracy = inc_model.evaluate(test_data_gen, verbose=1)
print('The test loss is '+ str(round(inc_test_loss,2))+' and the test accracy is '+ str(round(inc_test_accuracy,2)))

# + id="KOhdhh3DmD7a" colab_type="code" colab={}
inc_model.save_weights("model.h5")

# + id="KYi9SCarmM_J" colab_type="code" outputId="a4a03597-f0b3-4dba-de48-49f5210e0d63" colab={"base_uri": "https://localhost:8080/", "height": 72}
import PIL
from PIL import Image
img = Image.open("/content/face/test/owner/IMG_20190428_164249.jpg")
img = img.resize((150,150), PIL.Image.ANTIALIAS)
image = np.asarray(img)
shape1 = image.shape
print(shape1)
image = np.expand_dims(image, axis=0)
print(image.shape)
result = inc_model.predict(image)
print(result)


StarcoderdataJupyterScriptsDedupFiltered