{"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":"code","source":"# TO PRINT ALL OUTPUTS\nfrom IPython.core.interactiveshell import InteractiveShell\nInteractiveShell.ast_node_interactivity = \"all\"\n\n# INSTALLATIONS\n# Uncomment these in case an error occurs due to import\n\n#!pip install opencv-python\n#!pip install opencv-contrib-python\n#!pip install pytesseract","metadata":{"_uuid":"cdc03690-ae7b-41ae-9702-94c01cf441ee","_cell_guid":"b134abca-8b59-4a77-8f25-d318ca19d129","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:23:00.353597Z","iopub.execute_input":"2021-08-03T12:23:00.354103Z","iopub.status.idle":"2021-08-03T12:23:00.365551Z","shell.execute_reply.started":"2021-08-03T12:23:00.354032Z","shell.execute_reply":"2021-08-03T12:23:00.362733Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# IMPORTS\nimport os, sys, time, random\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport cv2 # computer vision and image processing\nfrom matplotlib import pyplot as plt # visualization\nimport imagehash # hashing\nfrom dask import bag, diagnostics # parallelizable operations\nfrom PIL import Image # Image processing\n\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.preprocessing import OneHotEncoder\n\nfrom keras.metrics import top_k_categorical_accuracy\nfrom keras import layers\nfrom keras.preprocessing import image\nfrom keras.applications.imagenet_utils import preprocess_input\nfrom keras.layers import Input, Dense, Activation, BatchNormalization, Flatten, Conv2D\nfrom keras.layers import AveragePooling2D, MaxPooling2D, Dropout\nfrom keras.models import Model\nfrom keras.losses import CategoricalCrossentropy\nimport keras.backend as K\nfrom keras.models import Sequential\nimport warnings\nwarnings.simplefilter(\"ignore\", category=DeprecationWarning)\n\n# PATHS\nTRAIN_CSV = '../input/humpback-whale-identification/train.csv'\nTRAIN = '../input/humpback-whale-identification/train/'\nTEST = '../input/humpback-whale-identification/test/'","metadata":{"_uuid":"93f2a5a5-d40f-4301-b2a5-182ac899fda6","_cell_guid":"1aef4e3a-fcb0-468d-83c1-e02eec9ab1fa","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:23:00.519739Z","iopub.execute_input":"2021-08-03T12:23:00.520236Z","iopub.status.idle":"2021-08-03T12:23:04.905843Z","shell.execute_reply.started":"2021-08-03T12:23:00.5202Z","shell.execute_reply":"2021-08-03T12:23:04.904946Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Finding Duplicates in the dataset through hashing algorithms.\n# Reused Code for Dask From https://www.kaggle.com/jpmiller/basic-eda-with-images\n# phash_simple didn't pick duplicates correctly; phash, on the other hand was better.\n# https://www.kaggle.com/martinpiotte/whale-recognition-model-with-score-0-78563\n# had multiple steps to narrow down images to only duplicates\n\ndef get_hash(file):     \n    return imagehash.phash(Image.open(file))\n\ndef build_hash_table(train_df):\n    filelist = [TRAIN + f for f in train_df['Image']]\n    hash_bag = bag.from_sequence(filelist).map(get_hash)\n    with diagnostics.ProgressBar():\n        hash_codes = hash_bag.compute()       \n    hash_codes_df = pd.DataFrame(hash_codes, columns=['hash_code'])\n    train_df['hc']  = hash_codes_df.astype('str')\n    train_df = train_df.drop_duplicates(subset=['hc'])\n    train_df = train_df.drop(columns = ['hc'], axis = 1)\n    \n    return train_df","metadata":{"_uuid":"d1c48539-bb4b-466f-8672-f31087d2500c","_cell_guid":"615d9761-80ef-428d-a054-d5ee91535c50","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:23:04.910627Z","iopub.execute_input":"2021-08-03T12:23:04.91099Z","iopub.status.idle":"2021-08-03T12:23:04.918187Z","shell.execute_reply.started":"2021-08-03T12:23:04.910953Z","shell.execute_reply":"2021-08-03T12:23:04.917325Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Read Train Data Reference\ntrain_df = pd.read_csv(TRAIN_CSV)\n\n# build_hash_table & remove duplicates\ntrain_df = build_hash_table(train_df)","metadata":{"_uuid":"691031a0-b2a7-4b19-8d11-7bb29048d669","_cell_guid":"1d4c8b55-246a-4164-9548-d5473ee6fb9c","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:23:05.491884Z","iopub.execute_input":"2021-08-03T12:23:05.492238Z","iopub.status.idle":"2021-08-03T12:28:24.545224Z","shell.execute_reply.started":"2021-08-03T12:23:05.492207Z","shell.execute_reply":"2021-08-03T12:28:24.544299Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Read Test Data Reference\ntest_df = pd.DataFrame(os.listdir(TEST),columns = ['Image'])\ntest_df['Id'] = \"\"","metadata":{"_uuid":"187c6803-78f3-4b28-ada6-3e1e274946b3","_cell_guid":"6f40872f-9f2b-4b8a-9ebf-b86ed7ebdbe0","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:28:24.551838Z","iopub.execute_input":"2021-08-03T12:28:24.55238Z","iopub.status.idle":"2021-08-03T12:28:24.56228Z","shell.execute_reply.started":"2021-08-03T12:28:24.552337Z","shell.execute_reply":"2021-08-03T12:28:24.561409Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# prepare images for Keras Model\n# Requires 4 dimensional / 3 dimensional input \n# (samples, size, size, channel)\n\nIMG_SIZE = 100\n\ndef prepare_images (df, dataset):\n    X_train = np.zeros((df.shape[0],IMG_SIZE, IMG_SIZE))\n    c = 0\n    \n    for item in df['Image']:\n        image = cv2.imread(dataset + item, 0)\n        image = cv2.resize(image,(IMG_SIZE, IMG_SIZE),cv2.INTER_NEAREST) \n        X_train[c] = image\n        c = c + 1\n        \n        if c%5000 ==1: \n            print(f'Processing Image : {c}')\n            \n    return X_train\n\ndef prepare_enc_labels(df):\n    le_enc = LabelEncoder()\n    y = df['Id']\n    encoded = le_enc.fit_transform(y)\n    ohe = OneHotEncoder(sparse=False)\n    y_train = ohe.fit_transform(encoded.reshape(len(encoded),1))\n    return y_train, le_enc","metadata":{"_uuid":"d4a3afb1-e368-4115-975b-4f2808b9d5bb","_cell_guid":"21b87b50-c325-4c5e-a68d-114a63473b73","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:28:24.5672Z","iopub.execute_input":"2021-08-03T12:28:24.567548Z","iopub.status.idle":"2021-08-03T12:28:24.576317Z","shell.execute_reply.started":"2021-08-03T12:28:24.567509Z","shell.execute_reply":"2021-08-03T12:28:24.575391Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prepare Training \n# Takes More than 5 Minutes to completely load\nX_train = prepare_images(train_df, TRAIN)\nX_train = X_train / 255  \nX_train = X_train.reshape((train_df.shape[0], IMG_SIZE, IMG_SIZE, 1))","metadata":{"_uuid":"72bbe073-c6a7-400a-8235-997ad6d3ed45","_cell_guid":"727d69ce-a328-4807-b7be-cfab4bae9bf4","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:28:24.58038Z","iopub.execute_input":"2021-08-03T12:28:24.581013Z","iopub.status.idle":"2021-08-03T12:30:35.182445Z","shell.execute_reply.started":"2021-08-03T12:28:24.580975Z","shell.execute_reply":"2021-08-03T12:30:35.18136Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prepare Labels with Encoding\ny_train, le_enc = prepare_enc_labels (train_df)","metadata":{"_uuid":"486c9abd-a34d-40a9-873e-8b404d9ae4a8","_cell_guid":"25c3c66b-f13f-4149-857c-889b67b2f6d4","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:30:35.190201Z","iopub.execute_input":"2021-08-03T12:30:35.190596Z","iopub.status.idle":"2021-08-03T12:30:35.322401Z","shell.execute_reply.started":"2021-08-03T12:30:35.190557Z","shell.execute_reply":"2021-08-03T12:30:35.321521Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Simple CNN Model\n# Chosen this network for hyperparameter tuning\n# Mostly adopted from https://www.tensorflow.org/tutorials/keras/classification\n# and https://www.kaggle.com/pestipeti/keras-cnn-starter\n\nimport tensorflow as tf\nimport tensorflow as tf\ntuned_model = Sequential()\ntuned_model.add(Conv2D(32, (5,5), strides = (1, 1), name = 'conv0', input_shape = (IMG_SIZE, IMG_SIZE, 1)))\ntuned_model.add(BatchNormalization(axis = 3, name = 'bn0'))\ntuned_model.add(Activation('tanh'))\ntuned_model.add(MaxPooling2D((2, 2), name='max_pool_1'))\n\ntuned_model.add(Conv2D(32, (5, 5), strides = (1, 1), name = 'conv1'))\ntuned_model.add(BatchNormalization(axis = 3, name = 'bn1'))\ntuned_model.add(Activation('tanh'))\ntuned_model.add(MaxPooling2D((2, 2), name='max_pool_2'))\n\ntuned_model.add(Flatten())\ntuned_model.add(Dense(units = 896, activation=\"tanh\", name='rl'))\ntuned_model.add(Dropout(0.8))\n\ntuned_model.add(Dense(y_train.shape[1], activation='softmax', name='sm'))\n\nopt = tf.keras.optimizers.Adam(learning_rate=0.0001)\n\n\ntuned_model.compile(optimizer= opt,loss='categorical_crossentropy',metrics=[tf.keras.metrics.TopKCategoricalAccuracy()])\ntuned_model.summary()","metadata":{"_uuid":"2a382bda-f986-44b5-8844-0af638938622","_cell_guid":"093de7d5-e148-4e68-a9d7-f24987588557","collapsed":false,"_kg_hide-input":false,"execution":{"iopub.status.busy":"2021-08-03T12:34:47.578453Z","iopub.execute_input":"2021-08-03T12:34:47.578845Z","iopub.status.idle":"2021-08-03T12:34:47.692743Z","shell.execute_reply.started":"2021-08-03T12:34:47.578808Z","shell.execute_reply":"2021-08-03T12:34:47.690989Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = tuned_model.fit(X_train, y_train, epochs=50, batch_size=100, verbose=1, validation_split = 0.1)","metadata":{"_uuid":"28f2a6c1-c097-4c25-b64b-980a0a65bc96","_cell_guid":"c65f55fc-5346-4dbd-b847-32d96ad89b59","collapsed":false,"scrolled":true,"execution":{"iopub.status.busy":"2021-08-03T12:35:00.162808Z","iopub.execute_input":"2021-08-03T12:35:00.163202Z","iopub.status.idle":"2021-08-03T12:39:37.90077Z","shell.execute_reply.started":"2021-08-03T12:35:00.163169Z","shell.execute_reply":"2021-08-03T12:39:37.899737Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prepare Test Data\n\nX_test = prepare_images(test_df, TEST)\nX_test = X_test/ 255\nX_test = X_test.reshape((test_df.shape[0], IMG_SIZE, IMG_SIZE, 1))","metadata":{"_uuid":"1460f556-8946-42ca-8148-e04facff98f1","_cell_guid":"55341388-87ad-4b0c-9dd2-f725c7bec8a0","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:39:37.906944Z","iopub.execute_input":"2021-08-03T12:39:37.907315Z","iopub.status.idle":"2021-08-03T12:40:43.20714Z","shell.execute_reply.started":"2021-08-03T12:39:37.907272Z","shell.execute_reply":"2021-08-03T12:40:43.2061Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Predict\npredictions = tuned_model.predict(np.array(X_test), verbose=1)","metadata":{"_uuid":"8d4d3ace-1685-449e-9181-64bcbfb6ae60","_cell_guid":"d4898705-b1d3-47b5-84a8-1b625668e3fb","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:41:36.529068Z","iopub.execute_input":"2021-08-03T12:41:36.529442Z","iopub.status.idle":"2021-08-03T12:41:38.944356Z","shell.execute_reply.started":"2021-08-03T12:41:36.529412Z","shell.execute_reply":"2021-08-03T12:41:38.943364Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i, pred in enumerate(predictions):\n    test_df.loc[i, 'Id'] = ' '.join(le_enc.inverse_transform(pred.argsort()[-5:][::-1]))","metadata":{"_uuid":"096bbdfd-2aa2-4d94-b48b-a2c7e08ce6bf","_cell_guid":"d26e64dd-e898-4dad-bd0d-9092ca25c1d9","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:41:38.9496Z","iopub.execute_input":"2021-08-03T12:41:38.949974Z","iopub.status.idle":"2021-08-03T12:41:46.07156Z","shell.execute_reply.started":"2021-08-03T12:41:38.949937Z","shell.execute_reply":"2021-08-03T12:41:46.070657Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.to_csv('submission.csv', index=False)","metadata":{"_uuid":"6aef8182-560b-422a-97e2-857299022fbf","_cell_guid":"a032028c-1cd9-4fa0-9808-0a56db8b5b5c","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:41:46.082521Z","iopub.execute_input":"2021-08-03T12:41:46.082843Z","iopub.status.idle":"2021-08-03T12:41:46.120643Z","shell.execute_reply.started":"2021-08-03T12:41:46.082808Z","shell.execute_reply":"2021-08-03T12:41:46.119723Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tuned_model.save(\"./Z5213413_FINAL.pkl\")","metadata":{"_uuid":"df8b9544-79eb-4cf6-b942-bbe5e5f51812","_cell_guid":"f2de6c2a-faad-4d03-a6b9-4e50b8083316","collapsed":false,"execution":{"iopub.status.busy":"2021-08-03T12:47:22.095733Z","iopub.execute_input":"2021-08-03T12:47:22.096151Z","iopub.status.idle":"2021-08-03T12:47:24.599296Z","shell.execute_reply.started":"2021-08-03T12:47:22.096118Z","shell.execute_reply":"2021-08-03T12:47:24.598376Z"},"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]}]}