{"cells":[{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","trusted":true},"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 os\nimport torch\nimport sys\nsys.path.insert(0, \"../input/weightedboxesfusion\")\nfrom ensemble_boxes import *\nimport glob\n\nfrom tqdm import tqdm\nimport shutil as sh","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"!cp -r ../input/yolov5/yolov5/* .","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"list(glob.glob(\"../input/yolov5multiscale/best_*\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"WEIGHT_FILE1 = '../input/yolov5multiscale/best_yolov5x_fold0.pt'\nWEIGHT_FILE2 = '../input/yolov5multiscale/best_yolov5x_fold1.pt'\nDIR_TEST = '../input/global-wheat-detection/test/'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Create Pseudo Labels","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nimport argparse\n\nfrom utils.datasets import *\nfrom utils.utils import *\n\n\ndef detect(save_img=False):\n    weights, imgsz = opt.weights,opt.img_size\n    source = '../input/global-wheat-detection/test/'\n    \n    # Initialize\n    device = torch_utils.select_device(opt.device)\n    half = False\n    # Load model\n    models = []\n    for w in weights:\n        models.append(torch.load(w, map_location=device)['model'].to(device).float().eval())\n\n\n    dataset = LoadImages(source, img_size=1024)\n\n    # Get names and colors\n\n    # Run inference\n    t0 = time.time()\n    img = torch.zeros((1, 3, imgsz, imgsz), device=device)  # init img\n    all_path=[]\n    all_bboxex =[]\n    all_score =[]\n    for path, img, im0s, vid_cap in dataset:\n        img = torch.from_numpy(img).to(device)\n        img = img.half() if half else img.float()  # uint8 to fp16/32\n        img /= 255.0  # 0 - 255 to 0.0 - 1.0\n        if img.ndimension() == 3:\n            img = img.unsqueeze(0)\n\n        # Inference\n        t1 = torch_utils.time_synchronized()\n        bboxes_2 = []\n        score_2 = []\n        for model in models:\n            pred = model(img, augment=opt.augment)[0]\n            pred = non_max_suppression(pred, 0.4, opt.iou_thres, merge=True, classes=None, agnostic=False)\n            t2 = torch_utils.time_synchronized()\n\n            bboxes = []\n            score = []\n            # Process detections\n            for i, det in enumerate(pred):  # detections per image\n                p, s, im0 = path, '', im0s\n                gn = torch.tensor(im0.shape)[[1, 0, 1, 0]]  #  normalization gain whwh\n                if det is not None and len(det):\n                    det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()\n                    for c in det[:, -1].unique():\n                        n = (det[:, -1] == c).sum()  # detections per class\n\n                    for *xyxy, conf, cls in det:\n                        if True:  # Write to file\n                            xywh = torch.tensor(xyxy).view(-1).numpy()  # normalized xywh\n                            bboxes.append(xywh)\n                            score.append(conf)\n            bboxes_2.append(bboxes)\n            score_2.append(score)\n        all_path.append(path)\n        all_score.append(score_2)\n        all_bboxex.append(bboxes_2)\n    return all_path,all_score,all_bboxex\n\n\n\nclass opt:\n    weights_folds = [WEIGHT_FILE1]\n    weights_folds.sort()\n    weights = weights_folds\n    img_size = 1024\n    conf_thres = 0.1\n    iou_thres = 0.94\n    augment = True\n    device = '0'\n    classes=None\n    agnostic_nms = True\n        \nopt.img_size = check_img_size(opt.img_size)\n\n\nwith torch.no_grad():\n    res = detect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def run_wbf(boxes,scores, image_size=1024, iou_thr=0.4, skip_box_thr=0.4, weights=None):\n    labels0 = [np.ones(len(scores[idx])) for idx in range(len(scores))]\n    boxes, scores, labels = weighted_boxes_fusion(boxes, scores, labels0, weights=None, iou_thr=iou_thr, skip_box_thr=skip_box_thr)\n    return boxes, scores, labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_path,all_score,all_bboxex = res","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results =[]\ntestdf_psuedo = []\n\ndef format_prediction_string(boxes, scores):\n    pred_strings = []\n    for j in zip(scores, boxes):\n        pred_strings.append(\"{0:.4f} {1} {2} {3} {4}\".format(j[0], j[1][0], j[1][1], j[1][2], j[1][3]))\n    return \" \".join(pred_strings)\n\n\nfor row in range(len(all_path)):\n    image_id = all_path[row].split(\"/\")[-1].split(\".\")[0]\n    boxes = all_bboxex[row]\n    scores = all_score[row]\n    boxes, scores, labels = run_wbf(boxes,scores)\n    boxes = (boxes*1024/1024).astype(np.int32).clip(min=0, max=1023)\n    boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n    boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n    \n    for box in boxes:\n        result = {\n            'image_id': 'kaushal28'+image_id,\n            'source': 'kaushal28',\n            'x': float(box[0]),\n            'y': float(box[1]),\n            'w': float(box[2]),\n            'h': float(box[3]),\n            'x_center': float(box[0]) + float(box[2])/2,\n            'y_center': float(box[1]) + float(box[3])/2,\n            'classes': 0\n        }\n        testdf_psuedo.append(result)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df_pseudo = pd.DataFrame(testdf_psuedo, columns=['image_id', 'x', 'y', 'w', 'h', 'x_center','y_center','classes', 'source'])\ntest_df_pseudo.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/global-wheat-detection/train.csv')\nbboxs = np.stack(train_df['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=',')))\nfor i, column in enumerate(['x', 'y', 'w', 'h']):\n    train_df[column] = bboxs[:,i]\ntrain_df.drop(columns=['bbox'], inplace=True)\ntrain_df['x_center'] = train_df['x'] + train_df['w']/2\ntrain_df['y_center'] = train_df['y'] + train_df['h']/2\ntrain_df['classes'] = 0\n\ntrain_df = train_df[['image_id','x', 'y', 'w', 'h','x_center','y_center','classes', 'source']]\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.concat([train_df, test_df_pseudo], ignore_index=True)\ntrain_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Train for a few epochs","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"index = list(train_df.image_id.unique())\nval_index = index[-50:]\nFOLD=0\n\nfor image_id, image_meta in tqdm(train_df.groupby('image_id')):\n    if image_id in val_index:\n        path2save = 'val2017/'\n    else:\n        path2save = 'train2017/'\n    \n    if image_meta['source'].unique()[0] == 'kaushal28':\n        source = 'test'\n        image_id = image_id[9:] # remove kaushal28 from the image_id\n    else:\n        source = 'train'\n\n    if not os.path.exists('convertor/fold{}/labels/'.format(FOLD)+path2save):\n        os.makedirs('convertor/fold{}/labels/'.format(FOLD)+path2save)\n\n    with open('convertor/fold{}/labels/'.format(FOLD) + path2save + image_id + \".txt\", 'w+') as f:\n        row = image_meta[['classes','x_center','y_center','w','h']].astype(float).values\n        row = row/1024\n        row = row.astype(str)\n        for j in range(len(row)):\n            text = ' '.join(row[j])\n            f.write(text)\n            f.write(\"\\n\")\n\n    if not os.path.exists('convertor/fold{}/images/{}'.format(FOLD, path2save)):\n        os.makedirs('convertor/fold{}/images/{}'.format(FOLD, path2save))\n\n    sh.copy(f\"../input/global-wheat-detection/{source}/{image_id}.jpg\", f'convertor/fold{FOLD}/images/{path2save}/{image_id}.jpg')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_config = f'''# train and val datasets (image directory or *.txt file with image paths)\ntrain: ./convertor/fold{FOLD}/images/train2017/\nval: ./convertor/fold{FOLD}/images/val2017/\n\n# number of classes\nnc: 1\n\n# class names\nnames: ['wheat']'''\n\nwith open('wheat_data_config.yaml', 'w') as f:\n    f.write(data_config)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%writefile yolov5x.yaml\n\n# parameters\nnc: 1  # number of classes\ndepth_multiple: 1.33  # model depth multiple\nwidth_multiple: 1.25  # layer channel multiple\n\n# anchors\nanchors:\n  - [116,90, 156,198, 373,326]  # P5/32\n  - [30,61, 62,45, 59,119]  # P4/16\n  - [10,13, 16,30, 33,23]  # P3/8\n\n# YOLOv5 backbone\nbackbone:\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, BottleneckCSP, [128]],\n   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8\n   [-1, 9, BottleneckCSP, [256]],\n   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16\n   [-1, 9, BottleneckCSP, [512]],\n   [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32\n   [-1, 1, SPP, [1024, [5, 9, 13]]],\n  ]\n\n# YOLOv5 head\nhead:\n  [[-1, 3, BottleneckCSP, [1024, False]],  # 9\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, BottleneckCSP, [512, False]],  # 13\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, BottleneckCSP, [256, False]],\n   [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 18 (P3/8-small)\n\n   [-2, 1, Conv, [256, 3, 2]],\n   [[-1, 14], 1, Concat, [1]],  # cat head P4\n   [-1, 3, BottleneckCSP, [512, False]],\n   [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 22 (P4/16-medium)\n\n   [-2, 1, Conv, [512, 3, 2]],\n   [[-1, 10], 1, Concat, [1]],  # cat head P5\n   [-1, 3, BottleneckCSP, [1024, False]],\n   [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 26 (P5/32-large)\n\n   [[], 1, Detect, [nc, anchors]],  # Detect(P5, P4, P3)\n  ]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"yolo_config = {\n    'epochs': 40,\n    'image_size': 1024,\n    'batch_size': 2,\n    'data_config': 'wheat_data_config.yaml',\n    'yolo_config': 'yolov5x.yaml',\n    'results_name': f'yolov5x_fold{FOLD}',\n    'weights': WEIGHT_FILE1\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if len(os.listdir(DIR_TEST)) > 10:\n    !(python train.py --img-size {yolo_config.get('image_size')} \\\n    --batch-size {yolo_config.get('batch_size')} \\\n    --epochs {yolo_config.get('epochs')} \\\n    --data {yolo_config.get('data_config')} \\\n    --cfg {yolo_config.get('yolo_config')} \\\n    --name {yolo_config.get('results_name')} \\\n    --weights {yolo_config.get('weights')})","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Train another model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.cuda.empty_cache()\n!rm -rf convertor","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class opt:\n    weights_folds = [WEIGHT_FILE2]\n    weights_folds.sort()\n    weights = weights_folds\n    img_size = 1024\n    conf_thres = 0.1\n    iou_thres = 0.94\n    augment = True\n    device = '0'\n    classes=None\n    agnostic_nms = True\n        \nopt.img_size = check_img_size(opt.img_size)\n\n\nwith torch.no_grad():\n    res = detect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_path,all_score,all_bboxex = res","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results =[]\ntestdf_psuedo = []\n\nfor row in range(len(all_path)):\n    image_id = all_path[row].split(\"/\")[-1].split(\".\")[0]\n    boxes = all_bboxex[row]\n    scores = all_score[row]\n    boxes, scores, labels = run_wbf(boxes,scores)\n    boxes = (boxes*1024/1024).astype(np.int32).clip(min=0, max=1023)\n    boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n    boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n    \n    for box in boxes:\n        result = {\n            'image_id': 'kaushal28'+image_id,\n            'source': 'kaushal28',\n            'x': float(box[0]),\n            'y': float(box[1]),\n            'w': float(box[2]),\n            'h': float(box[3]),\n            'x_center': float(box[0]) + float(box[2])/2,\n            'y_center': float(box[1]) + float(box[3])/2,\n            'classes': 0\n        }\n        testdf_psuedo.append(result)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df_pseudo = pd.DataFrame(testdf_psuedo, columns=['image_id', 'x', 'y', 'w', 'h', 'x_center','y_center','classes', 'source'])\ntest_df_pseudo.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/global-wheat-detection/train.csv')\nbboxs = np.stack(train_df['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=',')))\nfor i, column in enumerate(['x', 'y', 'w', 'h']):\n    train_df[column] = bboxs[:,i]\ntrain_df.drop(columns=['bbox'], inplace=True)\ntrain_df['x_center'] = train_df['x'] + train_df['w']/2\ntrain_df['y_center'] = train_df['y'] + train_df['h']/2\ntrain_df['classes'] = 0\n\ntrain_df = train_df[['image_id','x', 'y', 'w', 'h','x_center','y_center','classes', 'source']]\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.concat([train_df, test_df_pseudo], ignore_index=True)\ntrain_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"index = list(train_df.image_id.unique())\nval_index = index[-50:]\nFOLD=1\n\nfor image_id, image_meta in tqdm(train_df.groupby('image_id')):\n    if image_id in val_index:\n        path2save = 'val2017/'\n    else:\n        path2save = 'train2017/'\n    \n    if image_meta['source'].unique()[0] == 'kaushal28':\n        source = 'test'\n        image_id = image_id[9:] # remove kaushal28 from the image_id\n    else:\n        source = 'train'\n\n    if not os.path.exists('convertor/fold{}/labels/'.format(FOLD)+path2save):\n        os.makedirs('convertor/fold{}/labels/'.format(FOLD)+path2save)\n\n    with open('convertor/fold{}/labels/'.format(FOLD) + path2save + image_id + \".txt\", 'w+') as f:\n        row = image_meta[['classes','x_center','y_center','w','h']].astype(float).values\n        row = row/1024\n        row = row.astype(str)\n        for j in range(len(row)):\n            text = ' '.join(row[j])\n            f.write(text)\n            f.write(\"\\n\")\n\n    if not os.path.exists('convertor/fold{}/images/{}'.format(FOLD, path2save)):\n        os.makedirs('convertor/fold{}/images/{}'.format(FOLD, path2save))\n\n    sh.copy(f\"../input/global-wheat-detection/{source}/{image_id}.jpg\", f'convertor/fold{FOLD}/images/{path2save}/{image_id}.jpg')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.cuda.empty_cache()\nyolo_config = {\n    'epochs': 42,\n    'image_size': 1024,\n    'batch_size': 2,\n    'data_config': 'wheat_data_config.yaml',\n    'yolo_config': 'yolov5x.yaml',\n    'results_name': f'yolov5x_fold{FOLD}',\n    'weights': WEIGHT_FILE2\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if len(os.listdir(DIR_TEST)) > 10:\n    !(python train.py --img-size {yolo_config.get('image_size')} \\\n    --batch-size {yolo_config.get('batch_size')} \\\n    --epochs {yolo_config.get('epochs')} \\\n    --data {yolo_config.get('data_config')} \\\n    --cfg {yolo_config.get('yolo_config')} \\\n    --name {yolo_config.get('results_name')} \\\n    --weights {yolo_config.get('weights')})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!rm -rf convertor","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"class opt:\n    weights_folds = list(glob.glob(\"weights/best_*\")) if len(os.listdir(DIR_TEST)) > 10 else [WEIGHT_FILE1, WEIGHT_FILE2]\n    weights_folds.sort()\n    weights = weights_folds\n    img_size = 1024\n    conf_thres = 0.1\n    iou_thres = 0.94\n    augment = True\n    device = '0'\n    classes=None\n    agnostic_nms = True\n        \nopt.img_size = check_img_size(opt.img_size)\n\n\nwith torch.no_grad():\n    res = detect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"all_path,all_score,all_bboxex = res","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"results =[]\ndef format_prediction_string(boxes, scores):\n    pred_strings = []\n    for j in zip(scores, boxes):\n        pred_strings.append(\"{0:.4f} {1} {2} {3} {4}\".format(j[0], j[1][0], j[1][1], j[1][2], j[1][3]))\n    return \" \".join(pred_strings)\nfor row in range(len(all_path)):\n    image_id = all_path[row].split(\"/\")[-1].split(\".\")[0]\n    boxes = all_bboxex[row]\n    scores = all_score[row]\n    boxes, scores, labels = run_wbf(boxes,scores)\n    boxes = (boxes*1024/1024).astype(np.int32).clip(min=0, max=1023)\n    boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n    boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n    result = {'image_id': image_id,'PredictionString': format_prediction_string(boxes, scores)}\n    results.append(result)\ntest_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"!rm -rf ./*","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"test_df.to_csv('submission.csv', index=False)\ntest_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"size = 300\nidx =-1\nfont = cv2.FONT_HERSHEY_SIMPLEX \nimage = image = cv2.imread(all_path[idx], cv2.IMREAD_COLOR)\n# fontScale \nfontScale = 1\ncolor = (255, 0, 0) \n\n# Line thickness of 2 px \nthickness = 2\nfor b,s in zip(boxes,scores):\n    image = cv2.rectangle(image, (b[0],b[1]), (b[0]+b[2],b[1]+b[3]), (255,0,0), 1) \n    image = cv2.putText(image, '{:.2}'.format(s), (b[0]+np.random.randint(20),b[1]), font,  \n                   fontScale, color, thickness, cv2.LINE_AA)\nplt.figure(figsize=[20,20])\nplt.imshow(image[:,:,::-1])\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}