{"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":"<a id=\"1\"></a>\n# <p style=\"background-color:#000;font-family:newtimeroman;color:#fff;font-size:120%;text-align:center;border-radius:20px 80px;\">Introduction</p>\n\n> ### RetinaNet is one of the best one-stage object detection models that has proven to work well with dense and small scale objects. For this reason, it has become a popular object detection model to be used with aerial and satellite imagery. [read more...](https://developers.arcgis.com/python/guide/how-retinanet-works/)\n\n> ### In this notebook, I will be training RetinaNet architecture from [fizyr](https://github.com/fizyr/keras-retinanet) on [tensorflow-great-barrier-reef](https://www.kaggle.com/c/tensorflow-great-barrier-reef) dataset.","metadata":{}},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n# <p style=\"background-color:#000000;font-family:newtimeroman;color:#fff;font-size:120%;text-align:center;border-radius:20px 80px;\">Import Libraries</p>","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n# show images inline\n%matplotlib inline\n\nimport keras\nimport tensorflow\n\n# import miscellaneous modules\nimport matplotlib.pyplot as plt\nimport cv2\nimport os\nimport numpy as np\nimport time\n\nimport tensorflow as tf\n\n\n#Clone Git Repository\n!git clone https://github.com/fizyr/keras-retinanet.git\n%cd keras-retinanet/\n!python setup.py build_ext --inplace\n\n# import keras_retinanet\nfrom keras_retinanet import models\nfrom keras_retinanet.utils.image import read_image_bgr, preprocess_image, resize_image\nfrom keras_retinanet.utils.visualization import draw_box, draw_caption\nfrom keras_retinanet.utils.colors import label_color\nfrom keras_retinanet import models","metadata":{"execution":{"iopub.status.busy":"2021-12-22T11:51:13.475633Z","iopub.execute_input":"2021-12-22T11:51:13.475882Z","iopub.status.idle":"2021-12-22T11:51:25.775274Z","shell.execute_reply.started":"2021-12-22T11:51:13.475810Z","shell.execute_reply":"2021-12-22T11:51:25.774432Z"},"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n# <p style=\"background-color:#000000;font-family:newtimeroman;color:#fff;font-size:120%;text-align:center;border-radius:20px 80px;\">Load Data </p>","metadata":{}},{"cell_type":"code","source":"df_train = pd.read_csv(\"/kaggle/input/tensorflow-great-barrier-reef/train.csv\")\n\ndf_train=df_train.loc[df_train[\"annotations\"].astype(str) != \"[]\"]\ndf_train['annotations'] = df_train['annotations'].apply(eval)\n\ndf_train['image_path'] = \"/kaggle/input/tensorflow-great-barrier-reef/train_images/video_\" + df_train['video_id'].astype(str) + \"/\" + df_train['video_frame'].astype(str) + \".jpg\"\ndf_extrain=df_train.explode('annotations') # Single annotation per row\ndf_extrain.reset_index(inplace=True)\ndf_extrain.head()","metadata":{"execution":{"iopub.status.busy":"2021-12-22T11:51:25.777480Z","iopub.execute_input":"2021-12-22T11:51:25.777964Z","iopub.status.idle":"2021-12-22T11:51:26.053316Z","shell.execute_reply.started":"2021-12-22T11:51:25.777899Z","shell.execute_reply":"2021-12-22T11:51:26.052661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_extrain_main=pd.DataFrame(pd.json_normalize(df_extrain['annotations']), columns=['x', 'y', 'width', 'height']).join(df_extrain)\ndf_extrain_main['class']='Fish'\ndf_extrain_main=df_extrain_main[['image_path','x','y','width','height','class','video_id','video_frame']]\ndf_extrain_main.head(10)","metadata":{"execution":{"iopub.status.busy":"2021-12-22T11:51:26.054595Z","iopub.execute_input":"2021-12-22T11:51:26.054849Z","iopub.status.idle":"2021-12-22T11:51:26.145616Z","shell.execute_reply.started":"2021-12-22T11:51:26.054813Z","shell.execute_reply":"2021-12-22T11:51:26.144731Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n# <p style=\"background-color:#000000;font-family:newtimeroman;color:#fff;font-size:120%;text-align:center;border-radius:20px 80px;\">Download Pretrained Weights</p>","metadata":{}},{"cell_type":"code","source":"!pip install --upgrade git+https://github.com/broadinstitute/keras-resnet\nimport keras\nimport keras_resnet\nimport urllib.request\nPRETRAINED_MODEL = './snapshots/_pretrained_model.h5'\n#### OPTION 1: DOWNLOAD INITIAL PRETRAINED MODEL FROM FIZYR ####\nURL_MODEL = 'https://github.com/fizyr/keras-retinanet/releases/download/0.5.1/resnet50_coco_best_v2.1.0.h5'\nurllib.request.urlretrieve(URL_MODEL, PRETRAINED_MODEL)\nprint('Downloaded pretrained model to ' + PRETRAINED_MODEL)","metadata":{"execution":{"iopub.status.busy":"2021-12-22T11:51:26.147833Z","iopub.execute_input":"2021-12-22T11:51:26.148115Z","iopub.status.idle":"2021-12-22T11:51:55.328549Z","shell.execute_reply.started":"2021-12-22T11:51:26.148077Z","shell.execute_reply":"2021-12-22T11:51:55.326918Z"},"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n# <p style=\"background-color:#000000;font-family:newtimeroman;color:#fff;font-size:120%;text-align:center;border-radius:20px 80px;\">Transfoming Data Format </p>","metadata":{}},{"cell_type":"code","source":"\ndef create_tf_example(rowss,data_df):\n    \"\"\"Create a tf.Example entry for a given training image.\"\"\"\n    full_path = os.path.join(rowss.image_path)\n    with tf.io.gfile.GFile(full_path, 'rb') as fid:\n        encoded_jpg = fid.read()\n    encoded_jpg_io = io.BytesIO(encoded_jpg)\n    image = Image.open(encoded_jpg_io)\n    if image.format != 'JPEG':\n        raise ValueError('Image format not JPEG')\n\n    height = image.size[1] # Image height\n    width = image.size[0] # Image width\n    #print(width,height)\n    filename = f'{rowss.video_id}:{rowss.video_frame}'.encode('utf8') # Unique id of the image.\n    encoded_image_data = None # Encoded image bytes\n    image_format = 'jpeg'.encode('utf8') # b'jpeg' or b'png'\n\n    xmins = [] \n    xmaxs = [] \n    ymins = [] \n    ymaxs = [] \n    \n    # Convert ---> [xmin,ymin,width,height] to [xmins,xmaxs,ymins,ymaxs]\n    xmin = rowss['x']\n    xmax = rowss['x']+rowss['width']\n    ymin = rowss['y']\n    ymax = rowss['y']+rowss['height']\n    \n\n    #main_data.append((rowss['image_path'],xmins,xmaxs,ymins,ymaxs))\n    return rowss['image_path'],xmin,ymin,xmax,ymax","metadata":{"execution":{"iopub.status.busy":"2021-12-22T11:51:55.330334Z","iopub.execute_input":"2021-12-22T11:51:55.330626Z","iopub.status.idle":"2021-12-22T11:51:55.339708Z","shell.execute_reply.started":"2021-12-22T11:51:55.330587Z","shell.execute_reply":"2021-12-22T11:51:55.338865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nimport contextlib2\nimport io\nimport IPython\nimport json\nimport numpy as np\nimport os\nimport pathlib\nimport pandas as pd\nimport sys\nimport tensorflow as tf\nimport time\n\ntf_example1=[]\n\nfrom PIL import Image, ImageDraw\nfor index, row in df_extrain_main.iterrows():\n            if index % 1000 == 0:\n                print('Processed {0} images.'.format(index))\n            image_path,xmins,ymins,xmaxs,ymaxs=create_tf_example(row,df_extrain_main)\n            #print(image_path,xmins,xmaxs,ymins,ymaxs)\n            df_extrain_main.loc[index,'image_path']=image_path\n            df_extrain_main.loc[index,'x']=xmins\n            df_extrain_main.loc[index,'y']=ymins\n            df_extrain_main.loc[index,'width']=xmaxs\n            df_extrain_main.loc[index,'height']=ymaxs\n","metadata":{"execution":{"iopub.status.busy":"2021-12-22T11:51:55.341193Z","iopub.execute_input":"2021-12-22T11:51:55.341732Z","iopub.status.idle":"2021-12-22T11:53:35.012960Z","shell.execute_reply.started":"2021-12-22T11:51:55.341695Z","shell.execute_reply":"2021-12-22T11:53:35.012144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n# <p style=\"background-color:#000000;font-family:newtimeroman;color:#fff;font-size:120%;text-align:center;border-radius:20px 80px;\">Creating CSV for Training </p>","metadata":{}},{"cell_type":"code","source":"classes=pd.DataFrame([{'class':'Fish','label':0}])\nclasses.to_csv(\"classes.csv\",index=False,header=False)  # This CSV will be use in training\n\ndf_extrain_main['class']='Fish'\ndf_extrain_main[['image_path','x','y','width','height','class']].to_csv(\"annotation.csv\",index=False,header=False)","metadata":{"execution":{"iopub.status.busy":"2021-12-22T11:53:35.014370Z","iopub.execute_input":"2021-12-22T11:53:35.014647Z","iopub.status.idle":"2021-12-22T11:53:35.085631Z","shell.execute_reply.started":"2021-12-22T11:53:35.014612Z","shell.execute_reply":"2021-12-22T11:53:35.084895Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n# <p style=\"background-color:#000000;font-family:newtimeroman;color:#fff;font-size:120%;text-align:center;border-radius:20px 80px;\">Training RetinaNet</p>","metadata":{}},{"cell_type":"markdown","source":"### Training this model 60 epochs for demo purpose.","metadata":{}},{"cell_type":"code","source":"!keras_retinanet/bin/train.py --freeze-backbone --random-transform --weights {PRETRAINED_MODEL} --batch-size 1 --steps 500 --epochs 60 csv annotation.csv classes.csv","metadata":{"execution":{"iopub.status.busy":"2021-12-22T11:53:35.086950Z","iopub.execute_input":"2021-12-22T11:53:35.087227Z","iopub.status.idle":"2021-12-22T12:09:46.259694Z","shell.execute_reply.started":"2021-12-22T11:53:35.087191Z","shell.execute_reply":"2021-12-22T12:09:46.258828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n# <p style=\"background-color:#000000;font-family:newtimeroman;color:#fff;font-size:120%;text-align:center;border-radius:20px 80px;\">Load Trained Model</p>","metadata":{}},{"cell_type":"code","source":"model_path = os.path.join('snapshots', sorted(os.listdir('snapshots'), reverse=True)[0])\n#print(model_path)\n\n# load retinanet model\nmodel = models.load_model(model_path, backbone_name='resnet50')  ## Use backbone as resnet50\nmodel = models.convert_model(model)\n\n# load label to names mapping for visualization purposes\nlabels_to_names = pd.read_csv('classes.csv',header=None).T.loc[0].to_dict()","metadata":{"execution":{"iopub.status.busy":"2021-12-22T12:09:46.261600Z","iopub.execute_input":"2021-12-22T12:09:46.261886Z","iopub.status.idle":"2021-12-22T12:09:51.342767Z","shell.execute_reply.started":"2021-12-22T12:09:46.261846Z","shell.execute_reply":"2021-12-22T12:09:51.342039Z"},"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n# <p style=\"background-color:#000000;font-family:newtimeroman;color:#fff;font-size:120%;text-align:center;border-radius:20px 80px;\">Predicted vs Actual</p>","metadata":{}},{"cell_type":"code","source":"THRES_SCORE = 0.4  # Set Score Threshold Value\n\ndef df_plot_orinal(drawOG,img_path,df):\n    df=df[df['image_path']==img_path]\n    for i,r in df.iterrows():\n        cv2.rectangle(drawOG, (r['x'], r['y']), (r['width'], r['height']), (255,0,0),2)\n    \n\ndef img_inference(img_path):\n  image = read_image_bgr(img_path)\n\n  # copy to draw on\n  draw = image.copy()\n  draw = cv2.cvtColor(draw, cv2.COLOR_BGR2RGB)\n  drawOG = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n  # preprocess image for network\n  image = preprocess_image(image)\n  image, scale = resize_image(image)\n\n  # process image\n  start = time.time()\n  boxes, scores, labels = model.predict_on_batch(np.expand_dims(image, axis=0))\n  df_plot_orinal(drawOG,img_path,df_extrain_main)\n  # correct for image scale\n  boxes /= scale\n  # visualize detections\n  for box, score, label in zip(boxes[0], scores[0], labels[0]):\n      # scores are sorted so we can break\n      #print(score)\n      if score < THRES_SCORE:\n          continue\n      color = label_color(label)\n      b = box.astype(int)\n      draw_box(draw, b, color=color)\n      caption = \"{} {:.3f}%\".format(labels_to_names[label], score*100)\n    \n  fig = plt.figure(figsize=(20, 20))\n  ax1=fig.add_subplot(1, 2, 1)\n  plt.imshow(draw)\n  ax2=fig.add_subplot(1, 2, 2)\n  plt.imshow(drawOG)\n\n  ax1.title.set_text('Predicted')\n  ax2.title.set_text('Actual')\n  plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-22T12:22:12.496252Z","iopub.execute_input":"2021-12-22T12:22:12.496948Z","iopub.status.idle":"2021-12-22T12:22:12.508901Z","shell.execute_reply.started":"2021-12-22T12:22:12.496908Z","shell.execute_reply":"2021-12-22T12:22:12.508067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data=df_extrain_main.sample(n=5)  #Predict on Random 5 Image\nfor i,r in data.iterrows():\n    img_inference(r['image_path'])","metadata":{"execution":{"iopub.status.busy":"2021-12-22T12:22:15.040011Z","iopub.execute_input":"2021-12-22T12:22:15.040713Z","iopub.status.idle":"2021-12-22T12:22:18.721879Z","shell.execute_reply.started":"2021-12-22T12:22:15.040672Z","shell.execute_reply":"2021-12-22T12:22:18.721244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> ###  Not bad🤔, it could be more accurate by hyperparameter tuning⚙🛠\n> ### Next I will try to Fine tune the same model. \n","metadata":{}},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n# <p style=\"background-color:#000000;font-family:newtimeroman;color:#fff;font-size:120%;text-align:center;border-radius:20px 80px;\"> Great Barrier Reef API</p>","metadata":{}},{"cell_type":"code","source":"# Import the library that is used to submit the prediction result.\nimport sys\nINPUT_DIR = '/kaggle/input/tensorflow-great-barrier-reef/greatbarrierreef/'\nsys.path.insert(0, INPUT_DIR)\nimport greatbarrierreef\nenv = greatbarrierreef.make_env()   # initialize the environment\niter_test = env.iter_test()","metadata":{"execution":{"iopub.status.busy":"2021-12-22T12:09:59.087488Z","iopub.execute_input":"2021-12-22T12:09:59.087911Z","iopub.status.idle":"2021-12-22T12:09:59.120279Z","shell.execute_reply.started":"2021-12-22T12:09:59.087877Z","shell.execute_reply":"2021-12-22T12:09:59.119659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_dict = {\n    'id': [],\n    'prediction_string': [],\n}\n\nfor (image, sample_prediction_df) in iter_test:\n  print(image.shape,sample_prediction_df)\n\n  image = preprocess_image(image)\n  image, scale = resize_image(image)\n\n  # process image\n  start = time.time()\n  boxes, scores, labels = model.predict_on_batch(np.expand_dims(image, axis=0))\n  predictions=[]\n  # correct for image scale\n  boxes /= scale\n  # visualize detections\n  for box, score, label in zip(boxes[0], scores[0], labels[0]):\n      # scores are sorted so we can break\n      if score < THRES_SCORE:\n          continue\n      x_min = int(box[0])  \n      y_min = int(box[1])\n      x_max = int(box[2])\n      y_max = int(box[3])\n\n      bbox_width = x_max - x_min\n      bbox_height = y_max - y_min\n      predictions.append('{:.2f} {} {} {} {}'.format(score, x_min, y_min, bbox_width, bbox_height))\n\n  prediction_str = ' '.join(predictions)\n  sample_prediction_df['annotations'] = prediction_str\n  env.predict(sample_prediction_df)\n  print('Prediction:', prediction_str)\n\n#my_submission = pd.DataFrame(sample_prediction_df)\n# you could use any filename. We choose submission here\n#sample_prediction_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2021-12-22T12:09:59.123027Z","iopub.execute_input":"2021-12-22T12:09:59.123227Z","iopub.status.idle":"2021-12-22T12:09:59.810791Z","shell.execute_reply.started":"2021-12-22T12:09:59.123202Z","shell.execute_reply":"2021-12-22T12:09:59.809978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style=\"font-size:220%;text-align:center\"> If you find this notebook interesting, please do upvote :) </p>\n\n# <p style=\"text-align:center\"> <img src=\"https://media.giphy.com/media/3oEdva9BUHPIs2SkGk/giphy.gif\"> </p>\n## Checkout Inference Notebook: [🌟🐟Detection using Keras-RetinaNet [Inference]](https://www.kaggle.com/mahipalsingh/detection-using-keras-retinanet-inference)","metadata":{}},{"cell_type":"markdown","source":"<a id=\"1\"></a>\n# <p style=\"background-color:#000000;font-family:newtimeroman;color:#fff;font-size:120%;text-align:center;border-radius:20px 80px;\"> Reference </p>\n\n> ### [Fizyr Keras Retinanet](https://github.com/fizyr/keras-retinanet)\n> ### [Great Barrier Reef API Tutorial](https://www.kaggle.com/sohier/great-barrier-reef-api-tutorial)\n> ### [Reef- Starter Torch FasterRCNN Infer](https://www.kaggle.com/julian3833/reef-starter-torch-fasterrcnn-infer-lb-0-413)\n","metadata":{}}]}