{"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":"<br>\n\n<center><img src=\"https://inhabitat.com/wp-content/blogs.dir/1/files/2017/06/Great-Barrier-Reef-worth-banner-1580x530.jpg\" style=\"opacity: 0.85; filter: alpha(opacity=85); border-radius: 20%;\" width=110%></center>\n\n<h2 style=\"text-align: center; font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: underline; text-transform: none; letter-spacing: 2px; color: #40E0D0; background-color: #ffffff;\">TF - Great Barrier Reef - EfficientDet</h2>\n<h5 style=\"text-align: center; font-family: Verdana; font-size: 12px; font-style: normal; font-weight: bold; text-decoration: None; text-transform: none; letter-spacing: 1px; color: black; background-color: #ffffff;\">CREATED BY: DARIEN SCHETTLER</h5>\n\n<br>\n\n---\n\n<br>\n\n<center><div class=\"alert alert-block alert-danger\" style=\"margin: 2em; line-height: 1.7em; font-family: Verdana;\">\n    <b style=\"font-size: 18px;\">🛑 &nbsp; WARNING:</b><br><br><b>THIS IS A WORK IN PROGRESS</b><br>\n</div></center>\n\n\n<center><div class=\"alert alert-block alert-warning\" style=\"margin: 2em; line-height: 1.7em; font-family: Verdana;\">\n    <b style=\"font-size: 18px;\">👏 &nbsp; IF YOU FORK THIS OR FIND THIS HELPFUL &nbsp; 👏</b><br><br><b style=\"font-size: 22px; color: darkorange\">PLEASE UPVOTE!</b><br><br>This was a lot of work for me and while it may seem silly, it makes me feel appreciated when others like my work. 😅\n</div></center>\n\n\n","metadata":{"papermill":{"duration":0.120561,"end_time":"2021-11-06T21:15:09.611563","exception":false,"start_time":"2021-11-06T21:15:09.491002","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"<p id=\"toc\"></p>\n\n<br><br>\n\n<h1 style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; color: #40E0D0; background-color: #ffffff;\">TABLE OF CONTENTS</h1>\n\n---\n\n<h3 style=\"text-indent: 10vw; font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\"><a href=\"#imports\">0&nbsp;&nbsp;&nbsp;&nbsp;IMPORTS</a></h3>\n\n---\n\n<h3 style=\"text-indent: 10vw; font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\"><a href=\"#background_information\">1&nbsp;&nbsp;&nbsp;&nbsp;BACKGROUND INFORMATION</a></h3>\n\n---\n\n<h3 style=\"text-indent: 10vw; font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\"><a href=\"#setup\">2&nbsp;&nbsp;&nbsp;&nbsp;SETUP</a></h3>\n\n---\n\n<h3 style=\"text-indent: 10vw; font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\"><a href=\"#helper_functions\">3&nbsp;&nbsp;&nbsp;&nbsp;HELPER FUNCTIONS</a></h3>\n\n---\n\n<h3 style=\"text-indent: 10vw; font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\"><a href=\"#create_dataset\">4&nbsp;&nbsp;&nbsp;&nbsp;DATASET CREATION AND EXPLORATION</a></h3>\n\n---\n\n<h3 style=\"text-indent: 10vw; font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\"><a href=\"#modelling\">5&nbsp;&nbsp;&nbsp;&nbsp;MODELLING</a></h3>\n\n---","metadata":{"papermill":{"duration":0.085591,"end_time":"2021-11-06T21:15:09.78303","exception":false,"start_time":"2021-11-06T21:15:09.697439","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"<br>\n\n<a id=\"imports\"></a>\n\n<h1 style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; background-color: #ffffff; color: #40E0D0;\" id=\"imports\">0&nbsp;&nbsp;IMPORTS&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#toc\">&#10514;</a></h1>","metadata":{"papermill":{"duration":0.050527,"end_time":"2021-11-06T21:15:09.894476","exception":false,"start_time":"2021-11-06T21:15:09.843949","status":"completed"},"tags":[]}},{"cell_type":"code","source":"print(\"\\n... IMPORTS STARTING ...\\n\")\n\nprint(\"\\n... PIP/APT INSTALLS AND DOWNLOADS/ZIP STARTING ...\")\n# !pip install -q tensorflow-model-optimization\n# !pip install -q neural-structured-learning\n# !pip install -q tensorflow_datasets\n\n## Only to be used if we can figure out that TPU bug\n# !pip install -q tf-nightly\n\n# Try to skip and disable so we can submit w/o internet\n!pip install -q ../input/tensorflow-model-optimization/numpy-1.21.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl\n!pip install -q ../input/tensorflow-model-optimization/dm_tree-0.1.6-cp37-cp37m-manylinux_2_24_x86_64.whl\n!pip install -q ../input/tensorflow-model-optimization/six-1.16.0-py2.py3-none-any.whl\n!pip install -q ../input/tensorflow-model-optimization/tensorflow_model_optimization-0.7.0-py2.py3-none-any.whl\n!pip install -q ../input/neural-structued-learning/neural_structured_learning-1.3.1-py2.py3-none-any.whl\n!pip install --no-deps ../input/pycocotools/pycocotools-2.0-cp37-cp37m-linux_x86_64.whl\n\nprint(\"... 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# This is necessary to force the TPU client to have the same TF version as TF-Nightly\n# from cloud_tpu_client import Client\n# c = Client(tpu=''); c.configure_tpu_version(tf.__version__, restart_type='ifNeeded')\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\n# Competition Specific\nimport greatbarrierreef\nenv = greatbarrierreef.make_env()   # initialize the environment\n\ndef seed_it_all(seed=7):\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\")\n    \nprint(\"\\n... EFFICIENTDET SETUP STARTING ...\")\n\n# SET LIBRARY DIRECTORY\nLIB_DIR = \"/kaggle/input/google-automl-efficientdetefficientnet-oct-2021\"\n\n# To give access to automl files\nsys.path.insert(0, LIB_DIR)\nsys.path.insert(0, os.path.join(LIB_DIR, \"automl-master\"))\nsys.path.insert(0, os.path.join(LIB_DIR, \"automl-master\", \"efficientdet\"))\nsys.path.insert(0, os.path.join(LIB_DIR, \"automl-master\", \"efficientdet\", \"tf2\"))\n    \n# EfficientDET Module Imports\nimport hparams_config\nfrom tf2 import efficientdet_keras\nfrom tf2 import train_lib\nfrom tf2 import anchors\nfrom tf2 import efficientdet_keras\nfrom tf2 import label_util\nfrom tf2 import postprocess\nfrom tf2 import util_keras\nfrom tf2.train import setup_model\nfrom efficientdet import dataloader\nfrom visualize import vis_utils\nfrom inference import visualize_image\nprint(\"... EFFICIENTDET SETUP COMPLETE ...\\n\")\n\nprint(\"\\n... SEEDING FOR DETERMINISTIC BEHAVIOUR ...\\n\")\nseed_it_all()","metadata":{"papermill":{"duration":162.144149,"end_time":"2021-11-06T21:17:52.087371","exception":false,"start_time":"2021-11-06T21:15:09.943222","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-16T01:44:39.050611Z","iopub.execute_input":"2021-12-16T01:44:39.051035Z","iopub.status.idle":"2021-12-16T01:47:32.248094Z","shell.execute_reply.started":"2021-12-16T01:44:39.050925Z","shell.execute_reply":"2021-12-16T01:47:32.24726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<br>\n\n<a id=\"background_information\"></a>\n\n<h1 style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; color: #40E0D0; background-color: #ffffff;\" id=\"background_information\">1&nbsp;&nbsp;BACKGROUND INFORMATION&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#toc\">&#10514;</a></h1>\n\n---\n\n<b>I will leave this blank and refer people to my <a href=\"https://www.kaggle.com/dschettler8845/tf-find-the-cots-eda-baseline\" style=\"color: orange !important;\">EDA Notebook</a></b>\n","metadata":{"papermill":{"duration":0.05019,"end_time":"2021-11-06T21:17:52.231372","exception":false,"start_time":"2021-11-06T21:17:52.181182","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"<br>\n\n<a id=\"background_information\"></a>\n\n<h1 style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; color: #40E0D0; background-color: #ffffff;\" id=\"setup\">2&nbsp;&nbsp;SETUP&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#toc\">&#10514;</a></h1>\n\n---\n\n<b>I will leave this blank and refer people to my <a href=\"https://www.kaggle.com/dschettler8845/tf-find-the-cots-eda-baseline\" style=\"color: orange !important;\">EDA Notebook</a></b>","metadata":{"papermill":{"duration":0.052944,"end_time":"2021-11-06T21:17:52.65284","exception":false,"start_time":"2021-11-06T21:17:52.599896","status":"completed"},"tags":[]}},{"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":{"papermill":{"duration":0.07574,"end_time":"2021-11-06T21:17:52.892074","exception":false,"start_time":"2021-11-06T21:17:52.816334","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-16T01:47:32.249888Z","iopub.execute_input":"2021-12-16T01:47:32.250145Z","iopub.status.idle":"2021-12-16T01:47:32.266674Z","shell.execute_reply.started":"2021-12-16T01:47:32.250111Z","shell.execute_reply":"2021-12-16T01:47:32.265905Z"},"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    TFRECORD_DIR = os.path.join(KaggleDatasets().get_gcs_path('tf-efficientdet-tfrecords-640x640'), \"tfrecords\")\n    DATA_DIR = KaggleDatasets().get_gcs_path('tensorflow-great-barrier-reef')\n    DATASET_DIR = KaggleDatasets().get_gcs_path(\"binary-classifier-cots-dataset\")\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    TFRECORD_DIR = os.path.join(\"/kaggle/input/tf-efficientdet-tfrecords-640x640\", \"tfrecords\")\n    DATA_DIR = \"/kaggle/input/tensorflow-great-barrier-reef\"\n    DATASET_DIR = \"/kaggle/input/binary-classifier-cots-dataset\"\n    save_locally = load_locally = None\n    \n    \nprint(f\"\\n... DATA DIRECTORY PATH IS:\\n\\t--> {DATA_DIR}\")\n\nprint(f\"\\n... TFRECORD DIRECTORY PATH IS:\\n\\t--> {TFRECORD_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\n    \nprint(\"\\n\\n... DATA ACCESS SETUP COMPLETED ...\\n\")","metadata":{"papermill":{"duration":0.0797,"end_time":"2021-11-06T21:17:53.133972","exception":false,"start_time":"2021-11-06T21:17:53.054272","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-16T01:47:32.269402Z","iopub.execute_input":"2021-12-16T01:47:32.26981Z","iopub.status.idle":"2021-12-16T01:47:32.28688Z","shell.execute_reply.started":"2021-12-16T01:47:32.269775Z","shell.execute_reply":"2021-12-16T01:47:32.285834Z"},"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":{"papermill":{"duration":0.128128,"end_time":"2021-11-06T21:17:53.442803","exception":false,"start_time":"2021-11-06T21:17:53.314675","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-16T01:47:32.288542Z","iopub.execute_input":"2021-12-16T01:47:32.288745Z","iopub.status.idle":"2021-12-16T01:47:32.294779Z","shell.execute_reply.started":"2021-12-16T01:47:32.288721Z","shell.execute_reply":"2021-12-16T01:47:32.293805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"####################################################################\n# ####################     TEST API CODE      #################### #\n####################################################################\n# iter_test = env.iter_test()    # an iterator which loops over the test set and sample submission\n# for (pixel_array, sample_prediction_df) in iter_test:\n#     sample_prediction_df['annotations'] = 'abc,0.5 0 0 100 100'  # make your predictions here\n#     env.predict(sample_prediction_df)   # register your predictions\n####################################################################\n\nprint(\"\\n... BASIC DATA SETUP STARTING ...\\n\\n\")\n\nDEFAULT_PLOTLY_COLORS=[(31, 119, 180), (255, 127, 14), \n                       (44, 160, 44), (214, 39, 40),\n                       (148, 103, 189), (140, 86, 75),\n                       (227, 119, 194), (127, 127, 127),\n                       (188, 189, 34), (23, 190, 207)]\n\nTRAIN_CSV = os.path.join(DATA_DIR, \"train.csv\")\ntrain_df = pd.read_csv(TRAIN_CSV)\ntrain_df[\"img_path\"] = os.path.join(DATA_DIR, \"train_images\")+\"/video_\"+train_df.video_id.astype(str)+\"/\"+train_df.video_frame.astype(str)+\".jpg\"\ntrain_df[\"annotations\"] = train_df[\"annotations\"].apply(lambda x: ast.literal_eval(x))\ntrain_df[\"a_count\"] = train_df[\"annotations\"].apply(len)\ntrain_df[\"video_id\"] = train_df[\"video_id\"].astype(str)\ntrain_df[\"sequence\"] = train_df[\"sequence\"].astype(str)\n\nprint(\"\\n... TRAIN DATAFRAME ...\\n\")\ndisplay(train_df)\n\nprint(\"\\n... OBJ ONLY DATAFRAME ...\\n\")\nobj_only_df = train_df[train_df.a_count>0].reset_index(drop=True)\n\nprint(\"\\n... TEST DATAFRAME ...\\n\")\nTEST_CSV = os.path.join(DATA_DIR, \"test.csv\")\ntest_df = pd.read_csv(TEST_CSV)\ndisplay(test_df)\n\nprint(\"\\n... SS DATAFRAME ..\\n\")\nSS_CSV = os.path.join(DATA_DIR, \"example_sample_submission.csv\")\nss_df = pd.read_csv(SS_CSV)\ndisplay(ss_df)\n\n# Other constant definitions\nIMG_SHAPE = (720, 1280, 3)\nN_TRAIN = len(train_df)\nall_bboxes = train_df[train_df.a_count>0].annotations.to_list()\nall_bboxes = [item for sublist in all_bboxes for item in sublist]\nN_OBJECTS = len(all_bboxes)\nN_VIDEO = train_df.video_id.nunique()\nN_SEQ = train_df.sequence.nunique()\n\n\n### ################################################## ###\n###  FOR NOW WE WILL JUST DO A SIMPLE VAL/TRAIN SPLIT  ###\n### ################################################## ###\n\nsub_val_df = obj_only_df[::10]\nsub_val_df = sub_val_df.sample(len(sub_val_df)).reset_index(drop=True)\nsub_train_df = obj_only_df[~obj_only_df.image_id.isin(sub_val_df.image_id)].reset_index(drop=True)\n\nprint(\"\\n... TRAINING DATAFRAME ...\\n\")\ndisplay(sub_train_df)\n\nprint(\"\\n... VALIDATION DATAFRAME ...\\n\")\ndisplay(sub_val_df)\n\n# from sklearn.model_selection import GroupKFold\n# group_kfold = GroupKFold(n_splits=17)\n\n# for subset_id, (train_idxs, val_idxs) in enumerate(group_kfold.split(obj_only_df, groups=obj_only_df[\"sequence\"])):\n#     print(f\"\\n\\nTRAIN SUBSET #{subset_id} :  {train_idxs[:3]}...{train_idxs[-3:]}  ({len(train_idxs)} EXAMPLES)\\n\")\n#     sub_train_df = obj_only_df.iloc[train_idxs]\n#     display(sub_train_df.head(1))\n    \n#     print(f\"\\n\\nVALIDATION SUBSET #{subset_id} :  {val_idxs[:3]}...{val_idxs[-3:]}  ({len(val_idxs)} EXAMPLES)\\n\")\n#     sub_val_df = obj_only_df.iloc[val_idxs]\n#     display(sub_val_df.head(1))\n\nprint(\"\\n\\n... BASIC DATA SETUP FINISHING ...\\n\")","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:47:32.296484Z","iopub.execute_input":"2021-12-16T01:47:32.29676Z","iopub.status.idle":"2021-12-16T01:47:32.90363Z","shell.execute_reply.started":"2021-12-16T01:47:32.296722Z","shell.execute_reply":"2021-12-16T01:47:32.902906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<br>\n\n\n<a id=\"helper_functions\"></a>\n\n\n<h1 style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; color: #40E0D0; background-color: #ffffff;\" id=\"helper_functions\">\n    3&nbsp;&nbsp;HELPER FUNCTION & CLASSES&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#toc\">&#10514;</a>\n</h1>\n\n---","metadata":{"papermill":{"duration":0.054893,"end_time":"2021-11-06T21:17:54.695576","exception":false,"start_time":"2021-11-06T21:17:54.640683","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def flatten_l_o_l(nested_list):\n    \"\"\" Flatten a list of lists \"\"\"\n    return [item for sublist in nested_list for item in sublist]\n\ndef tf_load_img(img_path, reshape_to=None):\n    if reshape_to is None:\n        return tf.image.decode_image(tf.io.read_file(img_path), channels=3)\n    else:\n        return tf.image.resize(tf.image.decode_image(tf.io.read_file(img_path), channels=3), reshape_to)\n\ndef get_tl_br(bbox):\n    \"\"\" Return the top-left and bottom-right bounding box \"\"\"\n    return (bbox['x'], bbox['y']), (bbox['x']+bbox[\"width\"], bbox['y']+bbox[\"height\"])\n\ndef plot_image(img_path, annotations=None, **kwargs):\n    \"\"\" Plot an image and bounding boxes \"\"\"\n    img = np.array(tf_load_img(img_path))\n    \n    if annotations:\n        plt.figure(figsize=(20,10))\n        for i, bbox in enumerate(annotations):\n            tl_box, br_box = get_tl_br(bbox)\n            img = cv2.rectangle(img, tl_box, br_box, (255-2*i,14*i,0), 4)\n        plt.imshow(img)\n        plt.axis(False)\n        plt.title(f\"Bounding Boxes Shown in Red ({len(annotations)})\", fontweight=\"bold\")\n    else:\n        plt.figure(figsize=(20,10))\n        plt.imshow(img)\n        plt.axis(False)\n        plt.title(\"No Bounding Boxes\", fontweight=\"bold\")\n    plt.tight_layout()\n    plt.show()","metadata":{"papermill":{"duration":0.098071,"end_time":"2021-11-06T21:17:54.848036","exception":false,"start_time":"2021-11-06T21:17:54.749965","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-12-16T01:47:32.904807Z","iopub.execute_input":"2021-12-16T01:47:32.905368Z","iopub.status.idle":"2021-12-16T01:47:32.917304Z","shell.execute_reply.started":"2021-12-16T01:47:32.905331Z","shell.execute_reply":"2021-12-16T01:47:32.916552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<br>\n\n\n<a id=\"tfrecords\"></a>\n\n\n<h1 style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; color: #40E0D0; background-color: #ffffff;\" id=\"tfrecords\">\n    4&nbsp;&nbsp;SETUP FOR EFFICIENTDET&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#toc\">&#10514;</a>\n</h1>\n\n---\n\n<center><b><font color=\"red\" size=\"8\">SET THE MODEL CHECKPOINT BELOW!</font></b></center>","metadata":{}},{"cell_type":"markdown","source":"<h3 style=\"font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: #40E0D0; background-color: #ffffff;\">4.0 EFFICIENTDET UTILITY FUNCTIONS & CONSTANTS</h3>\n\n---\n\n","metadata":{}},{"cell_type":"code","source":"def _bytes_feature(value, is_list=False):\n    \"\"\"Returns a bytes_list from a string / byte.\"\"\"\n    if isinstance(value, type(tf.constant(0))):\n        value = value.numpy() # BytesList won't unpack a string from an EagerTensor.\n    \n    if not is_list:\n        value = [value]\n    \n    return tf.train.Feature(bytes_list=tf.train.BytesList(value=value))\n\n\ndef _float_feature(value, is_list=False):\n    \"\"\"Returns a float_list from a float / double.\"\"\"\n        \n    if not is_list:\n        value = [value]\n        \n    return tf.train.Feature(float_list=tf.train.FloatList(value=value))\n\n\ndef _int64_feature(value, is_list=False):\n    \"\"\"Returns an int64_list from a bool / enum / int / uint.\"\"\"\n        \n    if not is_list:\n        value = [value]\n        \n    return tf.train.Feature(int64_list=tf.train.Int64List(value=value))\n\n\nIMG_SHAPE   = (720, 1280, 3)\nINPUT_SHAPE = (640,640,3)\nMODEL_LEVEL = \"d1\"\nMODEL_NAME  = f\"efficientdet-{MODEL_LEVEL}\"\n\nN_EPOCH    = 50\nBATCH_SIZE = 8\n\nN_TRAIN      = len(sub_train_df)\nN_VAL        = len(sub_val_df)\nN_EX_PER_REC = 125\n\nCLASS_LABELS = [\"COTS\",]\nN_CLASSES_OD = len(CLASS_LABELS)+1 # Background + Foreground (COTS)\n\n# Whether or not we train from scratch or load\nDO_TRAIN=False\nPRETRAINED_MODEL_DIR=\"/kaggle/input/tf-find-cots-keras-efficientdet-implementation/efficientdet-d1-finetune/ckpt-50\"\n\nprint(\"\\n ... HYPERPARAMETER CONSTANTS ...\")\nprint(f\"\\t--> MODEL NAME         : {MODEL_NAME}\")\nprint(f\"\\t--> BATCH SIZE         : {BATCH_SIZE}\")\nprint(f\"\\t--> # OF EPOCHS        : {N_EPOCH}\")\nprint(f\"\\t--> IMAGE SHAPE        : {IMG_SHAPE}\")\nprint(f\"\\t--> INPUT SHAPE        : {INPUT_SHAPE}\")","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:47:32.919737Z","iopub.execute_input":"2021-12-16T01:47:32.920047Z","iopub.status.idle":"2021-12-16T01:47:32.934217Z","shell.execute_reply.started":"2021-12-16T01:47:32.920009Z","shell.execute_reply":"2021-12-16T01:47:32.933452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<br>\n\n\n<a id=\"efficientdet\"></a>\n\n\n<h1 style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; color: #40E0D0; background-color: #ffffff;\" id=\"efficientdet\">\n    5&nbsp;&nbsp;LOAD EFFICIENTDET&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#toc\">&#10514;</a>\n</h1>\n\n---","metadata":{}},{"cell_type":"markdown","source":"<h3 style=\"font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: #40E0D0; background-color: #ffffff;\">5.1 LOAD EFFICIENTDET MODEL AND INITIALIZE</h3>\n\n---\n","metadata":{}},{"cell_type":"code","source":"config = hparams_config.get_efficientdet_config(MODEL_NAME)\nKEY_CONFIGS = [\n    \"name\", \"image_size\", \"num_classes\", \"seg_num_classes\", \"heads\", \"train_file_pattern\",\n    \"val_file_pattern\", \"model_name\", \"model_dir\", \"pretrained_ckpt\", \"batch_size\", \"eval_samples\",\n    \"num_examples_per_epoch\", \"num_epochs\", \"steps_per_execution\", \"steps_per_epoch\", \n    \"profile\", \"val_json_file\", \"max_instances_per_image\", \"mixed_precision\", \n    \"learning_rate\", \"lr_warmup_init\", \"mean_rgb\", \"stddev_rgb\",\"scale_range\",\n              ]\n\nfor k in config.keys():\n    if k==\"model_optimizations\":\n        continue\n    elif k==\"nms_configs\":\n        for _k, _v in dict(config[k]).items():\n            print(f\"PARAMETER: {'     ' if _k not in KEY_CONFIGS else ' *** '}nms_config_{_k: <16}  ---->    VALUE:  {_v}\")\n        \n    else:\n        print(f\"PARAMETER: {'     ' if k not in KEY_CONFIGS else ' *** '}{k: <27}  ---->    VALUE:  {config[k]}\")\n        \n        \nDO_ADV_PROP=True\nMODEL_DIR = f\"/kaggle/working/{MODEL_NAME}-finetune\"\n\nos.makedirs(MODEL_DIR, exist_ok=True)\nconfig = hparams_config.get_efficientdet_config(MODEL_NAME)\noverrides = dict(\n    train_file_pattern=os.path.join(TFRECORD_DIR, \"train\", \"*.tfrec\"),\n    val_file_pattern=os.path.join(TFRECORD_DIR, \"val\", \"*.tfrec\"),\n    test_file_pattern=os.path.join(TFRECORD_DIR, \"test\", \"*.tfrec\"),\n    model_name=MODEL_NAME,\n    model_dir=MODEL_DIR,\n    pretrained_ckpt=MODEL_NAME,\n    batch_size=BATCH_SIZE,\n    eval_samples=N_VAL,\n    num_examples_per_epoch=N_TRAIN,\n    num_epochs=N_EPOCH,\n    steps_per_execution=1,\n    steps_per_epoch=N_TRAIN//BATCH_SIZE,\n    profile=None, val_json_file=None,\n    heads = ['object_detection',],\n    image_size = INPUT_SHAPE[:-1],\n    num_classes = N_CLASSES_OD,\n    input_rand_hflip=True,\n    jitter_min=0.999999, jitter_max=1.00001,\n    )\nconfig.override(overrides, True)\n# config.nms_configs.max_output_size = MAX_N_INSTANCES\n\n# Change how input preprocessing is done\nif DO_ADV_PROP:\n    config.override(dict(mean_rgb=0.0, stddev_rgb=1.0, scale_range=True), True)\n\n\ntf.keras.backend.clear_session()\n\nmodel = efficientdet_keras.EfficientDetModel(config=config)\nmodel.build((1,*INPUT_SHAPE))\n\nprint(\"\\n... MODEL PREDICTIONS ...\\n\")\npreds = model.predict(np.zeros((1,*INPUT_SHAPE)))\nfor i, name in enumerate([\"bboxes\", \"confidences\", \"classes\", \"valid_len\"]):\n    print(f\"\\n\\n\\t----- Examples Of {name.upper()} -----\\n\")\n    print(f\"Shape={preds[i].shape}\")\n    try:\n        if preds[i].shape[-2]==64:\n            print(preds[i][0, 0, 0, :5])\n        else:\n            print(preds[i][0, :5])  \n    except:\n        print(preds[i][0])","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:47:32.935912Z","iopub.execute_input":"2021-12-16T01:47:32.936528Z","iopub.status.idle":"2021-12-16T01:48:16.505386Z","shell.execute_reply.started":"2021-12-16T01:47:32.936492Z","shell.execute_reply":"2021-12-16T01:48:16.504585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3 style=\"font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: #40E0D0; background-color: #ffffff;\">5.2 CREATE A DATASET WITH THE CORRECT STRUCTURE </h3>\n\n---\n\n* **INPUT**\n    * Raw Image (640x640x3)\n\n\n* **OUTPUT/TARGET**\n    * Bounding Boxes\n    \n---\n\nWe first create the tfrecord datasets... then we instantiate a dataloader ","metadata":{}},{"cell_type":"code","source":"def tf_load_image(path, resize_to=INPUT_SHAPE):\n    \"\"\" Load an image with the correct shape using only TF\n    \n    Args:\n        path (tf.string): Path to the image to be loaded\n        resize_to (tuple, optional): Size to reshape image\n    \n    Returns:\n        3 channel tf.Constant image ready for training/inference\n    \n    \"\"\"\n    \n    img_bytes = tf.io.read_file(path)\n    img = tf.image.decode_png(img_bytes, channels=resize_to[-1])\n    img = tf.image.resize(img, resize_to[:-1])\n    img = tf.cast(img, tf.uint8)\n    \n    return img\n\ndef get_scaled_annotations(annotations, original_size=(720,1280), resize_to=(640,640), effdet_return=True):\n    \"\"\" Get annotations after rescaling \"\"\"\n    \n    # Calculate factors to use when identifying new bounding box coordinates\n    xr_factor, yr_factor = resize_to[1]/original_size[1], resize_to[0]/original_size[0]\n    \n    if effdet_return:\n        new_annotations = {\"xmin\":[], \"ymin\":[], \"xmax\":[], \"ymax\":[], \"area\":[]}\n        for annotation in annotations:\n            new_annotations[\"xmin\"].append((annotation[\"x\"]*xr_factor)/resize_to[1])\n            new_annotations[\"xmax\"].append(((annotation[\"x\"]+annotation[\"width\"])*xr_factor)/resize_to[1])\n            new_annotations[\"ymin\"].append((annotation[\"y\"]*yr_factor)/resize_to[0])\n            new_annotations[\"ymax\"].append(((annotation[\"y\"]+annotation[\"height\"])*yr_factor)/resize_to[0])\n            new_annotations[\"area\"].append(\n                (annotation[\"width\"]*xr_factor*annotation[\"height\"]*yr_factor) / \\\n                (resize_to[1]*resize_to[0])\n            )\n        return new_annotations\n    else:\n        raise NotImplementedError()\n\nsub_train_df[\"effdet_annotations\"] = sub_train_df.annotations.progress_apply(get_scaled_annotations)\nsub_val_df[\"effdet_annotations\"] = sub_val_df.annotations.progress_apply(get_scaled_annotations)\n\n# DEMONSTRATE\nplt.figure(figsize=(18,18))\nplt.title(\"Original Image and Bounding Boxes\", fontweight=\"bold\")\nplt.axis(False)\nimg = cv2.imread(sub_train_df.iloc[0][\"img_path\"])[..., ::-1].astype(np.uint8)\nimg = cv2.rectangle(img, \n                    (sub_train_df.iloc[0][\"annotations\"][0][\"x\"], sub_train_df.iloc[0][\"annotations\"][0][\"y\"]),\n                    (sub_train_df.iloc[0][\"annotations\"][0][\"x\"]+sub_train_df.iloc[0][\"annotations\"][0][\"width\"], sub_train_df.iloc[0][\"annotations\"][0][\"y\"]+sub_train_df.iloc[0][\"annotations\"][0][\"height\"]),\n                    (255, 0, 0), 2)\nplt.imshow(img)\nplt.show()\n\nplt.figure(figsize=(18,18))\nplt.title(\"Resized Image and Bounding Boxes\", fontweight=\"bold\")\nplt.axis(False)\nimg = tf_load_image(sub_train_df.iloc[0].img_path).numpy()\nimg = cv2.rectangle(img, \n                    (int(sub_train_df.iloc[0][\"effdet_annotations\"][\"xmin\"][0]*INPUT_SHAPE[1]), \n                     int(sub_train_df.iloc[0][\"effdet_annotations\"][\"ymin\"][0]*INPUT_SHAPE[0])),\n                    (int(sub_train_df.iloc[0][\"effdet_annotations\"][\"xmax\"][0]*INPUT_SHAPE[1]), \n                     int(sub_train_df.iloc[0][\"effdet_annotations\"][\"ymax\"][0]*INPUT_SHAPE[0])),\n                    (255, 0, 0), 2)\nplt.imshow(img)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:48:16.506947Z","iopub.execute_input":"2021-12-16T01:48:16.507199Z","iopub.status.idle":"2021-12-16T01:48:18.195289Z","shell.execute_reply.started":"2021-12-16T01:48:16.507164Z","shell.execute_reply":"2021-12-16T01:48:18.194502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3 style=\"font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: #40E0D0; background-color: #ffffff;\">5.3 INSTANIATE OUR DATALOADER</h3>\n\n---\n\nAugmentations are breaking the masks... so disablled for now","metadata":{}},{"cell_type":"code","source":"train_dl = dataloader.InputReader(\n    file_pattern=config.train_file_pattern,\n    is_training=\"train\" in config.train_file_pattern,\n)(config.as_dict())\n\nval_dl = dataloader.InputReader(\n    file_pattern=config.val_file_pattern,\n    is_training=\"train\" in config.val_file_pattern,\n)(config.as_dict())\n\n# test_dl = dataloader.InputReader(\n#     file_pattern=config.test_file_pattern,\n#     is_training=\"train\" in config.test_file_pattern,\n#     max_instances_per_image=config.max_instances_per_image\n# )(config.as_dict(), batch_size=1)\n\n\nprint(\"\\n... TRAIN DATALOADER ...\\n\")\nprint(train_dl)\n\nprint(\"\\n\\n... VALIDATION DATALOADER ...\\n\")\nprint(val_dl)\n\n# print(\"\\n\\n... TEST DATALOADER ...\\n\")\n# print(test_dl)\n\n\n\nprint(\"\\n\\n\\n\\n LETS SEE AN EXAMPLE FROM OUR TRAIN DATALOADER ...\\n\\n\")\n\nx = next(iter(train_dl))\n\n\nIDX = 1\nimg = x[0][IDX].numpy()\n\nplt.figure(figsize=(18,18))\nplt.title(\"Augmented - From Dataloader - Resized Image and Bounding Boxes\", fontweight=\"bold\")\nplt.axis(False)\n\nfor i in range(len(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)][\"effdet_annotations\"][\"area\"])):\n    img = cv2.rectangle(img, \n                        (int(x[1][\"groundtruth_data\"][IDX][i][1]), \n                         int(x[1][\"groundtruth_data\"][IDX][i][0])),\n                        (int(x[1][\"groundtruth_data\"][IDX][i][3]), \n                         int(x[1][\"groundtruth_data\"][IDX][i][2])),\n                        (255-10*i, 25*i, 0), 2)\nplt.imshow(img)\nplt.show()\n\nplt.figure(figsize=(18,18))\nplt.title(\"Original - From Disk - Resized Image and Bounding Boxes\", fontweight=\"bold\")\nplt.axis(False)\nimg = tf_load_image(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)].img_path).numpy()\nfor i in range(len(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)][\"effdet_annotations\"][\"area\"])):\n    img = cv2.rectangle(img,\n                        (int(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)][\"effdet_annotations\"][\"xmin\"][i]*INPUT_SHAPE[1]), \n                         int(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)][\"effdet_annotations\"][\"ymin\"][i]*INPUT_SHAPE[0])),\n                        (int(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)][\"effdet_annotations\"][\"xmax\"][i]*INPUT_SHAPE[1]), \n                         int(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)][\"effdet_annotations\"][\"ymax\"][i]*INPUT_SHAPE[0])),\n                        (255-10*i, 25*i, 0), 2)\nplt.imshow(img)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:48:18.198016Z","iopub.execute_input":"2021-12-16T01:48:18.198423Z","iopub.status.idle":"2021-12-16T01:48:23.946985Z","shell.execute_reply.started":"2021-12-16T01:48:18.198384Z","shell.execute_reply":"2021-12-16T01:48:23.946296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3 style=\"font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: #40E0D0; background-color: #ffffff;\">5.2 CREATE A DATASET WITH THE CORRECT STRUCTURE & LOAD MODEL</h3>\n\n---\n","metadata":{}},{"cell_type":"code","source":"if DO_TRAIN:\n    if not os.path.isdir(MODEL_NAME):\n        if DO_ADV_PROP:\n            !wget https://storage.googleapis.com/cloud-tpu-checkpoints/efficientdet/advprop/{MODEL_NAME}.tar.gz\n        else:\n            !wget https://storage.googleapis.com/cloud-tpu-checkpoints/efficientdet/coco2/{MODEL_NAME}.tar.gz\n        !tar -zxf {MODEL_NAME}.tar.gz\n        !rm -rf {MODEL_NAME}.tar.gz\n    \nwith strategy.scope():\n    model = train_lib.EfficientDetNetTrain(config=config)\n    model = setup_model(model, config)\n    \n    if DO_TRAIN:\n        util_keras.restore_ckpt(\n          model=model,\n          ckpt_path_or_file=tf.train.latest_checkpoint(MODEL_NAME),\n          ema_decay=config.moving_average_decay,\n          exclude_layers=['class_net']\n        )\n        ckpt_cb = tf.keras.callbacks.ModelCheckpoint(\n            os.path.join(MODEL_DIR, 'ckpt-{epoch:d}'),\n            verbose=1, save_freq=\"epoch\", save_weights_only=True)\n    else:\n        model.load_weights(PRETRAINED_MODEL_DIR)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:48:23.948092Z","iopub.execute_input":"2021-12-16T01:48:23.949008Z","iopub.status.idle":"2021-12-16T01:48:32.965287Z","shell.execute_reply.started":"2021-12-16T01:48:23.948968Z","shell.execute_reply":"2021-12-16T01:48:32.964545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3 style=\"font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: #40E0D0; background-color: #ffffff;\">5.3 TRAIN OR EVALUATE </h3>\n\n---\n","metadata":{}},{"cell_type":"code","source":"if DO_TRAIN:\n    history = model.fit(\n        train_dl,\n        epochs=config.num_epochs,\n        steps_per_epoch=config.steps_per_epoch,\n        callbacks=[ckpt_cb,],\n        validation_data=val_dl,\n        validation_steps=N_VAL//BATCH_SIZE\n    )\nelse:\n    # print(model.evaluate(train_dl, steps=config.steps_per_epoch))\n    print(model.evaluate(val_dl, steps=N_VAL//BATCH_SIZE))","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:48:32.966711Z","iopub.execute_input":"2021-12-16T01:48:32.966982Z","iopub.status.idle":"2021-12-16T01:48:32.971029Z","shell.execute_reply.started":"2021-12-16T01:48:32.966945Z","shell.execute_reply":"2021-12-16T01:48:32.970042Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3 style=\"font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: #40E0D0; background-color: #ffffff;\">5.4 COMPARE OUR ONE-OFF PREPROCESSING TO THE DATALOADER PREPROCESSING</h3>\n\n---\n","metadata":{}},{"cell_type":"code","source":"IDX = 1\nx = next(iter(val_dl))\nimg = x[0][IDX].numpy()\n\nplt.figure(figsize=(18,18))\nplt.title(\"Augmented - From Dataloader - Resized Image and Bounding Boxes\", fontweight=\"bold\")\nplt.axis(False)\n\nfor i in range(len(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)][\"effdet_annotations\"][\"area\"])):\n    img = cv2.rectangle(img, \n                        (int(x[1][\"groundtruth_data\"][IDX][i][1]), \n                         int(x[1][\"groundtruth_data\"][IDX][i][0])),\n                        (int(x[1][\"groundtruth_data\"][IDX][i][3]), \n                         int(x[1][\"groundtruth_data\"][IDX][i][2])),\n                        (255-10*i, 25*i, 0), 2)\nplt.imshow(img)\nplt.show()\n\nplt.figure(figsize=(18,18))\nplt.title(\"Original - From Disk - Resized Image and Bounding Boxes\", fontweight=\"bold\")\nplt.axis(False)\nimg = tf_load_image(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)].img_path).numpy()\nfor i in range(len(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)][\"effdet_annotations\"][\"area\"])):\n    img = cv2.rectangle(img,\n                        (int(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)][\"effdet_annotations\"][\"xmin\"][i]*INPUT_SHAPE[1]), \n                         int(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)][\"effdet_annotations\"][\"ymin\"][i]*INPUT_SHAPE[0])),\n                        (int(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)][\"effdet_annotations\"][\"xmax\"][i]*INPUT_SHAPE[1]), \n                         int(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)][\"effdet_annotations\"][\"ymax\"][i]*INPUT_SHAPE[0])),\n                        (255-10*i, 25*i, 0), 2)\nplt.imshow(img)\nplt.show()\nimg = tf_load_image(sub_train_df.iloc[x[1][\"source_ids\"][IDX].numpy().astype(np.int32)].img_path).numpy()","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:48:32.972388Z","iopub.execute_input":"2021-12-16T01:48:32.972706Z","iopub.status.idle":"2021-12-16T01:48:35.521669Z","shell.execute_reply.started":"2021-12-16T01:48:32.972673Z","shell.execute_reply":"2021-12-16T01:48:35.520946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3 style=\"font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: #40E0D0; background-color: #ffffff;\">5.5 VISUALIZE A BATCH OF PREDICTIONS </h3>\n\n---\n","metadata":{}},{"cell_type":"code","source":"def adv_image_preprocess(image):\n    return tf.cast(image, tf.float32)*2.0/255 - 1.0\n\ndef visualize_prediction(model, img, gt_df_row=None, image_id=99999, score_thresh=0.1, cat_index={1: {'id': 1, \"name\":'COTS'}}, full_size=False):\n    \n    # Image Setup\n    _img = img.copy()\n    _imgs = tf.expand_dims(adv_image_preprocess(_img), axis=0)\n    _image_ids = [image_id,]\n\n    # Prediction Portion\n    cls_outputs, box_outputs = model(_imgs, training=False)\n    nms_boxes_bs, nms_scores_bs, nms_classes_bs, _ = \\\n        postprocess.postprocess_global(config, cls_outputs, box_outputs)\n    preds = postprocess.generate_detections_from_nms_output(\n        nms_boxes_bs, nms_classes_bs, nms_scores_bs, _image_ids,\n    )\n    nms_classes_bs = tf.cast(nms_classes_bs, tf.int32).numpy()\n    nms_boxes_bs = nms_boxes_bs.numpy()\n    nms_scores_bs = nms_scores_bs.numpy()\n    \n    # Change Back To Full Size\n    if full_size:\n        _img = tf_load_image(gt_df_row.img_path, resize_to=IMG_SHAPE).numpy()\n        nms_boxes_bs[0][:, 0] = (nms_boxes_bs[0][:, 0]/INPUT_SHAPE[0])*IMG_SHAPE[0]\n        nms_boxes_bs[0][:, 1] = (nms_boxes_bs[0][:, 1]/INPUT_SHAPE[1])*IMG_SHAPE[1]\n        nms_boxes_bs[0][:, 2] = (nms_boxes_bs[0][:, 2]/INPUT_SHAPE[0])*IMG_SHAPE[0]\n        nms_boxes_bs[0][:, 3] = (nms_boxes_bs[0][:, 3]/INPUT_SHAPE[1])*IMG_SHAPE[1]\n        SHAPE_MULTIPLIER = IMG_SHAPE\n    else:\n        SHAPE_MULTIPLIER = INPUT_SHAPE\n    \n    # Ground Truth Plotting\n    if gt_dict is not None:\n        for i in range(len(gt_df_row[\"effdet_annotations\"][\"area\"])):\n            _img = cv2.rectangle(_img,\n                                 (int(gt_df_row[\"effdet_annotations\"][\"xmin\"][i]*SHAPE_MULTIPLIER[1]), \n                                  int(gt_df_row[\"effdet_annotations\"][\"ymin\"][i]*SHAPE_MULTIPLIER[0])),\n                                 (int(gt_df_row[\"effdet_annotations\"][\"xmax\"][i]*SHAPE_MULTIPLIER[1]), \n                                  int(gt_df_row[\"effdet_annotations\"][\"ymax\"][i]*SHAPE_MULTIPLIER[0])),\n                                 (255, 0, 0), 4)\n\n    \n    plt.figure(figsize=(20,20))\n    _img = vis_utils.visualize_boxes_and_labels_on_image_array(\n        _img.copy(),\n        nms_boxes_bs[0],\n        nms_classes_bs[0],\n        nms_scores_bs[0],\n        category_index=cat_index, \n        min_score_thresh=score_thresh,\n        line_thickness=3\n    )\n    plt.imshow(_img)\n    plt.show()\n\n\n\nprint(f\"\\n\\n{'-'*60}\\n\\t\\tONE BATCH OF TRAINING DATA \\n{'-'*60}\\n\\n\")\n\n# # FOR SQUARE IMAGE\n# for i in range(BATCH_SIZE):\n#     print(f\"\\n... EXAMPLE {i+1}/{BATCH_SIZE} OF VALIDATION BATCH ...\\n\")\n#     gt_df_row = sub_val_df.iloc[gt_dict[\"source_ids\"][i].numpy().astype(np.int32)]\n#     img = tf_load_image(gt_df_row.img_path).numpy()\n#     visualize_prediction(model, img, gt_df_row)\n\n_, gt_dict = next(iter(train_dl))\nfor i in range(BATCH_SIZE):\n    print(f\"\\n... EXAMPLE {i+1}/{BATCH_SIZE} OF VALIDATION BATCH ...\\n\")\n    gt_df_row = sub_train_df.iloc[gt_dict[\"source_ids\"][i].numpy().astype(np.int32)]\n    img = tf_load_image(gt_df_row.img_path).numpy()\n    visualize_prediction(model, img, gt_df_row, full_size=True)\n\n    \nprint(f\"\\n\\n{'-'*60}\\n\\t\\tONE BATCH OF VALIDATION DATA \\n{'-'*60}\\n\\n\")\n\n# # FOR SQUARE IMAGE\n# for i in range(BATCH_SIZE):\n#     print(f\"\\n... EXAMPLE {i+1}/{BATCH_SIZE} OF VALIDATION BATCH ...\\n\")\n#     gt_df_row = sub_val_df.iloc[gt_dict[\"source_ids\"][i].numpy().astype(np.int32)]\n#     img = tf_load_image(gt_df_row.img_path).numpy()\n#     visualize_prediction(model, img, gt_df_row)\n\n_, gt_dict = next(iter(val_dl))\nfor i in range(BATCH_SIZE):\n    print(f\"\\n... EXAMPLE {i+1}/{BATCH_SIZE} OF VALIDATION BATCH ...\\n\")\n    gt_df_row = sub_val_df.iloc[gt_dict[\"source_ids\"][i].numpy().astype(np.int32)]\n    img = tf_load_image(gt_df_row.img_path).numpy()\n    visualize_prediction(model, img, gt_df_row, full_size=True)","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:48:35.523173Z","iopub.execute_input":"2021-12-16T01:48:35.523642Z","iopub.status.idle":"2021-12-16T01:48:57.043153Z","shell.execute_reply.started":"2021-12-16T01:48:35.523606Z","shell.execute_reply":"2021-12-16T01:48:57.042259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3 style=\"font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: #40E0D0; background-color: #ffffff;\">5.6 CALCULATE COMPETITION METRIC</h3>\n\n---\n","metadata":{}},{"cell_type":"code","source":"import coco_metric\n_label_map={1:\"COTS\"}\nevaluator = coco_metric.EvaluationMetric(label_map=_label_map)\n\nfor images, gt_data in tqdm(val_dl, total=N_VAL//BATCH_SIZE):\n    cls_outputs, box_outputs = model(images, training=False)\n    detections = postprocess.generate_detections(config,\n                                                 cls_outputs,\n                                                 box_outputs,\n                                                 gt_data['image_scales'],\n                                                 gt_data['source_ids'])\n    tf.numpy_function(func=evaluator.update_state,\n                      inp=[gt_data['groundtruth_data'], postprocess.transform_detections(detections)], \n                      Tout=[])\n    \n# compute the final eval results.\nmetrics = evaluator.result()\nmetric_dict = {m_name:metrics[i] for i, m_name in enumerate(evaluator.metric_names)}\n\nfor i, cid in enumerate(sorted(_label_map.keys())):\n    name = 'AP_/%s' % _label_map[cid]\n    metric_dict[name] = metrics[i + len(evaluator.metric_names)]\n\nprint(f\"\\n\\n... METRIC DICTIONARY FOR {config.model_name} ...\\n\")\nfor k,v in metric_dict.items(): print(f\"\\t{k} --> {v}\")","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:52:57.689291Z","iopub.execute_input":"2021-12-16T01:52:57.69008Z","iopub.status.idle":"2021-12-16T01:53:38.969952Z","shell.execute_reply.started":"2021-12-16T01:52:57.690043Z","shell.execute_reply":"2021-12-16T01:53:38.969215Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<br>\n\n\n<a id=\"test_inference\"></a>\n\n\n<h1 style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; color: #40E0D0; background-color: #ffffff;\" id=\"test_inference\">\n    6&nbsp;&nbsp;TEST INFERENCE&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"#toc\">&#10514;</a>\n</h1>\n\n---","metadata":{}},{"cell_type":"code","source":"def model_inference(model, img, image_id=99999, score_thresh=0.1, cat_index={1: {'id': 1, \"name\":'COTS'}}, full_size=True, return_str=True, do_plot=False):\n    def __predict(__imgs, __image_ids, return_as_numpy=True):\n        cls_outputs, box_outputs = model(__imgs, training=False)\n        nms_boxes_bs, nms_scores_bs, nms_classes_bs, _ = \\\n        postprocess.postprocess_global(config, cls_outputs, box_outputs)\n        preds = postprocess.generate_detections_from_nms_output(\n            nms_boxes_bs, nms_classes_bs, nms_scores_bs, _image_ids,\n        )\n        if return_as_numpy:\n            return nms_classes_bs.numpy().astype(np.int32)[0], nms_boxes_bs.numpy()[0], nms_scores_bs.numpy()[0]\n        else:\n            return tf.cast(nms_classes_bs, tf.int32)[0], nms_boxes_bs[0], nms_scores_bs[0]\n    \n    __img = img.copy() # For display later\n    _imgs = tf.expand_dims(adv_image_preprocess(tf.image.resize(img, INPUT_SHAPE[:-1])), axis=0)\n    _image_ids = [image_id,]\n    \n    # Prediction Portion\n    nms_classes_bs, nms_boxes_bs, nms_scores_bs = __predict(_imgs, _image_ids, return_as_numpy=True)\n    \n    # Change Back To Full Size\n    if full_size:\n        nms_boxes_bs[:, 0] = ((nms_boxes_bs[:, 0]/INPUT_SHAPE[0])*IMG_SHAPE[0])\n        nms_boxes_bs[:, 1] = ((nms_boxes_bs[:, 1]/INPUT_SHAPE[1])*IMG_SHAPE[1])\n        nms_boxes_bs[:, 2] = ((nms_boxes_bs[:, 2]/INPUT_SHAPE[0])*IMG_SHAPE[0])\n        nms_boxes_bs[:, 3] = ((nms_boxes_bs[:, 3]/INPUT_SHAPE[1])*IMG_SHAPE[1])\n    nms_boxes_bs = nms_boxes_bs.astype(np.int32)\n    \n    if do_plot:\n        plt.figure(figsize=(20,20))\n        __img = vis_utils.visualize_boxes_and_labels_on_image_array(\n            __img,\n            nms_boxes_bs,\n            nms_classes_bs,\n            nms_scores_bs,\n            category_index=cat_index, \n            min_score_thresh=score_thresh,\n            line_thickness=3\n        )\n        plt.imshow(__img)\n        plt.show()\n\n    return_str = \"\"\n    for _cls, _box, _scr in zip(nms_classes_bs, nms_boxes_bs, nms_scores_bs):\n        if _scr<score_thresh:\n            continue\n        else:\n            return_str+=f\" {_scr} {_box[1]} {_box[0]} {_box[3]-_box[1]} {_box[2]-_box[0]}\"\n    return return_str.strip()","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:59:54.149119Z","iopub.execute_input":"2021-12-16T01:59:54.149394Z","iopub.status.idle":"2021-12-16T01:59:54.163533Z","shell.execute_reply.started":"2021-12-16T01:59:54.149364Z","shell.execute_reply":"2021-12-16T01:59:54.162803Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# an iterator which loops over the test set and sample submission\niter_test = env.iter_test()\n\nfor idx, (img, pred_df) in enumerate(tqdm(iter_test)):\n    infer_str = model_inference(model, img, do_plot=True if idx<3 else False)\n    pred_df['annotations'] = infer_str\n    env.predict(pred_df)","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:59:55.242796Z","iopub.execute_input":"2021-12-16T01:59:55.243664Z","iopub.status.idle":"2021-12-16T01:59:55.38677Z","shell.execute_reply.started":"2021-12-16T01:59:55.243612Z","shell.execute_reply":"2021-12-16T01:59:55.385904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-12-16T01:59:35.303798Z","iopub.execute_input":"2021-12-16T01:59:35.304076Z","iopub.status.idle":"2021-12-16T01:59:35.313499Z","shell.execute_reply.started":"2021-12-16T01:59:35.304043Z","shell.execute_reply":"2021-12-16T01:59:35.312684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}