{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport os\nimport json\nfrom datetime import datetime\n\nfrom PIL import Image\n\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Load the Data**"},{"metadata":{"trusted":true},"cell_type":"code","source":"DATA_DIR = '../input/iwildcam-2020-fgvc7/'\nTRAIN_DIR = DATA_DIR + 'train/'\nTEST_DIR = DATA_DIR + 'test/'\n\n# load the megadetector results\nmegadetector_results = json.load(open(DATA_DIR + 'iwildcam2020_megadetector_results.json'))\n#megadetector_results['images'][:2]\n\n# load train images annotations\ntrain_info = json.load(open(DATA_DIR + 'iwildcam2020_train_annotations.json'))\n# split json into several pandas dataframes\ntrain_annotations = pd.DataFrame(train_info['annotations'])\ntrain_images = pd.DataFrame(train_info['images'])\ntrain_categories = pd.DataFrame(train_info['categories'])\n\n# load test images info\ntest_info = json.load(open(DATA_DIR + 'iwildcam2020_test_information.json'))\n# split json into several pandas dataframes\ntest_images = pd.DataFrame(test_info['images'])\ntest_categories = pd.DataFrame(test_info['categories'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_annotations.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_images.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_categories.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Get the total number of images in the train and test sets:"},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Number of images in the train set is {}'.format(train_annotations.image_id.nunique()))\nprint('Number of images in the test set is {}'.format(test_images.file_name.nunique()))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Visulize train and test set"},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.pie([train_annotations.image_id.nunique(), test_images.file_name.nunique()], labels=['Train', 'Test'], autopct='%1.1f%%', \n           startangle=90, colors=['#fa4252', '#91bd3a'])\nplt.axis('equal')\nplt.title('Number of images in train and test sets', fontsize=14)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Let's check the number of animals found per image:\n\ncounts_per_image = train_annotations.groupby(by=['image_id']).sum().reset_index()[['image_id', 'count']].sort_values(by=['count'], ascending=False)\n# output top-5\ncounts_per_image.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"counts_per_image.tail(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.hist(counts_per_image['count'].values, bins=14, color='#91bd3a')\nplt.title('The distribution of the count of animals per image', fontsize=14)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"* most of the images are empty;\n* having more than 20 animals on one image is very rare."},{"metadata":{},"cell_type":"markdown","source":"look at the number of different categories of animals per image:"},{"metadata":{"trusted":true},"cell_type":"code","source":"category_counts_per_image = train_annotations.groupby(by=['image_id', 'category_id']).sum().reset_index()[['image_id', 'category_id', 'count']]\\\n.sort_values(by=['count'], ascending=False)\n# merge with category names\ncategory_counts_per_image = category_counts_per_image.merge(train_categories[['id', 'name']].rename(columns={'id':'category_id'}), on=['category_id'])\n# output top-5\ncategory_counts_per_image.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.hist(category_counts_per_image['count'].values, bins=14, color='#91bd3a')\nplt.title('The distribution of the animal category counts per image', fontsize=14)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Now let's look at the number of images for each category:\n\nnum_categories = train_categories.sort_values(by=['count'], ascending=False)\n# list the top-5\nnum_categories.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, axs = plt.subplots(1,2, figsize=(20,7))\nwidth = 0.8\nn_categories = 20\n# plot the top-n\naxs[0].bar(x=range(n_categories), height=num_categories['count'].values[:n_categories], width=width, color='#91bd3a')\naxs[0].set_xticks(np.array(range(n_categories)))\naxs[0].set_xticklabels(num_categories['name'].values[:n_categories], rotation=90)\naxs[0].set_title('TOP-{}'.format(n_categories))\n# plot the tail-n\naxs[1].bar(x=range(n_categories), height=num_categories[num_categories['count'] > 0]['count'].values[-n_categories:], width=width, color='#fa4252')\naxs[1].set_xticks(np.array(range(n_categories)))\naxs[1].set_xticklabels(num_categories[num_categories['count'] > 0]['name'].values[-n_categories:], rotation=90)\naxs[1].set_title('LAST-{}'.format(n_categories))\n\nplt.suptitle('The most and the least frequent categories', fontsize=16)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"* Most of the images are empty;\n* A lot of images captured humans;\n* Some of the categories were not captured at all;\n* The least frequent categories were captured by cameras just once!"},{"metadata":{},"cell_type":"markdown","source":"Let's explore the locations related to the train set images:"},{"metadata":{"trusted":true},"cell_type":"code","source":"print('The number of unique locations is {}'.format(train_images.location.nunique()))\nprint('The average number of images per location is {}'.format(train_images.groupby(by=['location']).id.count().mean()))\nprint('The minimum number of images per location is {}'.format(train_images.groupby(by=['location']).id.count().min()))\nprint('The maximum number of images per location is {}'.format(train_images.groupby(by=['location']).id.count().max()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(20,5))\nplt.hist(train_images.groupby(by=['location']).id.count(), bins=40, color='#91bd3a')\nplt.title('The distribution of the number of the images per location', fontsize=14)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":" * Most of the locations have less than 500 images, but for some of the locations the total number of images exceeds 8000.\n* For some of the locations there is only 1 image captured! Probably, this is why we want to have models, which extend to different locations."},{"metadata":{},"cell_type":"markdown","source":"Analyze the number of frames in sequences:"},{"metadata":{"trusted":true},"cell_type":"code","source":"frames_per_sequence = train_images.groupby(by=['seq_id']).frame_num.max()\n\nprint('The average number of frames is {}'.format(frames_per_sequence.mean()))\nprint('The minimum number of frames is {}'.format(frames_per_sequence.min()))\nprint('The maximum number of frames is {}'.format(frames_per_sequence.max()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.hist(frames_per_sequence.values, bins=40, color='#91bd3a')\nplt.title('The distribution of the number of frames')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Train Set Images Exploration"},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_first_category(img_id):\n    \"\"\"Find first the image category by id.\"\"\"\n    # get category id\n    category_id = train_annotations[train_annotations.image_id == img_id].category_id.values[0]\n    # get category name\n    category_name = train_categories[train_categories.id == category_id].name.values[0]\n    return category_id, category_name\n\ndef visualize_image_grid(rows, cols):\n    \"\"\"Visualize random grid of images with the first category.\"\"\"\n    filenames = train_images.file_name.unique()\n    \n    np.random.seed(42)\n    img_idx = np.random.randint(len(filenames), size=rows * cols)\n    \n    fig, axs = plt.subplots(rows, cols, figsize=(15,7))\n    \n    for r in range(rows):\n        for c in range(cols):\n            # get the image and image id\n            filename = filenames[img_idx[rows*r + c]]\n            img_id = filename.split('.')[0]\n            # get the category\n            category_id, category = get_first_category(img_id)\n            \n            img = Image.open(TRAIN_DIR + filename)\n            \n            axs[r,c].imshow(img)\n            axs[r,c].axis('off')\n            axs[r,c].set_title('{}:{}'.format(category_id, category))\n            \n    plt.suptitle('Train images', fontsize=16)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"visualize_image_grid(3, 3)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Visualize images for a specific category"},{"metadata":{"trusted":true},"cell_type":"code","source":"def visualize_cetagory(category_id, rows=3, cols=3, seed=42):\n    \"\"\"Function to visualize images of a specific category.\"\"\"\n    # filter by the category_id\n    copy = train_annotations[train_annotations.category_id == category_id]\n    # get the category name\n    category_name = train_categories[train_categories.id == category_id].name.values[0]\n    \n    # get random indices\n    np.random.seed(seed)\n    img_idx = np.random.randint(len(copy), size=rows * cols)\n    \n    # plot images\n    fig, axs = plt.subplots(rows, cols, figsize=(15,7))\n    \n    for r in range(rows):\n        for c in range(cols):\n            # get the image and image id\n            filename = copy.iloc[img_idx[rows*r + c]].image_id + '.jpg'\n            img_id = filename.split('.')[0]\n            \n            img = Image.open(TRAIN_DIR + filename)\n            \n            axs[r,c].imshow(img)\n            axs[r,c].axis('off')\n            axs[r,c].set_title('{}:{}'.format(category_id, category_name))\n            \n    plt.suptitle('Train images for {}:{}'.format(category_id, category_name), fontsize=16)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"visualize_cetagory(0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"visualize_cetagory(3) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"visualize_cetagory(112) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"visualize_cetagory(372) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def visualize_top_categories(n_categories=5, n_cols=5, seed=42):\n    \"\"\"Function to plot a grid of n_cols images for each of the top n_categories from the train set.\"\"\"\n    np.random.seed(seed)\n    \n    # get ids for the top n_categories\n    # excluding empty and human\n    top_categories = num_categories['id'].values[2:n_categories+2]\n    \n    # setup the image grid\n    fig, axs = plt.subplots(n_categories, n_cols, figsize=(18,10))\n    \n    for row in range(0, n_categories):\n        # get the category \n        category_id = top_categories[row]\n        \n        # get the category name\n        category_name = train_categories[train_categories.id == category_id].name.values[0]\n        \n        # filter the images by category\n        copy = train_annotations[train_annotations.category_id == category_id]\n        \n        # get random indices\n        img_idx = np.random.randint(len(copy), size=n_cols)\n        \n        for col in range(0, n_cols):\n            # get the image and image id\n            filename = copy.iloc[img_idx[col]].image_id + '.jpg'\n            img_id = filename.split('.')[0]\n            \n            img = Image.open(TRAIN_DIR + filename)\n            \n            axs[row,col].imshow(img)\n            axs[row,col].axis('off')\n            axs[row,col].set_title('{}:{}'.format(category_id, category_name))\n            \n    plt.suptitle('Train images for top-{} categories'.format(n_categories), fontsize=16)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"visualize_top_categories(n_categories=5)","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}