"""
# Importing libraries
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from glob import glob
import os

# From tensorflow
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense , Dropout , Flatten , Conv2D , MaxPooling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator


# Import Sklearn
from sklearn.preprocessing import StandardScaler 
from sklearn.model_selection import train_test_split 
from sklearn.metrics import classification_report
"""
# Loading data
"""
files=glob('../input/a-large-scale-fish-dataset/Fish_Dataset/Fish_Dataset/*/*/*')
len(files)
files[:3]
File_Path = pd.Series(files).astype(str)
Labels = list(map(lambda x: os.path.split(os.path.split(x)[0])[1],files))
Labels = pd.Series(Labels)
Labels[:2]
df = pd.concat([File_Path,Labels],axis=1)
df.columns = ['image', 'label']
df
"""
Removing GT images
"""
df = df[df["label"].apply(lambda x: x[-2:] != "GT")].reset_index(drop=True)
df
df.label.value_counts()
fig=plt.figure(figsize=(15,8))
sns.countplot(df['label'])
"""
Train test split
"""
x_train, x_test = train_test_split(df, test_size=0.2,random_state=30)
x_train, x_val = train_test_split(x_train, test_size=0.2, random_state=30)
print(x_test.shape)
print(x_train.shape)
print(x_val.shape)
"""
# Generating data
"""
img_gen = ImageDataGenerator(rescale = 1./255)
train = img_gen.flow_from_dataframe(dataframe=x_train, 
                                                 x_col='image', y_col='label', 
                                                 target_size=(200,200), color_mode='rgb', 
                                                 class_mode='categorical', shuffle=False)

test = img_gen.flow_from_dataframe(dataframe=x_test, 
                                                x_col='image', y_col='label', 
                                                target_size=(200,200), color_mode='rgb', 
                                                class_mode='categorical', shuffle=False)
val = img_gen.flow_from_dataframe(dataframe=x_val,
                                               x_col='image', y_col='label', 
                                               target_size=(200,200), color_mode='rgb', 
                                               class_mode='categorical',shuffle=False)
"""
# Model creation
"""
input_shape=(200,200,3)
model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=input_shape),
    tf.keras.layers.MaxPool2D(pool_size = (2,2)),
    tf.keras.layers.Conv2D(16, (3,3), activation='relu'),
    tf.keras.layers.MaxPool2D(pool_size = (2,2)),
    tf.keras.layers.Conv2D(16, (3,3), activation='relu'),
    tf.keras.layers.MaxPool2D(pool_size = (2,2)),
    tf.keras.layers.Conv2D(16, (3,3), activation='relu'),
    tf.keras.layers.MaxPool2D(pool_size = (2,2)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(512, activation='relu'),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(9, activation='softmax')
])

model.summary()
model.compile(optimizer='adam', 
              loss="categorical_crossentropy", 
              metrics=['accuracy']) 
"""
# Training model
"""
history = model.fit(train, validation_data=val, epochs=15)
accuracy = history.history['accuracy']
val_accuracy  = history.history['val_accuracy']

loss = history.history['loss']
val_loss = history.history['val_loss']
plt.figure(figsize=(15,10))

plt.subplot(2, 2, 1)
plt.plot(accuracy, label = "Training accuracy")
plt.plot(val_accuracy, label="Validation accuracy")
plt.legend()
plt.title("Training vs validation accuracy")


plt.subplot(2,2,2)
plt.plot(loss, label = "Training loss")
plt.plot(val_loss, label="Validation loss")
plt.legend()
plt.title("Training vs validation loss")

plt.show()
"""
# Prediction
"""
pred = model.predict(test)
pred = np.argmax(pred,axis = 1) 
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.metrics import accuracy_score
accuracy_score(test.labels,pred)
confusion_mtx = confusion_matrix(test.labels,pred) 
plt.figure(figsize=(10,8))
sns.heatmap(confusion_mtx,annot=True,annot_kws={"size": 10} , cmap="YlGnBu")
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.plot()
print(classification_report(test.labels,pred))
"""
## Test with database images
"""
from tensorflow.keras.preprocessing import image
def predict_it(image_location):
  test_image=image.load_img(image_location, target_size = (200,200))
  plt.imshow(test_image)
  test_image=image.img_to_array(test_image)
  test_image=test_image/255
  test_image = np.expand_dims(test_image, axis = 0)
  preds=np.argmax(model.predict(test_image))
  print(f'The fish is {list(test.class_indices.keys())[preds]}')
predict_it('../input/a-large-scale-fish-dataset/Fish_Dataset/Fish_Dataset/Black Sea Sprat/Black Sea Sprat/00001.png')
predict_it('../input/a-large-scale-fish-dataset/Fish_Dataset/Fish_Dataset/Gilt-Head Bream/Gilt-Head Bream/00001.png')
"""
## Test with online images
"""
from urllib.request import urlopen
from PIL import Image
def predict_url(url):
  img = Image.open(urlopen(url))
  plt.imshow(img)
  test_image=image.img_to_array(img)
  test_image=tf.image.resize(test_image, (200, 200))
  
  test_image=test_image/255
  test_image = np.expand_dims(test_image, axis = 0)
  preds=np.argmax(model.predict(test_image))
  print(f'The fish is {list(test.class_indices.keys())[preds]}')
predict_url('http://www.clovegarden.com/ingred/img/sf_seabrm03g.jpg')
predict_url('https://img3.exportersindia.com/product_images/bc-full/dir_14/401539/trout-fish-1538328.jpg')