import numpy as np
import pandas as pd
from pathlib import Path
import os.path
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
# Create a list with the filepaths for training and testing
dir_ = Path('../input/dogs-cats-images/dataset/training_set')
train_filepaths = list(dir_.glob(r'**/*.jpg'))

dir_ = Path('../input/dogs-cats-images/dataset/test_set')
test_filepaths = list(dir_.glob(r'**/*.jpg'))
def proc_img(filepath):
    """ Create a DataFrame with the filepath and the labels of the pictures
    """

    labels = [str(filepath[i]).split("/")[-2] \
              for i in range(len(filepath))]

    filepath = pd.Series(filepath, name='Filepath').astype(str)
    labels = pd.Series(labels, name='Label')

    # Concatenate filepaths and labels
    df = pd.concat([filepath, labels], axis=1)

    # Shuffle the DataFrame and reset index
    df = df.sample(frac=1,random_state=0).reset_index(drop = True)
    
    return df
train = proc_img(train_filepaths)
test = proc_img(test_filepaths)

print(f'Number of pictures in the training dataset: {train.shape[0]}\n')
print(f'Number of pictures in the test dataset: {test.shape[0]}\n')
print(f'Number of different labels: {len(train.Label.unique())}\n')
print(f'Labels: {train.Label.unique()}')


pd.set_option('display.max_colwidth',200)
train.head()
train.shape, test.shape
CLASSES = train['Label'].unique().tolist()
# Display some pictures of the dataset
fig, axes = plt.subplots(nrows=4, ncols=6, figsize=(15, 7),
                        subplot_kw={'xticks': [], 'yticks': []})

for i, ax in enumerate(axes.flat):
    ax.imshow(plt.imread(train.Filepath[i]))
    ax.set_title(train.Label[i], fontsize = 15)
plt.tight_layout(pad=0.5)
plt.show()
"""
### Data Preprocessing
"""
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# Preprocessing the Training set
train_datagen = ImageDataGenerator(rescale = 1./255,
                                   shear_range = 0.2,
                                   zoom_range = 0.2,
                                   horizontal_flip = True,
                                   validation_split=0.25)

training_set = train_datagen.flow_from_dataframe(dataframe=train,
                                                 x_col='Filepath',
                                                 y_col='Label',
                                                 subset='training')

 
val_set = train_datagen.flow_from_dataframe(dataframe=train,
                                             x_col='Filepath',
                                              y_col='Label',
                                            subset='validation')

# Preprocessing the Test set
test_datagen = ImageDataGenerator(rescale = 1./255)
test_set = test_datagen.flow_from_dataframe(dataframe=test,
                                            x_col='Filepath',
                                            y_col='Label')
"""
### MobileNet
"""
from keras import Sequential
from keras.applications import MobileNet
from tensorflow.keras.layers import Dense
base_Net = MobileNet(include_top = False, 
                         weights = '../input/keras-pretrained-models/MobileNet_NoTop_ImageNet.h5', 
                         input_shape = training_set.image_shape, 
                         pooling='avg',
                         classes = CLASSES)
#Adding the final layers to the above base models where the actual classification is done in the dense layers
model_Net = Sequential()
model_Net.add(base_Net)
model_Net.add(Dense(2, activation=('sigmoid')))

model_Net.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
model_Net.summary()
"""
* Training model on the Training_set and evaluating it on the val_set
"""
r=model_Net.fit(x = training_set, validation_data = val_set, epochs = 5,batch_size=128)
# plot the loss
import matplotlib.pyplot as plt
plt.plot(r.history['loss'], label='train loss')
plt.plot(r.history['val_loss'], label='val loss')
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend()
plt.show()

# plot the accuracy
plt.plot(r.history['accuracy'], label='train acc')
plt.plot(r.history['val_accuracy'], label='val acc')
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend()
plt.show()
pred = model_Net.predict(test_set)
model_Net.save('dogs_cat.h5')
"""
#### if you like this notebook plz upvote it :)
#### Thank you
"""