{"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":"# Preface","metadata":{}},{"cell_type":"markdown","source":"Firstly, I want to thank Xichao Wang (https://www.kaggle.com/sheepwang), whose code was my work basis. And I learn a lot from the communication with Xichao Wang via email. <br>\nBase on the code of Xichao Wang, I balance the data by using SMOTE and fine-tuning some parameters such as ***conf*** and ***iou-thres*** in detect.py. <br>\nSecondly, I want to thank my teammate jordon2000 (https://www.kaggle.com/jordon2000), who provided great effort for coding support and GPU resource.<br>\nEven though this is a competition, but the original target given by Professor Mu Li is that we can communicate here together, and learn from each other. I hope that through this platform, we can learn a lot from others.<br>\nThere are so many excellent talents here that I can learn how to code from scratch. I hope that we can further communicate and learn from each other. ","metadata":{}},{"cell_type":"markdown","source":"<span style=\"color: #E45D00; font-family: Segoe UI; font-size: 1.9em; font-weight: 300;\">Overview</span>\n\n&nbsp;&nbsp;✅Imbalanced Data Processing<br>\n&nbsp;&nbsp;✅Experience of using YOLOv5<br>\n&nbsp;&nbsp;✅Train the YOLOv5 model<br>\n&nbsp;&nbsp;✅Inference and detect cowboy outfits objects<br>\n&nbsp;&nbsp;✅Make Submission<br>\n\n    ","metadata":{}},{"cell_type":"markdown","source":"# Imbalanced Data Processing","metadata":{}},{"cell_type":"markdown","source":"![image.png](attachment:d526af58-13e6-449a-a3c2-ecb579b7e865.png)","metadata":{},"attachments":{"d526af58-13e6-449a-a3c2-ecb579b7e865.png":{"image/png":"iVBORw0KGgoAAAANSUhEUgAABQsAAAK2CAYAAADpMMrmAAAgAElEQVR4AezdP6im13U3bIHBRWKhzoKkEMQeFYkdm0gKUmGEICG4cap0gRAX7pzSX5kqVVCVOqg1qP1SvSjgNhEYhAohYYwxOJEJceMQsEDPyxy+mW80e87jmVtrrX2vWZdB0cx9zrP/XPu35j57IUXPXPyPAAECBAgQIECAAAECBAgQIECAAAECl8vlGQoECBAgQIAAAQIECBAgQIAAAQIECBC4K6BZKAcECBAgQIAAAQIECBAgQIAAAQIECNwIaBYKAgECBAgQIECAAAECBAgQIECAAAECNwKahYJAgAABAgQIECBAgAABAgQIECBAgMCNgGahIBAgQIAAAQIECBAgQIAAAQIECBAgcCOgWSgIBAgQIECAAAECBAgQIECAAAECBAjcCGgWCgIBAgQIECBAgAABAgQIECBAgAABAjcC7ZqFX/ziFy+///u/7y8GMiADMiADMiADMiADMiADMiADMiADMiADMnAgA3f7a7f9r12z8G6j0P8IECBAgAABAgQIECBAgAABAgQIEDgmcK2/pll4zNSnCBAgQIAAAQIECBAgQIAAAQIECLQU0CxseWwWTYAAAQIECBAgQIAAAQIECBAgQCBeQLMw3tSIBAgQIECAAAECBAgQIECAAAECBFoKaBa2PDaLJkCAAAECBAgQIECAAAECBAgQIBAvoFkYb2pEAgQIECBAgAABAgQIECBAgAABAi0FNAtbHptFEyBAgAABAgQIECBAgAABAgQIEIgX0CyMNzUiAQIECBAgQIAAAQIECBAgQIAAgZYCmoUtj82iCRAgQIAAAQIECBAgQIAAAQIECMQLaBbGmxqRAAECBAgQIECAAAECBAgQIECAQEsBzcKWx2bRBAgQIECAAAECBAgQIECAAAECBOIFNAvjTY1IgAABAgQIECBAgAABAgQIECBAoKWAZmHLY7NoAgQIECBAgAABAgQIECBAgAABAvECmoXxpkYkQIAAAQIECBAgQIAAAQIECBAg0FJAs7DlsVk0AQIECBAgQIAAAQIECBAgQIAAgXgBzcJ4UyMSIECAAAECBAgQIECAAAECBAgQaCmgWdjy2CyaAAECBAgQIECAAAECBAgQIECAQLyAZmG8qREJECBAgAABAgQIECBAgAABAgQItBTQLGx5bBZNgAABAgQIECBAgAABAgQIECBAIF5AszDe1IgECBAgQIAAAQIECBAgQIAAAQIEWgpoFrY8NosmQIAAAQIECBAgQIAAAQIECBAgEC+gWRhvakQCBAgQIECAAAECBAgQIECAAAECLQU0C1sem0UTIECAAAECBAgQIECAAAECBAgQiBfQLIw3NSIBAgQIECBAgAABAgQIECBAgACBlgKahS2PzaIJECBAgAABAgQIECBAgAABAgQIxAtoFsabGpEAAQIECBAgQIAAAQIECBAgQIBASwHNwpbHZtEECBAgQIAAAQIECBAgQIAAAQIE4gU0C+NNjUiAAAECBAgQIECAAAECBAgQIECgpYBmYaNje+H/+X8v/mIwJQONStNSCRAgQIAAAQIECBAgQIDAUyOgWdjoKKc0iexTQ/RuBvyPAAECBAgQIECAAAECBAgQqBfQLKw3PzyjJpom2qQMHC4UHyRAgAABAgQIECBAgAABAgQOC2gWHqar/+CkRpG9aozWV5gZCRAgQIAAAQIECBAgQIAAAc3CRhnQQNNAm5SBRqVpqQQIECBAgAABAgQIECBA4KkR0CxsdJSTGkX2qjHaqDQtlQABAgQIECBAgAABAgQIPDUCmoWNjlIDTQNtUgYalaalEiBAgAABAgQIECBAgACBp0ZAs7DRUU5qFNmrxmij0rRUAgQIECBAgAABAgQIECDw1AhoFjY6Sg00DbRJGWhUmpZKgAABAgQIECBAgAABAgSeGgHNwkZHOalRZK8ao41K01IJECBAgAABAgQIECBAgMBTI6BZ2OgoNdA00CZloFFpWioBAgQIECBAgAABAgQIEHhqBDQLGx3lpEaRvWqMNipNSyVAgAABAgQIECBAgAABAk+NgGZho6PUQNNAm5SBRqVpqQQIECBAgAABAgQIECBA4KkR0CxsdJSTGkX2qjHaqDQtlQABAgQIECBAgAABAgQIPDUCmoWNjlIDTQNtUgYalaalEiBAgAABAgQIECBAgACBp0ZAs7DRUU5qFNmrxmij0rRUAgQIECBAgAABAgQIECDw1AhoFjY6Sg00DbRJGWhUmpZKgAABAgQIECBAgAABAgSeGgHNwkZHOalRZK8ao41K01IJECBAgAABAgQIECBAgMBTI6BZ2OgoNdA00CZloFFpWioBAgQIECBAgAABAgQIEHhqBDQLGx3lpEaR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"}}},{"cell_type":"markdown","source":"We can see from the above graph, that the distribution of category data is extremely imbalanced in this competition. Actually, in the training data, there are only 25 'Belt' category bboxes, while the 'Sunglasses' and 'Jacket' are in all more than 2000 bboxes. <br>\nSo it's a big challege for us to do machine learning and model training.","metadata":{}},{"cell_type":"code","source":"#View the distributio of categories in traning data\nimport json\nfrom collections import Counter\njson_file_path = '/kaggle/input/cowboyoutfits/train.json'\ndata = json.load(open(json_file_path, 'r'))\ndict_cat = {}\nfor cat in data[\"categories\"]:\n    dict_cat[cat[\"id\"]]= cat[\"name\"]\nlist_cat = []\nfor ann in data[\"annotations\"]:\n    list_cat.append(dict_cat[ann[\"category_id\"]])\nCounter(list_cat)","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:26:21.170036Z","iopub.execute_input":"2021-08-08T05:26:21.170423Z","iopub.status.idle":"2021-08-08T05:26:21.321732Z","shell.execute_reply.started":"2021-08-08T05:26:21.170322Z","shell.execute_reply":"2021-08-08T05:26:21.320758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"There are 3 kinds of techniques to deal with imbalanced data: <br>\n* under-sampling\n* over-sampling\n* Customs Loss Function","metadata":{}},{"cell_type":"markdown","source":"\nIn this notebook, I will apply the second technique to inflate the training data to reduce the bias from the imbalanced dataset. But firstly let me briefly introduce the resampling techniques.<br>\n1. Under-sampling<br>\nIt means balances the dataset by reducing the size of the abundant class. This method is used when quantity of data is sufficient. By keeping all samples in the rare class and randomly selecting an equal number of samples in the abundant class, a balanced new dataset can be retrieved for further modelling.<br>\n2. Over-sampling<br>\nOn the contrary, oversampling is used when the quantity of data is insufficient. It tries to balance dataset by increasing the size of rare samples. Rather than getting rid of abundant samples, new rare samples are generated by using e.g. repetition, bootstrapping or SMOTE (Synthetic Minority Over-Sampling Technique) <br>\n3. Customs Loss Function<br>\nIt means we can change weight of loss to account for imbalance. Taking log function as an example:<br>\n$–(x*logp)+(1-x)log⁡(1-p))$, in which x is true label, p means prediction\nWhile the custom loss function transfers the log function into:<br>\n$A*x*log⁡(p)+(1-x)log⁡(1-p)$,\n$A$ means how is the ratio we want to balance the dataset. So for the imbalaced dataset, we should relatively change our loss function to make our prediction more precisely.","metadata":{}},{"cell_type":"markdown","source":"Note that there is no absolute advantage of one resampling method over another. Application of these two methods depends on the use case it applies to and the dataset itself. A combination of over- and under-sampling is often successful as well.\nIn this competition, I only apply over-sampling, which means I amplify the least data based on the quantities of the biggest dataset. I repeated the least dataset over and over to reach the largest dataset by using SMOTE.","metadata":{}},{"cell_type":"code","source":"# Firstly, we must import some libs\nimport os\nimport numpy as np\nimport pandas as pd\nimport gc\nimport cv2\nimport numpy as np\nimport pandas as pd\nfrom tqdm import tqdm\nimport json\nimport yaml\nfrom shutil import copyfile\nimport matplotlib.pyplot as plt\n\nimport torch\nfrom PIL import Image\nfrom sklearn.model_selection import train_test_split\nfrom imblearn.over_sampling import SMOTE","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:26:36.324860Z","iopub.execute_input":"2021-08-08T05:26:36.325271Z","iopub.status.idle":"2021-08-08T05:26:38.710198Z","shell.execute_reply.started":"2021-08-08T05:26:36.325235Z","shell.execute_reply":"2021-08-08T05:26:38.709357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### In the following function ***train_test_split***, the parameter ***stratify*** can split all categories (such as 'Belt', 'Jacket') in this parameter into train set and test set respectly.","metadata":{}},{"cell_type":"code","source":"# Split train dataset and test dataset according to annotation_id\nX = pd.DataFrame(data[\"annotations\"])\nY = pd.DataFrame(X[\"category_id\"])\nx_train,x_test,y_train,y_test=train_test_split(X,Y,test_size=0.1,random_state=1,stratify = Y)\nCounter(list(y_train[\"category_id\"]))","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:26:44.049999Z","iopub.execute_input":"2021-08-08T05:26:44.050321Z","iopub.status.idle":"2021-08-08T05:26:44.127348Z","shell.execute_reply.started":"2021-08-08T05:26:44.050290Z","shell.execute_reply":"2021-08-08T05:26:44.126537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Then, we will get the balanced training data by using SMOTE. And each category will has the same number of annotations.","metadata":{}},{"cell_type":"code","source":"# Using the SOMTE to inflate the imbanlanced data, such as 'Belt'\nx_train_only_id = pd.DataFrame(x_train['id'])\nX_SMOTE, Y_SMOTE = SMOTE().fit_resample(x_train_only_id.values,y_train.values)\nCounter(Y_SMOTE)","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:26:48.087449Z","iopub.execute_input":"2021-08-08T05:26:48.087860Z","iopub.status.idle":"2021-08-08T05:26:48.112327Z","shell.execute_reply.started":"2021-08-08T05:26:48.087823Z","shell.execute_reply":"2021-08-08T05:26:48.111312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Now the numbers of all categories training data are the same and balanced.","metadata":{}},{"cell_type":"markdown","source":"# Experience of using YOLOv5 ","metadata":{}},{"cell_type":"markdown","source":"I have tried all models including yolov5 S M L X with default hyperparameters, with trainning epochs are all 100. However, the best result in these models was from yolov5 M(yolov5m.pt). And even I enlarged the epoch times to 200 with model yolov5 M, the result was worsened than 100 epochs training in model yolov5 M. ","metadata":{}},{"cell_type":"code","source":"# Let's install Yolov5 to exploring a wonderful trip \n%cd /kaggle/working\n!git clone https://github.com/ultralytics/yolov5\n%cd /kaggle/working/yolov5\n%pip install -r requirements.txt","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:27:00.083479Z","iopub.execute_input":"2021-08-08T05:27:00.083865Z","iopub.status.idle":"2021-08-08T05:27:11.837315Z","shell.execute_reply.started":"2021-08-08T05:27:00.083807Z","shell.execute_reply":"2021-08-08T05:27:11.836246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data format transfering (from COCO to YOLO)","metadata":{}},{"cell_type":"code","source":"# Storing some dictionaries, {annotation_id:nubers}; {image_id:images in train.json}\ndf_annid = pd.DataFrame(X_SMOTE,columns=['ann_id'])\nprint(df_annid.head())\n# Storing the inflated annotations\ndict_annid = {}\nfor i,row in df_annid.iterrows():\n    annid = row['ann_id']\n    if annid in dict_annid:\n        dict_annid[annid] += 1\n    else:\n        dict_annid[annid] = 1\n# Storing the imageid and its json data\ndict_imgid = {}\nfor img in data[\"images\"]:\n    id = img['id']\n    dict_imgid[id] = img","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:27:16.258865Z","iopub.execute_input":"2021-08-08T05:27:16.259226Z","iopub.status.idle":"2021-08-08T05:27:16.965196Z","shell.execute_reply.started":"2021-08-08T05:27:16.259191Z","shell.execute_reply":"2021-08-08T05:27:16.964336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Transfer the categories to continuous ids\ncate_id_map = {}\nfor i, category in enumerate(data['categories']):     \n    cate_id_map[category['id']] = i\n    #id_cat[i] = category['id']\ncate_id_map","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:27:26.135148Z","iopub.execute_input":"2021-08-08T05:27:26.135496Z","iopub.status.idle":"2021-08-08T05:27:26.144441Z","shell.execute_reply.started":"2021-08-08T05:27:26.135464Z","shell.execute_reply":"2021-08-08T05:27:26.143485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# convert the bounding box from COCO to YOLO format.\ndef cc2yolo_bbox(img_width, img_height, bbox):\n    dw = 1. / img_width\n    dh = 1. / img_height\n    x = bbox[0] + bbox[2] / 2.0\n    y = bbox[1] + bbox[3] / 2.0\n    w = bbox[2]\n    h = bbox[3]\n \n    x = x * dw\n    w = w * dw\n    y = y * dh\n    h = h * dh\n    return (x, y, w, h)","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:27:34.235549Z","iopub.execute_input":"2021-08-08T05:27:34.235926Z","iopub.status.idle":"2021-08-08T05:27:34.241980Z","shell.execute_reply.started":"2021-08-08T05:27:34.235892Z","shell.execute_reply":"2021-08-08T05:27:34.240969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create the path for storing the txt files for yolov5\nyolo_anno_path = '/kaggle/working/training/yolo_anno/'\nif not os.path.exists(yolo_anno_path):\n    os.makedirs(yolo_anno_path)","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:27:41.145319Z","iopub.execute_input":"2021-08-08T05:27:41.145730Z","iopub.status.idle":"2021-08-08T05:27:41.152302Z","shell.execute_reply.started":"2021-08-08T05:27:41.145694Z","shell.execute_reply":"2021-08-08T05:27:41.151377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Building the train and validation images list\ndict_imgid_count = {} # this dictionary records how many images are the same\nf = open('/kaggle/working/train_valid.csv','w')\nf.write('id,file_name,split\\n')\nfor i in tqdm(range(len(data['annotations']))):\n    annid = data['annotations'][i]['id']\n    img_id = data['annotations'][i]['image_id']\n    filename = dict_imgid[img_id]['file_name']\n    yolo_txt_name = filename.split('.')[0] + '.txt' #remove .jpg\n    img_width = dict_imgid[img_id]['width']\n    img_height = dict_imgid[img_id]['height']\n    if annid in dict_annid:\n        temp_count = 1\n        if img_id in dict_imgid_count:\n            dict_imgid_count[img_id] += 1\n            temp_count = dict_imgid_count[img_id]\n        else:\n            dict_imgid_count[img_id] = 1        \n        arr = str(filename).split('.')\n        filename = arr[0] + '_' + str(temp_count) + '.' + arr[1]\n        f.write('{},{},train\\n'.format(img_id, filename))    \n    \n    yolo_txt_file = open(os.path.join(yolo_anno_path, yolo_txt_name), 'w')    \n    for anno in data['annotations']:\n        if anno['image_id'] == img_id:\n            yolo_bbox = cc2yolo_bbox(img_width, img_height, anno['bbox']) # \"bbox\": [x,y,width,height]        \n            yolo_txt_file.write('{} {} {} {} {}\\n'.format(cate_id_map[anno['category_id']], yolo_bbox[0], yolo_bbox[1], yolo_bbox[2], yolo_bbox[3]))\n    yolo_txt_file.close()\n\n# write validation files into the file train.csv\nfor i,row in x_test.iterrows():\n    img_id = row['image_id']\n    filename = dict_imgid[img_id]['file_name']\n    f.write('{},{},valid\\n'.format(img_id, filename))\n\nf.close()","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:27:43.962988Z","iopub.execute_input":"2021-08-08T05:27:43.963338Z","iopub.status.idle":"2021-08-08T05:27:48.677596Z","shell.execute_reply.started":"2021-08-08T05:27:43.963308Z","shell.execute_reply":"2021-08-08T05:27:48.676515Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Then we got the training and tesing dataframe\ndf = pd.read_csv('/kaggle/working/train_valid.csv')\nprint(df)","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:27:52.192119Z","iopub.execute_input":"2021-08-08T05:27:52.192476Z","iopub.status.idle":"2021-08-08T05:27:52.216765Z","shell.execute_reply.started":"2021-08-08T05:27:52.192442Z","shell.execute_reply":"2021-08-08T05:27:52.215798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Preparing txt files and image files for YOLOv5","metadata":{}},{"cell_type":"code","source":"# Preparing the data and structure directories for Yolov5\nos.makedirs('/kaggle/working/training/images/train', exist_ok=True)\nos.makedirs('/kaggle/working/training/images/valid', exist_ok=True)\n#\nos.makedirs('/kaggle/working/training/labels/train', exist_ok=True)\nos.makedirs('/kaggle/working/training/labels/valid', exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:27:59.771985Z","iopub.execute_input":"2021-08-08T05:27:59.772312Z","iopub.status.idle":"2021-08-08T05:27:59.778000Z","shell.execute_reply.started":"2021-08-08T05:27:59.772283Z","shell.execute_reply":"2021-08-08T05:27:59.776942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# copy the image files and annotations txt files to relevant folders\nfor i in tqdm(range(len(df))):\n    row = df.loc[i]\n    #name = row.file_name.split('.')[0]\n    \n    name_count = row.file_name.split('.')[0]\n    name = name_count.split('_')[0]\n    #if i<10:\n    #    print(name)\n    if row.split == 'train':        \n        copyfile(f'/kaggle/input/cowboyoutfits/images/{name}.jpg', f'/kaggle/working/training/images/train/{name_count}.jpg')\n        copyfile(f'/kaggle/working/training/yolo_anno/{name}.txt', f'/kaggle/working/training/labels/train/{name_count}.txt')\n    else:        \n        copyfile(f'/kaggle/input/cowboyoutfits/images/{name}.jpg', f'/kaggle/working/training/images/valid/{name}.jpg')\n        copyfile(f'/kaggle/working/training/yolo_anno/{name}.txt', f'/kaggle/working/training/labels/valid/{name}.txt')","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:28:02.810443Z","iopub.execute_input":"2021-08-08T05:28:02.810769Z","iopub.status.idle":"2021-08-08T05:28:38.266237Z","shell.execute_reply.started":"2021-08-08T05:28:02.810741Z","shell.execute_reply":"2021-08-08T05:28:38.265335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train the YOLOv5 model","metadata":{}},{"cell_type":"code","source":"# Firstly we create the yaml file\ndata_yaml = dict(\n    train = '/kaggle/working/training/images/train/',\n    val = '/kaggle/working/training/images/valid/',\n    nc = 5,\n    names = ['belt', 'sunglasses', 'boot', 'cowboy_hat', 'jacket']\n)\n\n# we will make the file under the yolov5/data/ directory.\nwith open('/kaggle/working/yolov5/data/data.yaml', 'w') as outfile:\n    yaml.dump(data_yaml, outfile, default_flow_style=True)\n    \n%cat /kaggle/working/yolov5/data/data.yaml # show your YAML file","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:28:41.460186Z","iopub.execute_input":"2021-08-08T05:28:41.460526Z","iopub.status.idle":"2021-08-08T05:28:42.113370Z","shell.execute_reply.started":"2021-08-08T05:28:41.460496Z","shell.execute_reply":"2021-08-08T05:28:42.112432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Before GO TRAIN, wandb must be set up and run\n# Install W&B \n##!pip install -q --upgrade wandb\n# Login with token, follow with the guide\n##import wandb\n##wandb.login()\n\n# For simply showing the code, I turn off W&B\nimport wandb\n!wandb off","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:28:54.269583Z","iopub.execute_input":"2021-08-08T05:28:54.269924Z","iopub.status.idle":"2021-08-08T05:28:56.520977Z","shell.execute_reply.started":"2021-08-08T05:28:54.269893Z","shell.execute_reply":"2021-08-08T05:28:56.519845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Choose some parameters for training\n> ##### For showing the code example, I only train one time. \n> ##### In my best training parameters, batch_size=24, epochs=100 and model=yolov5m.pt","metadata":{}},{"cell_type":"code","source":"# For showing the example code, I only select yolov5s model and 1 epoch to run.\nBATCH_SIZE = 16\nEPOCHS = 1 \nMODEL = 'yolov5s.pt' # this specify the model for training, you can use yolov5s.pt, yolov5l.pt, yolov5x.pt, etc.","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:30:35.457911Z","iopub.execute_input":"2021-08-08T05:30:35.458273Z","iopub.status.idle":"2021-08-08T05:30:35.465888Z","shell.execute_reply.started":"2021-08-08T05:30:35.458241Z","shell.execute_reply":"2021-08-08T05:30:35.463612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# GO TRAIN\n!python train.py --batch {BATCH_SIZE} \\\n                 --epochs {EPOCHS} \\\n                 --data data.yaml \\\n                 --weights {MODEL} \\\n                 --save_period 1\\\n                 --project cowboy-detection\\\n                 --name exp","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:30:39.960364Z","iopub.execute_input":"2021-08-08T05:30:39.960738Z","iopub.status.idle":"2021-08-08T05:37:50.811956Z","shell.execute_reply.started":"2021-08-08T05:30:39.960706Z","shell.execute_reply":"2021-08-08T05:37:50.811016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inference and detect cowboy outfits objects","metadata":{}},{"cell_type":"code","source":"# In the Dev phase, we will only use the valid data for predicition. \n# Don't forget change it to test data in the Final pahse.\nvalid_df = pd.read_csv('/kaggle/input/cowboyoutfits/valid.csv')\ntest_df = pd.read_csv('/kaggle/input/cowboyoutfits/test.csv')\nvalid_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:40:17.301622Z","iopub.execute_input":"2021-08-08T05:40:17.302015Z","iopub.status.idle":"2021-08-08T05:40:17.334536Z","shell.execute_reply.started":"2021-08-08T05:40:17.301975Z","shell.execute_reply":"2021-08-08T05:40:17.333772Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# make directory to store the validation data.\nos.makedirs('/kaggle/working/inference/valid', exist_ok=True)\nos.makedirs('/kaggle/working/inference/test', exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:40:22.387713Z","iopub.execute_input":"2021-08-08T05:40:22.388034Z","iopub.status.idle":"2021-08-08T05:40:22.394295Z","shell.execute_reply.started":"2021-08-08T05:40:22.388004Z","shell.execute_reply":"2021-08-08T05:40:22.393144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# copy the validation image to inference folder for detection process\nfor i in tqdm(range(len(valid_df))):\n    row = valid_df.loc[i]    \n    name = row.file_name.split('.')[0]\n    copyfile(f'/kaggle/input/cowboyoutfits/images/{name}.jpg', f'/kaggle/working/inference/valid/{name}.jpg')","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:40:27.722372Z","iopub.execute_input":"2021-08-08T05:40:27.722730Z","iopub.status.idle":"2021-08-08T05:40:37.815223Z","shell.execute_reply.started":"2021-08-08T05:40:27.722701Z","shell.execute_reply":"2021-08-08T05:40:37.814363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"##### Here, by using {MODEL_PATH}, you could use your trained model to inference and detect objects.<br> \nHowever, Kaggle has made a limitation for free users, when your training time reach to 6 hours, you cannot save your notebook. And when your training time reached to 9 hours, your training will be stopped by kaggle immediately. \n##### So I only use my best trained model to show the code, and you can use your trained model or any other trained model in inference phrase.","metadata":{}},{"cell_type":"code","source":"VALID_PATH = '/kaggle/working/inference/valid/'\n#MODEL_PATH = '/kaggle/working/yolo/cowboy-detection/exp5/weights/best.pt'\nMODEL_PATH = '/kaggle/input/bestmodelweights/exp8-m-100ep-withonesplit-best.pt'\nIMAGE_PATH = '/kaggle/input/cowboyoutfits/images/'","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:41:07.431476Z","iopub.execute_input":"2021-08-08T05:41:07.431803Z","iopub.status.idle":"2021-08-08T05:41:07.437212Z","shell.execute_reply.started":"2021-08-08T05:41:07.431774Z","shell.execute_reply":"2021-08-08T05:41:07.436221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Amazing Detection Objects","metadata":{}},{"cell_type":"markdown","source":"##### Here you can change many parameter such as ***conf*** and ***iou-thres***. <br>\nIn my experiments, when ***conf*** changed from 0.546 to 0.005, it will improve my dev result 2-3 percent.","metadata":{}},{"cell_type":"code","source":"# Let's begin the amazing time to detect the cowboy outfits objects\n!python detect.py --weights {MODEL_PATH} \\\n                  --source {VALID_PATH} \\\n                  --conf 0.005 \\\n                  --iou-thres 0.45 \\\n                  --save-txt \\\n                  --save-conf \\\n                  --augment","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:41:15.122106Z","iopub.execute_input":"2021-08-08T05:41:15.122472Z","iopub.status.idle":"2021-08-08T05:43:19.643443Z","shell.execute_reply.started":"2021-08-08T05:41:15.122439Z","shell.execute_reply":"2021-08-08T05:43:19.642533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# If you have run more than one times of detect.py, \n# the name of 'exp' in the path will be changed for storing the detecting results.\nPRED_PATH = '/kaggle/working/yolov5/runs/detect/exp/labels/'\n\n# list our prediction files path\nprediction_files = os.listdir(PRED_PATH)\nprint('Number of test images with detections: ', len(prediction_files))","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:43:27.955096Z","iopub.execute_input":"2021-08-08T05:43:27.955454Z","iopub.status.idle":"2021-08-08T05:43:27.963050Z","shell.execute_reply.started":"2021-08-08T05:43:27.955415Z","shell.execute_reply":"2021-08-08T05:43:27.962023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Make Submission","metadata":{}},{"cell_type":"code","source":"# convert yolo to coco annotation format\ndef yolo2cc_bbox(img_width, img_height, bbox):\n    x = (bbox[0] - bbox[2] * 0.5) * img_width\n    y = (bbox[1] - bbox[3] * 0.5) * img_height\n    w = bbox[2] * img_width\n    h = bbox[3] * img_height\n    \n    return (x, y, w, h)","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:43:56.056796Z","iopub.execute_input":"2021-08-08T05:43:56.057215Z","iopub.status.idle":"2021-08-08T05:43:56.062983Z","shell.execute_reply.started":"2021-08-08T05:43:56.057179Z","shell.execute_reply":"2021-08-08T05:43:56.062130Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# reverse the categories numer to the origin id\nre_cate_id_map = dict(zip(cate_id_map.values(), cate_id_map.keys()))\nprint(re_cate_id_map)","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:44:02.524623Z","iopub.execute_input":"2021-08-08T05:44:02.524985Z","iopub.status.idle":"2021-08-08T05:44:02.530768Z","shell.execute_reply.started":"2021-08-08T05:44:02.524954Z","shell.execute_reply":"2021-08-08T05:44:02.529502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_submission(df, PRED_PATH, IMAGE_PATH):\n    output = []\n    for i in tqdm(range(len(df))):\n        row = df.loc[i]\n        image_id = row['id']\n        file_name = row['file_name'].split('.')[0]\n        if f'{file_name}.txt' in prediction_files:\n            img = Image.open(f'{IMAGE_PATH}/{file_name}.jpg')\n            width, height = img.size\n            with open(f'{PRED_PATH}/{file_name}.txt', 'r') as file:\n                for line in file:\n                    preds = line.strip('\\n').split(' ')\n                    preds = list(map(float, preds)) #conver string to float\n                    cc_bbox = yolo2cc_bbox(width, height, preds[1:-1])\n                    result = {\n                        'image_id': image_id,\n                        'category_id': re_cate_id_map[preds[0]],\n                        'bbox': cc_bbox,\n                        'score': preds[-1]\n                    }\n\n                    output.append(result)\n    return output","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:44:20.995872Z","iopub.execute_input":"2021-08-08T05:44:20.996193Z","iopub.status.idle":"2021-08-08T05:44:21.004486Z","shell.execute_reply.started":"2021-08-08T05:44:20.996165Z","shell.execute_reply":"2021-08-08T05:44:21.003538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_data = make_submission(valid_df, PRED_PATH, IMAGE_PATH)\nop_pd = pd.DataFrame(sub_data)\nop_pd.sample(10)","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:44:34.662409Z","iopub.execute_input":"2021-08-08T05:44:34.662739Z","iopub.status.idle":"2021-08-08T05:44:35.631953Z","shell.execute_reply.started":"2021-08-08T05:44:34.662709Z","shell.execute_reply":"2021-08-08T05:44:35.631112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Finally, got your submitting zip file.","metadata":{}},{"cell_type":"code","source":"import zipfile \nop_pd.to_json('/kaggle/working/answer.json',orient='records')\nzf = zipfile.ZipFile('/kaggle/working/sample_answer.zip', 'w')\nzf.write('/kaggle/working/answer.json', 'answer.json')\nzf.close()","metadata":{"execution":{"iopub.status.busy":"2021-08-08T05:44:49.295825Z","iopub.execute_input":"2021-08-08T05:44:49.296185Z","iopub.status.idle":"2021-08-08T05:44:49.313235Z","shell.execute_reply.started":"2021-08-08T05:44:49.296153Z","shell.execute_reply":"2021-08-08T05:44:49.312471Z"},"trusted":true},"execution_count":null,"outputs":[]}]}