"""
# Mask Classier - using CNN for COVID-19 #  
"""
"""
![Wearing-face-masks-at-home-might-help-ward-off-COVID-19-spread-among-family-members-375x195.jpg](attachment:Wearing-face-masks-at-home-might-help-ward-off-COVID-19-spread-among-family-members-375x195.jpg)
"""
"""
Anyone travelling by bus, train, ferry or plane should wear a face covering to help reduce the risk of coronavirus transmission.

The new rules coincided with a further easing of lockdown in different countries - including the return to class of  school pupils and the reopening of shops.
In the following work We’ll try to classify if the person is using a mask or not .
"""
"""
This is a basic implementation using the ResNet50 model. I am a beginner so please feel free to offer corrections and suggestions.
"""
"""
# Imports
"""
import os
import pandas as pd
import numpy as np
import tensorflow
import keras
from keras.preprocessing.image import load_img
import matplotlib.pyplot as plt
from tensorflow.keras.applications import ResNet50
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense, Flatten, GlobalAveragePooling2D
from sklearn.datasets import load_files
from keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Activation, BatchNormalization
from keras.models import Sequential
import cv2
from keras.applications.resnet50 import ResNet50
from keras.preprocessing import image
from keras.applications.resnet50 import preprocess_input, decode_predictions
from keras_preprocessing.image import ImageDataGenerator
import numpy as np


#Test & Train dirs 

train_dir='/kaggle/input/withwithout-mask/maskdata/maskdata/train/'
test_dir='/kaggle/input/withwithout-mask/maskdata/maskdata/test/'
"""
Let's extract data from dir : for each dir we have target=y(0/1 - without/with mask) filenames=x(image path)
"""
def load_dataset(path):
    data = load_files(path) #load all files from the path
    files = np.array(data['filenames']) #get the file  
    targets = np.array(data['target'])#get the the classification labels as integer index
    target_labels = np.array(data['target_names'])#get the the classification labels 
    return files,targets,target_labels
    
x_train, y_train,target_labels = load_dataset(train_dir)
x_test, y_test,_ = load_dataset(test_dir)

print('Training set size : ' , x_train.shape[0])
print('Testing set size : ', x_test.shape[0])
"""
Show image example
"""
image = load_img(x_train[1])
plt.imshow(image)
"""
Show image shape
"""
im = cv2.imread(x_train[5])
h, w, c = im.shape
print('width:  ', w)
print('height: ', h)
print('channel:', c)
"""
# Parameters
"""
num_classes = 2
FAST_RUN       = False
IMAGE_WIDTH    =64
IMAGE_HEIGHT   =64
batch_size=50
image_size = 64
epoch =15
IMAGE_SIZE     =(IMAGE_WIDTH, IMAGE_HEIGHT)
IMAGE_CHANNELS =3
DROP_OUT_VALUE =0.1
FILTER_SIZE    =(3, 3)
POOL_SIZE      =(2, 2)
"""
Create model :)
"""
model = Sequential()

model.add(Conv2D(32, FILTER_SIZE, activation='relu', input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS)))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=POOL_SIZE))
#model.add(Dropout(DROP_OUT_VALUE))

model.add(Conv2D(64, FILTER_SIZE, activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=POOL_SIZE))
model.add(Dropout(DROP_OUT_VALUE))

model.add(Conv2D(128, FILTER_SIZE, activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=POOL_SIZE))
model.add(Dropout(DROP_OUT_VALUE))


model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(DROP_OUT_VALUE))
model.add(Dense(2, activation='softmax')) # 2 because we have cat and dog classes

model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

model.summary()
"""
Preprocessing the data via ImageDataGenerator.The data here is categorical as it is divided into two categories namely with & without mask.
"""



data_generator = ImageDataGenerator(preprocessing_function=preprocess_input,horizontal_flip=True,
                                   width_shift_range = 0.2,
                                   height_shift_range = 0.2)


train_generator = data_generator.flow_from_directory(
        train_dir,
        target_size=(image_size, image_size),
        batch_size=batch_size,
        class_mode='categorical')

validation_generator = data_generator.flow_from_directory(test_dir,target_size=(image_size, image_size),
        class_mode='categorical')

history=model.fit_generator(
        train_generator,
        epochs=epoch, 
        validation_data=validation_generator,
        validation_steps=1)
"""
Plot accuracy & lost for train & test set 
"""
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
# summarize history for loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
"""
Great results :)
"""