{"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":"# Happywhale - Whale and Dolphin Identification\n### Identify whales and dolphins by unique characteristics","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-input":false}},{"cell_type":"markdown","source":"In continuation of the previous HappyWhale competition called **Humpback Whale Identification** where the objective was to identify whale ID based on the tail images of the whales, this time comptitation has been made more challenging by adding images of the dolphins and the objective has remained the same, to identify Whale/Dolphin ID on the basis of shapes, features and markings (some natural, some acquired) of dorsal fins, backs, heads and flanks.\n\nIn the below data exploration we'll see that some species of the whales and dolphins have very distinct feature which can be identifed very easily without much efforts and some species have very similar features which are very hard distingish.\n\nThis competition expands that task significantly: data in this competition contains images of over 15,000 unique individual marine mammals from 30 different species collected from 28 different research organizations. Individuals have been manually identified and given an individual_id by marine researches, and your task is to correctly identify these individuals in images. It's a challenging task that has the potential to drive significant advancements in understanding and protecting marine mammals across the globe.\n\nSo now that our objective is clear we'll start exploring the provided information.","metadata":{"_kg_hide-output":false}},{"cell_type":"code","source":"import os\nos.listdir(\"/kaggle/input/happy-whale-and-dolphin\")","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2022-02-06T20:19:53.395701Z","iopub.execute_input":"2022-02-06T20:19:53.396177Z","iopub.status.idle":"2022-02-06T20:19:53.428696Z","shell.execute_reply.started":"2022-02-06T20:19:53.396050Z","shell.execute_reply":"2022-02-06T20:19:53.427824Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In the dataset, organisor has provided us following files/folders:-\n- train.csv file\n- sample_submissing.csv\n- train_images - contains images for the training dataset\n- test_images - contains images for the test dataset","metadata":{}},{"cell_type":"markdown","source":"Lets begin with exploration of train.csv file first\n\n#### Loading libraries","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport os\nimport plotly.express as px\nfrom cv2 import imread\nfrom random import sample\n\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:53.430219Z","iopub.execute_input":"2022-02-06T20:19:53.430638Z","iopub.status.idle":"2022-02-06T20:19:55.204650Z","shell.execute_reply.started":"2022-02-06T20:19:53.430609Z","shell.execute_reply":"2022-02-06T20:19:55.203809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv(\"/kaggle/input/happy-whale-and-dolphin/train.csv\")\ndisplay(train)","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:55.205890Z","iopub.execute_input":"2022-02-06T20:19:55.206167Z","iopub.status.idle":"2022-02-06T20:19:55.317953Z","shell.execute_reply.started":"2022-02-06T20:19:55.206138Z","shell.execute_reply":"2022-02-06T20:19:55.316871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From above we can see that in the train.csv file orgainior has given three fields as follows:-\n- Images - This is the name of the image that we can find in train_images directory\n- Species - This contains name of the species of the whales and dolphines.\n- Individual_ID - This contains ID of the individual whale/dolphin. This is the target variable in this competition.","metadata":{}},{"cell_type":"code","source":"print(f'Total number of Individual = {len(train.individual_id.unique())}.')\n\nprint(f'distinct count of each Individual are as follows :-')\n\ncount_df = train.individual_id.value_counts().rename_axis('unique_values').to_frame('counts')\n\nprint(f'Following are the first 5 individual IDs based on count :-')\ndisplay(count_df.head(5))\nprint(f'Following are the last 5 individual IDs based on count :-')\ndisplay(count_df.tail(5))\n\n\nfig = px.histogram(train, x=\"individual_id\",title=\"individual_id Distrbution\",)\nfig.show()\n","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:55.320789Z","iopub.execute_input":"2022-02-06T20:19:55.321625Z","iopub.status.idle":"2022-02-06T20:19:56.846604Z","shell.execute_reply.started":"2022-02-06T20:19:55.321592Z","shell.execute_reply":"2022-02-06T20:19:56.845720Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From the above frequnency distribution table and plot we can see that there is one individual with ID **37c7aba965a5** which has maximum number of images and we can see there are many individual IDs which have just 1 image in the training dataset.\n\nAs the Individual Id is the target variable in this competition, hence we can say that this is an imbalance data problem where for some individuals we have very few images. Also there is more than 15K unique individual, hence this has a high cardinality issues as well which we may try to resolve by merging the individuals on the bases of species.","metadata":{}},{"cell_type":"code","source":"print(f'Total number of species = {len(train.species.unique())}.')\n\nprint(f'distinct count of each species are as follows :-')\n\ncount_df = train.species.value_counts().rename_axis('Species').to_frame('counts')\nprint(f'Following are the First 5 Species based on count :-')\ndisplay(count_df.head(5))\nprint(f'Following are the last 5 Species based on count :-')\ndisplay(count_df.tail(5))\n\nfig = px.histogram(train, x=\"species\",color = \"species\",title=\"Species Distrbution\")\nfig.show()\n","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:56.847758Z","iopub.execute_input":"2022-02-06T20:19:56.848093Z","iopub.status.idle":"2022-02-06T20:19:57.444684Z","shell.execute_reply.started":"2022-02-06T20:19:56.848058Z","shell.execute_reply":"2022-02-06T20:19:57.444021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"While going through the name of the species we have found that there exists two different variants of the two species names as follows:-\n- Killer Whale is given as Kiler Whale as well\n- Bottlenose Dolphin is given as Bottlenose Dolpin as well.\n\nSo our next steps would be to correct these name and to the species exploration again.","metadata":{}},{"cell_type":"code","source":"train.species = train.species.replace(\"kiler_whale\",\"killer_whale\")\ntrain.species = train.species.replace(\"bottlenose_dolpin\",\"bottlenose_dolphin\")\n\nprint(f'Total number of species = {len(train.species.unique())}.')\n\nprint(f'distinct count of each species are as follows :-')\n\ncount_df = train.species.value_counts().rename_axis('Species').to_frame('counts')\nprint(f'Following are the First 5 Species based on count :-')\ndisplay(count_df.head(5))\nprint(f'Following are the last 5 Species based on count :-')\ndisplay(count_df.tail(5))\n\nfig = px.histogram(train, x=\"species\",color = \"species\",title=\"Species Distrbution\")\nfig.show()\n","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:57.445697Z","iopub.execute_input":"2022-02-06T20:19:57.446419Z","iopub.status.idle":"2022-02-06T20:19:57.904315Z","shell.execute_reply.started":"2022-02-06T20:19:57.446376Z","shell.execute_reply":"2022-02-06T20:19:57.903332Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- As from the above histogram plot we can see that the images for different species are not equally available, hence when building model to identify the species, we'll have to use data balancing technique.","metadata":{}},{"cell_type":"code","source":"train[\"Whale_dolphin_others\"] = [x[-1] for x in train.species.str.split(\"_\")]\n\nprint(f'distinct count of each whale/dolphin/others are as follows :-')\n\ncount_df = train.Whale_dolphin_others.value_counts().rename_axis('Whale_dolphin_others').to_frame('counts')\ndisplay(count_df)\n\nfig = px.histogram(train, x=\"Whale_dolphin_others\",color = \"Whale_dolphin_others\",title=\"Whale_dolphin_others Distrbution\")\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:57.905847Z","iopub.execute_input":"2022-02-06T20:19:57.906121Z","iopub.status.idle":"2022-02-06T20:19:58.468264Z","shell.execute_reply.started":"2022-02-06T20:19:57.906091Z","shell.execute_reply":"2022-02-06T20:19:58.467280Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"After doing research on the species on google and other notebooks of the competitions, one of which is [What about species](https://www.kaggle.com/kwentar/what-about-species) where Aleksey has done a very nice exploration on the species, we concluded following :-\n- Beluga is one of the species of the whale.\n- Not found much information on google but based on the above mentioend notebook we conclude that this is one of the species of the whales.\n\nSo our next steps would be to merge the Beluga and Globis to whale, then we would explore the name proportion of the whales and dolphines.","metadata":{}},{"cell_type":"code","source":"train[\"Whale_dolphin_others\"] = [\"whale\" if x in [\"beluga\",\"globis\"] else x for x in train.Whale_dolphin_others]\n\nfig = px.pie(train.Whale_dolphin_others, values=train.Whale_dolphin_others.value_counts().values, names=train.Whale_dolphin_others.value_counts().index,title=\"Number Of Training Images Of Whales and Dolphins\")\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:58.469703Z","iopub.execute_input":"2022-02-06T20:19:58.470690Z","iopub.status.idle":"2022-02-06T20:19:58.579341Z","shell.execute_reply.started":"2022-02-06T20:19:58.470641Z","shell.execute_reply":"2022-02-06T20:19:58.578587Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From above we can see that we exactly have 1/3rd part of image data containing images for the dolphins and 2/3rd part data as whale images and rest very small percentage of Globis specie. Reason for such imbalance could be obvious that just like previous competition, this competition was orignally desgined to identify whale individuals and dolphins could be add later to increase the complexity of the of the competition.\n\nAnyway, information provided for the species would helpful in first identifing whether image belongs a whale or a dolphin and than identifying the individuals id, which is just like idenfiying the gender or the race in the human face dataset and then identifying individual.","metadata":{}},{"cell_type":"code","source":"Species_DF = train[[\"species\",\"Whale_dolphin_others\"]].drop_duplicates()\nSpecies_GP_DF=Species_DF.groupby(\"Whale_dolphin_others\").agg(\"count\").rename(columns = {\"species\": \"Species_Count\"})\n                                                                  \nfig = px.pie(Species_GP_DF, values=Species_GP_DF.Species_Count, names=Species_GP_DF.index,title='Number Of Unique Species In Whales and Dolphins')\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:58.582420Z","iopub.execute_input":"2022-02-06T20:19:58.583042Z","iopub.status.idle":"2022-02-06T20:19:58.646805Z","shell.execute_reply.started":"2022-02-06T20:19:58.583002Z","shell.execute_reply":"2022-02-06T20:19:58.646143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From above we noticed that we have imbalance in the number of species of Dolphins and Whales as well. **Count of Dolphins spccies are almost 50% of the count of Whale species.**\n\nFuther lets explore number of Individual IDs on the Dophin/Whale group. ","metadata":{}},{"cell_type":"code","source":"Individuals_DF = train[[\"individual_id\",\"Whale_dolphin_others\"]].drop_duplicates()\nIndividuals_GP_DF = Individuals_DF.groupby(\"Whale_dolphin_others\").agg(\"count\").rename(columns = {\"individual_id\": \"Individual_ID_Count\"}) \n# display(Individuals_DF.groupby(\"Whale_dolphin_others\").agg(\"count\").rename(columns = {\"individual_id\": \"Individual_ID_Count\"}))\n\nfig = px.pie(Individuals_GP_DF, values=Individuals_GP_DF.Individual_ID_Count, names=Individuals_GP_DF.index,title='Number Of Individuals In Whales and Dolphins')\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:58.649015Z","iopub.execute_input":"2022-02-06T20:19:58.649405Z","iopub.status.idle":"2022-02-06T20:19:58.716373Z","shell.execute_reply.started":"2022-02-06T20:19:58.649374Z","shell.execute_reply":"2022-02-06T20:19:58.715422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Found Whales and Dolphins individual counts, we noticed that **count of unique individuals in Dolphin category are also almost 50% of the count of individuals in Whale Category.**\n\nNow that we have explored count of individuals in Dolphins and whales, we should now explore the number of Individuals in each species.","metadata":{}},{"cell_type":"code","source":"Individuals_DF = train[[\"individual_id\",\"species\"]].drop_duplicates()\nIndividuals_GP_DF = Individuals_DF.groupby(\"species\").agg(\"count\").rename(columns = {\"individual_id\": \"Individual_ID_Count\"}) \n\nc = dict(zip(Individuals_GP_DF.index.unique(), px.colors.qualitative.Alphabet))\nfig = px.pie(Individuals_GP_DF, values=Individuals_GP_DF.Individual_ID_Count,names=Individuals_GP_DF.index,color=Individuals_GP_DF.index,color_discrete_map=c,title='Species Wise Number of Individuals')\nfig.show()\n\ncount_df = train.species.value_counts().rename_axis('Species').to_frame('Imgae_counts')\nfig = px.pie(count_df, values=count_df.Imgae_counts, names=count_df.index,color=count_df.index,color_discrete_map=c,title='Species Wise Number of Images in training data')\nfig.show()\n","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:58.717755Z","iopub.execute_input":"2022-02-06T20:19:58.718452Z","iopub.status.idle":"2022-02-06T20:19:58.845998Z","shell.execute_reply.started":"2022-02-06T20:19:58.718405Z","shell.execute_reply":"2022-02-06T20:19:58.844821Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"by comparing number of individuals in each species by number of image count in the data we found following:-\n\n- By Individual count Dusky_dolphin has the most individuals which is not even in top 5 by training image count of species.\n- Beluga which is at the 2nd in training image count chart is at the 5th in Individual count chart.\n- BottleNose Dolphin which has most training images has is not even in top 5 species by Individual IDs count.\n- Humpback Whale and Blue Whale has almost similar position in the top 5 categories in both charts\n- Mellon Head Whale which is at the 4th in Individual count chart is on 9th in training image count chart.","metadata":{}},{"cell_type":"markdown","source":"Now that we have explored train.csv file, next let have a submission.csv file ","metadata":{}},{"cell_type":"code","source":"submission = pd.read_csv(\"/kaggle/input/happy-whale-and-dolphin/sample_submission.csv\")\ndisplay(submission)","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:58.847287Z","iopub.execute_input":"2022-02-06T20:19:58.847951Z","iopub.status.idle":"2022-02-06T20:19:58.925855Z","shell.execute_reply.started":"2022-02-06T20:19:58.847886Z","shell.execute_reply":"2022-02-06T20:19:58.924930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From the above sample submission file we can see our objective is submit top 5 Individual IDs which matches with the test image. organisor has mentioned that there can be some images in the test dataset which may not exists in the training data. Hence for those image we'll have predict new category called **new_individual**    ","metadata":{}},{"cell_type":"markdown","source":"## Image Data Exploration","metadata":{}},{"cell_type":"markdown","source":"Orgranisor has given us more than 51K images of Whales and dolphins mix. As our first step would to explore the images whales and dolphins seperately then we would explore images of the species.","metadata":{}},{"cell_type":"code","source":"def plot_grid(Images,species,n):\n    plt.figure(figsize=(15,15))\n    for i in range(1,n*n+1):\n        plt.subplot(n,n,i,frameon=False)\n        # plt.tight_layout()\n        plt.imshow(Images[i-1])\n        plt.title(species)","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:58.929038Z","iopub.execute_input":"2022-02-06T20:19:58.929447Z","iopub.status.idle":"2022-02-06T20:19:58.935273Z","shell.execute_reply.started":"2022-02-06T20:19:58.929411Z","shell.execute_reply":"2022-02-06T20:19:58.934227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Whale Images","metadata":{}},{"cell_type":"code","source":"train_image_path = \"/kaggle/input/happy-whale-and-dolphin/train_images\"\ntest_image_path = \"/kaggle/input/happy-whale-and-dolphin/test_images\"\n\nGrid_size = 4\n\nwhale_Image_id = sample(list(train[train.Whale_dolphin_others==\"whale\"].image),Grid_size*Grid_size)\nwhale_images = [imread(os.path.join(train_image_path,x)) for x in whale_Image_id]\nplot_grid(whale_images,\"Whale\",Grid_size)","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:19:58.936526Z","iopub.execute_input":"2022-02-06T20:19:58.937328Z","iopub.status.idle":"2022-02-06T20:20:10.796890Z","shell.execute_reply.started":"2022-02-06T20:19:58.937291Z","shell.execute_reply":"2022-02-06T20:20:10.796003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"whale_Image_id = sample(list(train[train.Whale_dolphin_others==\"whale\"].image),Grid_size*Grid_size)\nwhale_images = [imread(os.path.join(train_image_path,x)) for x in whale_Image_id]\nplot_grid(whale_images,\"Whale\",Grid_size)","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:20:10.798083Z","iopub.execute_input":"2022-02-06T20:20:10.798298Z","iopub.status.idle":"2022-02-06T20:20:23.257616Z","shell.execute_reply.started":"2022-02-06T20:20:10.798274Z","shell.execute_reply":"2022-02-06T20:20:23.256534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Dolphin Images","metadata":{}},{"cell_type":"code","source":"dolphin_Image_id = sample(list(train[train.Whale_dolphin_others==\"dolphin\"].image),Grid_size*Grid_size)\ndolphin_images = [imread(os.path.join(train_image_path,x)) for x in dolphin_Image_id]\nplot_grid(dolphin_images,\"Dolphin\",Grid_size)","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:20:23.259116Z","iopub.execute_input":"2022-02-06T20:20:23.259397Z","iopub.status.idle":"2022-02-06T20:20:38.151406Z","shell.execute_reply.started":"2022-02-06T20:20:23.259362Z","shell.execute_reply":"2022-02-06T20:20:38.150676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dolphin_Image_id = sample(list(train[train.Whale_dolphin_others==\"dolphin\"].image),Grid_size*Grid_size)\ndolphin_images = [imread(os.path.join(train_image_path,x)) for x in dolphin_Image_id]\nplot_grid(dolphin_images,\"Dolphin\",Grid_size)","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:20:38.152359Z","iopub.execute_input":"2022-02-06T20:20:38.153108Z","iopub.status.idle":"2022-02-06T20:20:52.410201Z","shell.execute_reply.started":"2022-02-06T20:20:38.153066Z","shell.execute_reply":"2022-02-06T20:20:52.409126Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Image Samples for each Species ","metadata":{}},{"cell_type":"code","source":"for i in train.species.unique():\n    species_image_id = sample(list(train[train.species==i].image),4)\n    species_images = [imread(os.path.join(train_image_path,x)) for x in species_image_id]\n    plot_grid(species_images,i,2)\n    ","metadata":{"execution":{"iopub.status.busy":"2022-02-06T20:20:52.411564Z","iopub.execute_input":"2022-02-06T20:20:52.411831Z","iopub.status.idle":"2022-02-06T20:22:28.740935Z","shell.execute_reply.started":"2022-02-06T20:20:52.411798Z","shell.execute_reply":"2022-02-06T20:22:28.739884Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Futher point to work on:-\n- As we can see from the image data exploration all images are not of the similar dimension, hence it would a good idea to explore the dimension distribution over dolphine and whales as well as on differnt species to explore for the biasness in the image dataset.\n-  Explore issues in the images like blur effect, high brightness, low contrast etc.\n\n\nThis above exploration of the image dataset would be helpful in chosing the required image augmentations and chosing the base NN architecture desgin,  ","metadata":{}},{"cell_type":"markdown","source":"# To be continued..","metadata":{}}]}