{"cells":[{"metadata":{"_uuid":"56149ab0-f23e-452c-820d-8b1168c06149","_cell_guid":"7114cc85-73f9-4f5e-9529-aab38f3cf89c","trusted":true},"cell_type":"code","source":"import os\nimport pathlib\n\nif \"models\" in pathlib.Path.cwd().parts:\n  while \"models\" in pathlib.Path.cwd().parts:\n    os.chdir('..')\nelif not pathlib.Path('models').exists():\n  !git clone --depth 1 https://github.com/tensorflow/models","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%pwd","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"71517b2c-eb4e-40cd-a39f-e96013a8098d","_cell_guid":"94d31e0b-8cd4-4ce0-b849-1ef8e8f98ac1","trusted":true},"cell_type":"code","source":"%%bash\ncd models/research\nprotoc object_detection/protos/*.proto --python_out=.\ncp object_detection/packages/tf2/setup.py .\npython -m pip install .\nexport PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%pwd","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1dd8c5d7-20dd-48a8-b3f8-9cf98d6f3ef8","_cell_guid":"3d4f360a-0654-4d9b-b051-fb7a8f1d902e","trusted":true},"cell_type":"code","source":"import numpy as np \nimport pandas as pd","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"00ba1a64-f119-4164-9893-9f66dc1abc54","_cell_guid":"ea92fe7f-c02a-43b8-93c3-bd1ef29540d6","trusted":true},"cell_type":"code","source":"train_csv = pd.read_csv('../input/global-wheat-detection/train.csv')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"62a1e5a6-bebf-44f5-9054-a3476e2228c8","_cell_guid":"63583902-6ed3-4a6b-9f9f-62589077200a","trusted":true},"cell_type":"code","source":"bboxes = np.stack(train_csv['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=',')))\nfor i, column in enumerate(['xmin', 'ymin', 'width', 'height']):\n    train_csv[column] = bboxes[:,i]\n    \ntrain_csv[\"xmax\"] = train_csv.apply(lambda col: col.xmin + col.width, axis=1)\ntrain_csv[\"ymax\"] = train_csv.apply(lambda col: col.ymin + col.height, axis = 1)\ntrain_csv.drop(columns=['bbox'], inplace=True)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"32e51d95-fc9d-4926-99d5-3be4c1799be0","_cell_guid":"fa5ac3b2-b393-4b5b-aeb6-ba2ca985fe46","trusted":true},"cell_type":"code","source":"xmax = np.array(train_csv[\"xmax\"].values.tolist())\nymax = np.array(train_csv[\"ymax\"].values.tolist())\ntrain_csv[\"xmax\"] = np.where(xmax > 1024, 1024, xmax).tolist()\ntrain_csv[\"ymax\"] = np.where(ymax > 1024, 1024, ymax).tolist()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3e7bfba3-c90c-48aa-966b-657510a16af4","_cell_guid":"e97ac1cc-b8f8-4569-8bfa-0cc026a72a89","trusted":true},"cell_type":"code","source":"train_csv[\"class\"] = \"wheat\"","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"60c1a9c0-d535-40f1-9b07-e6f8e97a2a52","_cell_guid":"70ea1587-524b-43d8-a34b-96797b4abcb9","trusted":true},"cell_type":"code","source":"del train_csv[\"source\"]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"bb1350d4-fe7e-4f54-b561-800f3a3e951a","_cell_guid":"ca985f7b-75a5-4f47-ad21-93b2b5417270","trusted":true},"cell_type":"code","source":"train_csv['filename']=train_csv['image_id']\ndel train_csv['image_id']","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"76ca8ebc-2c80-4e66-a8c8-0053282cb718","_cell_guid":"498216b4-14af-4e8b-981a-d976a946508f","trusted":true},"cell_type":"code","source":"train_csv['filename'] = train_csv['filename'] + '.jpg'","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"963a2989-c738-42c3-94ce-8321e7c0e388","_cell_guid":"550955b8-6a15-46aa-a986-fe8f7a83fdca","trusted":true},"cell_type":"code","source":"train_csv.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"21de7e1c-747b-4b9e-b183-02e813cfdbde","_cell_guid":"b8bdc4d8-4b86-42c2-bd1c-1b83e1b95fb6","trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nx_train, x_val = train_test_split(train_csv, test_size = 0.2)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6d0fd04f-f57e-4c72-bb30-1f7e3dc692ea","_cell_guid":"fd9b163c-ee43-44ab-ac3b-cf775c9accd1","trusted":true},"cell_type":"code","source":"x_train.to_csv('training.csv',index=False)\nx_val.to_csv('eval.csv',index=False)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"86bb68e4-04dd-42a9-bb44-c9ea7795445d","_cell_guid":"bf004481-cd3b-4d3d-a751-1dcf7da2e911","trusted":true},"cell_type":"code","source":"!wget http://download.tensorflow.org/models/object_detection/tf2/20200711/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8.tar.gz","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2e04cdbc-1d85-4383-86ac-bc2d4ef9b8cb","_cell_guid":"7149d7d2-f54d-4650-bc06-a704dcf06872","trusted":true},"cell_type":"code","source":"!tar --gunzip --extract --verbose --file=faster_rcnn_resnet50_v1_640x640_coco17_tpu-8.tar.gz","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"open(\"generate_tfrecord.py\",\"w+\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%pwd","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%writefile '/kaggle/working/generate_tfrecord.py'\nfrom __future__ import division\nfrom __future__ import print_function\nfrom __future__ import absolute_import\n\nimport os\nimport io\nimport pandas as pd\nimport tensorflow as tf\n\nfrom PIL import Image\nfrom object_detection.utils import dataset_util\nfrom collections import namedtuple, OrderedDict\n\nflags = tf.compat.v1.app.flags\nflags.DEFINE_string('csv_input', '', 'Path to the CSV input')\nflags.DEFINE_string('output_path', '', 'Path to output TFRecord')\nflags.DEFINE_string('image_dir', '', 'Path to images')\nFLAGS = flags.FLAGS\n\n\n# TO-DO replace this with label map\ndef class_text_to_int(row_label):\n    if row_label == 'wheat':\n        return 1\n    else:\n        None\n\n\ndef split(df, group):\n    data = namedtuple('data', ['filename', 'object'])\n    gb = df.groupby(group)\n    return [data(filename, gb.get_group(x)) for filename, x in zip(gb.groups.keys(), gb.groups)]\n\n\ndef create_tf_example(group, path):\n    with tf.compat.v1.gfile.GFile(os.path.join(path, '{}'.format(group.filename)), 'rb') as fid:\n        encoded_jpg = fid.read()\n    encoded_jpg_io = io.BytesIO(encoded_jpg)\n    image = Image.open(encoded_jpg_io)\n    width, height = image.size\n\n    filename = group.filename.encode('utf8')\n    image_format = b'jpg'\n    xmins = []\n    xmaxs = []\n    ymins = []\n    ymaxs = []\n    classes_text = []\n    classes = []\n\n    for index, row in group.object.iterrows():\n        xmins.append(row['xmin'] / width)\n        xmaxs.append(row['xmax'] / width)\n        ymins.append(row['ymin'] / height)\n        ymaxs.append(row['ymax'] / height)\n        classes_text.append(row['class'].encode('utf8'))\n        classes.append(class_text_to_int(row['class']))\n\n    tf_example = tf.train.Example(features=tf.train.Features(feature={\n        'image/height': dataset_util.int64_feature(height),\n        'image/width': dataset_util.int64_feature(width),\n        'image/filename': dataset_util.bytes_feature(filename),\n        'image/source_id': dataset_util.bytes_feature(filename),\n        'image/encoded': dataset_util.bytes_feature(encoded_jpg),\n        'image/format': dataset_util.bytes_feature(image_format),\n        'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),\n        'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),\n        'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),\n        'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),\n        'image/object/class/text': dataset_util.bytes_list_feature(classes_text),\n        'image/object/class/label': dataset_util.int64_list_feature(classes),\n    }))\n    return tf_example\n\n\ndef main(_):\n    writer = tf.io.TFRecordWriter(FLAGS.output_path)\n    path = os.path.join(FLAGS.image_dir)\n    examples = pd.read_csv(FLAGS.csv_input)\n    grouped = split(examples, 'filename')\n    for group in grouped:\n        tf_example = create_tf_example(group, path)\n        writer.write(tf_example.SerializeToString())\n\n    writer.close()\n    output_path = os.path.join(os.getcwd(), FLAGS.output_path)\n    print('Successfully created the TFRecords: {}'.format(output_path))\n\n\nif __name__ == '__main__':\n    tf.compat.v1.app.run()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"open(\"label_map.txt\",\"w+\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%writefile '/kaggle/working/label_map.txt'\nitem {\n  id: 1\n  name: 'wheat'\n}","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"659fa9ec-c8fa-4c2d-b5fd-a4833dc94753","_cell_guid":"ce021bf9-c6d3-4ddc-b04f-bdebaefca54f","trusted":true},"cell_type":"code","source":"!python /kaggle/working/generate_tfrecord.py --csv_input=/kaggle/working/training.csv  --output_path=train.record --image_dir=../input/global-wheat-detection/train","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"42e47552-edd5-40ba-a284-b0ec10c6516d","_cell_guid":"42716707-1334-4a11-acdc-b3ae5c098efd","trusted":true},"cell_type":"code","source":"!python3 /kaggle/working/generate_tfrecord.py --csv_input=eval.csv  --output_path=eval.record --image_dir=../input/global-wheat-detection/train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"open(\"pipeline.config\",\"w+\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%writefile '/kaggle/working/models/research/object_detection/configs/tf2/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8.config'\nmodel {\n  faster_rcnn {\n    num_classes: 1\n    image_resizer {\n      keep_aspect_ratio_resizer {\n        min_dimension: 640\n        max_dimension: 640\n        pad_to_max_dimension: true\n      }\n    }\n    feature_extractor {\n      type: 'faster_rcnn_resnet50_keras'\n      batch_norm_trainable: true\n    }\n    first_stage_anchor_generator {\n      grid_anchor_generator {\n        scales: [0.25, 0.5, 1.0, 2.0]\n        aspect_ratios: [0.5, 1.0, 2.0]\n        height_stride: 16\n        width_stride: 16\n      }\n    }\n    first_stage_box_predictor_conv_hyperparams {\n      op: CONV\n      regularizer {\n        l2_regularizer {\n          weight: 0.0\n        }\n      }\n      initializer {\n        truncated_normal_initializer {\n          stddev: 0.01\n        }\n      }\n    }\n    first_stage_nms_score_threshold: 0.0\n    first_stage_nms_iou_threshold: 0.7\n    first_stage_max_proposals: 300\n    first_stage_localization_loss_weight: 2.0\n    first_stage_objectness_loss_weight: 1.0\n    initial_crop_size: 14\n    maxpool_kernel_size: 2\n    maxpool_stride: 2\n    second_stage_box_predictor {\n      mask_rcnn_box_predictor {\n        use_dropout: false\n        dropout_keep_probability: 1.0\n        fc_hyperparams {\n          op: FC\n          regularizer {\n            l2_regularizer {\n              weight: 0.0\n            }\n          }\n          initializer {\n            variance_scaling_initializer {\n              factor: 1.0\n              uniform: true\n              mode: FAN_AVG\n            }\n          }\n        }\n        share_box_across_classes: true\n      }\n    }\n    second_stage_post_processing {\n      batch_non_max_suppression {\n        score_threshold: 0.0\n        iou_threshold: 0.6\n        max_detections_per_class: 100\n        max_total_detections: 300\n      }\n      score_converter: SOFTMAX\n    }\n    second_stage_localization_loss_weight: 2.0\n    second_stage_classification_loss_weight: 1.0\n    use_static_shapes: true\n    use_matmul_crop_and_resize: true\n    clip_anchors_to_image: true\n    use_static_balanced_label_sampler: true\n    use_matmul_gather_in_matcher: true\n  }\n}\n\ntrain_config: {\n  batch_size: 5\n  sync_replicas: true\n  startup_delay_steps: 0\n  replicas_to_aggregate: 8\n  num_steps: 25000\n  optimizer {\n    momentum_optimizer: {\n      learning_rate: {\n        cosine_decay_learning_rate {\n          learning_rate_base: .04\n          total_steps: 25000\n          warmup_learning_rate: .013333\n          warmup_steps: 2000\n        }\n      }\n      momentum_optimizer_value: 0.9\n    }\n    use_moving_average: false\n  }\n  fine_tune_checkpoint_version: V2\n  fine_tune_checkpoint: \"/kaggle/working/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8/checkpoint/ckpt-0\"\n  fine_tune_checkpoint_type: \"detection\"\n  data_augmentation_options {\n    random_horizontal_flip {\n    }\n  }\n\n  max_number_of_boxes: 150\n  unpad_groundtruth_tensors: false\n  use_bfloat16: true  # works only on TPUs\n}\n\ntrain_input_reader: {\n  label_map_path: \"/kaggle/working/label_map.txt\"\n  tf_record_input_reader {\n    input_path: \"/kaggle/working/train.record\"\n  }\n}\n\neval_config: {\n  metrics_set: \"coco_detection_metrics\"\n  use_moving_averages: false\n  batch_size: 1;\n}\n\neval_input_reader: {\n  label_map_path: \"/kaggle/working/label_map.txt\"\n  shuffle: false\n  num_epochs: 1\n  tf_record_input_reader {\n    input_path: \"/kaggle/working/eval.record\"\n  }\n}","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"904a552d-e963-4764-85be-d1274f254db8","_cell_guid":"372e1909-ada5-4cf8-8a9d-58e7ad1bdbc5","trusted":true},"cell_type":"code","source":"!mkdir ./tuned","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%pwd","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%cd /kaggle/working/models/research/","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"83537e04-823a-4f0f-abb6-28d4a7555e07","_cell_guid":"f8db9c0f-c1ab-49ab-9f3f-467ec4c6f413","trusted":true},"cell_type":"code","source":"!python object_detection/model_main_tf2.py \\\n    --num_train_steps=2500 \\\n    --sample_1_of_n_eval_examples=1 \\\n    --pipeline_config_path=/kaggle/working/models/research/object_detection/configs/tf2/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8.config \\\n    --model_dir=/kaggle/working/tuned \\\n    --alsologtostderr","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%pwd\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!python object_detection/exporter_main_v2.py \\\n    --pipeline_config_path /kaggle/working/models/research/object_detection/configs/tf2/faster_rcnn_resnet50_v1_640x640_coco17_tpu-8.config \\\n    --trained_checkpoint_dir /kaggle/working/tuned \\\n    --output_directory /kaggle/working/output","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%cd /kaggle/working","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport os\nimport six.moves.urllib as urllib\nimport sys\nimport tarfile\nimport tensorflow as tf\nimport zipfile\n\nfrom collections import defaultdict\nfrom io import StringIO\nfrom matplotlib import pyplot as plt\nfrom PIL import Image\nfrom IPython.display import display","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from object_detection.utils import ops as utils_ops\nfrom object_detection.utils import label_map_util\nfrom object_detection.utils import visualization_utils as vis_util","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"utils_ops.tf = tf.compat.v1\ntf.gfile = tf.io.gfile","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_model():\n    model = tf.saved_model.load('/kaggle/working/output/saved_model')\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"PATH_TO_LABELS = '/kaggle/working/label_map.txt'\ncategory_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"PATH_TO_TEST_IMAGES_DIR = pathlib.Path('../input/global-wheat-detection/test')\nTEST_IMAGE_PATHS = sorted(list(PATH_TO_TEST_IMAGES_DIR.glob(\"*.jpg\")))\nTEST_IMAGE_PATHS","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"detection_model = load_model()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def run_inference_for_single_image(model, image):\n    image = np.asarray(image)\n    input_tensor = tf.convert_to_tensor(image)\n    input_tensor = input_tensor[tf.newaxis,...]\n\n    model_fn = model.signatures['serving_default']\n    output_dict = model_fn(input_tensor)\n\n    num_detections = int(output_dict.pop('num_detections'))\n    output_dict = {key:value[0, :num_detections].numpy() \n                 for key,value in output_dict.items()}\n    output_dict['num_detections'] = num_detections\n\n    output_dict['detection_classes'] = output_dict['detection_classes'].astype(np.int64)\n    if 'detection_masks' in output_dict:\n        detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(\n              output_dict['detection_masks'], output_dict['detection_boxes'],\n               image.shape[0], image.shape[1])      \n        \n        detection_masks_reframed = tf.cast(detection_masks_reframed > 0.5,\n                                       tf.uint8)\n        \n        output_dict['detection_masks_reframed'] = detection_masks_reframed.numpy()\n    \n    return output_dict","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%pwd\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import csv\nfilename = 'submission1.csv'\nfields = ['image_id', 'PredictionString']\nwith open(filename, 'w') as csvfile:\n    csvwriter = csv.writer(csvfile)\n    csvwriter.writerow(fields)\n    \n    for image_path in TEST_IMAGE_PATHS:\n        image_np = np.array(Image.open(image_path))\n        hel = run_inference_for_single_image(detection_model,image_np)\n        h = round(pd.DataFrame(hel['detection_boxes'])*1024,0)\n        r = pd.DataFrame(hel['detection_scores'])\n        h['D'] = r\n        score = h['D']\n        xmin = h[1]\n        xmax = h[3]\n        ymin = h[0]\n        ymax = h[2]\n        for i in np.arange(0,len(xmin)):\n            if(score[i]>0.5):\n                s = [\"{:.1f}\".format(score[i]),int(xmin[i]), int(ymin[i]), int(xmax[i]-xmin[i]), int(ymax[i]-ymin[i])]\n                x = ' '.join([str(elem) for elem in s])\n                y = str(image_path).strip('.jpg') \n                row = [y, x]\n                csvwriter.writerow(row)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\ndata = pd.read_csv('/kaggle/working/submission1.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np \nfor i in np.arange(0,len(data['image_id'])):\n    data['image_id'][i] = data['image_id'][i][35:44] ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.to_csv('submission.csv',index = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}