{"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":"# <div style=\"color:white;display:fill;border-radius:5px;background-color:#75B7BF;letter-spacing:0.1px;overflow:hidden\"><p style=\"padding:20px;color:white;overflow:hidden;margin:0;font-size:100%;text-align:center\">IMPORT</p></div>\n****\n","metadata":{}},{"cell_type":"code","source":"!pip install -U -q kaleido","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:19.617497Z","iopub.execute_input":"2022-03-29T07:56:19.617812Z","iopub.status.idle":"2022-03-29T07:56:28.533713Z","shell.execute_reply.started":"2022-03-29T07:56:19.617782Z","shell.execute_reply":"2022-03-29T07:56:28.532740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"\\n... IMPORTS STARTING ...\\n\")\n\n# print(\"\\n... PIP/APT INSTALLS AND DOWNLOADS/ZIP STARTING ...\")\n# print(\"... PIP/APT INSTALLS COMPLETE ...\\n\")\n\nprint(\"\\n\\tVERSION INFORMATION\")\n# Machine Learning and Data Science Imports\nimport tensorflow as tf; print(f\"\\t\\t– TENSORFLOW VERSION: {tf.__version__}\");\nimport tensorflow_addons as tfa; print(f\"\\t\\t– TENSORFLOW ADDONS VERSION: {tfa.__version__}\");\nimport pandas as pd; pd.options.mode.chained_assignment = None;\nimport numpy as np; print(f\"\\t\\t– NUMPY VERSION: {np.__version__}\");\nimport sklearn; print(f\"\\t\\t– SKLEARN VERSION: {sklearn.__version__}\");\nfrom sklearn.preprocessing import RobustScaler, PolynomialFeatures\nfrom pandarallel import pandarallel; pandarallel.initialize();\nfrom sklearn.model_selection import GroupKFold;\n\n# RAPIDS\n# import cudf, cupy, cuml\n\n# Built In Imports\nfrom kaggle_datasets import KaggleDatasets\nfrom collections import Counter\nfrom datetime import datetime\nfrom glob import glob\nimport warnings\nimport requests\nimport hashlib\nimport imageio\nimport IPython\nimport sklearn\nimport urllib\nimport zipfile\nimport pickle\nimport random\nimport shutil\nimport string\nimport json\nimport math\nimport time\nimport gzip\nimport ast\nimport sys\nimport io\nimport os\nimport gc\nimport re\n\n# Visualization Imports\nfrom matplotlib.colors import ListedColormap\nimport matplotlib.patches as patches\nimport plotly.graph_objects as go\nimport matplotlib.pyplot as plt\nfrom tqdm.notebook import tqdm; tqdm.pandas();\nimport plotly.express as px\nimport seaborn as sns\nfrom PIL import Image, ImageEnhance\nimport matplotlib; print(f\"\\t\\t– MATPLOTLIB VERSION: {matplotlib.__version__}\");\nfrom matplotlib import animation, rc; rc('animation', html='jshtml')\nimport plotly\nimport PIL\nimport cv2\n\ndef seed_it_all(seed=42):\n    \"\"\" Attempt to be Reproducible \"\"\"\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    random.seed(seed)\n    np.random.seed(seed)\n    tf.random.set_seed(seed)\n\n    \nprint(\"\\n\\n... IMPORTS COMPLETE ...\\n\")","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:28.537801Z","iopub.execute_input":"2022-03-29T07:56:28.538090Z","iopub.status.idle":"2022-03-29T07:56:28.555007Z","shell.execute_reply.started":"2022-03-29T07:56:28.538059Z","shell.execute_reply":"2022-03-29T07:56:28.554273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <div style=\"color:white;display:fill;border-radius:5px;background-color:#75B7BF;letter-spacing:0.1px;overflow:hidden\"><p style=\"padding:20px;color:white;overflow:hidden;margin:0;font-size:100%;text-align:center\">SETUP</p></div>\n****\n","metadata":{}},{"cell_type":"code","source":"print(f\"\\n... ACCELERATOR SETUP STARTING ...\\n\")\n\n# Detect hardware, return appropriate distribution strategy\ntry:\n    # TPU detection. No parameters necessary if TPU_NAME environment variable is set. On Kaggle this is always the case.\n    TPU = tf.distribute.cluster_resolver.TPUClusterResolver()  \nexcept ValueError:\n    TPU = None\n\nif TPU:\n    print(f\"\\n... RUNNING ON TPU - {TPU.master()}...\")\n    tf.config.experimental_connect_to_cluster(TPU)\n    tf.tpu.experimental.initialize_tpu_system(TPU)\n    strategy = tf.distribute.experimental.TPUStrategy(TPU)\nelse:\n    print(f\"\\n... RUNNING ON CPU/GPU ...\")\n    # Yield the default distribution strategy in Tensorflow\n    #   --> Works on CPU and single GPU.\n    strategy = tf.distribute.get_strategy() \n\n# What Is a Replica?\n#    --> A single Cloud TPU device consists of FOUR chips, each of which has TWO TPU cores. \n#    --> Therefore, for efficient utilization of Cloud TPU, a program should make use of each of the EIGHT (4x2) cores. \n#    --> Each replica is essentially a copy of the training graph that is run on each core and \n#        trains a mini-batch containing 1/8th of the overall batch size\nN_REPLICAS = strategy.num_replicas_in_sync\n    \nprint(f\"... # OF REPLICAS: {N_REPLICAS} ...\\n\")\n\nprint(f\"\\n... ACCELERATOR SETUP COMPLTED ...\\n\")","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:28.555942Z","iopub.execute_input":"2022-03-29T07:56:28.556369Z","iopub.status.idle":"2022-03-29T07:56:28.566947Z","shell.execute_reply.started":"2022-03-29T07:56:28.556318Z","shell.execute_reply":"2022-03-29T07:56:28.566091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"\\n... DATA ACCESS SETUP STARTED ...\\n\")\n\nif TPU:\n    # Google Cloud Dataset path to training and validation images\n    DATA_DIR = KaggleDatasets().get_gcs_path('happy-whale-and-dolphin')\n    save_locally = tf.saved_model.SaveOptions(experimental_io_device='/job:localhost')\n    load_locally = tf.saved_model.LoadOptions(experimental_io_device='/job:localhost')\nelse:\n    # Local path to training and validation images\n    DATA_DIR = \"/kaggle/input/happy-whale-and-dolphin\"\n    save_locally = None\n    load_locally = None\n\nEXTRA_DATA_DIR = \"/kaggle/input/extra-happywhale-metadata\"\nEMBED_DATA_DIR = \"/kaggle/input/baseline-solution-train-embed\"\n    \nprint(f\"\\n... DATA DIRECTORY PATH IS:\\n\\t--> {DATA_DIR}\")\nprint(f\"\\n... EXTRA METADATA DIRECTORY PATH IS:\\n\\t--> {EXTRA_DATA_DIR}\")\n\nprint(f\"\\n... IMMEDIATE CONTENTS OF DATA DIRECTORY IS:\")\nfor file in tf.io.gfile.glob(os.path.join(DATA_DIR, \"*\")): print(f\"\\t--> {file}\")\n\nprint(f\"\\n... IMMEDIATE CONTENTS OF EXTRA METADATA DIRECTORY IS:\")\nfor file in tf.io.gfile.glob(os.path.join(EXTRA_DATA_DIR, \"*\")): print(f\"\\t--> {file}\")\n\nprint(f\"\\n... IMMEDIATE CONTENTS OF EMBED DATA DIRECTORY IS:\")\nfor file in tf.io.gfile.glob(os.path.join(EMBED_DATA_DIR, \"*\")): print(f\"\\t--> {file}\")\n\n","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:28.568764Z","iopub.execute_input":"2022-03-29T07:56:28.568982Z","iopub.status.idle":"2022-03-29T07:56:28.589933Z","shell.execute_reply.started":"2022-03-29T07:56:28.568957Z","shell.execute_reply":"2022-03-29T07:56:28.589360Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"\\n... XLA OPTIMIZATIONS STARTING ...\\n\")\n\nprint(f\"\\n... CONFIGURE JIT (JUST IN TIME) COMPILATION ...\\n\")\n# enable XLA optmizations (10% speedup when using @tf.function calls)\ntf.config.optimizer.set_jit(True)\n\nprint(f\"\\n... XLA OPTIMIZATIONS COMPLETED ...\\n\")","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:28.590824Z","iopub.execute_input":"2022-03-29T07:56:28.591093Z","iopub.status.idle":"2022-03-29T07:56:28.596562Z","shell.execute_reply.started":"2022-03-29T07:56:28.591061Z","shell.execute_reply":"2022-03-29T07:56:28.596057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <div style=\"color:white;display:fill;border-radius:5px;background-color:#75B7BF;letter-spacing:0.1px;overflow:hidden\"><p style=\"padding:20px;color:white;overflow:hidden;margin:0;font-size:100%;text-align:center\">HELPING FUNCTIONS</p></div>\n****","metadata":{}},{"cell_type":"markdown","source":"# <div style=\"color:white;display:fill;border-radius:5px;background-color:#75B7BF;letter-spacing:0.1px;overflow:hidden\"><p style=\"padding:20px;color:white;overflow:hidden;margin:0;font-size:100%;text-align:center\">LOADING DATA</p></div>\n****\n","metadata":{}},{"cell_type":"code","source":"TRAIN_CSV = os.path.join(DATA_DIR, \"train.csv\")\ntrain_df = pd.read_csv(TRAIN_CSV)","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:28.597628Z","iopub.execute_input":"2022-03-29T07:56:28.598469Z","iopub.status.idle":"2022-03-29T07:56:28.673023Z","shell.execute_reply.started":"2022-03-29T07:56:28.598433Z","shell.execute_reply":"2022-03-29T07:56:28.672374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check the number of train_images and length of csv file.\nif len(os.listdir('../input/happy-whale-and-dolphin/train_images')) == train_df.shape[0]:\n    train_len = train_df.shape[0]\nelse:\n    print(\"Check again your training folder dataset!\")","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:28.674055Z","iopub.execute_input":"2022-03-29T07:56:28.674463Z","iopub.status.idle":"2022-03-29T07:56:28.702903Z","shell.execute_reply.started":"2022-03-29T07:56:28.674419Z","shell.execute_reply":"2022-03-29T07:56:28.701966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:28.704171Z","iopub.execute_input":"2022-03-29T07:56:28.704410Z","iopub.status.idle":"2022-03-29T07:56:28.716386Z","shell.execute_reply.started":"2022-03-29T07:56:28.704382Z","shell.execute_reply":"2022-03-29T07:56:28.715523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"\\n... BASIC DATA SETUP STARTING ...\\n\\n\")\n\n# Thanks @karthickp6 for noticing this\nFIX_NAME_MAPPING = {\"bottlenose_dolpin\":\"bottlenose_dolphin\", \n                    \"kiler_whale\":\"killer_whale\",\n                    \"pilot_whale\":\"short_finned_pilot_whale\",\n                    \"globis\":\"short_finned_pilot_whale\"}\n\nprint(\"\\n... TRAIN DATAFRAME ...\\n\")\n# Image Path \ntrain_df[\"img_path\"] = os.path.join(DATA_DIR, \"train_images\")+\"/\"+train_df.image\n# Image Shape\nif os.path.isdir(EXTRA_DATA_DIR):\n    EX_META_TRAIN_CSV = os.path.join(EXTRA_DATA_DIR, \"train.csv\")\n    ex_train_df = pd.read_csv(EX_META_TRAIN_CSV)\n    train_df[\"img_shape\"] = ex_train_df[\"img_shape\"]\n    train_df[\"img_width\"] = ex_train_df[\"img_width\"]\n    train_df[\"img_height\"] = ex_train_df[\"img_height\"]\nelse:\n    train_df[\"img_shape\"] = [plt.imread(train_df[\"img_path\"].values[i]).shape for i in range(train_len)]\n    train_df[\"img_width\"] = train_df[\"img_shape\"][1]\n    train_df[\"img_height\"] = train_df[\"img_shape\"][0]\ntrain_df[\"species\"] = train_df[\"species\"].apply(lambda x: x if x not in FIX_NAME_MAPPING.keys() else FIX_NAME_MAPPING[x])\nall_species = sorted(train_df.species.unique().tolist())\n# The number of each image of Individual ID\ntrain_df[\"n_img_of_ind\"] = train_df.individual_id.map(train_df.individual_id.value_counts().to_dict())\nspecies_int2str_map = {i:_s for i,_s in enumerate(all_species)}\nspecies_str2int_map = {v:k for k,v in species_int2str_map.items()}\n\nall_individuals = sorted(train_df.individual_id.unique().tolist())\nind_int2str_map = {i:_s for i,_s in enumerate(all_individuals)}\nind_str2int_map = {v:k for k,v in ind_int2str_map.items()}\n\ntrain_df[\"ind_sparse\"] = train_df[\"individual_id\"].map(ind_str2int_map)\ntrain_df[\"species_sparse\"] = train_df[\"species\"].map(species_str2int_map)\n\ndisplay(train_df)\n\nprint(\"\\n... TEST DATAFRAME ...\\n\")\nTEST_CSV = os.path.join(DATA_DIR, \"sample_submission.csv\")\nEX_META_TEST_CSV = os.path.join(EXTRA_DATA_DIR, \"test.csv\")\ntest_df = pd.read_csv(TEST_CSV)\nex_test_df = pd.read_csv(EX_META_TEST_CSV)\ntest_df[\"img_path\"] = os.path.join(DATA_DIR, \"test_images\")+\"/\"+test_df.image\ntest_df[\"img_shape\"] = ex_test_df[\"img_shape\"]\ntest_df[\"img_width\"] = ex_test_df[\"img_width\"]\ntest_df[\"img_height\"] = ex_test_df[\"img_height\"]\ntest_df = test_df.drop(columns=[\"predictions\"])\ndisplay(test_df)\n\nprint(\"\\n... Sample Submission DATAFRAME ..\\n\")\nSS_CSV = os.path.join(DATA_DIR, \"sample_submission.csv\")\nss_df = pd.read_csv(SS_CSV)\ndisplay(ss_df)\n\nprint(\"\\n\\n... BASIC DATA SETUP FINISHING ...\\n\")","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:28.717808Z","iopub.execute_input":"2022-03-29T07:56:28.718411Z","iopub.status.idle":"2022-03-29T07:56:29.156074Z","shell.execute_reply.started":"2022-03-29T07:56:28.718375Z","shell.execute_reply":"2022-03-29T07:56:29.155212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <div style=\"color:white;display:fill;border-radius:5px;background-color:#75B7BF;letter-spacing:0.1px;overflow:hidden\"><p style=\"padding:20px;color:white;overflow:hidden;margin:0;font-size:100%;text-align:center\">DATASET EXPLORATION</p></div>\n****\n","metadata":{}},{"cell_type":"markdown","source":"# <div style=\"color:white;display:fill;border-radius:5px;background-color:#75B7BF;letter-spacing:0.1px;overflow:hidden\"><p style=\"padding:20px;color:white;overflow:hidden;margin:0;font-size:70%;text-align:left\">TRAIN METADATA</p></div>\n","metadata":{}},{"cell_type":"code","source":"N_TRAIN = len(train_df)\nN_TEST = len(ss_df)\nN_SPECIES = train_df[\"species\"].nunique()\nN_INDIV = train_df[\"individual_id\"].nunique()\nprint(f\"\\n... NUMBER OF UNIQUE TRAINING IMAGES: {N_TRAIN} ...\")\nprint(f\"... NUMBER OF UNIQUE SPECIES IN TRAINING DATASET: {N_SPECIES} ...\")\nprint(f\"... NUMBER OF UNIQUE INDIVIDUALS IN TRAINING DATASET: {N_INDIV} ...\")\nprint(\"\\n... TRAIN DATAFRAME PANDAS DESCRIPTION ...\\n\\n\")\ndisplay(train_df.describe().T)","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:29.158479Z","iopub.execute_input":"2022-03-29T07:56:29.158725Z","iopub.status.idle":"2022-03-29T07:56:29.216117Z","shell.execute_reply.started":"2022-03-29T07:56:29.158688Z","shell.execute_reply":"2022-03-29T07:56:29.215238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plotly stuff\ncolor_discrete_sequence=px.colors.qualitative.Light24\ncategory_orders={\"species\": all_species}\n\n# Species Plot\nfig = px.histogram(train_df, \"species\", \n                   color=\"species\", \n                   color_discrete_sequence=color_discrete_sequence, \n                   category_orders=category_orders, \n                   title=\"<b>UNIQUE SPECIES DISTRIBUTION</b>\")\nfig.show(renderer=\"png\")","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:29.217468Z","iopub.execute_input":"2022-03-29T07:56:29.217940Z","iopub.status.idle":"2022-03-29T07:56:30.066551Z","shell.execute_reply.started":"2022-03-29T07:56:29.217891Z","shell.execute_reply":"2022-03-29T07:56:30.065196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Individual ID Plot\ntmp_df = train_df.groupby(\"individual_id\")[[\"species\", \"individual_id\"]].first()\ntmp_df[\"n_count\"] = train_df.groupby(\"individual_id\").size()\nprint(\"\\n... OUTLIER ...\\n\")\ndisplay(tmp_df[tmp_df[\"n_count\"]>300])\ntmp_df = tmp_df[tmp_df[\"n_count\"]<300] # There is one outlier\nfig = px.histogram(tmp_df, \"n_count\", log_y=True,\n                   color=\"species\", color_discrete_sequence=color_discrete_sequence, \n                   category_orders=category_orders, \n                   title=\"<b># OF EXAMPLES PER UNIQUE INDIVIDUAL DISTRIBUTION</b>\")\nfig.show(renderer=\"png\")\n","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:30.068323Z","iopub.execute_input":"2022-03-29T07:56:30.068983Z","iopub.status.idle":"2022-03-29T07:56:30.666876Z","shell.execute_reply.started":"2022-03-29T07:56:30.068937Z","shell.execute_reply":"2022-03-29T07:56:30.666082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tmp_df_raw = pd.DataFrame()\ntmp_df_round = pd.DataFrame()\nround_to=100\n\ntmp_df_raw[\"raw_img_shape\"] = train_df.groupby(\"img_shape\")[\"img_path\"].count().keys()\ntmp_df_raw[\"raw_img_width\"] = tmp_df_raw[\"raw_img_shape\"].apply(lambda x: ast.literal_eval(x)[1])\ntmp_df_raw[\"raw_img_height\"] = tmp_df_raw[\"raw_img_shape\"].apply(lambda x: ast.literal_eval(x)[0])\ntmp_df_raw[\"area\"] = tmp_df_raw[\"raw_img_width\"]*tmp_df_raw[\"raw_img_height\"]\ntmp_df_raw[\"raw_n_count\"] = tmp_df_raw.groupby(\"raw_img_shape\")[\"area\"].count().values\ntmp_df_raw[\"raw_n_count__2\"] = tmp_df_raw[\"raw_n_count\"]**2\n\ntmp_df_round[\"round_img_shape\"] = train_df.img_shape.apply(lambda x: str(tuple([int(round_to*round(x/round_to)) if x!=3 else x for x in ast.literal_eval(x)]))).value_counts().keys()\ntmp_df_round[\"round_img_width\"] = tmp_df_round[\"round_img_shape\"].apply(lambda x: int(round_to*round(ast.literal_eval(x)[1]/round_to)))\ntmp_df_round[\"round_img_height\"] = tmp_df_round[\"round_img_shape\"].apply(lambda x: int(round_to*round(ast.literal_eval(x)[0]/round_to)))\ntmp_df_round[\"area\"] = tmp_df_round[\"round_img_width\"]*tmp_df_round[\"round_img_height\"]\ntmp_df_round[\"round_n_count\"] = train_df.img_shape.apply(lambda x: str(tuple([int(round_to*round(x/round_to)) if x!=3 else x for x in ast.literal_eval(x)]))).value_counts().values\ntmp_df_round[\"round_n_count__2\"] = tmp_df_round[\"round_n_count\"]**2\n\n# Image Shape Plot\nfig = px.scatter(tmp_df_raw, x=\"raw_img_width\", y=\"raw_img_height\", \n                 color=\"area\", size=\"raw_n_count\", size_max=2, \n                 title=f\"<b>Image Shapes Within The Dataset (No Rounding - <i>Many Individual Sizes</i>)</b>\")\nfig.update_layout(yaxis_range=[0, tmp_df_round.round_img_height.max()+100], \n                  xaxis_range=[0, tmp_df_round.round_img_width.max()+100])\nfig.show(renderer=\"png\")","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:30.668399Z","iopub.execute_input":"2022-03-29T07:56:30.668807Z","iopub.status.idle":"2022-03-29T07:56:33.819946Z","shell.execute_reply.started":"2022-03-29T07:56:30.668770Z","shell.execute_reply":"2022-03-29T07:56:33.819091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Image Shape Plot\nfig = px.scatter(tmp_df_round, x=\"round_img_width\", y=\"round_img_height\", \n                 color=\"area\", size=\"round_n_count\", size_max=100,\n                 title=f\"<b>Image Shapes Within The Dataset (Round To Nearest {round_to})</b>\")\nfig.update_layout(yaxis_range=[0, tmp_df_round.round_img_height.max()+100], \n                  xaxis_range=[0, tmp_df_round.round_img_width.max()+100])\nfig.show(renderer=\"png\")","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:33.821464Z","iopub.execute_input":"2022-03-29T07:56:33.821918Z","iopub.status.idle":"2022-03-29T07:56:34.102882Z","shell.execute_reply.started":"2022-03-29T07:56:33.821876Z","shell.execute_reply":"2022-03-29T07:56:34.102028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <div style=\"color:white;display:fill;border-radius:5px;background-color:#75B7BF;letter-spacing:0.1px;overflow:hidden\"><p style=\"padding:20px;color:white;overflow:hidden;margin:0;font-size:70%;text-align:left\">VISUALIZE THE UNIQUE SPECIES PRESENT IN THE DATASET</p></div>\n","metadata":{}},{"cell_type":"code","source":"for _s in all_species:\n    ex_img_paths = train_df[train_df.species==_s].sample(2).img_path.values\n    plt.figure(figsize=(20,10))\n    for i, ex_img_path in enumerate(ex_img_paths):\n        plt.subplot(1,2,i+1)\n        ex_img = cv2.imread(ex_img_path)[..., ::-1]\n        plt.title(f\"Example #{i+1} of species={_s}\\n(shape={ex_img.shape})\", fontweight=\"bold\")\n        plt.axis(False)\n        plt.imshow(ex_img)\n    plt.tight_layout()\n    plt.show()\n    ","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:56:34.104353Z","iopub.execute_input":"2022-03-29T07:56:34.104823Z","iopub.status.idle":"2022-03-29T07:57:22.008656Z","shell.execute_reply.started":"2022-03-29T07:56:34.104774Z","shell.execute_reply":"2022-03-29T07:57:22.004073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n# <div style=\"color:white;display:fill;border-radius:5px;background-color:#75B7BF;letter-spacing:0.1px;overflow:hidden\"><p style=\"padding:20px;color:white;overflow:hidden;margin:0;font-size:70%;text-align:left\">VISUALIZE EXAMPLES OF UNIQUE INDIVIDUALS IN THE DATASET</p></div>\n","metadata":{}},{"cell_type":"code","source":"for i, (img_id, img_id_df) in enumerate(train_df[train_df.n_img_of_ind==3].groupby(\"individual_id\")):\n    if i==3:\n        break\n    ex_img_paths = img_id_df.img_path.values\n    \n    plt.figure(figsize=(20,4))\n    for i, ex_img_path in enumerate(ex_img_paths):\n        plt.subplot(1,3,i+1)\n        ex_img = cv2.imread(ex_img_path)[..., ::-1]\n        plt.title(f\"Example #{i+1} of image_id={img_id}\\n(shape={ex_img.shape})\", fontweight=\"bold\")\n        plt.axis(False)\n        plt.imshow(ex_img)\n    plt.tight_layout()\n    plt.show()\n    print(\"\\n\\n\\n\")","metadata":{"execution":{"iopub.status.busy":"2022-03-29T07:57:22.009897Z","iopub.execute_input":"2022-03-29T07:57:22.010153Z","iopub.status.idle":"2022-03-29T07:57:26.964502Z","shell.execute_reply.started":"2022-03-29T07:57:22.010122Z","shell.execute_reply":"2022-03-29T07:57:26.963412Z"},"trusted":true},"execution_count":null,"outputs":[]}]}