{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Introduction to Finding Disney Problem Statement\nOur approach - In order to classify different Disney characters, we need a classification model based on CNNs. We have used Google's Tensorflow as the DL framework as it supports the high level Keras API. Tensorflow Hub was used to fetch mobilenet_v2. We added a layer to suit our need and retrained the model.\n\nData organization - Upon having a look at the dataset we found few corrupt files, images containing both Mickey and Donald and similar noisy data, thus we could not use the dataset available on kaggle and had to re-upload the dataset with the change. All the images were converted to a size 224\\*224 including training and test data. The dataset didn't had augmented images so we have to do it.","metadata":{}},{"cell_type":"markdown","source":"## **1. Importing Necessary Libraries 🧾**","metadata":{}},{"cell_type":"code","source":"# Necessary utility modules and libraries\nimport os\nimport shutil\nimport pathlib\nimport random\nimport datetime\n# Plotting libraries \nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nfrom PIL import ImageFile, Image\nimport cv2\nImageFile.LOAD_TRUNCATED_IMAGES = True\n\n# Libraries for building the model\nimport tensorflow as tf\nimport tensorflow_hub as hub\nimport tensorflow as tf\nfrom tensorflow.keras import datasets, layers, models\nfrom tensorflow.keras.preprocessing import image_dataset_from_directory\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.layers import Dense, Conv2D, Flatten, MaxPool2D\nfrom keras.models import Sequential\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"id":"x0Cm8BBJdaYs","execution":{"iopub.status.busy":"2022-11-10T21:05:35.638218Z","iopub.execute_input":"2022-11-10T21:05:35.638672Z","iopub.status.idle":"2022-11-10T21:05:37.467257Z","shell.execute_reply.started":"2022-11-10T21:05:35.638586Z","shell.execute_reply":"2022-11-10T21:05:37.466261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install gdown","metadata":{"id":"dwlWKxMkdgbB","outputId":"d09b1918-d5d1-4511-e055-0f3727e88449","execution":{"iopub.status.busy":"2022-11-10T21:05:37.469486Z","iopub.execute_input":"2022-11-10T21:05:37.470501Z","iopub.status.idle":"2022-11-10T21:05:46.805035Z","shell.execute_reply.started":"2022-11-10T21:05:37.470461Z","shell.execute_reply":"2022-11-10T21:05:46.803835Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **2. Downloading the dataset from Google Drive ☁️**","metadata":{}},{"cell_type":"code","source":"!gdown --id 1rkhzvsXYfpNFufYbmTWABtS6kxozevjB","metadata":{"id":"WAvZ8OcfdjOu","outputId":"b02ad6ec-78a3-429b-ad43-eb903c4d4011","execution":{"iopub.status.busy":"2022-11-10T21:05:46.807697Z","iopub.execute_input":"2022-11-10T21:05:46.808619Z","iopub.status.idle":"2022-11-10T21:05:48.982228Z","shell.execute_reply.started":"2022-11-10T21:05:46.808565Z","shell.execute_reply":"2022-11-10T21:05:48.981049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!unzip disney.zip","metadata":{"id":"wU2t41pydpIS","outputId":"2c4f15d2-19a8-4968-e7db-0dd24cd39d87","execution":{"iopub.status.busy":"2022-11-10T21:05:48.986232Z","iopub.execute_input":"2022-11-10T21:05:48.987981Z","iopub.status.idle":"2022-11-10T21:05:52.054110Z","shell.execute_reply.started":"2022-11-10T21:05:48.987935Z","shell.execute_reply":"2022-11-10T21:05:52.052754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **3. Fixing Data format and path 🔧**","metadata":{}},{"cell_type":"code","source":"train_path = \"disney/train/train\"\ntest_path = \"disney/test/test\"\nbatch_size = 32\nimg_height = 224\nimg_width = 224","metadata":{"id":"dZnPI1vldzS5","execution":{"iopub.status.busy":"2022-11-10T21:05:52.056316Z","iopub.execute_input":"2022-11-10T21:05:52.056770Z","iopub.status.idle":"2022-11-10T21:05:52.062667Z","shell.execute_reply.started":"2022-11-10T21:05:52.056724Z","shell.execute_reply":"2022-11-10T21:05:52.061588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images = []\nfor folder in os.listdir(train_path):\n  for image in os.listdir(train_path + '/' + folder):\n    images.append(os.path.join(train_path, folder, image))\n\nplt.figure(1, figsize=(15, 9))\nplt.axis('off')\nn = 0\nfor i in range(16):\n  n += 1\n  random_img = random.choice(images)\n  imgs = cv2.imread(random_img)\n  plt.subplot(4, 4, n)\n  plt.axis('off')\n  rgb = cv2.cvtColor(imgs, cv2.COLOR_BGR2RGB)\n  plt.imshow(rgb)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-11-10T21:06:19.647629Z","iopub.execute_input":"2022-11-10T21:06:19.648710Z","iopub.status.idle":"2022-11-10T21:06:20.600409Z","shell.execute_reply.started":"2022-11-10T21:06:19.648666Z","shell.execute_reply":"2022-11-10T21:06:20.599361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **4. Image Augmentation 🔁**","metadata":{}},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(rescale=1./255,shear_range=.2,zoom_range=.2,horizontal_flip=True)\ntest_datagen = ImageDataGenerator(rescale=1./255)","metadata":{"id":"PJXPhycXdrQ4","execution":{"iopub.status.busy":"2022-11-10T21:06:20.602127Z","iopub.execute_input":"2022-11-10T21:06:20.603187Z","iopub.status.idle":"2022-11-10T21:06:20.609586Z","shell.execute_reply.started":"2022-11-10T21:06:20.603149Z","shell.execute_reply":"2022-11-10T21:06:20.608492Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_set = train_datagen.flow_from_directory(train_path,target_size=(img_height,img_width),batch_size=batch_size,color_mode=\"rgb\",\n                                                 class_mode='categorical',shuffle=True,subset='training')\ntest_set = test_datagen.flow_from_directory(\"disney/test\",target_size=(img_height,img_width),\n                                            batch_size=batch_size, shuffle=False,color_mode=\"rgb\",class_mode=None)\n","metadata":{"id":"KpudO7lbd9j9","outputId":"9e370e00-c258-474e-c045-bbddc426cf25","execution":{"iopub.status.busy":"2022-11-10T21:06:20.611161Z","iopub.execute_input":"2022-11-10T21:06:20.612012Z","iopub.status.idle":"2022-11-10T21:06:20.931263Z","shell.execute_reply.started":"2022-11-10T21:06:20.611974Z","shell.execute_reply":"2022-11-10T21:06:20.930265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **5. Defining and Training the Model 🤖**","metadata":{}},{"cell_type":"code","source":"def create_model(model_url, num_classes, img_size=(224,224)):\n    '''\n    Creates a tensorflow model using the model_url and the no. of different classes.\n\n    model_url: The url of the pretrained tensorflow hub model\n    num_classes: The no. of different classes.\n    '''\n    # Download the pre-trained model and use it as a keras layer\n    feature_extraction = hub.KerasLayer(model_url, trainable=False, input_shape=(img_size)+(3,), name=\"feature_extractor_layer\")\n    \n    # Create our own model\n    model = tf.keras.Sequential([\n        feature_extraction,\n        layers.Dense(num_classes, activation=\"softmax\", name=\"output_layer\")                             \n    ])\n\n    # Returns uncompiled model\n    return model","metadata":{"id":"x3AAm5fSeQhj","execution":{"iopub.status.busy":"2022-11-10T21:06:20.933890Z","iopub.execute_input":"2022-11-10T21:06:20.934249Z","iopub.status.idle":"2022-11-10T21:06:20.940478Z","shell.execute_reply.started":"2022-11-10T21:06:20.934213Z","shell.execute_reply":"2022-11-10T21:06:20.939561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Model URL\nmobilenet_v2 = \"https://tfhub.dev/google/imagenet/mobilenet_v2_130_224/classification/5\"\n\n# Creating the Efficient-net model\nmodel_mobilenet_v2 = create_model(model_url=mobilenet_v2,num_classes=6)\n\n# Compile the model\nmodel_mobilenet_v2.compile(loss=\"categorical_crossentropy\", optimizer=tf.keras.optimizers.Adam(), metrics=[\"accuracy\"])\n\n# Summary of the model\nmodel_mobilenet_v2.summary()","metadata":{"id":"65rArNMKeTxt","outputId":"d46055db-6d93-4594-9484-faba8859e8e4","execution":{"iopub.status.busy":"2022-11-10T21:06:20.942024Z","iopub.execute_input":"2022-11-10T21:06:20.942687Z","iopub.status.idle":"2022-11-10T21:06:27.079719Z","shell.execute_reply.started":"2022-11-10T21:06:20.942649Z","shell.execute_reply":"2022-11-10T21:06:27.078594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def my_gen(gen):\n    while True:\n        try:\n            data, labels = next(gen)\n            yield data, labels\n        except:\n            pass","metadata":{"id":"aB1OpPZRelxQ","execution":{"iopub.status.busy":"2022-11-10T21:06:27.081227Z","iopub.execute_input":"2022-11-10T21:06:27.081592Z","iopub.status.idle":"2022-11-10T21:06:27.087141Z","shell.execute_reply.started":"2022-11-10T21:06:27.081556Z","shell.execute_reply":"2022-11-10T21:06:27.086019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model_mobilenet_v2.fit_generator(my_gen(training_set),epochs=15,steps_per_epoch=len(training_set))","metadata":{"id":"TBM88MfAeZIm","outputId":"54e0289c-8df7-465d-afe3-c10730573714","execution":{"iopub.status.busy":"2022-11-10T21:06:27.088850Z","iopub.execute_input":"2022-11-10T21:06:27.089233Z","iopub.status.idle":"2022-11-10T21:15:41.991786Z","shell.execute_reply.started":"2022-11-10T21:06:27.089197Z","shell.execute_reply":"2022-11-10T21:15:41.990686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **6. Generating Predictions 🤔**","metadata":{}},{"cell_type":"code","source":"predicts = model_mobilenet_v2.predict_generator(test_set, verbose = True)","metadata":{"id":"i8UUh0s3edyv","outputId":"3c785702-461c-4137-cfc2-8debea475915","execution":{"iopub.status.busy":"2022-11-10T21:15:41.993492Z","iopub.execute_input":"2022-11-10T21:15:41.994459Z","iopub.status.idle":"2022-11-10T21:15:43.685456Z","shell.execute_reply.started":"2022-11-10T21:15:41.994420Z","shell.execute_reply":"2022-11-10T21:15:43.684502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict = np.argmax(predicts,axis=-1)\nlabel_index = {v: k for k,v in training_set.class_indices.items()}\n\nsubmit = [label_index[p] for p in predict]\n\ndf = pd.DataFrame(columns=['character_id', 'label'])\ndf['character_id'] = [os.path.basename(x) for x in test_set.filenames]\ndf['label'] = submit","metadata":{"id":"c4IAK439gs6J","execution":{"iopub.status.busy":"2022-11-10T21:15:43.687402Z","iopub.execute_input":"2022-11-10T21:15:43.688124Z","iopub.status.idle":"2022-11-10T21:15:43.717507Z","shell.execute_reply.started":"2022-11-10T21:15:43.688084Z","shell.execute_reply":"2022-11-10T21:15:43.716268Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['character_id'] = df.character_id.apply(lambda x: x.split('.')[0])","metadata":{"id":"tq0fxUzqheyP","execution":{"iopub.status.busy":"2022-11-10T21:15:43.721221Z","iopub.execute_input":"2022-11-10T21:15:43.721496Z","iopub.status.idle":"2022-11-10T21:15:43.729699Z","shell.execute_reply.started":"2022-11-10T21:15:43.721471Z","shell.execute_reply":"2022-11-10T21:15:43.728508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"id":"Qw6EvhvBhnk1","outputId":"73ca4837-257c-46bc-c764-d69289869568","execution":{"iopub.status.busy":"2022-11-10T21:15:43.731364Z","iopub.execute_input":"2022-11-10T21:15:43.732202Z","iopub.status.idle":"2022-11-10T21:15:43.750345Z","shell.execute_reply.started":"2022-11-10T21:15:43.732164Z","shell.execute_reply":"2022-11-10T21:15:43.749401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.to_csv('submission.csv',index=False)","metadata":{"id":"ggvPCxwKhtVj","execution":{"iopub.status.busy":"2022-11-10T21:15:43.751429Z","iopub.execute_input":"2022-11-10T21:15:43.752800Z","iopub.status.idle":"2022-11-10T21:15:43.765402Z","shell.execute_reply.started":"2022-11-10T21:15:43.752762Z","shell.execute_reply":"2022-11-10T21:15:43.764569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from IPython.display import HTML\nimport base64\n\n# function that takes in a dataframe and creates a text link to  \ndef create_download_link(df, title = \"Download CSV file\", filename = \"submission.csv\"):  \n    csv = df.to_csv(index=False)\n    b64 = base64.b64encode(csv.encode())\n    payload = b64.decode()\n    html = '<a download=\"{filename}\" href=\"data:text/csv;base64,{payload}\" target=\"_blank\">{title}</a>'\n    html = html.format(payload=payload,title=title,filename=filename)\n    return HTML(html)\n\n# create a random sample dataframe\ndata = df\n\n# create a link to download the dataframe\ncreate_download_link(data)","metadata":{"id":"5PnhF0j_iGmV","outputId":"33d56def-1185-43b7-fb6a-c437a353f22f","execution":{"iopub.status.busy":"2022-11-10T21:18:58.477268Z","iopub.execute_input":"2022-11-10T21:18:58.477693Z","iopub.status.idle":"2022-11-10T21:18:58.489910Z","shell.execute_reply.started":"2022-11-10T21:18:58.477661Z","shell.execute_reply":"2022-11-10T21:18:58.488843Z"},"trusted":true},"execution_count":null,"outputs":[]}]}