{"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":"> 前言：训练环境是colab pro,数据处理部分是在本地完成的。最开始的时候折腾了好久mmdetection，奈何水平有限，debug了许久浪费了许多宝贵的时间仍不能正常训练评估TnT，遂放弃，转去研究YOLOv5。最后只剩一个星期左右调整、训练模型（final phase的结果还是在7号上午才跑出来的-。-）。所以超参数只是粗调了一下，训练的epoch也不充分，不过还是得到一个还不错的结果，供大家参考，希望各位不吝赐教。\n","metadata":{}},{"cell_type":"markdown","source":"\n   MMdetection GitHub链接：[https://github.com/open-mmlab/mmdetection](http://)\n   \n   YOLOv5 GitHub链接：[https://github.com/ultralytics/yolov5](http://)","metadata":{}},{"cell_type":"markdown","source":"Models:\n* Yolov5x6\n* Yolov5x6-transformer(1 transformer module)\n* Yolov5l6-transformer(2 transformer modules)","metadata":{}},{"cell_type":"markdown","source":"# Requirements","metadata":{}},{"cell_type":"code","source":"import os\nimport shutil\nimport json\nimport yaml\nimport random\nimport pandas as pd","metadata":{"execution":{"iopub.status.busy":"2021-08-10T06:59:19.666755Z","iopub.execute_input":"2021-08-10T06:59:19.667137Z","iopub.status.idle":"2021-08-10T06:59:19.774201Z","shell.execute_reply.started":"2021-08-10T06:59:19.667061Z","shell.execute_reply":"2021-08-10T06:59:19.773364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!git clone https://github.com/ultralytics/yolov5\n%cd yolov5\n!pip install -qr requirements.txt\n%cd ..","metadata":{"execution":{"iopub.status.busy":"2021-08-10T06:59:22.041983Z","iopub.execute_input":"2021-08-10T06:59:22.042307Z","iopub.status.idle":"2021-08-10T06:59:32.599478Z","shell.execute_reply.started":"2021-08-10T06:59:22.042278Z","shell.execute_reply":"2021-08-10T06:59:32.598597Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Install wandb to automatically track and visualize YOLOv5 🚀 runs (RECOMMENDED) ","metadata":{}},{"cell_type":"code","source":"# !pip install -q --upgrade wandb\n# key=YOUR_WANDB_TOKEN\n# import wandb\n# wandb.login(key=key)\n!wandb off","metadata":{"execution":{"iopub.status.busy":"2021-08-10T06:59:32.601270Z","iopub.execute_input":"2021-08-10T06:59:32.601631Z","iopub.status.idle":"2021-08-10T06:59:34.931103Z","shell.execute_reply.started":"2021-08-10T06:59:32.601593Z","shell.execute_reply":"2021-08-10T06:59:34.930049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data preprocessing","metadata":{}},{"cell_type":"code","source":"data = json.load(open('../input/cowboyoutfits/train.json', 'r'))\nann = data['annotations']\nrandom.seed(34)\nrandom.shuffle(ann)","metadata":{"execution":{"iopub.status.busy":"2021-08-10T06:59:34.934539Z","iopub.execute_input":"2021-08-10T06:59:34.934988Z","iopub.status.idle":"2021-08-10T06:59:34.998996Z","shell.execute_reply.started":"2021-08-10T06:59:34.934942Z","shell.execute_reply":"2021-08-10T06:59:34.998164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Show the counts of each kind","metadata":{}},{"cell_type":"code","source":"ci = [87, 1034, 131, 318, 588]  # category_id, 分别对应belt,sunglasses,boot,cowboy_hat,jacket\n\nprint('total:')\nfor i in ci:\n    count = 0\n    for j in ann:\n        if j['category_id'] == i:\n            count += 1\n    print(f'id: {i} counts: {count}')","metadata":{"execution":{"iopub.status.busy":"2021-08-10T06:59:35.000569Z","iopub.execute_input":"2021-08-10T06:59:35.000928Z","iopub.status.idle":"2021-08-10T06:59:35.014929Z","shell.execute_reply.started":"2021-08-10T06:59:35.000892Z","shell.execute_reply":"2021-08-10T06:59:35.013909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Split train set&val set**\n\nPS: 核心思想是将标注框分类抽样，总共抽50张图片，但是由于各类数量差距过大，所以并没有严格按照某个比例，这里只选了几个大概的数字，**分别表示val set中该类的最少数量**","metadata":{}},{"cell_type":"code","source":"total_id = set(each['image_id'] for each in ann)\nval_id = set()\na, b, c, d, e = 0, 0, 0, 0, 0  # 用于每类的计数\nfor each in ann:\n    if (each['category_id'] == ci[0]) and (a < 2):\n        val_id.add(each['image_id'])\n        a += 1\n    elif (each['category_id'] == ci[1]) and (b < 20):\n        val_id.add(each['image_id'])\n        b += 1\n    elif (each['category_id'] == ci[2]) and (c < 4):\n        val_id.add(each['image_id'])\n        c += 1\n    elif (each['category_id'] == ci[3]) and (d < 7):\n        val_id.add(each['image_id'])\n        d += 1\n    elif (each['category_id'] == ci[4]) and (e < 17):\n        val_id.add(each['image_id'])\n        e += 1\n\nval_ann = []\nfor imid in val_id:\n    for each_ann in ann:\n        if each_ann['image_id'] == imid:\n            val_ann.append(each_ann)\n            \nlen(val_id),len(val_ann)","metadata":{"execution":{"iopub.status.busy":"2021-08-10T06:59:35.016372Z","iopub.execute_input":"2021-08-10T06:59:35.017097Z","iopub.status.idle":"2021-08-10T06:59:35.098693Z","shell.execute_reply.started":"2021-08-10T06:59:35.017058Z","shell.execute_reply":"2021-08-10T06:59:35.097706Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('val set:')\nfor kind in ci:\n    num = 0\n    for i in val_ann:\n        if i['category_id'] == kind:\n            num += 1\n    print(f'id: {kind} counts: {num}')","metadata":{"execution":{"iopub.status.busy":"2021-08-10T06:59:35.099950Z","iopub.execute_input":"2021-08-10T06:59:35.100346Z","iopub.status.idle":"2021-08-10T06:59:35.106929Z","shell.execute_reply.started":"2021-08-10T06:59:35.100305Z","shell.execute_reply":"2021-08-10T06:59:35.105682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# The rest images are for training\ntrain_id = total_id - val_id\ntrain_ann = []\nfor each_ann in ann:\n    for tid in train_id:\n        if each_ann['image_id'] == tid:\n            train_ann.append(each_ann)\n            break\nlen(train_id), len(train_ann)","metadata":{"execution":{"iopub.status.busy":"2021-08-10T06:59:35.366146Z","iopub.execute_input":"2021-08-10T06:59:35.366480Z","iopub.status.idle":"2021-08-10T06:59:36.454505Z","shell.execute_reply.started":"2021-08-10T06:59:35.366448Z","shell.execute_reply":"2021-08-10T06:59:36.453652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Make dirs and generate yolo-type data structure**\n\nfor more information: [https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data](http://)","metadata":{}},{"cell_type":"code","source":"os.makedirs('./data/images/train', exist_ok=True)\nos.makedirs('./data/images/val', exist_ok=True)\n          \ntrain_img = []\n# Move train images\nfor j in data['images']:\n    for i in train_id:\n        if j['id'] == i:\n            shutil.copy('../input/cowboyoutfits/images/'+j['file_name'], './data/images/train')\n            train_img.append(j)\n            \nval_img = []\n# Move val images\nfor j in data['images']:\n    for i in val_id:\n        if j['id'] == i:\n            shutil.copy('../input/cowboyoutfits/images/'+j['file_name'], './data/images/val')\n            val_img.append(j)\n\nlen(val_img), len(train_img)","metadata":{"execution":{"iopub.status.busy":"2021-08-10T06:59:39.051425Z","iopub.execute_input":"2021-08-10T06:59:39.054171Z","iopub.status.idle":"2021-08-10T07:00:11.438067Z","shell.execute_reply.started":"2021-08-10T06:59:39.054122Z","shell.execute_reply":"2021-08-10T07:00:11.437091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.makedirs('./data/labels/train', exist_ok=True)\nos.makedirs('./data/labels/val', exist_ok=True)\n\ntrain_info = [(each['id'], each['file_name'].split('.')[0], each['width'], each['height']) for each in train_img]\nval_info = [(each['id'], each['file_name'].split('.')[0], each['width'], each['height']) for each in val_img]\n\ntrans = {f'{each}': f'{idx}' for (idx, each) in enumerate(ci)}  # Mapping the category_ids\n\n# Create *.txt files for training\nfor (imid, fn, w, h) in train_info:\n    with open('./data/labels/train/' + fn + '.txt', 'w') as t_f:\n        for t_ann in train_ann:\n            if t_ann['image_id'] == imid:\n                # convert X_min,Y_min,w,h to X_center/width,Y_center/height,w/width,h/height\n                bbox = [str((t_ann['bbox'][0] + (t_ann['bbox'][2] / 2) - 1) / float(w)) + ' ',\n                        str((t_ann['bbox'][1] + (t_ann['bbox'][3] / 2) - 1) / float(h)) + ' ',\n                        str(t_ann['bbox'][2] / float(w)) + ' ', \n                        str(t_ann['bbox'][3] / float(h))]\n                t_f.write(trans[str(t_ann['category_id'])] + ' ' + str(bbox[0] + bbox[1] + bbox[2] + bbox[3]))\n                t_f.write('\\n')\n\n\n# Create *.txt files for evaluating\nfor (imid, fn, w, h) in val_info:\n    with open('./data/labels/val/' + fn + '.txt', 'w') as v_f:\n        for v_ann in val_ann:\n            if v_ann['image_id'] == imid:\n                # convert X_min,Y_min,w,h to X_center/width,Ycenter/height,w/width,h/height\n                bbox = [str((v_ann['bbox'][0] + (v_ann['bbox'][2] / 2) - 1) / float(w)) + ' ',\n                        str((v_ann['bbox'][1] + (v_ann['bbox'][3] / 2) - 1) / float(h)) + ' ',\n                        str(v_ann['bbox'][2] / float(w)) + ' ',\n                        str(v_ann['bbox'][3] / float(h))]\n                v_f.write(trans[str(v_ann['category_id'])] + ' ' + str(bbox[0] + bbox[1] + bbox[2] + bbox[3]))\n                v_f.write('\\n')","metadata":{"execution":{"iopub.status.busy":"2021-08-10T07:00:11.442216Z","iopub.execute_input":"2021-08-10T07:00:11.442560Z","iopub.status.idle":"2021-08-10T07:00:14.845009Z","shell.execute_reply.started":"2021-08-10T07:00:11.442526Z","shell.execute_reply":"2021-08-10T07:00:14.844161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cat ./data/labels/val/15eb34a12667056b.txt","metadata":{"execution":{"iopub.status.busy":"2021-08-10T07:00:14.846725Z","iopub.execute_input":"2021-08-10T07:00:14.847067Z","iopub.status.idle":"2021-08-10T07:00:15.490054Z","shell.execute_reply.started":"2021-08-10T07:00:14.847033Z","shell.execute_reply":"2021-08-10T07:00:15.489147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training config\n* 一共训练了3个模型，最后推理的时候作ensemble\n* data config和hyp config都是一样的，不同的是具体的model config","metadata":{}},{"cell_type":"markdown","source":"**data config**","metadata":{}},{"cell_type":"code","source":"data_yaml = dict(\n    path = './data',  # dataset root dir\n    train = 'images/train',  # train images (relative to 'path')\n    val = 'images/val',   # val images (relative to 'path')\n    test = 'images/test',  # test images (relative to 'path') 推理的时候才用得到\n    nc = 5,\n    names = ['belt', 'sunglasses', 'boot', 'cowboy_hat', 'jacket'],\n    download = 'None'\n    )\nwith open('./my_data_config.yaml', 'w') as f:\n    yaml.dump(data_yaml, f, default_flow_style=False)","metadata":{"execution":{"iopub.status.busy":"2021-08-10T07:00:15.491987Z","iopub.execute_input":"2021-08-10T07:00:15.492389Z","iopub.status.idle":"2021-08-10T07:00:15.501275Z","shell.execute_reply.started":"2021-08-10T07:00:15.492350Z","shell.execute_reply":"2021-08-10T07:00:15.500456Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cat ./my_data_config.yaml","metadata":{"execution":{"iopub.status.busy":"2021-08-10T07:00:15.502685Z","iopub.execute_input":"2021-08-10T07:00:15.503233Z","iopub.status.idle":"2021-08-10T07:00:16.140603Z","shell.execute_reply.started":"2021-08-10T07:00:15.503194Z","shell.execute_reply":"2021-08-10T07:00:16.139709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**hyp config**","metadata":{}},{"cell_type":"code","source":"hyp_yaml = dict(\n    lr0 = 0.01,  # initial learning rate (SGD=1E-2, Adam=1E-3)\n    lrf = 0.16,  # final OneCycleLR learning rate (lr0 * lrf)\n    momentum = 0.937,  # SGD momentum/Adam beta1\n    weight_decay = 0.0005,  # optimizer weight decay 5e-4\n    warmup_epochs = 5.0,  # warmup epochs (fractions ok)\n    warmup_momentum = 0.8,  # warmup initial momentum\n    warmup_bias_lr = 0.1,  # warmup initial bias lr\n    box = 0.05,  # box loss gain\n    cls = 0.3,  # cls loss gain\n    cls_pw = 1.0,  # cls BCELoss positive_weight\n    obj = 0.7,  # obj loss gain (scale with pixels)\n    obj_pw = 1.0,  # obj BCELoss positive_weight\n    iou_t = 0.20,  # IoU training threshold\n    anchor_t = 4.0,  # anchor-multiple threshold\n    fl_gamma = 0.0,  # focal loss gamma (efficientDet default gamma=1.5)\n    hsv_h = 0.015,  # image HSV-Hue augmentation (fraction)\n    hsv_s = 0.7,  # image HSV-Saturation augmentation (fraction)\n    hsv_v = 0.4,  # image HSV-Value augmentation (fraction)\n    degrees = 0.0,  # image rotation (+/- deg)\n    translate = 0.1,  # image translation (+/- fraction)\n    scale = 0.25,  # image scale (+/- gain)\n    shear = 0.0,  # image shear (+/- deg)\n    perspective = 0.0,  # image perspective (+/- fraction), range 0-0.001\n    flipud = 0.0,  # image flip up-down (probability)\n    fliplr = 0.5,  # image flip left-right (probability)\n    mosaic = 1.0,  # image mosaic (probability)\n    mixup = 0.0,  # image mixup (probability)\n    copy_paste = 0.0  # segment copy-paste (probability)\n    )\nwith open('./my_hyp_config.yaml', 'w') as f:\n    yaml.dump(hyp_yaml, f, default_flow_style=False)","metadata":{"execution":{"iopub.status.busy":"2021-08-10T07:00:16.142220Z","iopub.execute_input":"2021-08-10T07:00:16.142598Z","iopub.status.idle":"2021-08-10T07:00:16.154352Z","shell.execute_reply.started":"2021-08-10T07:00:16.142559Z","shell.execute_reply":"2021-08-10T07:00:16.152446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cat ./my_hyp_config.yaml","metadata":{"execution":{"iopub.status.busy":"2021-08-10T07:00:16.184338Z","iopub.execute_input":"2021-08-10T07:00:16.184752Z","iopub.status.idle":"2021-08-10T07:00:16.826199Z","shell.execute_reply.started":"2021-08-10T07:00:16.184711Z","shell.execute_reply":"2021-08-10T07:00:16.825293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Model configs**","metadata":{}},{"cell_type":"markdown","source":"1. yolov5x6","metadata":{}},{"cell_type":"code","source":"model1_yaml = dict(\n    nc = 5,  # number of classes\n    depth_multiple = 1.33,  # model depth multiple\n    width_multiple = 1.25,  # layer channel multiple\n    anchors = 3,  # 这里把默认的anchors配置改成了3以启用autoanchor, 获取针对自己训练时的img_size的更优质的anchor size\n    \n    # YOLOv5 backbone\n    backbone =\n      # [from, number, module, args]\n      [[-1, 1, 'Focus', [64, 3]],  # 0-P1/2\n       [-1, 1, 'Conv', [128, 3, 2]],  # 1-P2/4\n       [-1, 3, 'C3', [128]],\n       [-1, 1, 'Conv', [256, 3, 2]],  # 3-P3/8\n       [-1, 9, 'C3', [256]],\n       [-1, 1, 'Conv', [512, 3, 2]],  # 5-P4/16\n       [-1, 9, 'C3', [512]],\n       [-1, 1, 'Conv', [768, 3, 2]],  # 7-P5/32\n       [-1, 3, 'C3', [768]],\n       [-1, 1, 'Conv', [1024, 3, 2]],  # 9-P6/64\n       [-1, 1, 'SPP', [1024, [3, 5, 7]]],\n       [-1, 3, 'C3', [1024, 'False']],  # 11\n      ],\n\n    # YOLOv5 head\n    head =\n      [[-1, 1, 'Conv', [768, 1, 1]],\n       [-1, 1, 'nn.Upsample', ['None', 2, 'nearest']],\n       [[-1, 8], 1, 'Concat', [1]],  # cat backbone P5\n       [-1, 3, 'C3', [768, 'False']],  # 15\n\n       [-1, 1, 'Conv', [512, 1, 1]],\n       [-1, 1, 'nn.Upsample', ['None', 2, 'nearest']],\n       [[-1, 6], 1, 'Concat', [1]],  # cat backbone P4\n       [-1, 3, 'C3', [512, 'False']],  # 19\n\n       [-1, 1, 'Conv', [256, 1, 1]],\n       [-1, 1, 'nn.Upsample', ['None', 2, 'nearest']],\n       [[-1, 4], 1, 'Concat', [1]],  # cat backbone P3\n       [-1, 3, 'C3', [256, 'False']],  # 23 (P3/8-small)\n\n       [-1, 1, 'Conv', [256, 3, 2]],\n       [[-1, 20], 1, 'Concat', [1]],  # cat head P4\n       [-1, 3, 'C3', [512, 'False']],  # 26 (P4/16-medium)\n\n       [-1, 1, 'Conv', [512, 3, 2]],\n       [[-1, 16], 1, 'Concat', [1]],  # cat head P5\n       [-1, 3, 'C3', [768, 'False']],  # 29 (P5/32-large)\n\n       [-1, 1, 'Conv', [768, 3, 2]],\n       [[-1, 12], 1, 'Concat', [1]],  # cat head P6\n       [-1, 3, 'C3', [1024, 'False']],  # 32 (P6/64-xlarge)\n\n       [[23, 26, 29, 32], 1, 'Detect', ['nc', 'anchors']],  # Detect(P3, P4, P5, P6)\n      ]\n    )\nwith open('./yolov5x6.yaml', 'w') as f:\n    yaml.dump(model1_yaml, f, default_flow_style=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-10T07:00:16.155626Z","iopub.execute_input":"2021-08-10T07:00:16.156326Z","iopub.status.idle":"2021-08-10T07:00:16.181813Z","shell.execute_reply.started":"2021-08-10T07:00:16.156287Z","shell.execute_reply":"2021-08-10T07:00:16.180895Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"2. yolov5x6-transformer\n\nPS: 我只加了一个transformer模块, 加多了似乎OOM了，配置好的朋友可以试试多加几个","metadata":{}},{"cell_type":"code","source":"model2_yaml = dict(\n    nc = 5,  # number of classes\n    depth_multiple = 1.33,  # model depth multiple\n    width_multiple = 1.25,  # layer channel multiple\n    anchors = 3,  # 这里把默认的anchors配置改成了3以启用autoanchor, 获取针对自己训练时的img_size的更优质的anchor size\n    \n    # YOLOv5 backbone\n    backbone =\n      # [from, number, module, args]\n      [[-1, 1, 'Focus', [64, 3]],  # 0-P1/2\n       [-1, 1, 'Conv', [128, 3, 2]],  # 1-P2/4\n       [-1, 3, 'C3', [128]],\n       [-1, 1, 'Conv', [256, 3, 2]],  # 3-P3/8\n       [-1, 9, 'C3', [256]],\n       [-1, 1, 'Conv', [512, 3, 2]],  # 5-P4/16\n       [-1, 9, 'C3', [512]],\n       [-1, 1, 'Conv', [768, 3, 2]],  # 7-P5/32\n       [-1, 3, 'C3', [768]],\n       [-1, 1, 'Conv', [1024, 3, 2]],  # 9-P6/64\n       [-1, 1, 'SPP', [1024, [3, 5, 7]]],\n       [-1, 3, 'C3TR', [1024, 'False']],  # 11  <-------- C3TR() Transformer module\n      ],\n\n    # YOLOv5 head\n    head =\n      [[-1, 1, 'Conv', [768, 1, 1]],\n       [-1, 1, 'nn.Upsample', ['None', 2, 'nearest']],\n       [[-1, 8], 1, 'Concat', [1]],  # cat backbone P5\n       [-1, 3, 'C3', [768, 'False']],  # 15\n\n       [-1, 1, 'Conv', [512, 1, 1]],\n       [-1, 1, 'nn.Upsample', ['None', 2, 'nearest']],\n       [[-1, 6], 1, 'Concat', [1]],  # cat backbone P4\n       [-1, 3, 'C3', [512, 'False']],  # 19\n\n       [-1, 1, 'Conv', [256, 1, 1]],\n       [-1, 1, 'nn.Upsample', ['None', 2, 'nearest']],\n       [[-1, 4], 1, 'Concat', [1]],  # cat backbone P3\n       [-1, 3, 'C3', [256, 'False']],  # 23 (P3/8-small)\n\n       [-1, 1, 'Conv', [256, 3, 2]],\n       [[-1, 20], 1, 'Concat', [1]],  # cat head P4\n       [-1, 3, 'C3', [512, 'False']],  # 26 (P4/16-medium)\n\n       [-1, 1, 'Conv', [512, 3, 2]],\n       [[-1, 16], 1, 'Concat', [1]],  # cat head P5\n       [-1, 3, 'C3', [768, 'False']],  # 29 (P5/32-large)\n\n       [-1, 1, 'Conv', [768, 3, 2]],\n       [[-1, 12], 1, 'Concat', [1]],  # cat head P6\n       [-1, 3, 'C3', [1024, 'False']],  # 32 (P6/64-xlarge)\n\n       [[23, 26, 29, 32], 1, 'Detect', ['nc', 'anchors']],  # Detect(P3, P4, P5, P6)\n      ]\n    )\nwith open('./yolov5x6-transformer.yaml', 'w') as f:\n    yaml.dump(model2_yaml, f, default_flow_style=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-10T07:00:16.828095Z","iopub.execute_input":"2021-08-10T07:00:16.828460Z","iopub.status.idle":"2021-08-10T07:00:16.853125Z","shell.execute_reply.started":"2021-08-10T07:00:16.828421Z","shell.execute_reply":"2021-08-10T07:00:16.852278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"3. yolov5l6-transformer","metadata":{}},{"cell_type":"code","source":"model3_yaml = dict(\n    nc = 5,  # number of classes\n    depth_multiple = 1.0,  # model depth multiple\n    width_multiple = 1.0,  # layer channel multiple\n    anchors = 3,  # 这里把默认的anchors配置改成了3以启用autoanchor, 获取针对自己训练时的img_size的更优质的anchor size\n    \n    # YOLOv5 backbone\n    backbone =\n      # [from, number, module, args]\n      [[-1, 1, 'Focus', [64, 3]],  # 0-P1/2\n       [-1, 1, 'Conv', [128, 3, 2]],  # 1-P2/4\n       [-1, 3, 'C3', [128]],\n       [-1, 1, 'Conv', [256, 3, 2]],  # 3-P3/8\n       [-1, 9, 'C3', [256]],\n       [-1, 1, 'Conv', [512, 3, 2]],  # 5-P4/16\n       [-1, 9, 'C3TR', [512]],  #   <-------- C3TR() Transformer module\n       [-1, 1, 'Conv', [768, 3, 2]],  # 7-P5/32\n       [-1, 3, 'C3', [768]],\n       [-1, 1, 'Conv', [1024, 3, 2]],  # 9-P6/64\n       [-1, 1, 'SPP', [1024, [3, 5, 7]]],\n       [-1, 3, 'C3TR', [1024, 'False']],  # 11  <-------- C3TR() Transformer module\n      ],\n\n    # YOLOv5 head\n    head =\n      [[-1, 1, 'Conv', [768, 1, 1]],\n       [-1, 1, 'nn.Upsample', ['None', 2, 'nearest']],\n       [[-1, 8], 1, 'Concat', [1]],  # cat backbone P5\n       [-1, 3, 'C3', [768, 'False']],  # 15\n\n       [-1, 1, 'Conv', [512, 1, 1]],\n       [-1, 1, 'nn.Upsample', ['None', 2, 'nearest']],\n       [[-1, 6], 1, 'Concat', [1]],  # cat backbone P4\n       [-1, 3, 'C3', [512, 'False']],  # 19\n\n       [-1, 1, 'Conv', [256, 1, 1]],\n       [-1, 1, 'nn.Upsample', ['None', 2, 'nearest']],\n       [[-1, 4], 1, 'Concat', [1]],  # cat backbone P3\n       [-1, 3, 'C3', [256, 'False']],  # 23 (P3/8-small)\n\n       [-1, 1, 'Conv', [256, 3, 2]],\n       [[-1, 20], 1, 'Concat', [1]],  # cat head P4\n       [-1, 3, 'C3', [512, 'False']],  # 26 (P4/16-medium)\n\n       [-1, 1, 'Conv', [512, 3, 2]],\n       [[-1, 16], 1, 'Concat', [1]],  # cat head P5\n       [-1, 3, 'C3', [768, 'False']],  # 29 (P5/32-large)\n\n       [-1, 1, 'Conv', [768, 3, 2]],\n       [[-1, 12], 1, 'Concat', [1]],  # cat head P6\n       [-1, 3, 'C3', [1024, 'False']],  # 32 (P6/64-xlarge)\n\n       [[23, 26, 29, 32], 1, 'Detect', ['nc', 'anchors']],  # Detect(P3, P4, P5, P6)\n      ],\n    )\nwith open('./yolov5l6-transformer.yaml', 'w') as f:\n    yaml.dump(model3_yaml, f, default_flow_style=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-10T07:00:16.856101Z","iopub.execute_input":"2021-08-10T07:00:16.856356Z","iopub.status.idle":"2021-08-10T07:00:16.879113Z","shell.execute_reply.started":"2021-08-10T07:00:16.856329Z","shell.execute_reply":"2021-08-10T07:00:16.878295Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Code for training","metadata":{}},{"cell_type":"code","source":"!python ./yolov5/train.py \\\n          --data ./my_data_config.yaml \\\n          --cfg ./yolov5x6.yaml \\\n          --hyp ./my_hyp_config.yaml \\\n          --cache --exist-ok --multi-scale \\\n          --project ./Cow_Boy_Outfits_Detection --name yolov5x6 \\\n          --img-size 1088 --batch-size 2 --epochs 1 --workers 2 --weights yolov5x6.pt  #  实际train了100个epoch","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![x6.png](https://i.loli.net/2021/08/09/bAse4onhl2U3WJH.png)","metadata":{}},{"cell_type":"code","source":"!python ./yolov5/train.py \\\n          --data ./my_data_config.yaml \\\n          --cfg ./yolov5x6-transformer.yaml \\\n          --hyp ./my_hyp_config.yaml \\\n          --cache --exist-ok --multi-scale \\\n          --project ./Cow_Boy_Outfits_Detection --name yolov5x6-transformer \\\n          --img-size 832 --batch-size 4 --epochs 1 --workers 2 --weights yolov5x6.pt  #  实际train了80个epoch","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![x6t.png](https://i.loli.net/2021/08/09/bIafdFBKJmT9GCZ.png)","metadata":{}},{"cell_type":"code","source":"!python ./yolov5/train.py \\\n          --data ./my_data_config.yaml \\\n          --cfg ./yolov5l6-transformer.yaml \\\n          --hyp ./my_hyp_config.yaml \\\n          --cache --exist-ok --multi-scale \\\n          --project ./Cow_Boy_Outfits_Detection --name yolov5l6-transformer \\\n          --img-size 640 --batch-size 2 --epochs 1 --workers 2 --weights yolov5l6.pt  #  实际train了100个epoch","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![l6t.png](https://i.loli.net/2021/08/09/ueOJlQfmtnAiaT8.png)","metadata":{}},{"cell_type":"markdown","source":"# Inference","metadata":{}},{"cell_type":"code","source":"os.makedirs('./data/images/test', exist_ok=True)\ntest_data = pd.read_csv('../input/cowboyoutfits/test.csv')\nfor each in test_data['file_name']:\n    shutil.copy(f'../input/cowboyoutfits/images/{each}', './data/images/test')","metadata":{"execution":{"iopub.status.busy":"2021-08-10T07:00:16.880589Z","iopub.execute_input":"2021-08-10T07:00:16.881058Z","iopub.status.idle":"2021-08-10T07:00:24.688444Z","shell.execute_reply.started":"2021-08-10T07:00:16.881021Z","shell.execute_reply":"2021-08-10T07:00:24.687597Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!python ./yolov5/val.py --weights \\\n         ./Cow_Boy_Outfits_Detection/yolov5x6/weights/best.pt \\\n         ./Cow_Boy_Outfits_Detection/yolov5x6-transformer/weights/best.pt \\\n         ./Cow_Boy_Outfits_Detection/yolov5l6-transformer/weights/best.pt \\\n         --data ./my_data_config.yaml \\\n         --project ./Cow_Boy_Outfits_Detection --name test_960_0.45_0.001 \\\n         --task test --augment --save-json --exist-ok \\\n         --imgsz 960 --batch-size 8 --iou-thres 0.45 --conf 0.001  # 选取折中一点的imgsz","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![val_batch2_pred.jpg](https://i.loli.net/2021/08/09/bNtZyCpEYBuiVGQ.jpg)","metadata":{}},{"cell_type":"markdown","source":"# Get submission","metadata":{}},{"cell_type":"code","source":"import zipfile\nsubmission = json.load(open('./Cow_Boy_Outfits_Detection/test_960_0.45_0.001/best_predictions.json', 'r'))\ntrans_imid = {f\"{i.split('.')[0]}\": j for i, j in zip(test_data['file_name'], test_data['id'])}\ntrans_cid = {k: v for (v, k) in trans.items()}\nfor each in submission:\n    each['image_id'] = trans_imid[f\"{each['image_id']}\"]\n    each['category_id'] = trans_cid[f\"{each['category_id']}\"]\n\nwith open('./Cow_Boy_Outfits_Detection/answer.json', 'w') as f:\n    json.dump(submission, f)\n    \n# Get answer.zip file\nzf = zipfile.ZipFile('./Cow_Boy_Outfits_Detection/answer.zip', 'w')\nzf.write('./Cow_Boy_Outfits_Detection/answer.json', 'answer.json')\nzf.close()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Thank you!! XD**","metadata":{}}]}