{"cells":[{"metadata":{},"cell_type":"markdown","source":"Inspired by IRONSIGHT(@ravi02516)'s notebook [\"End to End EffiecientDet Training Keras\"](https://www.kaggle.com/ravi02516/end-to-end-effiecientdet-training-keras).\n\nThanks😉","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"!git clone https://github.com/google/automl.git","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install pycocotools","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport tensorflow as tf\nfrom kaggle_datasets import KaggleDatasets\nimport pickle\nos.chdir(\"/kaggle/working/automl/efficientdet\")\n\nSEED = 777\nos.environ['PYTHONHASHSEED'] = str(SEED)\nnp.random.seed(SEED)\ntf.random.set_seed(SEED)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# latest commit on 7/29/2020\n!git checkout e2ca3361f4c00380a7002e2c9a7ebda1b7f06787","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Detect hardware, return appropriate distribution strategy\ntry:\n    # TPU detection. No parameters necessary if TPU_NAME environment variable is\n    # set: this is always the case on Kaggle.\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n    print('Running on TPU ', tpu.master())\nexcept ValueError:\n    tpu = None\n\nif tpu:\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    ds_strategy = tf.distribute.experimental.TPUStrategy(tpu)\nelse:\n    # Default distribution strategy in Tensorflow. Works on CPU and single GPU.\n    ds_strategy = tf.distribute.get_strategy()\n\nprint(\"REPLICAS: \", ds_strategy.num_replicas_in_sync)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TF_REC_DS_PATH = KaggleDatasets().get_gcs_path('global-wheat-detection-tfrecord')\ntraining_file_pattern = [TF_REC_DS_PATH + f'/{fold}.tfrecord' for fold in range(0,9)]\nvalidation_file_pattern = TF_REC_DS_PATH + f'/{9}.tfrecord'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nimport os\nfrom absl import app\nfrom absl import flags\nfrom absl import logging\nimport tensorflow as tf\nfrom tensorflow.python.client import device_lib\nimport dataloader\nimport hparams_config\nimport utils\nfrom keras import train_lib\n\nFLAGS={'tpu':None,'gcp_project':None,'tpu_zone':None,'eval_master':'',\n      'eval_name':None,'strategy':None,'num_cores':8,'use_fake_data':False,\n      'use_xla':False,'model_dir':\"/model\",'hparams':'num_classes=1, max_instances_per_image=120, clip_gradients_norm=2.0','batch_size':64,\n      'eval_samples':342,'iterations_per_loop':100,'training_file_pattern':training_file_pattern,\n      'validation_file_pattern':validation_file_pattern,'val_json_file':None,'testdev_dir':None,\n      'num_examples_per_epoch':3079,'num_epochs':None,'mode':'train',\n      'model_name':'efficientdet-d0','eval_after_training':False,\n      'debug':False,'profile':False,'min_eval_interval':180,\n      'eval_timeout':None}\n\n\nif tpu:\n    FLAGS['strategy'] = 'tpu'\n\n# Parse and override hparams\nconfig = hparams_config.get_detection_config(FLAGS[\"model_name\"])\nconfig.override(FLAGS[\"hparams\"])\n\n# Parse image size in case it is in string format.\nconfig.image_size = utils.parse_image_size(config.image_size)\n\n\n# Check data path\nif FLAGS[\"mode\"] in ('train',\n                    'train_and_eval') and FLAGS[\"training_file_pattern\"] is None:\n    raise RuntimeError('You must specify --training_file_pattern for training.')\nif FLAGS[\"mode\"] in ('eval', 'train_and_eval'):\n    if FLAGS[\"validation_file_pattern\"] is None:\n        raise RuntimeError('You must specify --validation_file_pattern '\n                        'for evaluation.')\n\n\nsteps_per_epoch = FLAGS['num_examples_per_epoch'] // FLAGS['batch_size']\nvalidation_steps = FLAGS['eval_samples'] // FLAGS['batch_size']\n\nparams = dict(\n    config.as_dict(),\n    model_name=FLAGS[\"model_name\"],\n    iterations_per_loop=FLAGS[\"iterations_per_loop\"],\n    model_dir=FLAGS[\"model_dir\"],\n    num_examples_per_epoch=FLAGS[\"num_examples_per_epoch\"],\n    steps_per_epoch=steps_per_epoch,\n    strategy=FLAGS[\"strategy\"],\n    batch_size=FLAGS[\"batch_size\"] // ds_strategy.num_replicas_in_sync,\n    num_shards=ds_strategy.num_replicas_in_sync,\n    val_json_file=FLAGS[\"val_json_file\"],\n    testdev_dir=FLAGS[\"testdev_dir\"],\n    mode=FLAGS[\"mode\"],\n    iou_loss_type='ciou',\n    moving_average_decay=0\n)\n\n# set mixed precision policy by keras api.\nprecision = utils.get_precision(params['strategy'], params['mixed_precision'])\npolicy = tf.keras.mixed_precision.experimental.Policy(precision)\ntf.keras.mixed_precision.experimental.set_policy(policy)\n\ndef get_dataset(is_training, params):\n    file_pattern = (\n        FLAGS[\"training_file_pattern\"]\n        if is_training else FLAGS[\"validation_file_pattern\"])\n    return dataloader.InputReader(\n        file_pattern,\n        is_training=is_training,\n        use_fake_data=FLAGS[\"use_fake_data\"],\n        max_instances_per_image=config.max_instances_per_image)(\n            params)\n        \ntf.keras.backend.clear_session()\nwith ds_strategy.scope():\n    model = train_lib.EfficientDetNetTrain(params['var_freeze_expr'], params['model_name'], config)\n    height, width = utils.parse_image_size(params['image_size'])\n    model.build((params['batch_size'], height, width, 3))\n    model.summary()\n\n    model.compile(\n        optimizer=train_lib.get_optimizer(params),\n        loss={\n            'box_loss':\n                train_lib.BoxLoss(\n                    params['delta'],reduction=tf.keras.losses.Reduction.NONE),\n            'box_iou_loss':\n                train_lib.BoxIouLoss(\n                    params['iou_loss_type'],\n                    params['min_level'],\n                    params['max_level'],\n                    params['num_scales'],\n                    params['aspect_ratios'],\n                    params['anchor_scale'],\n                    params['image_size'],\n                    reduction=tf.keras.losses.Reduction.NONE),\n            'class_loss':\n                train_lib.FocalLoss(\n                    params['alpha'],\n                    params['gamma'],\n                    label_smoothing=params['label_smoothing'],\n                    reduction=tf.keras.losses.Reduction.NONE)\n        })\n\n\nhistory = model.fit(\n    get_dataset(True, params=params),\n    steps_per_epoch=steps_per_epoch,\n    epochs=15,\n    validation_data=get_dataset(False, params=params),\n    validation_steps=validation_steps\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# reference: https://qiita.com/mgmk2/items/556ca3f4471ada9c69f0\ndef get_model_weights_as_numpy(model):\n    weights = {}\n    for v in model.weights:\n        weights[v.name] = v.numpy()\n    return weights\n\ndef set_model_weights_from_numpy(weights, model):\n    for v in model.weights:\n        if v.name in weights.keys():\n            v.assign(weights[v.name])\n        else:\n            print('Not loaded weights: ' + v.name)\n\nmodel_weights = get_model_weights_as_numpy(model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nfrom keras import efficientdet_keras\nfrom object_detection import tf_example_decoder\nimport inference\nfrom PIL import Image\nimport glob\n\nimgs = []\n\nfor f in glob.iglob('/kaggle/input/global-wheat-detection/test/*'):\n    imgs.append(np.array(Image.open(f)))\n\n    \nconfig = hparams_config.get_efficientdet_config(params['model_name'])\nconfig.override(FLAGS[\"hparams\"])\nconfig.is_training_bn = False\nconfig.image_size = params['image_size']\nconfig.nms_configs.score_thresh = 0.2\n\ntf.keras.backend.clear_session()\nwith ds_strategy.scope():\n    model_inference = efficientdet_keras.EfficientDetModel(config=config)\n    model_inference.build((1, None, None, 3))\n    set_model_weights_from_numpy(model_weights, model_inference)\n\nboxes, scores, classes, valid_len = model_inference(imgs, training=False, post_mode='global')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%matplotlib inline\nimport matplotlib.pyplot as plt\n\nfig = plt.figure(figsize=(30,50))\n\nfor i, img in enumerate(imgs):\n    length = valid_len[i]\n    img = inference.visualize_image(\n        img,\n        boxes[i].numpy()[:length],\n        classes[i].numpy().astype(np.int)[:length],\n        scores[i].numpy()[:length],\n        min_score_thresh=config.nms_configs.score_thresh,\n        max_boxes_to_draw=config.nms_configs.max_output_size)\n    fig.add_subplot(5, 2, i+1)\n    plt.imshow(img)\n\nfig.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import shutil\nshutil.rmtree(\"/kaggle/working/automl\")","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}