{"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":"# Cowboy Outfits Detection Megvii_YOLOX","metadata":{}},{"cell_type":"markdown","source":" ## Overview\n -   Install YOLOX\n \n -   Prepare CowboyOutfits datasets in YOLOX /data/datasets\n \n -   Prepare our YOLOX exp & cococlasses\n \n -   Train with pre-trained models\n \n -   Evaluation\n\n -   Visualize demo\n\n -   Output & Submit\n \n -   Score","metadata":{}},{"cell_type":"markdown","source":"## YOLOX\n![YOLOX](https://z3.ax1x.com/2021/08/03/fPjkpq.png)\n\n [https://github.com/Megvii-BaseDetection/YOLOX](https://github.com/Megvii-BaseDetection/YOLOX)\n\n YOLOX is an anchor-free version of YOLO, with a simpler design but better performance! It aims to bridge the gap between research and industrial communities. For more details, please refer to Megvii's [report on Arxiv](https://arxiv.org/abs/2107.08430)","metadata":{}},{"cell_type":"markdown","source":"## Install YOLOX","metadata":{}},{"cell_type":"markdown","source":"1.   Install YOLOX","metadata":{"execution":{"iopub.status.busy":"2021-08-06T15:11:37.061319Z","iopub.execute_input":"2021-08-06T15:11:37.061816Z","iopub.status.idle":"2021-08-06T15:11:37.070415Z","shell.execute_reply.started":"2021-08-06T15:11:37.06177Z","shell.execute_reply":"2021-08-06T15:11:37.068406Z"}}},{"cell_type":"code","source":"%%capture\n!git clone https://github.com/Megvii-BaseDetection/YOLOX.git\n!pip3 install -r YOLOX/requirements.txt\n!cd YOLOX && pip install -e .","metadata":{"execution":{"iopub.status.busy":"2021-08-10T09:48:15.628920Z","iopub.execute_input":"2021-08-10T09:48:15.629238Z","iopub.status.idle":"2021-08-10T09:48:54.936027Z","shell.execute_reply.started":"2021-08-10T09:48:15.629164Z","shell.execute_reply":"2021-08-10T09:48:54.934958Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"2.   Install [apex](https://github.com/NVIDIA/apex) & [pycocotools](https://github.com/cocodataset/cocoapi)","metadata":{"execution":{"iopub.status.busy":"2021-08-06T15:12:13.46048Z","iopub.execute_input":"2021-08-06T15:12:13.460917Z","iopub.status.idle":"2021-08-06T15:12:13.467129Z","shell.execute_reply.started":"2021-08-06T15:12:13.46088Z","shell.execute_reply":"2021-08-06T15:12:13.465711Z"}}},{"cell_type":"code","source":"%%capture\n!git clone https://github.com/NVIDIA/apex\n!cd apex && pip3 install -v --disable-pip-version-check --no-cache-dir --global-option=\"--cpp_ext\" --global-option=\"--cuda_ext\" ./\n!pip3 install cython\n!pip3 install 'git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI'","metadata":{"execution":{"iopub.status.busy":"2021-08-10T09:48:54.937816Z","iopub.execute_input":"2021-08-10T09:48:54.938165Z","iopub.status.idle":"2021-08-10T09:53:28.503655Z","shell.execute_reply.started":"2021-08-10T09:48:54.938123Z","shell.execute_reply":"2021-08-10T09:53:28.502565Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":" ## Prepare CowboyOutfits datasets in YOLOX /data/datasets","metadata":{"execution":{"iopub.status.busy":"2021-08-06T15:14:07.123493Z","iopub.execute_input":"2021-08-06T15:14:07.123949Z","iopub.status.idle":"2021-08-06T15:14:07.127998Z","shell.execute_reply.started":"2021-08-06T15:14:07.123905Z","shell.execute_reply":"2021-08-06T15:14:07.127092Z"}}},{"cell_type":"markdown","source":"1.    Because the image_id is too large, direct use of the data set will report an error,so replace image_id and create a new mapping of category_id to 1-5 ( Thanks [yyHry](https://www.kaggle.com/herunyu/yolox-for-cowboyoutfits#%E6%95%B0%E6%8D%AE%E9%A2%84%E5%A4%84%E7%90%86),this part is using his code )\n\n```python\nTypeError: can't convert np.ndarray of type numpy.ulonglong. The only supported types are: float64, float32, float16, complex64, complex128, int64, int32, int16, int8, uint8, and bool.\n```","metadata":{}},{"cell_type":"code","source":"import json\nfrom copy import deepcopy\n# data_list = ['merged_train.json',]\ndata_list = ['/kaggle/input/cowboyoutfits/train.json']\n# data_list = ['new_valid.json']\n\ncat = {87:1, 1034:5, 131:2, 318:3, 588:4}\n\ndict_list = []\nfor idx, data in enumerate(data_list):\n    with open(data) as f:\n        dict_list.append(json.load(f))\n\nnew_data = {}\nprint(dict_list[0].keys())\n\n\nnew_data['info'] = dict_list[0]['info']\n# new_data['licenses'] = dict_list[0]['licenses']\nnew_categories = []\nfor category in dict_list[0]['categories']:\n    new_category = deepcopy(category)\n    new_category['id'] = cat[category['id']]\n    new_categories.append(new_category)\nnew_data['categories'] = new_categories\nnew_data['annotations'] = []\nnew_data['images'] = []\nprint(new_data)\n\nanno_count = 1\nanno_id_dict = {}\ncount = 1\nanno_dict = {}\nfor data in dict_list:\n    annotations = []\n    for annotation in data['annotations']:\n        new_annotation = deepcopy(annotation)\n        new_annotation['category_id'] = cat[annotation['category_id']]\n        if annotation['image_id'] not in anno_dict:\n            new_annotation['image_id'] = anno_count\n            anno_dict[annotation['image_id']] = anno_count\n            anno_count += 1\n            anno_id_dict[anno_count] = 1\n        else:\n            new_annotation['image_id'] = anno_dict[annotation['image_id']]\n            anno_id_dict[anno_dict[annotation['image_id']]] += 1\n        new_annotation['id'] = count\n        count +=1\n        annotations.append(new_annotation)\n    \n    new_data['annotations'] = annotations\n\n    images = []\n    \n    for image in data['images']:\n        new_image = deepcopy(image)\n        new_image['id'] = anno_dict[image['id']]\n        images.append(new_image)\n    new_data['images'] = images\n\n    print(f'annotation size: {len(new_data[\"annotations\"])}')\n    print(f'image size: {len(new_data[\"images\"])}')\n\nwith open('./train.json', 'w') as res:\n    json.dump(new_data, res)","metadata":{"execution":{"iopub.status.busy":"2021-08-10T09:53:28.505794Z","iopub.execute_input":"2021-08-10T09:53:28.506143Z","iopub.status.idle":"2021-08-10T09:53:29.126440Z","shell.execute_reply.started":"2021-08-10T09:53:28.506105Z","shell.execute_reply":"2021-08-10T09:53:29.125423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"2.   Split Train and Valid Data Set  ( Thanks [nekokiku ](https://www.kaggle.com/nekokiku) &     [Joshua Z. Zhang](https://www.kaggle.com/zhreshold),this part is using their code )","metadata":{}},{"cell_type":"code","source":"import random\nimport copy\nimport json\nfrom pycocotools.coco import COCO\n\ndef create_subset(c, cats, test_n=180):\n    new_coco = {}\n    new_coco['info'] = {\"description\": \"CowboySuit\",\n                        \"url\": \"http://github.com/dmlc/glu|on-cv\",\n                        \"version\": \"1.0\",\"year\": 2021,\n                        \"contributor\": \"GluonCV/AutoGluon\",\n                        \"date_created\": \"2021/07/01\"}\n    new_coco[\"licenses\"]: [\n        {\"url\": \"http://creativecommons.org/licenses/by/2.0/\",\"id\": 4,\"name\": \"Attribution License\"}]\n    cat_ids = c.getCatIds(cats)\n    train_img_ids = set()\n\n    test_img_ids = set()\n    for cat in cat_ids[::-1]:\n        img_ids = copy.copy(c.getImgIds(catIds=[cat]))\n        random.shuffle(img_ids)\n        tn = min(test_n, int(len(img_ids) * 0.5))\n        new_test = set(img_ids[:tn])\n        exist_test_ids = new_test.intersection(train_img_ids)\n        test_ids = new_test.difference(exist_test_ids)\n        train_ids = set(img_ids).difference(test_ids)\n        print(tn, len(img_ids), len(new_test), len(test_ids), len(train_ids))\n        train_img_ids.update(train_ids)\n        test_img_ids.update(test_ids)\n        print(len(test_img_ids))\n\n    # prune duplicates\n    dup = train_img_ids.intersection(test_img_ids)\n    train_img_ids = train_img_ids - dup\n\n    train_anno_ids = set()\n    test_anno_ids = set()\n    for cat in cat_ids:\n        train_anno_ids.update(c.getAnnIds(imgIds=list(train_img_ids), catIds=[cat]))\n        test_anno_ids.update(c.getAnnIds(imgIds=list(test_img_ids), catIds=[cat]))\n\n    assert len(train_img_ids.intersection(test_img_ids)) == 0, 'img id conflicts, {} '.format(train_img_ids.intersection(test_img_ids))\n    assert len(train_anno_ids.intersection(test_anno_ids)) == 0, 'anno id conflicts'\n    print('train img ids #:', len(train_img_ids), 'train anno #:', len(train_anno_ids))\n    print('test img ids #:', len(test_img_ids), 'test anno #:', len(test_anno_ids))\n    new_coco_test = copy.deepcopy(new_coco)\n\n    new_coco[\"images\"] = c.loadImgs(list(train_img_ids))\n    new_coco[\"annotations\"] = c.loadAnns(list(train_anno_ids))\n    for ann in new_coco[\"annotations\"]:\n        ann.pop('segmentation', None)\n    new_coco[\"categories\"] = c.loadCats(cat_ids)\n\n    new_coco_test[\"images\"] = c.loadImgs(list(test_img_ids))\n    new_coco_test[\"annotations\"] = c.loadAnns(list(test_anno_ids))\n    for ann in new_coco_test[\"annotations\"]:\n        ann.pop('segmentation', None)\n    new_coco_test[\"categories\"] = c.loadCats(cat_ids)\n    print('new train split, images:', len(new_coco[\"images\"]), 'annos:', len(new_coco[\"annotations\"]))\n    print('new test split, images:', len(new_coco_test[\"images\"]), 'annos:', len(new_coco_test[\"annotations\"]))\n    return new_coco, new_coco_test\n\ncoco = COCO('./train.json')\n\nnc, nc_test = create_subset(coco, ['belt', 'sunglasses', 'boot', 'cowboy_hat', 'jacket', ])\n\nwith open('./new_train.json', 'w') as f:\n    json.dump(nc, f)\n\nwith open('./new_valid.json', 'w') as f:\n    json.dump(nc_test, f)","metadata":{"execution":{"iopub.status.busy":"2021-08-10T09:53:29.128385Z","iopub.execute_input":"2021-08-10T09:53:29.128885Z","iopub.status.idle":"2021-08-10T09:53:29.460375Z","shell.execute_reply.started":"2021-08-10T09:53:29.128843Z","shell.execute_reply":"2021-08-10T09:53:29.459607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"3.   Prepare CowboyOutfits datasets in YOLOX /data/datasets","metadata":{}},{"cell_type":"code","source":"!mkdir YOLOX/datasets/COCO\n!mkdir YOLOX/datasets/COCO/annotations","metadata":{"execution":{"iopub.status.busy":"2021-08-10T09:53:29.461719Z","iopub.execute_input":"2021-08-10T09:53:29.462039Z","iopub.status.idle":"2021-08-10T09:53:30.813937Z","shell.execute_reply.started":"2021-08-10T09:53:29.462005Z","shell.execute_reply":"2021-08-10T09:53:30.812855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp new_train.json YOLOX/datasets/COCO/annotations/instances_train2017.json #(eval error,so use train.json instead of new_train.json)\n#!cp ../input/cowboyoutfits/train.json YOLOX/datasets/COCO/annotations/instances_train2017.json\n!cp new_valid.json YOLOX/datasets/COCO/annotations/instances_val2017.json\n!ls YOLOX/datasets/COCO/annotations","metadata":{"execution":{"iopub.status.busy":"2021-08-10T09:53:30.815431Z","iopub.execute_input":"2021-08-10T09:53:30.815787Z","iopub.status.idle":"2021-08-10T09:53:32.847993Z","shell.execute_reply.started":"2021-08-10T09:53:30.815748Z","shell.execute_reply":"2021-08-10T09:53:32.846963Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ln -s /kaggle/input/cowboyoutfits/images YOLOX/datasets/COCO/train2017\n!ln -s /kaggle/input/cowboyoutfits/images YOLOX/datasets/COCO/val2017","metadata":{"execution":{"iopub.status.busy":"2021-08-10T09:53:32.851835Z","iopub.execute_input":"2021-08-10T09:53:32.852145Z","iopub.status.idle":"2021-08-10T09:53:34.199753Z","shell.execute_reply.started":"2021-08-10T09:53:32.852111Z","shell.execute_reply":"2021-08-10T09:53:34.198668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prepare our YOLOX exp & cococlasses","metadata":{}},{"cell_type":"markdown","source":"1.   Set your own exp, here use yolox_x","metadata":{}},{"cell_type":"code","source":"!echo \"        self.num_classes = 5\" >> YOLOX/exps/default/yolox_x.py\n#!echo \"        self.max_epoch = 50\" >> YOLOX/exps/default/yolox_x.py\n!echo \"        self.max_epoch = 10\" >> YOLOX/exps/default/yolox_x.py #Use your own settings, here using 10 epochs\n!echo \"        self.eval_interval = 1\" >> YOLOX/exps/default/yolox_x.py\n!echo \"        self.warmup_epochs = 2\" >> YOLOX/exps/default/yolox_x.py\n#!echo \"        self.min_lr_ratio = 0.05\" >> YOLOX/exps/default/yolox_x.py\n\n!cat YOLOX/exps/default/yolox_x.py","metadata":{"execution":{"iopub.status.busy":"2021-08-10T09:53:34.202834Z","iopub.execute_input":"2021-08-10T09:53:34.203187Z","iopub.status.idle":"2021-08-10T09:53:37.519940Z","shell.execute_reply.started":"2021-08-10T09:53:34.203158Z","shell.execute_reply":"2021-08-10T09:53:37.519044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"2.   Set coco_classes","metadata":{}},{"cell_type":"code","source":"!echo \"COCO_CLASSES = ('belt','boot','cowboy_hat','jacket','sunglasses')\" > \"YOLOX/yolox/data/datasets/coco_classes.py\"\n!cat YOLOX/yolox/data/datasets/coco_classes.py","metadata":{"execution":{"iopub.status.busy":"2021-08-10T09:53:37.522163Z","iopub.execute_input":"2021-08-10T09:53:37.522524Z","iopub.status.idle":"2021-08-10T09:53:38.972282Z","shell.execute_reply.started":"2021-08-10T09:53:37.522486Z","shell.execute_reply":"2021-08-10T09:53:38.971241Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"3.   Download pre-trained models","metadata":{}},{"cell_type":"code","source":"!wget https://github.com/Megvii-BaseDetection/storage/releases/download/0.0.1/yolox_x.pth\n!mv yolox_x.pth yolox_x.pth.tar","metadata":{"execution":{"iopub.status.busy":"2021-08-10T09:53:38.974292Z","iopub.execute_input":"2021-08-10T09:53:38.974773Z","iopub.status.idle":"2021-08-10T09:53:50.912828Z","shell.execute_reply.started":"2021-08-10T09:53:38.974726Z","shell.execute_reply":"2021-08-10T09:53:50.911412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train with pre-trained models","metadata":{}},{"cell_type":"code","source":"!python YOLOX/tools/train.py -f YOLOX/exps/default/yolox_x.py -d 1 -b 4 --fp16 -o -c yolox_x.pth.tar\n'''\ntest:\ntotal_loss: 4.0, iou_loss: 1.9, l1_loss: 0.0, conf_loss: 1.6, cls_loss: 0.5,\nCodalab's map = 64\n'''","metadata":{"execution":{"iopub.status.busy":"2021-08-10T09:54:54.847393Z","iopub.execute_input":"2021-08-10T09:54:54.847744Z","iopub.status.idle":"2021-08-10T10:04:25.918697Z","shell.execute_reply.started":"2021-08-10T09:54:54.847712Z","shell.execute_reply":"2021-08-10T10:04:25.917749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Evaluation","metadata":{}},{"cell_type":"code","source":"!python YOLOX/tools/eval.py -f YOLOX/exps/default/yolox_x.py -c YOLOX_outputs/yolox_x/latest_ckpt.pth -b 4 -d 1 --conf 0.001 --fp16 --fuse","metadata":{"execution":{"iopub.status.busy":"2021-08-10T10:04:32.889878Z","iopub.execute_input":"2021-08-10T10:04:32.890218Z","iopub.status.idle":"2021-08-10T10:05:14.559093Z","shell.execute_reply.started":"2021-08-10T10:04:32.890184Z","shell.execute_reply":"2021-08-10T10:05:14.558156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualize demo","metadata":{}},{"cell_type":"code","source":"!mv YOLOX_outputs/yolox_x/latest_ckpt.pth YOLOX_outputs/yolox_x/latest_ckpt.pth.tar","metadata":{"execution":{"iopub.status.busy":"2021-08-10T10:06:01.762289Z","iopub.execute_input":"2021-08-10T10:06:01.762640Z","iopub.status.idle":"2021-08-10T10:06:02.434545Z","shell.execute_reply.started":"2021-08-10T10:06:01.762608Z","shell.execute_reply":"2021-08-10T10:06:02.433564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!python YOLOX/tools/demo.py image -n yolox-x -c YOLOX_outputs/yolox_x/latest_ckpt.pth.tar --path ../input/cowboyoutfits/images/005b9630718c06c7.jpg --conf 0.25 --nms 0.45 --tsize 640 --save_result --device gpu\n'''\nBecause of the problem of kaggle environment, you can download the results to view,\nexample\n\"!cp ./YOLOX_outputs/yolox_x/vis_res/2021_08_10_08_16_12/005b9630718c06c7.jpg ./\"\ndownload 005b9630718c06c7.jpg\n'''","metadata":{"execution":{"iopub.status.busy":"2021-08-10T10:18:05.878151Z","iopub.execute_input":"2021-08-10T10:18:05.878535Z","iopub.status.idle":"2021-08-10T10:18:12.045035Z","shell.execute_reply.started":"2021-08-10T10:18:05.878503Z","shell.execute_reply":"2021-08-10T10:18:12.044048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp ./YOLOX_outputs/yolox_x/vis_res/2021_08_10_10_18_11/00032e1703df8793.jpg ./","metadata":{"execution":{"iopub.status.busy":"2021-08-10T10:18:20.772723Z","iopub.execute_input":"2021-08-10T10:18:20.773102Z","iopub.status.idle":"2021-08-10T10:18:20.962002Z","shell.execute_reply.started":"2021-08-10T10:18:20.773058Z","shell.execute_reply":"2021-08-10T10:18:20.960795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![demo.png](https://z3.ax1x.com/2021/08/06/fuoySH.jpg)","metadata":{"execution":{"iopub.status.busy":"2021-08-06T18:03:48.972709Z","iopub.execute_input":"2021-08-06T18:03:48.97307Z","iopub.status.idle":"2021-08-06T18:03:49.618728Z","shell.execute_reply.started":"2021-08-06T18:03:48.973039Z","shell.execute_reply":"2021-08-06T18:03:49.617861Z"}}},{"cell_type":"markdown","source":"## Output & Submit","metadata":{}},{"cell_type":"markdown","source":"1.   Define the predict function to return output","metadata":{}},{"cell_type":"code","source":"def predict(pth,jpg):\n    %cd YOLOX\n    from yolox.exp import get_exp\n    from loguru import logger\n    from yolox.utils import fuse_model, get_model_info, postprocess, vis\n    from yolox.data.data_augment import preproc\n    import torch,cv2\n    exp=get_exp('exps/default/yolox_x.py','yolox_x')\n    model = exp.get_model()\n    #logger.info(\"Model Summary: {}\".format(get_model_info(model, exp.test_size)))\n    model.cuda()\n    model.eval()\n    ckpt_file=pth\n    ckpt = torch.load(ckpt_file, map_location=\"cpu\")\n    model.load_state_dict(ckpt[\"model\"])\n    model = fuse_model(model)\n    img = cv2.imread(jpg)\n    img, ratio = preproc(img, exp.test_size, (0.485, 0.456, 0.406), (0.229, 0.224, 0.225)) # test_size = (640, 640)\n    img = torch.from_numpy(img).unsqueeze(0)\n    img = img.cuda()\n    outputs = model(img)\n    #outputs = postprocess(outputs, 5, exp.test_conf, exp.nmsthre) #test_conf = 0.01 nmsthre = 0.65\n    outputs = postprocess(outputs, 5, 0.25 , 0.45)\n    output = outputs[0]\n    if output==None:\n        %cd ..\n        return None,None,None\n    output = output.cpu()\n    bboxes = output[:, 0:4]\n    bboxes=bboxes/ratio\n    cls = output[:, 6]\n    scores = output[:, 4] * output[:, 5]\n    %cd ..\n    return bboxes,cls,scores","metadata":{"execution":{"iopub.status.busy":"2021-08-10T10:06:51.690328Z","iopub.execute_input":"2021-08-10T10:06:51.690748Z","iopub.status.idle":"2021-08-10T10:06:51.717711Z","shell.execute_reply.started":"2021-08-10T10:06:51.690711Z","shell.execute_reply":"2021-08-10T10:06:51.716750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pth='/kaggle/working/YOLOX_outputs/yolox_x/latest_ckpt.pth.tar'\n# yolox's cls to dataset category_id\ncategories={0:87,1:131,2:318,3:588,4:1034}","metadata":{"execution":{"iopub.status.busy":"2021-08-10T10:06:53.675543Z","iopub.execute_input":"2021-08-10T10:06:53.675867Z","iopub.status.idle":"2021-08-10T10:06:53.680057Z","shell.execute_reply.started":"2021-08-10T10:06:53.675836Z","shell.execute_reply":"2021-08-10T10:06:53.679177Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"2.   Use output and 'valid.csv'/'test.csv' to return submissions","metadata":{}},{"cell_type":"code","source":"from PIL import Image\ndef create_submission(df,pth,score_thresh=0.1):\n    results = []\n    for index, row in df.iterrows():\n        img_id = row['id']\n        file_name = row['file_name']\n        img = Image.open(file_name)\n        width, height = img.size\n        bboxes,cls,scores=predict(pth,file_name)\n        if cls==None:\n            continue\n        for i, p in enumerate(scores):\n            if p> score_thresh:\n                roi = bboxes[i]\n                pred = {'image_id': img_id,\n                        'category_id': categories[int(cls[i])],\n                        'bbox': [float(roi[0]), float(roi[1]), float(roi[2]-roi[0]), float(roi[3]-roi[1])], #yolox bbox is xmin,ymin,xmax,ymax,submission is xmin,ymin,w,h\n                        'score': float(p)}\n                results.append(pred)\n        #print(results)\n\n    return results","metadata":{"execution":{"iopub.status.busy":"2021-08-10T10:06:59.044037Z","iopub.execute_input":"2021-08-10T10:06:59.044434Z","iopub.status.idle":"2021-08-10T10:06:59.053173Z","shell.execute_reply.started":"2021-08-10T10:06:59.044399Z","shell.execute_reply":"2021-08-10T10:06:59.052131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%capture\nimport pandas as pd\nimport os\nroot = '/kaggle/input/cowboyoutfits'\nsubmission_df = pd.read_csv('/kaggle/input/cowboyoutfits/test.csv')  # replace with test.csv on the last day\nsubmission_df['file_name'] = submission_df.apply(lambda x: os.path.join(root, 'images', x['file_name']), axis=1)\nsubmission = create_submission(submission_df, pth)","metadata":{"execution":{"iopub.status.busy":"2021-08-10T08:25:29.047777Z","iopub.execute_input":"2021-08-10T08:25:29.048097Z","iopub.status.idle":"2021-08-10T08:25:35.904438Z","shell.execute_reply.started":"2021-08-10T08:25:29.048068Z","shell.execute_reply":"2021-08-10T08:25:35.903586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create json and zip\nimport zipfile\nimport json\nsubmission_name = '/kaggle/working/answer.json'\nwith open(submission_name, 'w') as f:\n    json.dump(submission, f)\nzf = zipfile.ZipFile('/kaggle/working/sample_answer.zip', 'w')\nzf.write(submission_name, 'answer.json')\nzf.close()","metadata":{"execution":{"iopub.status.busy":"2021-08-10T08:25:26.090569Z","iopub.execute_input":"2021-08-10T08:25:26.091139Z","iopub.status.idle":"2021-08-10T08:25:26.110304Z","shell.execute_reply.started":"2021-08-10T08:25:26.091098Z","shell.execute_reply":"2021-08-10T08:25:26.10892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"3.   Visualize again (  Thanks [nekokiku ](https://www.kaggle.com/nekokiku) & [snow clem](https://www.kaggle.com/snowclem),this part is using their code )","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nfrom tqdm import tqdm\nimport cv2\nimport json\nimport os\nimport matplotlib.pyplot as plt\nfrom PIL import Image, ImageDraw\nfrom matplotlib.patches import Rectangle \n\ndef get_xyxy_from_cowboy(img_name, df, json_label):\n    xy_list = []\n    fname_id_dict = {}\n    for idx, row in df.iterrows():\n        fname_id_dict.update({row['file_name']: row['id']})\n    print('len(valid)=', len(fname_id_dict))\n    with open(json_label) as f:\n        jdata = json.load(f)\n        for dict in tqdm(jdata):\n            image_id = fname_id_dict[img_name]\n            if image_id == dict['image_id']:\n                # x_min, y_min, x_max, y_max = dict['bbox']\n                x, y, w, h = dict['bbox']\n                print(dict['category_id'])\n                x_min, y_min, w, h = x, y,w,h\n                xy_list.append([int(x_min), int(y_min), int(w), int(h)])\n\n    return xy_list\n\n\ndef draw_rect(img, xy_list):\n    for xy in xy_list:\n        #cv2.rectangle(img, (xy[0], xy[1]), (xy[2], xy[3]), (0, 0, 255), 2)\n        print(xy)\n        return Rectangle((xy[0],xy[1]),xy[2], xy[3],fc ='none',ec ='r', lw =2)  \n\n\ndataset_path = '../input/cowboyoutfits/images'\ndf = pd.read_csv('../input/cowboyoutfits/test.csv')\nimg_name = df['file_name'].sample(1).tolist()[0]\njson_label = r'answer.json'\n\n#img_name='d4ab52b2598b8f08.jpg'\nprint(img_name)\nimg = cv2.imread(os.path.join(dataset_path, img_name))\nprint(img.shape)  # (h,w,c)\n\nxy_list = get_xyxy_from_cowboy(img_name, df, json_label)\ntmp=draw_rect(img, xy_list)\n\nfig = plt.figure() \nax = fig.add_subplot() \nplt.imshow(img)\nax.add_patch(tmp) ","metadata":{"execution":{"iopub.status.busy":"2021-08-10T08:25:50.256533Z","iopub.execute_input":"2021-08-10T08:25:50.256863Z","iopub.status.idle":"2021-08-10T08:25:50.305208Z","shell.execute_reply.started":"2021-08-10T08:25:50.256828Z","shell.execute_reply":"2021-08-10T08:25:50.303162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Score\n![Score.png](https://z3.ax1x.com/2021/08/06/fu4ioF.png)","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}