{"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":"# Training Yolov5 for Kaggle Competitions  [Setup Tutorial]","metadata":{}},{"cell_type":"markdown","source":"## Firstly, look at the data","metadata":{}},{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport imageio\nimport matplotlib.pyplot as plt\n\nmonitor = True\nload = True\n\ndf = pd.read_csv('../input/tensorflow-great-barrier-reef/train.csv')\ndisplay(df)\n\nsamples_labeled = df[df['annotations']!='[]']\nsamples_no_labels = df[df['annotations']=='[]']\n\nprint(samples_labeled.shape)\nprint(samples_no_labels.shape)\n\nfig, axs = plt.subplots(1,1)\nnames = ['Annotated', 'Not Annotated']\nvals = [samples_labeled.shape[0],samples_no_labels.shape[0]]\nbarlist=axs.bar(names,vals)\nbarlist[0].set_color('g')\nbarlist[1].set_color('r')\n\naxs.set_ylabel(\"Amount of Data Points\")\naxs.set_title(\"Amount of annotated vs non-annotated samples\")\nplt.show()","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-02-20T02:23:24.506594Z","iopub.execute_input":"2022-02-20T02:23:24.507101Z","iopub.status.idle":"2022-02-20T02:23:24.958016Z","shell.execute_reply.started":"2022-02-20T02:23:24.507013Z","shell.execute_reply":"2022-02-20T02:23:24.957358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I'm gonna drop some non-annotated samples so the dataset is more balanced.","metadata":{}},{"cell_type":"code","source":"n = abs(samples_labeled.shape[0]-samples_no_labels.shape[0])\nsamples_to_drop = df[df['annotations']=='[]'].sample(n = n)\ndisplay(samples_to_drop.index)","metadata":{"execution":{"iopub.status.busy":"2022-02-20T02:23:24.959751Z","iopub.execute_input":"2022-02-20T02:23:24.959994Z","iopub.status.idle":"2022-02-20T02:23:24.974427Z","shell.execute_reply.started":"2022-02-20T02:23:24.959960Z","shell.execute_reply":"2022-02-20T02:23:24.973604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def annotation_to_list(annotation):\n    if annotation.annotations=='[]':\n        return []\n    annotation_list = []\n    an = [int(s.strip('{}').split(': ')[1]) for s  in (annotation.annotations.strip(\"[]{}\")).split(',')]\n    box_count = len(an)/4\n    for b in range(int(box_count)):\n        annotation_list.append(an[b*4:b*4+4])\n    return annotation_list","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-20T02:23:24.976169Z","iopub.execute_input":"2022-02-20T02:23:24.976577Z","iopub.status.idle":"2022-02-20T02:23:24.983152Z","shell.execute_reply.started":"2022-02-20T02:23:24.976539Z","shell.execute_reply":"2022-02-20T02:23:24.982293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.patches as patches\n\nn=3\nsamples = df[df['annotations']!='[]'].sample(n = n)\n\ndisplay(samples)\nwidth=1280\nheight=720\npath = \"../input/tensorflow-great-barrier-reef/train_images/video_\"\nfig, axs = plt.subplots(n,1,figsize=(n*5,n*10))\ni=0\nj=0\nfor d in samples.itertuples():\n    scatters_x = []\n    scatters_y = []\n    im = imageio.imread(path + str(d.video_id) + \"/\" + str(d.image_id.split(\"-\")[1]) + \".jpg\")\n    for x,y,w,h in annotation_to_list(d):\n        rect = patches.Rectangle((x,y), w,h, linewidth=3, edgecolor='r', facecolor='None')\n        axs[i].add_patch(rect)\n        scatters_x.append(x+w/2)\n        scatters_y.append(y+h/2)\n        print(x,y,w,h)\n    axs[i].imshow(im)\n    axs[i].set_title(str(x)+\" \" + str(y)+\" \" + str(w)+\" \" + str(h))\n    i+=1\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-20T02:23:24.985305Z","iopub.execute_input":"2022-02-20T02:23:24.985756Z","iopub.status.idle":"2022-02-20T02:23:26.622993Z","shell.execute_reply.started":"2022-02-20T02:23:24.985722Z","shell.execute_reply":"2022-02-20T02:23:26.622199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The data is made up of frames for three videos which have annotations attached to them.\n\nThe annotation format is as follows :\n```\nx_min, y_min, width, height\n```\nin pixel units.\n\nEach image is of size 1280x720","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-16T15:10:57.42484Z","iopub.execute_input":"2022-02-16T15:10:57.425308Z","iopub.status.idle":"2022-02-16T15:10:57.436861Z","shell.execute_reply.started":"2022-02-16T15:10:57.425273Z","shell.execute_reply":"2022-02-16T15:10:57.435865Z"}}},{"cell_type":"markdown","source":"## Setting up the directory structure for the images\n\nFirst we have to copy over all images to the working directory, as we cannot manipulate the directory structure of the input. This might take a moment, especially for larger datasets.","metadata":{}},{"cell_type":"code","source":"!cp -r \"../input/tensorflow-great-barrier-reef/train_images\" ./","metadata":{"execution":{"iopub.status.busy":"2022-02-20T02:23:26.624167Z","iopub.execute_input":"2022-02-20T02:23:26.624438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Yolov5 also requires a specific directory structure for the training and validation data. Here is my final directory tree for this specific competition.\n\n![image.png](attachment:c33ea48d-9945-4a30-9be7-c587e40a41b6.png)","metadata":{},"attachments":{"c33ea48d-9945-4a30-9be7-c587e40a41b6.png":{"image/png":"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"}}},{"cell_type":"markdown","source":"The directory path must align with the data file used as input when training the network later on. \n\nThis is how my data.yaml file looked for this particular competition:\n```\npath: /kaggle/working/  # dataset root dir\ntrain: ./images/train # train images (relative to 'path') 128 images\nval: ./images/val\n\n# Classes\nnc: 1  # number of classes\nnames: ['starfish']  # class names\n```\n\nIf the train image directory is defined as ./images/train, then the network will look for corresponding labels in ./labels/train. The names of the jpg files in the image directory must correspond exactly to the txt files in the labels directory. \n\nnc corresponds to the amount of classes that are to be predicted, note that \"nothing\" is not counted as a class. \n\nnames is a list of names for every class that is to be predicted.\n\nFurthermore, the labels are required to be in \"Coco\"-format, i.e:\n```\nclass_id x_center y_center width height\n```\nand all values have to be normalized (between 0-1) with a new line for each annotation. \n\nThis means we must switch the directiory structure as well as reformat the annotations for this dataset.","metadata":{}},{"cell_type":"code","source":"def write_to_file(filename,annotations, width=1280,height=720):\n    f = open(filename, \"w\")\n    annotations = annotation_to_list(annotations)\n    for annotation in annotations:\n        x,y,w,h = annotation\n        f.write(str(0) + \" \" + str((x+w/2)/width) + \" \" + str((y+h/2)/height) + \" \" + str(w/width) + \" \" + str(h/height) + \"\\n\")\n    f.close()","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport shutil\ndf[\"image\"] = pd.NaT\ndf[\"data_type\"] = \"train\"\ni=0\nos.makedirs(\"./labels/train\")\nos.makedirs(\"./labels/val\")\nos.makedirs(\"./images/train\")      \nos.makedirs(\"./images/val\") \nval_ratio = 5\n\nfor dirname, _, filenames in os.walk('./train_images'):\n    for filename in filenames:\n        if '.jpg' in filename:\n            idx = df[df['image_id']==dirname.split('video_')[1]+'-'+filename.strip('.jpg')].index[0]               \n            if idx not in samples_to_drop.index:\n                if i%val_ratio==0:\n                    os.replace(dirname+\"/\"+filename, \"./images/val/\"+df.loc[idx,'image_id']+\".jpg\")\n                    df.loc[idx,'image'] = \"./images/val/\"+df.loc[idx,'image_id']+\".jpg\"\n\n                    df.loc[idx,\"data_type\"] = \"val\"\n                    write_to_file(\"./labels/val/\"+df.loc[idx,'image_id']+\".txt\", df.loc[idx])\n\n                else:\n                    os.replace(dirname+\"/\"+filename, \"./images/train/\"+df.loc[idx,'image_id']+\".jpg\")\n                    df.loc[idx,'image'] = \"./images/train/\"+df.loc[idx,'image_id']+\".jpg\"\n                    write_to_file(\"./labels/train/\"+df.loc[idx,'image_id']+\".txt\", df.loc[idx])\n                i+=1\ndisplay(df)","metadata":{"_kg_hide-input":true,"scrolled":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"samples = df[df['image_id'] == '1-9229']\nprint(\"Before (Competition Format)\")\nfor i in samples['annotations'].values[0].split('},'):\n    print(i.strip(''))\nprint(\"-------------------------------\")\nprint(\"After (CoCo-format):\")\n!cat {samples['image'].values[0].replace('images','labels').replace('jpg','txt')}","metadata":{"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Network configuration and Training","metadata":{}},{"cell_type":"markdown","source":"Network configuration with Yolov5 is defined in a .yaml file that is used as parameter to the train.py script. This files should include number of classes, network depth and width, anchors and finally, the head and backbone of the network.\n\nSince we are transfer-learning, the backbone has to be frozen before training. We don't have to worry about the shape as Yolov5 automatically reshapes input layer.\n\n.yaml files for the different sized yolov5 networks can be found at the ultralytics github.\n\nhttps://github.com/ultralytics/yolov5/tree/master/models","metadata":{}},{"cell_type":"code","source":"!cat ../input/coralreefdata/reef.yaml","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\n# Downloading necessary files and yolov5 directory\n!git clone https://github.com/ultralytics/yolov5  # clone\n%pip install -qr yolov5/requirements.txt  # install\n\n# Setting parameters\nEPOCHS = 25\nIMG_WIDTH = 1280\nIMG_HEIGHT = 720\nBATCH_SIZE = 32\ndata_file = '../input/coralreefdata/reef_data.yaml'\nconf_file = '../input/coralreefdata/reef.yaml'\n\n# Make sure you download the correct size network\nmodel = None\nmodel_name = None\n\nif load:\n    model_name = '../input/k/yousseftaoudi/training-yolov5-on-competition-data-tutorial/yolov5/runs/train/exp/weights/best.pt'\n    model = torch.hub.load('../input/k/yousseftaoudi/training-yolov5-on-competition-data-tutorial/yolov5', 'custom', path=model_name, force_reload=True, source='local')  # custom model\nelse:\n    model = torch.hub.load('ultralytics/yolov5', 'yolov5s') # Pretrained\n    model_name = 'yolov5s.pt'\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls ../input/k/yousseftaoudi/training-yolov5-on-competition-data-tutorial","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Training is done through running the yolov5/train.py file. You need to define a set of parameters in order to run properly.\n\nRelevant Parameters:\n\n- img - Image size = {x}, for accurate results this parameter should be the lonegst dimension of the image.\n \n- batch - Batch size = {x}\n\n- epochs - Training epochs = {x}\n\n- data - .yaml file for the data configuration\n- weights - pre-trained weights (.pt file), can be found in the yolov5 repository cloned earlier.\n\n- freeze - {x} amount of layers that are to be frozen (size of the backbone) \n\n- hyp - yaml file defining hyperparameters for the network, default settings are found here: https://github.com/ultralytics/yolov5/blob/4103ce9ad0393cc27f6c80457894ad7be0cb1f0d/data/hyps/hyp.finetune.yaml\n\n- noval - use parameter if you dont want a validation set.\n\n- evolve - will run fine-tuning of a base-network {x} amount of times in order to find the best hyperparameters.\n\n- workers - {x} amount of python threads.\n\n- optimizer - Adam/SGD/AdamW\n\nFor this particular network, we will only use a couple of these parameters.","metadata":{}},{"cell_type":"markdown","source":"Login to wandb if you want to monitor training. ","metadata":{}},{"cell_type":"code","source":"!pip install wandb","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if monitor:\n    from kaggle_secrets import UserSecretsClient\n\n    user_secrets = UserSecretsClient()\n    secret_value_0 = user_secrets.get_secret(\"api_key\")\n    !wandb login {secret_value_0}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!python yolov5/train.py --img {IMG_WIDTH} --batch {BATCH_SIZE} --epochs {EPOCHS}\\\n    --data {data_file} --cfg {conf_file} --weights {model_name} --freeze 9 --optimizer Adam\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Run this and you will get a custom trained .pt yolov5 network on your data!","metadata":{}},{"cell_type":"code","source":"import imageio as io\nfrom matplotlib.pyplot import figure\nfigure(figsize=(25, 10), dpi=80)\n\nresults = \"yolov5/runs/train/exp/results.png\"\nim = io.imread(results)\nplt.imshow(im)\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Inference on Training images","metadata":{}},{"cell_type":"code","source":"import shutil\nn=10\nsamples = df[df['annotations']!='[]'].sample(n = n)\n\n# Best network is saved here\nmodel_name = \"yolov5/runs/train/exp/weights/best.pt\"\n\n\nos.makedirs(\"./test\")\nfor index, row in samples.iterrows():\n    print(row.image)\n    shutil.copy(row.image,\"./test\")\n\n!python yolov5/detect.py --weights {model_name} --img-size {IMG_WIDTH} --conf 0.2 --source ./test\nfig, axs = plt.subplots(n,1,figsize=(n*10,n*10))\n\nfor i, (index, row) in enumerate(samples.iterrows()):\n    try:\n        print(\"yolov5/runs/detect/exp/\"+row.image.split('/')[3])\n        im = imageio.imread(\"./yolov5/runs/detect/exp/\"+row.image.split('/')[3])\n        axs[i].imshow(im)\n    except:\n        print(i,\"pass\")\n        pass\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"If you're interested in inference and prediction using your trained network on test data/submission data, checkout the inference counterpart of this notebook:\n\nhttps://www.kaggle.com/yousseftaoudi/help-protect-the-great-barrier-reef-inference","metadata":{}},{"cell_type":"code","source":"!rm -r  \"./images\"\n!rm -r  \"./labels\"\n!rm -r  \"./train_images\"\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}