{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"# clone keras-retinanet from github and install it\n!git clone https://github.com/fizyr/keras-retinanet.git\n!pip install --upgrade keras\n%cd keras-retinanet/\n!pip install .","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# build keras-retinanet using script setup.py\n!python setup.py build_ext --inplace","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# install tensorflow-gpu\n!pip install tensorflow-gpu","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# set up environment\nimport io\nimport numpy as np\nimport tensorflow as tf\nimport pandas as pd\nimport seaborn as sns\nfrom pylab import rcParams\nimport matplotlib.pyplot as plt\nfrom matplotlib import rc\nimport matplotlib.patches as patches\nfrom pandas.plotting import register_matplotlib_converters\nfrom sklearn.model_selection import train_test_split\nimport urllib\nimport os\nimport csv\nimport cv2\nimport time\nfrom PIL import Image\n\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, draw_detections\nfrom keras_retinanet.utils.colors import label_color","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# grab and check out training data\npath = '/kaggle/input/global-wheat-detection/'\ntrain_data = pd.read_csv(path + 'train.csv')\ntrain_data.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# split into train and test sets\ndf_train, df_test = train_test_split(train_data,test_size=0.2, random_state=2020)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# re-format train and test data to match requirements of keras-retinanet: path/to/image.jpg,x1,y1,x2,y2,class_name\n# current format: xmin, ymin, width, height\ndef formatKRN(data):\n    dataset = {'img': [], 'x1':[], 'y1':[], 'x2':[], 'y2':[], 'class':[]}\n    for index, row in data.iterrows():\n        dat = row['bbox']\n        dat = dat.replace('[', '')\n        dat = dat.replace(']', '')\n        dat = dat.split(',')\n        dat = [int(float(ii)) for ii in dat]\n        dataset['img'].append(path + 'train/' + row['image_id'] + '.jpg')\n        dataset['x1'].append(dat[0])\n        dataset['y1'].append(dat[1])\n        dataset['x2'].append(dat[0] + dat[2])\n        dataset['y2'].append(dat[1] + dat[3])\n        dataset['class'].append('whead')\n    \n    return pd.DataFrame(dataset)\n\ndf_train = formatKRN(data=df_train)\ndf_test = formatKRN(data=df_test)\n\nprint(df_train.shape, df_test.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_test.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# function for plotting image and bboxes\ndef draw_train_img_and_bboxes(df, i, col):\n    imgid = df['img'][i]\n    img = Image.open(imgid)\n    bboxes = df[df.img == imgid][['x1', 'y1', 'x2', 'y2']]\n    fig,ax = plt.subplots(1, figsize=(10, 10))\n    ax.imshow(img)\n    for index, row in bboxes.iterrows():    \n        rect = patches.Rectangle(xy=(row['x1'], row['y1']), \n                                 width=row['x2']-row['x1'], \n                                 height=row['y2']-row['y1'], \n                                 linewidth=1, edgecolor=col, facecolor='none')\n        ax.add_patch(rect)\n        plt.title(imgid)\n\ndef draw_test_img_and_bboxes(df, i, predboxes, colobs, colpred, minscore):\n    imgid = df['img'][i]\n    img = Image.open(imgid)\n    bboxes = df[df.img == imgid][['x1', 'y1', 'x2', 'y2']]\n    fig,ax = plt.subplots(1, figsize=(10, 10))\n    \n    # draw observed bboxes on test image\n    for index, row in bboxes.iterrows():    \n        rect = patches.Rectangle(xy=(row['x1'], row['y1']), \n                                 width=row['x2']-row['x1'], \n                                 height=row['y2']-row['y1'], \n                                 linewidth=1, edgecolor=colobs, facecolor='none')\n        ax.add_patch(rect)        \n        \n    # draw predicted bboxes on test image\n    for box, score, label in zip(boxes[0], scores[0], labels[0]):\n        if score < minscore: # (scores are sorted)\n            break\n        b = box.astype(int)\n        rect = patches.Rectangle(xy=(b[0], b[1]), width=b[2], height=b[3], linewidth=1, \n                                 edgecolor=colpred, facecolor='none')\n        ax.add_patch(rect)\n    \n    ax.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot a sample image with boxes\ndraw_train_img_and_bboxes(df=df_train, i=12041, col='yellow')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# files required for training\ndf_train.to_csv('trainDatFile.csv', index=False, header=None)\nwith open('classFile.csv', 'w') as f:\n    f.write('{},{}\\n'.format('whead',0))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!head trainDatFile.csv","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!head classFile.csv","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# dowload pre-trained model (weights) to use as starting point in training\npretrainedMod = './snapshots/_pretrained_model.h5'\npretrainedModUrl = 'https://github.com/fizyr/keras-retinanet/releases/download/0.5.1/resnet50_coco_best_v2.1.0.h5'\nurllib.request.urlretrieve(pretrainedModUrl, pretrainedMod)\nprint('Downloaded pretrained model to ' + pretrainedMod)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# train with script train.py from keras_retinanet github repository ****************\n!keras_retinanet/bin/train.py \\\n--freeze-backbone \\\n--random-transform \\\n--weights {pretrainedMod} \\\n--batch-size 4 \\\n--steps 200 \\\n--epochs 10 \\\ncsv trainDatFile.csv classFile.csv","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# load trained model and convert to inference model (because we freezed backbone layer in training)\nmodel = models.load_model('snapshots/resnet50_csv_10.h5', backbone_name='resnet50')\nmodel = models.convert_model(model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# make prediction on single image (i=index in df_test) and plot together with observed bboxes\ni = 909\nimage = read_image_bgr(df_test['img'][i])\nimage = preprocess_image(image)\nimage, scale = resize_image(image)\nboxes, scores, labels = model.predict_on_batch(np.expand_dims(image, axis=0))\nboxes /= scale # bring predicted boxes back to the images' original scale\ndraw_test_img_and_bboxes(df_test, \n                         i=i, \n                         predboxes=boxes, \n                         colobs='red', colpred='blue', \n                         minscore=0.65)","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}