!pip install caer canaro
# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import matplotlib.pyplot as plt
plt.figure(figsize=(14, 14))
from tensorflow.keras import utils
from keras.utils.vis_utils import plot_model
from tensorflow.keras.callbacks import LearningRateScheduler
from sklearn.model_selection import train_test_split
import cv2 as cv
import caer
import canaro
import gc

# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" 
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session
IMG_SIZE = (80, 80)
CHANNELS = 1
CHAR_PATH = r'../input/the-simpsons-characters-dataset/simpsons_dataset'
BATCH_SIZE = 32
EPOCHS = 20
# read character names and # of images (len) from the respective directories
CHAR_DICT = {}
for char in os.listdir(CHAR_PATH):
    CHAR_DICT[char] = len(os.listdir(os.path.join(CHAR_PATH, char)))
    
# sort keys based on len value descending order
CHAR_DICT = caer.sort_dict(CHAR_DICT, descending=True)
CHAR_DICT
# consider first 10 characters
CHARACTERS = []
for i in CHAR_DICT[:10]:
    CHARACTERS.append(i[0])
    
CHARACTERS
# Create training data
train = caer.preprocess_from_dir(CHAR_PATH, CHARACTERS, channels=CHANNELS, IMG_SIZE=IMG_SIZE, isShuffle=True)
len(train)
train.shape
plt.imshow(train[0][0])
plt.show()
# Separate feature_set from labels 
feature_set, labels = caer.sep_train(train, IMG_SIZE=IMG_SIZE)
# Normalize the feaure set and get dummy of labels
feature_set = caer.normalize(feature_set)
labels = utils.to_categorical(labels, len(characters))
# Train and Validation split
# x_train, x_val, y_train, y_val = train_val_split(feature_set, labels, val_ratio=.2)
split_data = train_test_split(feature_set, labels, test_size=.2)
x_train, x_val, y_train, y_val = (np.array(item) for item in split_data)
len(feature_set), len(x_train), len(y_train), len(x_val), len(y_val)
# garbage collect
# del train
# del feature_set
# del labels
# gc.collect()
BATCH_SIZE
# Image data generator

datagen = canaro.generators.imageDataGenerator()
train_gen = datagen.flow(x_train, y_train, batch_size=BATCH_SIZE)
# Create a model
model = canaro.models.createSimpsonsModel(IMG_SIZE=IMG_SIZE, channels=CHANNELS, 
                                          output_dim=len(CHARACTERS), loss='binary_crossentropy', 
                                          decay=1e-6, learning_rate=0.001, momentum=0.9, nesterov=True)
plot_model(model)
callbacks_list = [LearningRateScheduler(canaro.lr_schedule)]
training = model.fit(train_gen,
                    steps_per_epoch = len(x_train)//BATCH_SIZE,
                    epochs = EPOCHS,
                    validation_data = (x_val, y_val),
                    validation_steps = len(y_val)//BATCH_SIZE,
                    callbacks = callbacks_list)
CHARACTERS
def preprocess_img(img):
    img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    img = cv.resize(img, IMG_SIZE)
    img = caer.reshape(img, IMG_SIZE, 1)
    return img
# Evalue Model Predictions
test_img_path = '../input/the-simpsons-characters-dataset/kaggle_simpson_testset/kaggle_simpson_testset/krusty_the_clown_5.jpg'

img = cv.imread(test_img_path)
plt.imshow(img);
plt.title('Raw Image')
plt.show();

# Process Image
processed_img = preprocess_img(img)
plt.imshow(processed_img[0]);
plt.title('Processed Image')
plt.show();
plt.imshow(processed_img[0]);
actual = 'krusty_the_clown'
prediction = model.predict(processed_img)
prediction = CHARACTERS[np.argmax(prediction[0])]

plt.title(f'Actual:{actual}, Predictions:{prediction}')
"""
__It's a correct predictions. To be honest, I had to try multiple test images, to get a correct prediction. It was expected though.. our accuracy was just 47%. We should use a better Network for better accuracy__

"""