{"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":"## Init","metadata":{}},{"cell_type":"code","source":"from itertools import groupby\nimport numpy as np\nfrom tqdm.notebook import tqdm\ntqdm.pandas()\nimport pandas as pd\nimport os\nimport pickle\nimport cv2\nfrom multiprocessing import Pool\nimport matplotlib.pyplot as plt\nimport ast\nimport glob\nimport time\nimport torch\n\nimport shutil\nfrom shutil import copyfile\nimport sys\nsys.path.append('../input/tensorflow-great-barrier-reef')\n\nfrom joblib import Parallel, delayed\n\nfrom IPython.display import display, HTML\n\nfrom matplotlib import animation, rc\nrc('animation', html='jshtml')\n\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:23:16.835128Z","iopub.execute_input":"2022-02-13T18:23:16.835469Z","iopub.status.idle":"2022-02-13T18:23:18.444013Z","shell.execute_reply.started":"2022-02-13T18:23:16.835394Z","shell.execute_reply":"2022-02-13T18:23:18.443285Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Define Validation Images and Labels Dir","metadata":{}},{"cell_type":"code","source":"!ls -l","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:23:18.447335Z","iopub.execute_input":"2022-02-13T18:23:18.447536Z","iopub.status.idle":"2022-02-13T18:23:19.120794Z","shell.execute_reply.started":"2022-02-13T18:23:18.447512Z","shell.execute_reply":"2022-02-13T18:23:19.119942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv('../input/tensorflow-great-barrier-reef/train.csv')\n#train=pd.read_csv('../input/more-annotations/more_annotations_train.csv')\n\ntrain['pos'] = train.annotations != '[]'","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:23:19.122984Z","iopub.execute_input":"2022-02-13T18:23:19.123268Z","iopub.status.idle":"2022-02-13T18:23:19.186144Z","shell.execute_reply.started":"2022-02-13T18:23:19.123225Z","shell.execute_reply":"2022-02-13T18:23:19.185481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#fold='fold4'\nfold_no ='fold1'\n!mkdir -p ./yolo_data/{fold_no}/images/val\n!mkdir -p ./yolo_data/{fold_no}/images/train\n\n!mkdir -p ./yolo_data/{fold_no}/labels/val\n!mkdir -p ./yolo_data/{fold_no}/labels/train","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:23:19.188348Z","iopub.execute_input":"2022-02-13T18:23:19.188755Z","iopub.status.idle":"2022-02-13T18:23:22.125888Z","shell.execute_reply.started":"2022-02-13T18:23:19.188719Z","shell.execute_reply":"2022-02-13T18:23:22.124773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train[\"NumBBox\"]=train['annotations'].apply(lambda x: str.count(x, 'x'))\ntrain['New_number_bbox'] = train['annotations'].apply(lambda x:len(eval(x)))\ntrain[train['NumBBox']>0].shape","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:23:22.127685Z","iopub.execute_input":"2022-02-13T18:23:22.128143Z","iopub.status.idle":"2022-02-13T18:23:22.820898Z","shell.execute_reply.started":"2022-02-13T18:23:22.128091Z","shell.execute_reply":"2022-02-13T18:23:22.820216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train[\"NumBBox\"].sum())","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:23:22.822293Z","iopub.execute_input":"2022-02-13T18:23:22.822695Z","iopub.status.idle":"2022-02-13T18:23:22.828673Z","shell.execute_reply.started":"2022-02-13T18:23:22.822658Z","shell.execute_reply":"2022-02-13T18:23:22.827788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip uninstall -q -y scikit-learn\n!pip install -q scikit-learn","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:23:22.830073Z","iopub.execute_input":"2022-02-13T18:23:22.830527Z","iopub.status.idle":"2022-02-13T18:23:37.164187Z","shell.execute_reply.started":"2022-02-13T18:23:22.830486Z","shell.execute_reply":"2022-02-13T18:23:37.163336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"neg_img_count=30\ngroups=dict(list(train.groupby(['video_id','sequence'])))\ngroups_neg_ids={}\nfor i in groups:\n    t=groups[i]\n    t['shifted']= (t.NumBBox.shift(1)) \n\n    t.fillna(0,inplace=True)\n    t['shifted']= t.shifted.astype('int').clip(0,1)\n    #for i in tmp.NumBBox.values:\n    # check for neg frames before or after the bbox\n    t1=t[(t.shifted!=t.NumBBox) & ((t.shifted==0) & (t.NumBBox!=0 )) |((t.shifted!=0) & (t.NumBBox==0 ))]\n    neg_seq_frame=t1[t1.shifted==0].sequence_frame.values # this is to take frames prior to object frame\n    frame_indices1=[]\n    for f in neg_seq_frame:\n        frame_indices1=frame_indices1+(np.arange(f-neg_img_count,f)).tolist() #generate the frame no prior to object frame\n        \n    pos_seq_frame=t1[t1.shifted==1].sequence_frame.values # this is to take frames after   object frame\n    frame_indices2=[]\n    for f in pos_seq_frame:\n        frame_indices2= frame_indices2+(np.arange(f ,f+neg_img_count)).tolist()    #generate the frame no after object frame \n     \n    frame_indices=np.concatenate([frame_indices1,frame_indices2])\n    neg_img_ids=t[(t.sequence_frame.isin(frame_indices)) & (t.NumBBox==0)].image_id.values #gather image ids\n    groups_neg_ids[i]=neg_img_ids\n     \ntotal_neg_list=[a for a in groups_neg_ids.values() ]\ntotal_neg_list=np.concatenate(total_neg_list)\n#df_train=train[(train[\"NumBBox\"]>0 )| (train.image_id.isin(total_neg_list)) ]\ndf_train=train[(train[\"NumBBox\"]>0 )  ]\ndf_train.sample(2)\ndf_train.shape,train[train[\"NumBBox\"]==0].shape\ndf_train=df_train.sort_values(by=['video_id','sequence','sequence_frame']).reset_index(drop=True)\n\ngkf_video=False\ndf_train['fold'] = -1\nCV=False\nif CV and gkf_video:\n    \n    from sklearn.model_selection import GroupKFold\n    kf = GroupKFold(n_splits = 5) \n    df_train = df_train.reset_index(drop=True)\n    df_train['fold'] = -1\n    for fold, (train_idx, val_idx) in enumerate(kf.split(df_train, y = df_train.video_id.tolist(), groups=df_train.sequence)):\n        df_train.loc[val_idx, 'fold'] = fold\n    display(df_train.fold.value_counts())\nelif CV:\n    df_train.loc[df_train.video_id==0,'fold']=0\n    df_train.loc[df_train.video_id==1,'fold']=1\n    df_train.loc[df_train.video_id==2,'fold']=2\nelse:\n    #test_train_split=pd.read_csv('../input/reef-a-cv-strategy-subsequences/train-validation-split/train-0.1.csv')\n    #test_train_split=pd.read_csv('/kaggle/input/reef-a-cv-strategy-subsequences/train-validation-split/train-0.1.csv')\n    #df_train =pd.merge(df_train,test_train_split[['image_id','is_train']],on='image_id') \n     \n    test_train_split=pd.read_csv('../input/reef-a-cv-strategy-subsequences/train-validation-split/train-0.1.csv')\n    '''\n    from sklearn.model_selection import StratifiedGroupKFold\n    sgkf = StratifiedGroupKFold(n_splits=8)\n    for fold, (t_idx, v_idx) in enumerate( sgkf.split(test_train_split, test_train_split.has_annotations, test_train_split.subsequence_id) ):\n        test_train_split.loc[v_idx,'fold'] = fold\n    \n    \n    fold=1\n    \n    test_train_split['is_train']=True\n    test_train_split.loc[test_train_split.fold==1,'is_train']=False\n    '''\n    df_train =pd.merge(df_train,test_train_split[['image_id','is_train']],on='image_id') \n     ","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:23:37.16585Z","iopub.execute_input":"2022-02-13T18:23:37.166125Z","iopub.status.idle":"2022-02-13T18:23:37.470093Z","shell.execute_reply.started":"2022-02-13T18:23:37.166084Z","shell.execute_reply":"2022-02-13T18:23:37.469357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:23:37.471343Z","iopub.execute_input":"2022-02-13T18:23:37.471581Z","iopub.status.idle":"2022-02-13T18:23:37.493718Z","shell.execute_reply.started":"2022-02-13T18:23:37.471551Z","shell.execute_reply":"2022-02-13T18:23:37.492878Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm.notebook import tqdm","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:23:37.496948Z","iopub.execute_input":"2022-02-13T18:23:37.497178Z","iopub.status.idle":"2022-02-13T18:23:37.500233Z","shell.execute_reply.started":"2022-02-13T18:23:37.49715Z","shell.execute_reply":"2022-02-13T18:23:37.499554Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#df_train[df_train.image_id=='0-4176']","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:23:37.501607Z","iopub.execute_input":"2022-02-13T18:23:37.502169Z","iopub.status.idle":"2022-02-13T18:23:37.510134Z","shell.execute_reply.started":"2022-02-13T18:23:37.502114Z","shell.execute_reply":"2022-02-13T18:23:37.509374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fold_no=1\n\nannos = []\ncount=0\nfor i, x in tqdm(df_train.iterrows()):\n    if (x.fold == fold_no) or (not x.is_train):\n        mode = 'val'\n        count+=1\n    else:\n        # train\n        mode = 'train'\n        #if not x.pos: \n        #    continue\n        # val\n    copyfile(f'../input/tensorflow-great-barrier-reef/train_images/video_{x.video_id}/{x.video_frame}.jpg',\n                f'/kaggle/working/yolo_data/fold{fold_no}/images/{mode}/{x.image_id}.jpg')\n    #if not x.pos:\n    #    continue\n    r = ''\n    anno = eval(x.annotations)\n    #if x.NumBBox==0 or x.image_id=='0-4176' :\n        \n    #    print(x.NumBBox) \n    for an in anno:\n#            annos.append(an)\n        r += '0 {} {} {} {}\\n'.format((an['x'] + an['width'] / 2) / 1280,\n                                        (an['y'] + an['height'] / 2) / 720,\n                                        an['width'] / 1280, an['height'] / 720)\n    with open(f'/kaggle/working/yolo_data/fold{fold_no}/labels/{mode}/{x.image_id}.txt', 'w') as fp:\n        #if x.NumBBox==0:\n            \n        #    print(len(anno))\n        fp.write(r)","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:23:37.513027Z","iopub.execute_input":"2022-02-13T18:23:37.513338Z","iopub.status.idle":"2022-02-13T18:24:31.614324Z","shell.execute_reply.started":"2022-02-13T18:23:37.513295Z","shell.execute_reply":"2022-02-13T18:24:31.613625Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#fold\n!ls /kaggle/working/ ","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:31.615605Z","iopub.execute_input":"2022-02-13T18:24:31.616259Z","iopub.status.idle":"2022-02-13T18:24:32.27979Z","shell.execute_reply.started":"2022-02-13T18:24:31.616218Z","shell.execute_reply":"2022-02-13T18:24:32.279031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls /kaggle/working/yolo_data/fold{fold}/labels/val | wc -l #884 for fold1\n#!ls /kaggle/working/yolo_data/fold4/labels/val  \nlen(os.listdir('/kaggle/working/yolo_data/fold1/images/val'))\n ","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:32.281716Z","iopub.execute_input":"2022-02-13T18:24:32.282301Z","iopub.status.idle":"2022-02-13T18:24:32.952151Z","shell.execute_reply.started":"2022-02-13T18:24:32.282258Z","shell.execute_reply":"2022-02-13T18:24:32.95136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(os.listdir('/kaggle/working/yolo_data/fold1/images/train'))","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:32.953865Z","iopub.execute_input":"2022-02-13T18:24:32.95437Z","iopub.status.idle":"2022-02-13T18:24:32.966049Z","shell.execute_reply.started":"2022-02-13T18:24:32.954318Z","shell.execute_reply":"2022-02-13T18:24:32.965153Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## YOLOV5 Install","metadata":{}},{"cell_type":"code","source":"!rm -r /kaggle/working/yolov5\n!git clone https://github.com/ultralytics/yolov5 # clone\n#!cp -r /kaggle/input/yolos6tiles/yolov5 /kaggle/working/\n%cd yolov5\n%pip install -qr requirements.txt  # install\n\nfrom yolov5 import utils\ndisplay = utils.notebook_init()  # check","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:32.967487Z","iopub.execute_input":"2022-02-13T18:24:32.967788Z","iopub.status.idle":"2022-02-13T18:24:44.597494Z","shell.execute_reply.started":"2022-02-13T18:24:32.967752Z","shell.execute_reply":"2022-02-13T18:24:44.59661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Config","metadata":{}},{"cell_type":"code","source":"fold_no","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:44.620643Z","iopub.execute_input":"2022-02-13T18:24:44.621397Z","iopub.status.idle":"2022-02-13T18:24:44.626832Z","shell.execute_reply.started":"2022-02-13T18:24:44.621362Z","shell.execute_reply":"2022-02-13T18:24:44.626051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import yaml\ndata = '''\n# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]\npath: ../yolo_data/fold1/  # dataset root dir\ntrain: images/train  # train images (relative to 'path') 128 images\nval: images/val  # val images (relative to 'path') 128 images\ntest:  # test images (optional)\n\n# Classes\nnc: 1  # number of classes\nnames: ['reef']  # class names\n\n\n# Download script/URL (optional)\n# download: https://ultralytics.com/assets/coco128.zip\n'''\n\ndata = dict( \n    train = f'/kaggle/working/yolo_data/fold{fold_no}/images/train',\n    val = f'/kaggle/working/yolo_data/fold{fold_no}/images/val',\n    \n    nc    = 1, # number of classes\n    names =  ['cots'] # classes\n    )\n\nwith open('/kaggle/working/yolov5/data/reef_f1_naive.yaml', 'w') as outfile:\n    yaml.dump(data, outfile, default_flow_style=False)\n\n%cat /kaggle/working/yolov5/data/reef_f1_naive.yaml","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:44.628396Z","iopub.execute_input":"2022-02-13T18:24:44.628976Z","iopub.status.idle":"2022-02-13T18:24:45.307382Z","shell.execute_reply.started":"2022-02-13T18:24:44.628935Z","shell.execute_reply":"2022-02-13T18:24:45.306632Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#with open('/kaggle/working/yolov5/data/reef_f1_naive.yaml', 'w') as fp:\n#    fp.write(data)ss","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:45.310527Z","iopub.execute_input":"2022-02-13T18:24:45.310762Z","iopub.status.idle":"2022-02-13T18:24:45.316358Z","shell.execute_reply.started":"2022-02-13T18:24:45.310734Z","shell.execute_reply":"2022-02-13T18:24:45.315673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## F2 Score Helpers\nreference : [competition metric implementation](https://www.kaggle.com/bamps53/competition-metric-implementation)","metadata":{}},{"cell_type":"code","source":"def calc_iou(bboxes1, bboxes2, bbox_mode='yolo'):\n    assert len(bboxes1.shape) == 2 and bboxes1.shape[1] == 4\n    assert len(bboxes2.shape) == 2 and bboxes2.shape[1] == 4\n    bboxes1 = bboxes1.copy()\n    bboxes2 = bboxes2.copy()\n    \n    if bbox_mode == 'xywh':\n        bboxes1[:, 2:] += bboxes1[:, :2]\n        bboxes2[:, 2:] += bboxes2[:, :2]\n    \n    if bbox_mode == 'yolo':\n        bboxes1[:, 0:2] =bboxes1[:, 0:2]-bboxes1[:, 2:]/2 #for yolo\n        bboxes2[:, 0:2] =bboxes2[:, 0:2]- bboxes2[:, 2:]/2\n        bboxes1[:, 2:] += bboxes1[:, :2]\n        bboxes2[:, 2:] += bboxes2[:, :2]\n      \n    x11, y11, x12, y12 = np.split(bboxes1, 4, axis=1)\n    x21, y21, x22, y22 = np.split(bboxes2, 4, axis=1)\n    xA = np.maximum(x11, np.transpose(x21))\n    yA = np.maximum(y11, np.transpose(y21))\n    xB = np.minimum(x12, np.transpose(x22))\n    yB = np.minimum(y12, np.transpose(y22))\n    interArea = np.maximum((xB - xA ), 0) * np.maximum((yB - yA), 0)\n    boxAArea = (x12 - x11) * (y12 - y11)\n    boxBArea = (x22 - x21) * (y22 - y21 )\n    iou = interArea / (boxAArea + np.transpose(boxBArea) - interArea)\n    return iou\n\ndef f_beta(tp, fp, fn, beta=2,eps=1e-3 ):\n    return (((1+beta**2)*tp)+eps) / ((1+beta**2)*tp + beta**2*fn+fp+eps)\n\ndef calc_is_correct_at_iou_th(gt_bboxes, pred_bboxes, iou_th, verbose=False):\n    gt_bboxes = gt_bboxes.copy()\n    pred_bboxes = pred_bboxes.copy()\n    \n    tp = 0\n    fp = 0\n    for k, pred_bbox in enumerate(pred_bboxes): # fixed in ver.7\n        ious = calc_iou(gt_bboxes, pred_bbox[None, 1:])\n        max_iou = ious.max()\n        if max_iou > iou_th:\n            tp += 1\n            gt_bboxes = np.delete(gt_bboxes, ious.argmax(), axis=0)\n        else:\n            fp += 1 # we take FP that is not able to match to gt.\n        if len(gt_bboxes) == 0:\n            fp += len(pred_bboxes) - (k + 1) # fix in ver.7\n            break\n\n    fn = len(gt_bboxes)\n    return tp, fp, fn\n\ndef calc_is_correct(gt_bboxes, pred_bboxes):\n    \"\"\"\n    gt_bboxes: (N, 4) np.array in xywh format\n    pred_bboxes: (N, 5) np.array in conf+xywh format\n    \"\"\"\n    if len(gt_bboxes) == 0 and len(pred_bboxes) == 0:\n        tps, fps, fns = 0, 0, 0\n        return tps, fps, fns\n    \n    elif len(gt_bboxes) == 0:\n        tps, fps, fns = 0, len(pred_bboxes)*11, 0\n        return tps, fps, fns\n    \n    elif len(pred_bboxes) == 0:\n        tps, fps, fns = 0, 0, len(gt_bboxes)*11\n        return tps, fps, fns\n    \n    pred_bboxes = pred_bboxes[pred_bboxes[:,0].argsort()[::-1]] # sort by conf\n    \n    tps, fps, fns = 0, 0, 0\n    for iou_th in np.arange(0.3, 0.85, 0.05):\n        tp, fp, fn = calc_is_correct_at_iou_th(gt_bboxes, pred_bboxes, iou_th)\n        tps += tp\n        fps += fp\n        fns += fn\n    return tps, fps, fns\ndef calc_is_correct1(gt_bboxes, pred_bboxes,iou_th=0.3):\n    \"\"\"\n    gt_bboxes: (N, 4) np.array in xywh format\n    pred_bboxes: (N, 5) np.array in conf+xywh format\n    \"\"\"\n    if len(gt_bboxes) == 0 and len(pred_bboxes) == 0:\n        tps, fps, fns = 0, 0, 0\n        return tps, fps, fns\n    \n    elif len(gt_bboxes) == 0:\n        tps, fps, fns = 0, len(pred_bboxes)*11, 0\n        return tps, fps, fns\n    \n    elif len(pred_bboxes) == 0:\n        tps, fps, fns = 0, 0, len(gt_bboxes)*11\n        return tps, fps, fns\n    \n    pred_bboxes = pred_bboxes[pred_bboxes[:,0].argsort()[::-1]] # sort by conf\n    \n    tps, fps, fns = 0, 0, 0\n    #for iou_th in np.arange(0.3, 0.85, 0.05):\n    tps, fps, fns = calc_is_correct_at_iou_th(gt_bboxes, pred_bboxes, iou_th)\n    #tps += tp\n    #fps += fp\n    #fns += fn\n    return tps, fps, fns\ndef calc_f2_score(gt_bboxes_list, pred_bboxes_list, verbose=False):\n    \"\"\"\n    gt_bboxes_list: list of (N, 4) np.array in xywh format\n    pred_bboxes_list: list of (N, 5) np.array in conf+xywh format\n    \"\"\"\n    tps, fps, fns = 0, 0, 0\n    for gt_bboxes, pred_bboxes in zip(gt_bboxes_list, pred_bboxes_list):\n        tp, fp, fn = calc_is_correct(gt_bboxes, pred_bboxes)\n        tps += tp\n        fps += fp\n        fns += fn\n        if verbose:\n            num_gt = len(gt_bboxes)\n            num_pred = len(pred_bboxes)\n            print(f'num_gt:{num_gt:<3} num_pred:{num_pred:<3} tp:{tp:<3} fp:{fp:<3} fn:{fn:<3}')\n    return f_beta(tps, fps, fns, beta=2)\n    \ndef calc_f2_score1(gt_bboxes_list, pred_bboxes_list, verbose=False):\n    \"\"\"\n    gt_bboxes_list: list of (N, 4) np.array in xywh format\n    pred_bboxes_list: list of (N, 5) np.array in conf+xywh format\n    \"\"\"\n    fbeta_list=[]\n    tps, fps, fns = 0, 0, 0\n    for iou_th in np.arange(0.3, 0.85, 0.05):\n        for gt_bboxes, pred_bboxes in zip(gt_bboxes_list, pred_bboxes_list):\n        \n    \n            tp, fp, fn = calc_is_correct(gt_bboxes, pred_bboxes,iou_th)\n            tps += tp\n            fps += fp\n            fns += fn\n            if verbose:\n                num_gt = len(gt_bboxes)\n                num_pred = len(pred_bboxes)\n                print(f'num_gt:{num_gt:<3} num_pred:{num_pred:<3} tp:{tp:<3} fp:{fp:<3} fn:{fn:<3}')\n        #print('fbeta at ',iou_th,f_beta(tps, fps, fns, beta=2))\n        fbeta_list.append(f_beta(tps, fps, fns, beta=2) )\n    return np.mean(fbeta_list)","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:45.318124Z","iopub.execute_input":"2022-02-13T18:24:45.318887Z","iopub.status.idle":"2022-02-13T18:24:45.350337Z","shell.execute_reply.started":"2022-02-13T18:24:45.318846Z","shell.execute_reply":"2022-02-13T18:24:45.349688Z"},"_kg_hide-input":true,"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from glob import glob\n#print(fold)\npaths = glob(f'/kaggle/working/yolo_data/fold{fold_no}/labels/val/*')\nval_len = len(paths) \nval_len","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:45.351526Z","iopub.execute_input":"2022-02-13T18:24:45.351964Z","iopub.status.idle":"2022-02-13T18:24:45.365611Z","shell.execute_reply.started":"2022-02-13T18:24:45.351929Z","shell.execute_reply":"2022-02-13T18:24:45.364939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile /kaggle/working/yolov5/utils/augmentations.py\n\n\"\"\"\nImage augmentation functions\n\"\"\"\n\nimport math\nimport random\n\nimport cv2\nimport numpy as np\n\nfrom utils.general import LOGGER, check_version, colorstr, resample_segments, segment2box\nfrom utils.metrics import bbox_ioa\n\n\nclass Albumentations:\n    # YOLOv5 Albumentations class (optional, only used if package is installed)\n    def __init__(self,crop_height=1800,width=3200):\n        self.transform = None\n        try:\n            import albumentations as A\n            check_version(A.__version__, '1.0.3', hard=True)  # version requirement\n\n            self.transform = A.Compose([\n                  A.OneOf([ A.RandomCrop(width=width, height=crop_height,p=0.5),\n                          A.CenterCrop(width=width, height=crop_height,p=0.0),\n                          #A.RandomSizedBBoxSafeCrop(width=width, height=crop_height,p=0.0)\n                          \n                          A.RandomResizedCrop (width=3200,height=1792, scale=(0.15, 1.0), \n                                               ratio=(0.75, 1.3333333333333333), \n                                               interpolation=1, always_apply=False, p=0.0)\n            \n                         ], p=1),\n                A.Resize(width=3200, height=1824,p=1),\n                #A.RandomResizedCrop(width=320, height=320,p=1)\n                #A.RandomSizedCrop( (320,640), 640, 640,p=1) ,\n                #A.UnsharpMask(p=0.25),\n                A.Blur(p=0.01),\n                A.MedianBlur(p=0.01),\n                A.ToGray(p=0.01),\n                A.OneOf([A.CLAHE(p=0.3,clip_limit=4),A.Sharpen(p=0.3)],p=0.3),\n                #A.CLAHE(p=0.3,clip_limit=6),\n                A.RandomBrightnessContrast(p=0.0),\n                A.RandomGamma(p=0.2),\n                A.ImageCompression(quality_lower=75, p=0.0)],\n                bbox_params=A.BboxParams(format='yolo',min_area=99, min_visibility=0.1, \n                                         label_fields=['class_labels']))\n\n            LOGGER.info(colorstr('albumentations: ') + ', '.join(f'{x}' for x in self.transform.transforms if x.p))\n        except ImportError:  # package not installed, skip\n            pass\n        except Exception as e:\n            LOGGER.info(colorstr('albumentations: ') + f'{e}')\n\n    def __call__(self, im, labels, p=1.0):\n        if self.transform and random.random() < p:\n            new = self.transform(image=im, bboxes=labels[:, 1:], class_labels=labels[:, 0])  # transformed\n            im, labels = new['image'], np.array([[c, *b] for c, b in zip(new['class_labels'], new['bboxes'])])\n        return im, labels\n\n\ndef augment_hsv(im, hgain=0.5, sgain=0.5, vgain=0.5):\n    # HSV color-space augmentation\n    if hgain or sgain or vgain:\n        r = np.random.uniform(-1, 1, 3) * [hgain, sgain, vgain] + 1  # random gains\n        hue, sat, val = cv2.split(cv2.cvtColor(im, cv2.COLOR_BGR2HSV))\n        dtype = im.dtype  # uint8\n\n        x = np.arange(0, 256, dtype=r.dtype)\n        lut_hue = ((x * r[0]) % 180).astype(dtype)\n        lut_sat = np.clip(x * r[1], 0, 255).astype(dtype)\n        lut_val = np.clip(x * r[2], 0, 255).astype(dtype)\n\n        im_hsv = cv2.merge((cv2.LUT(hue, lut_hue), cv2.LUT(sat, lut_sat), cv2.LUT(val, lut_val)))\n        cv2.cvtColor(im_hsv, cv2.COLOR_HSV2BGR, dst=im)  # no return needed\n\n\ndef hist_equalize(im, clahe=True, bgr=False):\n    # Equalize histogram on BGR image 'im' with im.shape(n,m,3) and range 0-255\n    yuv = cv2.cvtColor(im, cv2.COLOR_BGR2YUV if bgr else cv2.COLOR_RGB2YUV)\n    if clahe:\n        c = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))\n        yuv[:, :, 0] = c.apply(yuv[:, :, 0])\n    else:\n        yuv[:, :, 0] = cv2.equalizeHist(yuv[:, :, 0])  # equalize Y channel histogram\n    return cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR if bgr else cv2.COLOR_YUV2RGB)  # convert YUV image to RGB\n\n\ndef replicate(im, labels):\n    # Replicate labels\n    h, w = im.shape[:2]\n    boxes = labels[:, 1:].astype(int)\n    x1, y1, x2, y2 = boxes.T\n    s = ((x2 - x1) + (y2 - y1)) / 2  # side length (pixels)\n    for i in s.argsort()[:round(s.size * 0.5)]:  # smallest indices\n        x1b, y1b, x2b, y2b = boxes[i]\n        bh, bw = y2b - y1b, x2b - x1b\n        yc, xc = int(random.uniform(0, h - bh)), int(random.uniform(0, w - bw))  # offset x, y\n        x1a, y1a, x2a, y2a = [xc, yc, xc + bw, yc + bh]\n        im[y1a:y2a, x1a:x2a] = im[y1b:y2b, x1b:x2b]  # im4[ymin:ymax, xmin:xmax]\n        labels = np.append(labels, [[labels[i, 0], x1a, y1a, x2a, y2a]], axis=0)\n\n    return im, labels\n\n\ndef letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32):\n    # Resize and pad image while meeting stride-multiple constraints\n    shape = im.shape[:2]  # current shape [height, width]\n    if isinstance(new_shape, int):\n        new_shape = (new_shape, new_shape)\n\n    # Scale ratio (new / old)\n    r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])\n    if not scaleup:  # only scale down, do not scale up (for better val mAP)\n        r = min(r, 1.0)\n\n    # Compute padding\n    ratio = r, r  # width, height ratios\n    new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))\n    dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding\n    if auto:  # minimum rectangle\n        dw, dh = np.mod(dw, stride), np.mod(dh, stride)  # wh padding\n    elif scaleFill:  # stretch\n        dw, dh = 0.0, 0.0\n        new_unpad = (new_shape[1], new_shape[0])\n        ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]  # width, height ratios\n\n    dw /= 2  # divide padding into 2 sides\n    dh /= 2\n\n    if shape[::-1] != new_unpad:  # resize\n        im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)\n    top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))\n    left, right = int(round(dw - 0.1)), int(round(dw + 0.1))\n    im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add border\n    return im, ratio, (dw, dh)\n\n\ndef random_perspective(im, targets=(), segments=(), degrees=10, translate=.1, scale=.1, shear=10, perspective=0.0,\n                       border=(0, 0)):\n    # torchvision.transforms.RandomAffine(degrees=(-10, 10), translate=(0.1, 0.1), scale=(0.9, 1.1), shear=(-10, 10))\n    # targets = [cls, xyxy]\n\n    height = im.shape[0] + border[0] * 2  # shape(h,w,c)\n    width = im.shape[1] + border[1] * 2\n\n    # Center\n    C = np.eye(3)\n    C[0, 2] = -im.shape[1] / 2  # x translation (pixels)\n    C[1, 2] = -im.shape[0] / 2  # y translation (pixels)\n\n    # Perspective\n    P = np.eye(3)\n    P[2, 0] = random.uniform(-perspective, perspective)  # x perspective (about y)\n    P[2, 1] = random.uniform(-perspective, perspective)  # y perspective (about x)\n\n    # Rotation and Scale\n    R = np.eye(3)\n    a = random.uniform(-degrees, degrees)\n    # a += random.choice([-180, -90, 0, 90])  # add 90deg rotations to small rotations\n    s = random.uniform(1 - scale, 1 + scale)\n    # s = 2 ** random.uniform(-scale, scale)\n    R[:2] = cv2.getRotationMatrix2D(angle=a, center=(0, 0), scale=s)\n\n    # Shear\n    S = np.eye(3)\n    S[0, 1] = math.tan(random.uniform(-shear, shear) * math.pi / 180)  # x shear (deg)\n    S[1, 0] = math.tan(random.uniform(-shear, shear) * math.pi / 180)  # y shear (deg)\n\n    # Translation\n    T = np.eye(3)\n    T[0, 2] = random.uniform(0.5 - translate, 0.5 + translate) * width  # x translation (pixels)\n    T[1, 2] = random.uniform(0.5 - translate, 0.5 + translate) * height  # y translation (pixels)\n\n    # Combined rotation matrix\n    M = T @ S @ R @ P @ C  # order of operations (right to left) is IMPORTANT\n    if (border[0] != 0) or (border[1] != 0) or (M != np.eye(3)).any():  # image changed\n        if perspective:\n            im = cv2.warpPerspective(im, M, dsize=(width, height), borderValue=(114, 114, 114))\n        else:  # affine\n            im = cv2.warpAffine(im, M[:2], dsize=(width, height), borderValue=(114, 114, 114))\n\n    # Visualize\n    # import matplotlib.pyplot as plt\n    # ax = plt.subplots(1, 2, figsize=(12, 6))[1].ravel()\n    # ax[0].imshow(im[:, :, ::-1])  # base\n    # ax[1].imshow(im2[:, :, ::-1])  # warped\n\n    # Transform label coordinates\n    n = len(targets)\n    if n:\n        use_segments = any(x.any() for x in segments)\n        new = np.zeros((n, 4))\n        if use_segments:  # warp segments\n            segments = resample_segments(segments)  # upsample\n            for i, segment in enumerate(segments):\n                xy = np.ones((len(segment), 3))\n                xy[:, :2] = segment\n                xy = xy @ M.T  # transform\n                xy = xy[:, :2] / xy[:, 2:3] if perspective else xy[:, :2]  # perspective rescale or affine\n\n                # clip\n                new[i] = segment2box(xy, width, height)\n\n        else:  # warp boxes\n            xy = np.ones((n * 4, 3))\n            xy[:, :2] = targets[:, [1, 2, 3, 4, 1, 4, 3, 2]].reshape(n * 4, 2)  # x1y1, x2y2, x1y2, x2y1\n            xy = xy @ M.T  # transform\n            xy = (xy[:, :2] / xy[:, 2:3] if perspective else xy[:, :2]).reshape(n, 8)  # perspective rescale or affine\n\n            # create new boxes\n            x = xy[:, [0, 2, 4, 6]]\n            y = xy[:, [1, 3, 5, 7]]\n            new = np.concatenate((x.min(1), y.min(1), x.max(1), y.max(1))).reshape(4, n).T\n\n            # clip\n            new[:, [0, 2]] = new[:, [0, 2]].clip(0, width)\n            new[:, [1, 3]] = new[:, [1, 3]].clip(0, height)\n\n        # filter candidates\n        i = box_candidates(box1=targets[:, 1:5].T * s, box2=new.T, area_thr=0.01 if use_segments else 0.10)\n        targets = targets[i]\n        targets[:, 1:5] = new[i]\n\n    return im, targets\n\n\ndef copy_paste(im, labels, segments, p=0.5):\n    # Implement Copy-Paste augmentation https://arxiv.org/abs/2012.07177, labels as nx5 np.array(cls, xyxy)\n    n = len(segments)\n    if p and n:\n        h, w, c = im.shape  # height, width, channels\n        im_new = np.zeros(im.shape, np.uint8)\n        for j in random.sample(range(n), k=round(p * n)):\n            l, s = labels[j], segments[j]\n            box = w - l[3], l[2], w - l[1], l[4]\n            ioa = bbox_ioa(box, labels[:, 1:5])  # intersection over area\n            if (ioa < 0.30).all():  # allow 30% obscuration of existing labels\n                labels = np.concatenate((labels, [[l[0], *box]]), 0)\n                segments.append(np.concatenate((w - s[:, 0:1], s[:, 1:2]), 1))\n                cv2.drawContours(im_new, [segments[j].astype(np.int32)], -1, (255, 255, 255), cv2.FILLED)\n\n        result = cv2.bitwise_and(src1=im, src2=im_new)\n        result = cv2.flip(result, 1)  # augment segments (flip left-right)\n        i = result > 0  # pixels to replace\n        # i[:, :] = result.max(2).reshape(h, w, 1)  # act over ch\n        im[i] = result[i]  # cv2.imwrite('debug.jpg', im)  # debug\n\n    return im, labels, segments\n\n\ndef cutout(im, labels, p=0.5):\n    # Applies image cutout augmentation https://arxiv.org/abs/1708.04552\n    if random.random() < p:\n        h, w = im.shape[:2]\n        scales = [0.5] * 1 + [0.25] * 2 + [0.125] * 4 + [0.0625] * 8 + [0.03125] * 16  # image size fraction\n        for s in scales:\n            mask_h = random.randint(1, int(h * s))  # create random masks\n            mask_w = random.randint(1, int(w * s))\n\n            # box\n            xmin = max(0, random.randint(0, w) - mask_w // 2)\n            ymin = max(0, random.randint(0, h) - mask_h // 2)\n            xmax = min(w, xmin + mask_w)\n            ymax = min(h, ymin + mask_h)\n\n            # apply random color mask\n            im[ymin:ymax, xmin:xmax] = [random.randint(64, 191) for _ in range(3)]\n\n            # return unobscured labels\n            if len(labels) and s > 0.03:\n                box = np.array([xmin, ymin, xmax, ymax], dtype=np.float32)\n                ioa = bbox_ioa(box, labels[:, 1:5])  # intersection over area\n                labels = labels[ioa < 0.60]  # remove >60% obscured labels\n\n    return labels\n\n\ndef mixup(im, labels, im2, labels2):\n    # Applies MixUp augmentation https://arxiv.org/pdf/1710.09412.pdf\n    r = np.random.beta(32.0, 32.0)  # mixup ratio, alpha=beta=32.0\n    im = (im * r + im2 * (1 - r)).astype(np.uint8)\n    labels = np.concatenate((labels, labels2), 0)\n    return im, labels\n\n\ndef box_candidates(box1, box2, wh_thr=2, ar_thr=100, area_thr=0.1, eps=1e-16):  # box1(4,n), box2(4,n)\n    # Compute candidate boxes: box1 before augment, box2 after augment, wh_thr (pixels), aspect_ratio_thr, area_ratio\n    w1, h1 = box1[2] - box1[0], box1[3] - box1[1]\n    w2, h2 = box2[2] - box2[0], box2[3] - box2[1]\n    ar = np.maximum(w2 / (h2 + eps), h2 / (w2 + eps))  # aspect ratio\n    return (w2 > wh_thr) & (h2 > wh_thr) & (w2 * h2 / (w1 * h1 + eps) > area_thr) & (ar < ar_thr)  # candidates","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-13T18:24:45.367436Z","iopub.execute_input":"2022-02-13T18:24:45.368243Z","iopub.status.idle":"2022-02-13T18:24:45.381395Z","shell.execute_reply.started":"2022-02-13T18:24:45.368203Z","shell.execute_reply":"2022-02-13T18:24:45.380557Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Iterate over different up-sizing values to note CV at each step","metadata":{}},{"cell_type":"code","source":"def strip_optimizer(f='best.pt', s=''):  # from utils.general import *; strip_optimizer()\n    # Strip optimizer from 'f' to finalize training, optionally save as 's'\n    x = torch.load(f, map_location=torch.device('cpu'))\n    if x.get('ema'):\n        x['model'] = x['ema']  # replace model with ema\n    for k in 'optimizer', 'best_fitness', 'wandb_id', 'ema', 'updates':  # keys\n        x[k] = None\n    x['epoch'] = -1\n    x['model'].half()  # to FP16\n    for p in x['model'].parameters():\n        p.requires_grad = False\n    torch.save(x, s or f)\n    mb = os.path.getsize(s or f) / 1E6  # filesize","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:45.383177Z","iopub.execute_input":"2022-02-13T18:24:45.383508Z","iopub.status.idle":"2022-02-13T18:24:45.393169Z","shell.execute_reply.started":"2022-02-13T18:24:45.383404Z","shell.execute_reply":"2022-02-13T18:24:45.392419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"strip_optim=False\n\nif strip_optim:\n    \n    #!cp /kaggle/input/yolos6cropsbs2/*.pt /kaggle/working/\n    !cp /kaggle/input/s6-perspective/yolov5/kaggle-Reef/exp/weights/best.pt /kaggle/working/\n    #strip_optimizer('/kaggle/working/best_crops_440_736.pt' )\n    strip_optimizer('/kaggle/working/best.pt' )\nelse:\n    None\n    \n ","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:45.394247Z","iopub.execute_input":"2022-02-13T18:24:45.394434Z","iopub.status.idle":"2022-02-13T18:24:45.405896Z","shell.execute_reply.started":"2022-02-13T18:24:45.394413Z","shell.execute_reply":"2022-02-13T18:24:45.40517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"1280*4","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:45.407233Z","iopub.execute_input":"2022-02-13T18:24:45.407757Z","iopub.status.idle":"2022-02-13T18:24:45.417555Z","shell.execute_reply.started":"2022-02-13T18:24:45.407637Z","shell.execute_reply":"2022-02-13T18:24:45.416907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile /kaggle/working/yolov5/val.py\n\n# YOLOv5 🚀 by Ultralytics, GPL-3.0 license\n\"\"\"\nValidate a trained YOLOv5 model accuracy on a custom dataset\nUsage:\n    $ python path/to/val.py --weights yolov5s.pt --data coco128.yaml --img 640\nUsage - formats:\n    $ python path/to/val.py --weights yolov5s.pt                 # PyTorch\n                                      yolov5s.torchscript        # TorchScript\n                                      yolov5s.onnx               # ONNX Runtime or OpenCV DNN with --dnn\n                                      yolov5s.xml                # OpenVINO\n                                      yolov5s.engine             # TensorRT\n                                      yolov5s.mlmodel            # CoreML (MacOS-only)\n                                      yolov5s_saved_model        # TensorFlow SavedModel\n                                      yolov5s.pb                 # TensorFlow GraphDef\n                                      yolov5s.tflite             # TensorFlow Lite\n                                      yolov5s_edgetpu.tflite     # TensorFlow Edge TPU\n\"\"\"\n\nimport argparse\nimport json\nimport os\nimport sys\nfrom pathlib import Path\nfrom threading import Thread\n\nimport numpy as np\nimport torch\nfrom tqdm import tqdm\n\nFILE = Path(__file__).resolve()\nROOT = FILE.parents[0]  # YOLOv5 root directory\nif str(ROOT) not in sys.path:\n    sys.path.append(str(ROOT))  # add ROOT to PATH\nROOT = Path(os.path.relpath(ROOT, Path.cwd()))  # relative\n\nfrom models.common import DetectMultiBackend\nfrom utils.callbacks import Callbacks\nfrom utils.datasets import create_dataloader\nfrom utils.general import (LOGGER, box_iou, check_dataset, check_img_size, check_requirements, check_yaml,\n                           coco80_to_coco91_class, colorstr, increment_path, non_max_suppression, print_args,\n                           scale_coords, xywh2xyxy, xyxy2xywh)\nfrom utils.metrics import ConfusionMatrix, ap_per_class\nfrom utils.plots import output_to_target, plot_images, plot_val_study\nfrom utils.torch_utils import select_device, time_sync\nimport random\ndef seed_everything(seed: int) -> None:\n    random.seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True\nseed_everything(42)\n\ndef save_one_txt(predn, save_conf, shape, file):\n    # Save one txt result\n    gn = torch.tensor(shape)[[1, 0, 1, 0]]  # normalization gain whwh\n    for *xyxy, conf, cls in predn.tolist():\n        xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()  # normalized xywh\n        line = (cls, *xywh, conf) if save_conf else (cls, *xywh)  # label format\n        with open(file, 'a') as f:\n            f.write(('%g ' * len(line)).rstrip() % line + '\\n')\n\n\ndef save_one_json(predn, jdict, path, class_map):\n    # Save one JSON result {\"image_id\": 42, \"category_id\": 18, \"bbox\": [258.15, 41.29, 348.26, 243.78], \"score\": 0.236}\n    image_id = int(path.stem) if path.stem.isnumeric() else path.stem\n    box = xyxy2xywh(predn[:, :4])  # xywh\n    box[:, :2] -= box[:, 2:] / 2  # xy center to top-left corner\n    for p, b in zip(predn.tolist(), box.tolist()):\n        jdict.append({'image_id': image_id,\n                      'category_id': class_map[int(p[5])],\n                      'bbox': [round(x, 3) for x in b],\n                      'score': round(p[4], 5)})\n\n\ndef process_batch(detections, labels, iouv):\n    \"\"\"\n    Return correct predictions matrix. Both sets of boxes are in (x1, y1, x2, y2) format.\n    Arguments:\n        detections (Array[N, 6]), x1, y1, x2, y2, conf, class\n        labels (Array[M, 5]), class, x1, y1, x2, y2\n    Returns:\n        correct (Array[N, 10]), for 10 IoU levels\n    \"\"\"\n    correct = torch.zeros(detections.shape[0], iouv.shape[0], dtype=torch.bool, device=iouv.device)\n    iou = box_iou(labels[:, 1:], detections[:, :4])\n    x = torch.where((iou >= iouv[0]) & (labels[:, 0:1] == detections[:, 5]))  # IoU above threshold and classes match\n    if x[0].shape[0]:\n        matches = torch.cat((torch.stack(x, 1), iou[x[0], x[1]][:, None]), 1).cpu().numpy()  # [label, detection, iou]\n        if x[0].shape[0] > 1:\n            matches = matches[matches[:, 2].argsort()[::-1]]\n            matches = matches[np.unique(matches[:, 1], return_index=True)[1]]\n            # matches = matches[matches[:, 2].argsort()[::-1]]\n            matches = matches[np.unique(matches[:, 0], return_index=True)[1]]\n        matches = torch.Tensor(matches).to(iouv.device)\n        correct[matches[:, 1].long()] = matches[:, 2:3] >= iouv\n    return correct\n\n\n@torch.no_grad()\ndef run(data,\n        weights=None,  # model.pt path(s)\n        batch_size=32,  # batch size\n        imgsz=640,  # inference size (pixels)\n        conf_thres=0.001,  # confidence threshold\n        iou_thres=0.6,  # NMS IoU threshold\n        task='val',  # train, val, test, speed or study\n        device='',  # cuda device, i.e. 0 or 0,1,2,3 or cpu\n        workers=8,  # max dataloader workers (per RANK in DDP mode)\n        single_cls=False,  # treat as single-class dataset\n        augment=False,  # augmented inference\n        verbose=False,  # verbose output\n        save_txt=False,  # save results to *.txt\n        save_hybrid=False,  # save label+prediction hybrid results to *.txt\n        save_conf=False,  # save confidences in --save-txt labels\n        save_json=False,  # save a COCO-JSON results file\n        project=ROOT / 'runs/val',  # save to project/name\n        name='exp',  # save to project/name\n        exist_ok=False,  # existing project/name ok, do not increment\n        half=True,  # use FP16 half-precision inference\n        dnn=False,  # use OpenCV DNN for ONNX inference\n        model=None,\n        dataloader=None,\n        save_dir=Path(''),\n        plots=True,\n        callbacks=Callbacks(),\n        compute_loss=None,\n        ):\n    # Initialize/load model and set device\n    training = model is not None\n    if training:  # called by train.py\n        device, pt, jit, engine = next(model.parameters()).device, True, False, False  # get model device, PyTorch model\n\n        half &= device.type != 'cpu'  # half precision only supported on CUDA\n        model.half() if half else model.float()\n    else:  # called directly\n        device = select_device(device, batch_size=batch_size)\n\n        # Directories\n        save_dir = increment_path(Path(project) / name, exist_ok=exist_ok)  # increment run\n        (save_dir / 'labels' if save_txt else save_dir).mkdir(parents=True, exist_ok=True)  # make dir\n\n        # Load model\n        model = DetectMultiBackend(weights, device=device, dnn=dnn, data=data)\n        stride, pt, jit, engine = model.stride, model.pt, model.jit, model.engine\n        imgsz = check_img_size(imgsz, s=stride)  # check image size\n        half &= (pt or jit or engine) and device.type != 'cpu'  # half precision only supported by PyTorch on CUDA\n        if pt or jit:\n            model.model.half() if half else model.model.float()\n        elif engine:\n            batch_size = model.batch_size\n        else:\n            half = False\n            batch_size = 1  # export.py models default to batch-size 1\n            device = torch.device('cpu')\n            LOGGER.info(f'Forcing --batch-size 1 square inference shape(1,3,{imgsz},{imgsz}) for non-PyTorch backends')\n\n        # Data\n        data = check_dataset(data)  # check\n\n    # Configure\n    model.eval()\n    is_coco = isinstance(data.get('val'), str) and data['val'].endswith('coco/val2017.txt')  # COCO dataset\n    nc = 1 if single_cls else int(data['nc'])  # number of classes\n    iouv = torch.linspace(0.3, 0.85, 11).to(device)  # iou vector for mAP@0.5:0.95\n    #iouv=torch.tensor([0.05,0.3,0.85]).to(device) \n    niou = iouv.numel()\n    print('no of niou',niou)\n\n    # Dataloader\n    if not training:\n        model.warmup(imgsz=(1, 3, imgsz, imgsz), half=half)  # warmup\n        pad = 0.0 if task == 'speed' else 0.5\n        task = task if task in ('train', 'val', 'test') else 'val'  # path to train/val/test images\n        dataloader = create_dataloader(data[task], imgsz, batch_size, stride, single_cls, pad=pad, rect=pt,\n                                       workers=workers, prefix=colorstr(f'{task}: '))[0]\n\n    seen = 0\n    confusion_matrix = ConfusionMatrix(nc=nc)\n    names = {k: v for k, v in enumerate(model.names if hasattr(model, 'names') else model.module.names)}\n    class_map = coco80_to_coco91_class() if is_coco else list(range(1000))\n    s = ('%20s' + '%11s' * 6) % ('Class', 'Images', 'Labels', 'P', 'R', 'mAP@.5', 'mAP@.5:.95')\n    dt, p, r, f1, mp, mr, map50, map = [0.0, 0.0, 0.0], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0\n    loss = torch.zeros(3, device=device)\n    jdict, stats, ap, ap_class = [], [], [], []\n    pbar = tqdm(dataloader, desc=s, bar_format='{l_bar}{bar:10}{r_bar}{bar:-10b}')  # progress bar\n    for batch_i, (im, targets, paths, shapes) in enumerate(pbar):\n        t1 = time_sync()\n        if pt or jit or engine:\n            im = im.to(device, non_blocking=True)\n            targets = targets.to(device)\n        im = im.half() if half else im.float()  # uint8 to fp16/32\n        im /= 255  # 0 - 255 to 0.0 - 1.0\n        nb, _, height, width = im.shape  # batch size, channels, height, width\n        t2 = time_sync()\n        dt[0] += t2 - t1\n\n        # Inference\n        out, train_out = model(im) if training else model(im, augment=augment, val=True)  # inference, loss outputs\n        dt[1] += time_sync() - t2\n\n        # Loss\n        if compute_loss:\n            loss += compute_loss([x.float() for x in train_out], targets)[1]  # box, obj, cls\n\n        # NMS\n        targets[:, 2:] *= torch.Tensor([width, height, width, height]).to(device)  # to pixels\n        lb = [targets[targets[:, 0] == i, 1:] for i in range(nb)] if save_hybrid else []  # for autolabelling\n        t3 = time_sync()\n        out = non_max_suppression(out, conf_thres, iou_thres, labels=lb, multi_label=True, agnostic=single_cls)\n        dt[2] += time_sync() - t3\n\n        # Metrics\n        for si, pred in enumerate(out):\n            labels = targets[targets[:, 0] == si, 1:]\n            nl = len(labels)\n            tcls = labels[:, 0].tolist() if nl else []  # target class\n            path, shape = Path(paths[si]), shapes[si][0]\n            seen += 1\n\n            if len(pred) == 0:\n                if nl:\n                    stats.append((torch.zeros(0, niou, dtype=torch.bool), torch.Tensor(), torch.Tensor(), tcls))\n                continue\n\n            # Predictions\n            if single_cls:\n                pred[:, 5] = 0\n            predn = pred.clone()\n            scale_coords(im[si].shape[1:], predn[:, :4], shape, shapes[si][1])  # native-space pred\n\n            # Evaluate\n            if nl:\n                tbox = xywh2xyxy(labels[:, 1:5])  # target boxes\n                scale_coords(im[si].shape[1:], tbox, shape, shapes[si][1])  # native-space labels\n                labelsn = torch.cat((labels[:, 0:1], tbox), 1)  # native-space labels\n                correct = process_batch(predn, labelsn, iouv)\n                if plots:\n                    confusion_matrix.process_batch(predn, labelsn)\n            else:\n                correct = torch.zeros(pred.shape[0], niou, dtype=torch.bool)\n            stats.append((correct.cpu(), pred[:, 4].cpu(), pred[:, 5].cpu(), tcls))  # (correct, conf, pcls, tcls)\n\n            # Save/log\n            if save_txt:\n                save_one_txt(predn, save_conf, shape, file=save_dir / 'labels' / (path.stem + '.txt'))\n            if save_json:\n                save_one_json(predn, jdict, path, class_map)  # append to COCO-JSON dictionary\n            callbacks.run('on_val_image_end', pred, predn, path, names, im[si])\n\n        # Plot images\n        if plots and batch_i < 3:\n            f = save_dir / f'val_batch{batch_i}_labels.jpg'  # labels\n            Thread(target=plot_images, args=(im, targets, paths, f, names), daemon=True).start()\n            f = save_dir / f'val_batch{batch_i}_pred.jpg'  # predictions\n            Thread(target=plot_images, args=(im, output_to_target(out), paths, f, names), daemon=True).start()\n\n    # Compute metrics\n    stats = [np.concatenate(x, 0) for x in zip(*stats)]  # to numpy\n    if len(stats) and stats[0].any():\n        tp, fp, p, r, f1, ap, ap_class,f2 = ap_per_class(*stats, plot=plots, save_dir=save_dir, names=names)\n        #print('ap shape',ap.shape,ap)\n        #print('f1 shape return',f1.shape,f1,'p',p.shape)\n        print('f2 shape',f2.shape,f2,'meanf2 score',f2.mean() )\n        ap50, ap = ap[:, 0], ap.mean(1)  # AP@0.5, AP@0.5:0.95\n        #f2=f2.mean()\n        mp, mr, map50, map = p.mean(), r.mean(), ap50.mean(), ap.mean()\n        nt = np.bincount(stats[3].astype(np.int64), minlength=nc)  # number of targets per class\n    else:\n        nt = torch.zeros(1)\n        f2=torch.zeros(1)\n\n    # Print results\n    pf = '%20s' + '%11i' * 2 + '%11.3g' * 4  # print format\n    LOGGER.info(pf % ('all', seen, nt.sum(), mp, mr, map50, map ))\n\n    # Print results per class\n    if (verbose or (nc < 50 and not training)) and nc > 1 and len(stats):\n        for i, c in enumerate(ap_class):\n            LOGGER.info(pf % (names[c], seen, nt[c], p[i], r[i], ap50[i], ap[i]))\n\n    # Print speeds\n    t = tuple(x / seen * 1E3 for x in dt)  # speeds per image\n    if not training:\n        shape = (batch_size, 3, imgsz, imgsz)\n        LOGGER.info(f'Speed: %.1fms pre-process, %.1fms inference, %.1fms NMS per image at shape {shape}' % t)\n\n    # Plots\n    if plots:\n        confusion_matrix.plot(save_dir=save_dir, names=list(names.values()))\n        callbacks.run('on_val_end')\n\n    # Save JSON\n    if save_json and len(jdict):\n        w = Path(weights[0] if isinstance(weights, list) else weights).stem if weights is not None else ''  # weights\n        anno_json = str(Path(data.get('path', '../coco')) / 'annotations/instances_val2017.json')  # annotations json\n        pred_json = str(save_dir / f\"{w}_predictions.json\")  # predictions json\n        LOGGER.info(f'\\nEvaluating pycocotools mAP... saving {pred_json}...')\n        with open(pred_json, 'w') as f:\n            json.dump(jdict, f)\n\n        try:  # https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocoEvalDemo.ipynb\n            check_requirements(['pycocotools'])\n            from pycocotools.coco import COCO\n            from pycocotools.cocoeval import COCOeval\n\n            anno = COCO(anno_json)  # init annotations api\n            pred = anno.loadRes(pred_json)  # init predictions api\n            eval = COCOeval(anno, pred, 'bbox')\n            if is_coco:\n                eval.params.imgIds = [int(Path(x).stem) for x in dataloader.dataset.img_files]  # image IDs to evaluate\n            eval.evaluate()\n            eval.accumulate()\n            eval.summarize()\n            map, map50 = eval.stats[:2]  # update results (mAP@0.5:0.95, mAP@0.5)\n        except Exception as e:\n            LOGGER.info(f'pycocotools unable to run: {e}')\n\n    # Return results\n    model.float()  # for training\n    if not training:\n        s = f\"\\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir / 'labels'}\" if save_txt else ''\n        LOGGER.info(f\"Results saved to {colorstr('bold', save_dir)}{s}\")\n    maps = np.zeros(nc) + map\n    for i, c in enumerate(ap_class):\n        maps[c] = ap[i]\n    return (mp, mr, map50, map, *(loss.cpu() / len(dataloader)).tolist()), maps, t,f2.mean() \n\n\ndef parse_opt():\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--data', type=str, default=ROOT / 'data/coco128.yaml', help='dataset.yaml path')\n    parser.add_argument('--weights', nargs='+', type=str, default=ROOT / 'yolov5s.pt', help='model.pt path(s)')\n    parser.add_argument('--batch-size', type=int, default=32, help='batch size')\n    parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=640, help='inference size (pixels)')\n    parser.add_argument('--conf-thres', type=float, default=0.001, help='confidence threshold')\n    parser.add_argument('--iou-thres', type=float, default=0.6, help='NMS IoU threshold')\n    parser.add_argument('--task', default='val', help='train, val, test, speed or study')\n    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')\n    parser.add_argument('--workers', type=int, default=8, help='max dataloader workers (per RANK in DDP mode)')\n    parser.add_argument('--single-cls', action='store_true', help='treat as single-class dataset')\n    parser.add_argument('--augment', action='store_true', help='augmented inference')\n    parser.add_argument('--verbose', action='store_true', help='report mAP by class')\n    parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')\n    parser.add_argument('--save-hybrid', action='store_true', help='save label+prediction hybrid results to *.txt')\n    parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')\n    parser.add_argument('--save-json', action='store_true', help='save a COCO-JSON results file')\n    parser.add_argument('--project', default=ROOT / 'runs/val', help='save to project/name')\n    parser.add_argument('--name', default='exp', help='save to project/name')\n    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')\n    parser.add_argument('--half', action='store_true', help='use FP16 half-precision inference')\n    parser.add_argument('--dnn', action='store_true', help='use OpenCV DNN for ONNX inference')\n    opt = parser.parse_args()\n    opt.data = check_yaml(opt.data)  # check YAML\n    opt.save_json |= opt.data.endswith('coco.yaml')\n    opt.save_txt |= opt.save_hybrid\n    print_args(FILE.stem, opt)\n    return opt\n\n\ndef main(opt):\n    check_requirements(requirements=ROOT / 'requirements.txt', exclude=('tensorboard', 'thop'))\n\n    if opt.task in ('train', 'val', 'test'):  # run normally\n        if opt.conf_thres > 0.001:  # https://github.com/ultralytics/yolov5/issues/1466\n            LOGGER.info(f'WARNING: confidence threshold {opt.conf_thres} >> 0.001 will produce invalid mAP values.')\n        run(**vars(opt))\n\n    else:\n        weights = opt.weights if isinstance(opt.weights, list) else [opt.weights]\n        opt.half = True  # FP16 for fastest results\n        if opt.task == 'speed':  # speed benchmarks\n            # python val.py --task speed --data coco.yaml --batch 1 --weights yolov5n.pt yolov5s.pt...\n            opt.conf_thres, opt.iou_thres, opt.save_json = 0.25, 0.45, False\n            for opt.weights in weights:\n                run(**vars(opt), plots=False)\n\n        elif opt.task == 'study':  # speed vs mAP benchmarks\n            # python val.py --task study --data coco.yaml --iou 0.7 --weights yolov5n.pt yolov5s.pt...\n            for opt.weights in weights:\n                f = f'study_{Path(opt.data).stem}_{Path(opt.weights).stem}.txt'  # filename to save to\n                x, y = list(range(256, 1536 + 128, 128)), []  # x axis (image sizes), y axis\n                for opt.imgsz in x:  # img-size\n                    LOGGER.info(f'\\nRunning {f} --imgsz {opt.imgsz}...')\n                    r, _, t = run(**vars(opt), plots=False)\n                    y.append(r + t)  # results and times\n                np.savetxt(f, y, fmt='%10.4g')  # save\n            os.system('zip -r study.zip study_*.txt')\n            plot_val_study(x=x)  # plot\n\n\nif __name__ == \"__main__\":\n    opt = parse_opt()\n    main(opt)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-13T18:24:45.419432Z","iopub.execute_input":"2022-02-13T18:24:45.419836Z","iopub.status.idle":"2022-02-13T18:24:45.438372Z","shell.execute_reply.started":"2022-02-13T18:24:45.419801Z","shell.execute_reply":"2022-02-13T18:24:45.437385Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile  /kaggle/working/yolov5/utils/metrics.py\n\n# YOLOv5 🚀 by Ultralytics, GPL-3.0 license\n\"\"\"\nModel validation metrics\n\"\"\"\n\nimport math\nimport warnings\nfrom pathlib import Path\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport torch\n\n\ndef fitness(x):\n    # Model fitness as a weighted combination of metrics\n    w = [0.0, 0.0, 0.1, 0.35,0.55]  # weights for [P, R, mAP@0.5, mAP@0.5:0.95]\n    return (x[:, :5] * w).sum(1)\n\n\ndef ap_per_class(tp, conf, pred_cls, target_cls, plot=False, save_dir='.', names=(), eps=1e-16):\n    \"\"\" Compute the average precision, given the recall and precision curves.\n    Source: https://github.com/rafaelpadilla/Object-Detection-Metrics.\n    # Arguments\n        tp:  True positives (nparray, nx1 or nx10).\n        conf:  Objectness value from 0-1 (nparray).\n        pred_cls:  Predicted object classes (nparray).\n        target_cls:  True object classes (nparray).\n        plot:  Plot precision-recall curve at mAP@0.5\n        save_dir:  Plot save directory\n    # Returns\n        The average precision as computed in py-faster-rcnn.\n    \"\"\"\n\n    # Sort by objectness\n    i = np.argsort(-conf)\n    tp, conf, pred_cls = tp[i], conf[i], pred_cls[i]\n\n    # Find unique classes\n    unique_classes, nt = np.unique(target_cls, return_counts=True)\n    nc = unique_classes.shape[0]  # number of classes, number of detections\n\n    # Create Precision-Recall curve and compute AP for each class\n    px, py = np.linspace(0, 1, 1000), []  # for plotting\n    ap, p, r = np.zeros((nc, tp.shape[1])), np.zeros((tp.shape[1], 1000)), np.zeros((tp.shape[1], 1000))\n    f2= np.zeros((nc, tp.shape[1]))\n    #print('tpshape',tp.shape[1])\n    for ci, c in enumerate(unique_classes):\n        i = pred_cls == c\n        n_l = nt[ci]  # number of labels\n        n_p = i.sum()  # number of predictions\n\n        if n_p == 0 or n_l == 0:\n            continue\n        else:\n            # Accumulate FPs and TPs\n            fpc = (1 - tp[i]).cumsum(0)\n            tpc = tp[i].cumsum(0)\n\n            # Recall\n            recall = tpc / (n_l + eps)  # recall curve\n            for th in range(0,tp.shape[1]):\n                \n                r[th] = np.interp(-px, -conf[i], recall[:,th], left=0)  # negative x, xp because xp decreases\n            #print('recall shape',recall.shape,'r',r.shape)# 3,1000\n            # Precision\n            precision = tpc / (tpc + fpc)  # precision curve\n            for th in range(0,tp.shape[1]):\n                p[th] = np.interp(-px, -conf[i], precision[:,th], left=1)  # p at pr_score\n            #print('precision shape',precision.shape,'r',p.shape) # 3 1000\n            # AP from recall-precision curve\n            beta2 = 2 ** 2\n            for j in range(tp.shape[1]):\n                ap[ci, j], mpre, mrec = compute_ap(recall[:, j], precision[:, j])\n               \n                if plot and j == 0:\n                    py.append(np.interp(px, mrec, mpre))  # precision at mAP@0.5\n\n    # Compute F1 (harmonic mean of precision and recall)\n    f1 = 2 * p * r / (p + r + eps)\n    #print('f1 shape',f1.shape) 3,1000\n    names = [v for k, v in names.items() if k in unique_classes]  # list: only classes that have data\n    names = {i: v for i, v in enumerate(names)}  # to dict\n    if plot:\n        plot_pr_curve(px, py, ap, Path(save_dir) / 'PR_curve.png', names)\n        plot_mc_curve(px, f1[1][None,:], Path(save_dir) / 'F1_curve.png', names, ylabel='F1')\n        plot_mc_curve(px, p[1][None,:], Path(save_dir) / 'P_curve.png', names, ylabel='Precision')\n        plot_mc_curve(px, r[1][None,:], Path(save_dir) / 'R_curve.png', names, ylabel='Recall')\n\n    #i = f1.mean(0).argmax(-1)  # max F1 index\n    i = f1.argmax(-1) # get max across 1k detections\n    p, r, f1 = p[np.arange(len(p)), i], r[np.arange(len(r)), i], f1[np.arange(len(f1)), i]\n    #p=3,r  get max across all detections for three thresholds\n    denom = beta2 * p + r\n                 \n    denom[denom == 0.0] = 1  # avoid division by 0\n    f2  = ((1 + beta2) * p* r )/ denom\n    f2=f2[None,:]\n    f1=f1[1] #get 0.3 tresholds\n    \n    tp = (r * nt).round()  # true positives\n    fp = (tp / (p + eps) - tp).round()  # false positives\n    return tp[1], fp[1], p[1], r[1], f1, ap, unique_classes.astype('int32'),f2\n\n\ndef compute_ap(recall, precision):\n    \"\"\" Compute the average precision, given the recall and precision curves\n    # Arguments\n        recall:    The recall curve (list)\n        precision: The precision curve (list)\n    # Returns\n        Average precision, precision curve, recall curve\n    \"\"\"\n\n    # Append sentinel values to beginning and end\n    mrec = np.concatenate(([0.0], recall, [1.0]))\n    mpre = np.concatenate(([1.0], precision, [0.0]))\n\n    # Compute the precision envelope\n    mpre = np.flip(np.maximum.accumulate(np.flip(mpre)))\n\n    # Integrate area under curve\n    method = 'interp'  # methods: 'continuous', 'interp'\n    if method == 'interp':\n        x = np.linspace(0, 1, 101)  # 101-point interp (COCO)\n        ap = np.trapz(np.interp(x, mrec, mpre), x)  # integrate\n    else:  # 'continuous'\n        i = np.where(mrec[1:] != mrec[:-1])[0]  # points where x axis (recall) changes\n        ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1])  # area under curve\n\n    return ap, mpre, mrec\n\n\nclass ConfusionMatrix:\n    # Updated version of https://github.com/kaanakan/object_detection_confusion_matrix\n    def __init__(self, nc, conf=0.25, iou_thres=0.45):\n        self.matrix = np.zeros((nc + 1, nc + 1))\n        self.nc = nc  # number of classes\n        self.conf = conf\n        self.iou_thres = iou_thres\n\n    def process_batch(self, detections, labels):\n        \"\"\"\n        Return intersection-over-union (Jaccard index) of boxes.\n        Both sets of boxes are expected to be in (x1, y1, x2, y2) format.\n        Arguments:\n            detections (Array[N, 6]), x1, y1, x2, y2, conf, class\n            labels (Array[M, 5]), class, x1, y1, x2, y2\n        Returns:\n            None, updates confusion matrix accordingly\n        \"\"\"\n        detections = detections[detections[:, 4] > self.conf]\n        gt_classes = labels[:, 0].int()\n        detection_classes = detections[:, 5].int()\n        iou = box_iou(labels[:, 1:], detections[:, :4])\n\n        x = torch.where(iou > self.iou_thres)\n        if x[0].shape[0]:\n            matches = torch.cat((torch.stack(x, 1), iou[x[0], x[1]][:, None]), 1).cpu().numpy()\n            if x[0].shape[0] > 1:\n                matches = matches[matches[:, 2].argsort()[::-1]]\n                matches = matches[np.unique(matches[:, 1], return_index=True)[1]]\n                matches = matches[matches[:, 2].argsort()[::-1]]\n                matches = matches[np.unique(matches[:, 0], return_index=True)[1]]\n        else:\n            matches = np.zeros((0, 3))\n\n        n = matches.shape[0] > 0\n        m0, m1, _ = matches.transpose().astype(np.int16)\n        for i, gc in enumerate(gt_classes):\n            j = m0 == i\n            if n and sum(j) == 1:\n                self.matrix[detection_classes[m1[j]], gc] += 1  # correct\n            else:\n                self.matrix[self.nc, gc] += 1  # background FP\n\n        if n:\n            for i, dc in enumerate(detection_classes):\n                if not any(m1 == i):\n                    self.matrix[dc, self.nc] += 1  # background FN\n\n    def matrix(self):\n        return self.matrix\n\n    def tp_fp(self):\n        tp = self.matrix.diagonal()  # true positives\n        fp = self.matrix.sum(1) - tp  # false positives\n        # fn = self.matrix.sum(0) - tp  # false negatives (missed detections)\n        return tp[:-1], fp[:-1]  # remove background class\n\n    def plot(self, normalize=True, save_dir='', names=()):\n        try:\n            import seaborn as sn\n\n            array = self.matrix / ((self.matrix.sum(0).reshape(1, -1) + 1E-6) if normalize else 1)  # normalize columns\n            array[array < 0.005] = np.nan  # don't annotate (would appear as 0.00)\n\n            fig = plt.figure(figsize=(12, 9), tight_layout=True)\n            sn.set(font_scale=1.0 if self.nc < 50 else 0.8)  # for label size\n            labels = (0 < len(names) < 99) and len(names) == self.nc  # apply names to ticklabels\n            with warnings.catch_warnings():\n                warnings.simplefilter('ignore')  # suppress empty matrix RuntimeWarning: All-NaN slice encountered\n                sn.heatmap(array, annot=self.nc < 30, annot_kws={\"size\": 8}, cmap='Blues', fmt='.2f', square=True,\n                           xticklabels=names + ['background FP'] if labels else \"auto\",\n                           yticklabels=names + ['background FN'] if labels else \"auto\").set_facecolor((1, 1, 1))\n            fig.axes[0].set_xlabel('True')\n            fig.axes[0].set_ylabel('Predicted')\n            fig.savefig(Path(save_dir) / 'confusion_matrix.png', dpi=250)\n            plt.close()\n        except Exception as e:\n            print(f'WARNING: ConfusionMatrix plot failure: {e}')\n\n    def print(self):\n        for i in range(self.nc + 1):\n            print(' '.join(map(str, self.matrix[i])))\n\n\ndef bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False, eps=1e-7):\n    # Returns the IoU of box1 to box2. box1 is 4, box2 is nx4\n    box2 = box2.T\n\n    # Get the coordinates of bounding boxes\n    if x1y1x2y2:  # x1, y1, x2, y2 = box1\n        b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3]\n        b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3]\n    else:  # transform from xywh to xyxy\n        b1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2\n        b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2\n        b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2\n        b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2\n\n    # Intersection area\n    inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \\\n            (torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)\n\n    # Union Area\n    w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + eps\n    w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps\n    union = w1 * h1 + w2 * h2 - inter + eps\n\n    iou = inter / union\n    if CIoU or DIoU or GIoU:\n        cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)  # convex (smallest enclosing box) width\n        ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)  # convex height\n        if CIoU or DIoU:  # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1\n            c2 = cw ** 2 + ch ** 2 + eps  # convex diagonal squared\n            rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 +\n                    (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4  # center distance squared\n            if CIoU:  # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47\n                v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2)\n                with torch.no_grad():\n                    alpha = v / (v - iou + (1 + eps))\n                return iou - (rho2 / c2 + v * alpha)  # CIoU\n            return iou - rho2 / c2  # DIoU\n        c_area = cw * ch + eps  # convex area\n        return iou - (c_area - union) / c_area  # GIoU https://arxiv.org/pdf/1902.09630.pdf\n    return iou  # IoU\n\ndef box_iou(box1, box2):\n    # https://github.com/pytorch/vision/blob/master/torchvision/ops/boxes.py\n    \"\"\"\n    Return intersection-over-union (Jaccard index) of boxes.\n    Both sets of boxes are expected to be in (x1, y1, x2, y2) format.\n    Arguments:\n        box1 (Tensor[N, 4])\n        box2 (Tensor[M, 4])\n    Returns:\n        iou (Tensor[N, M]): the NxM matrix containing the pairwise\n            IoU values for every element in boxes1 and boxes2\n    \"\"\"\n\n    def box_area(box):\n        # box = 4xn\n        return (box[2] - box[0]) * (box[3] - box[1])\n\n    area1 = box_area(box1.T)\n    area2 = box_area(box2.T)\n\n    # inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2)\n    inter = (torch.min(box1[:, None, 2:], box2[:, 2:]) - torch.max(box1[:, None, :2], box2[:, :2])).clamp(0).prod(2)\n    return inter / (area1[:, None] + area2 - inter)  # iou = inter / (area1 + area2 - inter)\n\n\ndef bbox_ioa(box1, box2, eps=1E-7):\n    \"\"\" Returns the intersection over box2 area given box1, box2. Boxes are x1y1x2y2\n    box1:       np.array of shape(4)\n    box2:       np.array of shape(nx4)\n    returns:    np.array of shape(n)\n    \"\"\"\n\n    box2 = box2.transpose()\n\n    # Get the coordinates of bounding boxes\n    b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3]\n    b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3]\n\n    # Intersection area\n    inter_area = (np.minimum(b1_x2, b2_x2) - np.maximum(b1_x1, b2_x1)).clip(0) * \\\n                 (np.minimum(b1_y2, b2_y2) - np.maximum(b1_y1, b2_y1)).clip(0)\n\n    # box2 area\n    box2_area = (b2_x2 - b2_x1) * (b2_y2 - b2_y1) + eps\n\n    # Intersection over box2 area\n    return inter_area / box2_area\n\n\ndef wh_iou(wh1, wh2):\n    # Returns the nxm IoU matrix. wh1 is nx2, wh2 is mx2\n    wh1 = wh1[:, None]  # [N,1,2]\n    wh2 = wh2[None]  # [1,M,2]\n    inter = torch.min(wh1, wh2).prod(2)  # [N,M]\n    return inter / (wh1.prod(2) + wh2.prod(2) - inter)  # iou = inter / (area1 + area2 - inter)\n\n\n# Plots ----------------------------------------------------------------------------------------------------------------\n\ndef plot_pr_curve(px, py, ap, save_dir='pr_curve.png', names=()):\n    # Precision-recall curve\n    fig, ax = plt.subplots(1, 1, figsize=(9, 6), tight_layout=True)\n    py = np.stack(py, axis=1)\n\n    if 0 < len(names) < 21:  # display per-class legend if < 21 classes\n        for i, y in enumerate(py.T):\n            ax.plot(px, y, linewidth=1, label=f'{names[i]} {ap[i, 0]:.3f}')  # plot(recall, precision)\n    else:\n        ax.plot(px, py, linewidth=1, color='grey')  # plot(recall, precision)\n\n    ax.plot(px, py.mean(1), linewidth=3, color='blue', label='all classes %.3f mAP@0.5' % ap[:, 0].mean())\n    ax.set_xlabel('Recall')\n    ax.set_ylabel('Precision')\n    ax.set_xlim(0, 1)\n    ax.set_ylim(0, 1)\n    plt.legend(bbox_to_anchor=(1.04, 1), loc=\"upper left\")\n    fig.savefig(Path(save_dir), dpi=250)\n    plt.close()\n\n\ndef plot_mc_curve(px, py, save_dir='mc_curve.png', names=(), xlabel='Confidence', ylabel='Metric'):\n    # Metric-confidence curve\n    fig, ax = plt.subplots(1, 1, figsize=(9, 6), tight_layout=True)\n\n    if 0 < len(names) < 21:  # display per-class legend if < 21 classes\n        for i, y in enumerate(py):\n            ax.plot(px, y, linewidth=1, label=f'{names[i]}')  # plot(confidence, metric)\n    else:\n        ax.plot(px, py.T, linewidth=1, color='grey')  # plot(confidence, metric)\n\n    y = py.mean(0)\n    ax.plot(px, y, linewidth=3, color='blue', label=f'all classes {y.max():.2f} at {px[y.argmax()]:.3f}')\n    ax.set_xlabel(xlabel)\n    ax.set_ylabel(ylabel)\n    ax.set_xlim(0, 1)\n    ax.set_ylim(0, 1)\n    plt.legend(bbox_to_anchor=(1.04, 1), loc=\"upper left\")\n    fig.savefig(Path(save_dir), dpi=250)\n    plt.close()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-13T18:24:45.443219Z","iopub.execute_input":"2022-02-13T18:24:45.443606Z","iopub.status.idle":"2022-02-13T18:24:45.459097Z","shell.execute_reply.started":"2022-02-13T18:24:45.443579Z","shell.execute_reply":"2022-02-13T18:24:45.458171Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile /kaggle/working/yolov5/models/yolo1.py\n \n\"\"\"\nYOLO-specific modules\nUsage:\n    $ python path/to/models/yolo.py --cfg yolov5s.yaml\n\"\"\"\n\nimport argparse\nimport sys\nfrom copy import deepcopy\nfrom pathlib import Path\n\nFILE = Path(__file__).resolve()\nROOT = FILE.parents[1]  # YOLOv5 root directory\nif str(ROOT) not in sys.path:\n    sys.path.append(str(ROOT))  # add ROOT to PATH\n# ROOT = ROOT.relative_to(Path.cwd())  # relative\n\nfrom models.common import *\nfrom models.experimental import *\nfrom utils.autoanchor import check_anchor_order\nfrom utils.general import LOGGER, check_version, check_yaml, make_divisible, print_args\nfrom utils.plots import feature_visualization\nfrom utils.torch_utils import fuse_conv_and_bn, initialize_weights, model_info, scale_img, select_device, time_sync\n\ntry:\n    import thop  # for FLOPs computation\nexcept ImportError:\n    thop = None\n\n\nclass Detect(nn.Module):\n    stride = None  # strides computed during build\n    onnx_dynamic = False  # ONNX export parameter\n\n    def __init__(self, nc=80, anchors=(), ch=(), inplace=True):  # detection layer\n        super().__init__()\n        self.nc = nc  # number of classes\n        self.no = nc + 5  # number of outputs per anchor\n        self.nl = len(anchors)  # number of detection layers\n        self.na = len(anchors[0]) // 2  # number of anchors\n        self.grid = [torch.zeros(1)] * self.nl  # init grid\n        self.anchor_grid = [torch.zeros(1)] * self.nl  # init anchor grid\n        self.register_buffer('anchors', torch.tensor(anchors).float().view(self.nl, -1, 2))  # shape(nl,na,2)\n        self.m = nn.ModuleList(nn.Conv2d(x, self.no * self.na, 1) for x in ch)  # output conv\n        self.inplace = inplace  # use in-place ops (e.g. slice assignment)\n\n    def forward(self, x):\n        z = []  # inference output\n        for i in range(self.nl):\n            x[i] = self.m[i](x[i])  # conv\n            bs, _, ny, nx = x[i].shape  # x(bs,255,20,20) to x(bs,3,20,20,85)\n            x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()\n\n            if not self.training:  # inference\n                if self.onnx_dynamic or self.grid[i].shape[2:4] != x[i].shape[2:4]:\n                    self.grid[i], self.anchor_grid[i] = self._make_grid(nx, ny, i)\n\n                y = x[i].sigmoid()\n                if self.inplace:\n                    y[..., 0:2] = (y[..., 0:2] * 2 - 0.5 + self.grid[i]) * self.stride[i]  # xy\n                    y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # wh\n                else:  # for YOLOv5 on AWS Inferentia https://github.com/ultralytics/yolov5/pull/2953\n                    xy = (y[..., 0:2] * 2 - 0.5 + self.grid[i]) * self.stride[i]  # xy\n                    wh = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i]  # wh\n                    y = torch.cat((xy, wh, y[..., 4:]), -1)\n                z.append(y.view(bs, -1, self.no))\n\n        return x if self.training else (torch.cat(z, 1), x)\n\n    def _make_grid(self, nx=20, ny=20, i=0):\n        d = self.anchors[i].device\n        if check_version(torch.__version__, '1.10.0'):  # torch>=1.10.0 meshgrid workaround for torch>=0.7 compatibility\n            yv, xv = torch.meshgrid([torch.arange(ny, device=d), torch.arange(nx, device=d)], indexing='ij')\n        else:\n            yv, xv = torch.meshgrid([torch.arange(ny, device=d), torch.arange(nx, device=d)])\n        grid = torch.stack((xv, yv), 2).expand((1, self.na, ny, nx, 2)).float()\n        anchor_grid = (self.anchors[i].clone() * self.stride[i]) \\\n            .view((1, self.na, 1, 1, 2)).expand((1, self.na, ny, nx, 2)).float()\n        return grid, anchor_grid\n\n\nclass Model(nn.Module):\n    def __init__(self, cfg='yolov5s.yaml', ch=3, nc=None, anchors=None):  # model, input channels, number of classes\n        super().__init__()\n        if isinstance(cfg, dict):\n            self.yaml = cfg  # model dict\n        else:  # is *.yaml\n            import yaml  # for torch hub\n            self.yaml_file = Path(cfg).name\n            with open(cfg, encoding='ascii', errors='ignore') as f:\n                self.yaml = yaml.safe_load(f)  # model dict\n\n        # Define model\n        ch = self.yaml['ch'] = self.yaml.get('ch', ch)  # input channels\n        if nc and nc != self.yaml['nc']:\n            LOGGER.info(f\"Overriding model.yaml nc={self.yaml['nc']} with nc={nc}\")\n            self.yaml['nc'] = nc  # override yaml value\n        if anchors:\n            LOGGER.info(f'Overriding model.yaml anchors with anchors={anchors}')\n            self.yaml['anchors'] = round(anchors)  # override yaml value\n        self.model, self.save = parse_model(deepcopy(self.yaml), ch=[ch])  # model, savelist\n        self.names = [str(i) for i in range(self.yaml['nc'])]  # default names\n        self.inplace = self.yaml.get('inplace', True)\n\n        # Build strides, anchors\n        m = self.model[-1]  # Detect()\n        if isinstance(m, Detect):\n            s = 256  # 2x min stride\n            m.inplace = self.inplace\n            m.stride = torch.tensor([s / x.shape[-2] for x in self.forward(torch.zeros(1, ch, s, s))])  # forward\n            m.anchors /= m.stride.view(-1, 1, 1)\n            check_anchor_order(m)\n            self.stride = m.stride\n            self._initialize_biases()  # only run once\n\n        # Init weights, biases\n        initialize_weights(self)\n        self.info()\n        LOGGER.info('')\n\n    def forward(self, x, augment=False, profile=False, visualize=False):\n        if augment:\n            return self._forward_augment(x)  # augmented inference, None\n        return self._forward_once(x, profile, visualize)  # single-scale inference, train\n\n    def _forward_augment(self, x):\n        img_size = x.shape[-2:]  # height, width\n        s = [1, 0.83, 0.67]  # scales\n        #s = [1, 0.72]  # scales\n        f = [None, 3, None]  # flips (2-ud, 3-lr)\n        y = []  # outputs\n        for si, fi in zip(s, f):\n            xi = scale_img(x.flip(fi) if fi else x, si, gs=int(self.stride.max()))\n            yi = self._forward_once(xi)[0]  # forward\n            # cv2.imwrite(f'img_{si}.jpg', 255 * xi[0].cpu().numpy().transpose((1, 2, 0))[:, :, ::-1])  # save\n            yi = self._descale_pred(yi, fi, si, img_size)\n            y.append(yi)\n        y = self._clip_augmented(y)  # clip augmented tails\n        return torch.cat(y, 1), None  # augmented inference, train\n\n    def _forward_once(self, x, profile=False, visualize=False):\n        y, dt = [], []  # outputs\n        for m in self.model:\n            if m.f != -1:  # if not from previous layer\n                x = y[m.f] if isinstance(m.f, int) else [x if j == -1 else y[j] for j in m.f]  # from earlier layers\n            if profile:\n                self._profile_one_layer(m, x, dt)\n            x = m(x)  # run\n            y.append(x if m.i in self.save else None)  # save output\n            if visualize:\n                feature_visualization(x, m.type, m.i, save_dir=visualize)\n        return x\n\n    def _descale_pred(self, p, flips, scale, img_size):\n        # de-scale predictions following augmented inference (inverse operation)\n        if self.inplace:\n            p[..., :4] /= scale  # de-scale\n            if flips == 2:\n                p[..., 1] = img_size[0] - p[..., 1]  # de-flip ud\n            elif flips == 3:\n                p[..., 0] = img_size[1] - p[..., 0]  # de-flip lr\n        else:\n            x, y, wh = p[..., 0:1] / scale, p[..., 1:2] / scale, p[..., 2:4] / scale  # de-scale\n            if flips == 2:\n                y = img_size[0] - y  # de-flip ud\n            elif flips == 3:\n                x = img_size[1] - x  # de-flip lr\n            p = torch.cat((x, y, wh, p[..., 4:]), -1)\n        return p\n\n    def _clip_augmented(self, y):\n        # Clip YOLOv5 augmented inference tails\n        nl = self.model[-1].nl  # number of detection layers (P3-P5)\n        g = sum(4 ** x for x in range(nl))  # grid points\n        e = 1  # exclude layer count\n        i = (y[0].shape[1] // g) * sum(4 ** x for x in range(e))  # indices\n        y[0] = y[0][:, :-i]  # large\n        i = (y[-1].shape[1] // g) * sum(4 ** (nl - 1 - x) for x in range(e))  # indices\n        y[-1] = y[-1][:, i:]  # small\n        return y\n\n    def _profile_one_layer(self, m, x, dt):\n        c = isinstance(m, Detect)  # is final layer, copy input as inplace fix\n        o = thop.profile(m, inputs=(x.copy() if c else x,), verbose=False)[0] / 1E9 * 2 if thop else 0  # FLOPs\n        t = time_sync()\n        for _ in range(10):\n            m(x.copy() if c else x)\n        dt.append((time_sync() - t) * 100)\n        if m == self.model[0]:\n            LOGGER.info(f\"{'time (ms)':>10s} {'GFLOPs':>10s} {'params':>10s}  {'module'}\")\n        LOGGER.info(f'{dt[-1]:10.2f} {o:10.2f} {m.np:10.0f}  {m.type}')\n        if c:\n            LOGGER.info(f\"{sum(dt):10.2f} {'-':>10s} {'-':>10s}  Total\")\n\n    def _initialize_biases(self, cf=None):  # initialize biases into Detect(), cf is class frequency\n        # https://arxiv.org/abs/1708.02002 section 3.3\n        # cf = torch.bincount(torch.tensor(np.concatenate(dataset.labels, 0)[:, 0]).long(), minlength=nc) + 1.\n        m = self.model[-1]  # Detect() module\n        for mi, s in zip(m.m, m.stride):  # from\n            b = mi.bias.view(m.na, -1)  # conv.bias(255) to (3,85)\n            b.data[:, 4] += math.log(8 / (640 / s) ** 2)  # obj (8 objects per 640 image)\n            b.data[:, 5:] += math.log(0.6 / (m.nc - 0.999999)) if cf is None else torch.log(cf / cf.sum())  # cls\n            mi.bias = torch.nn.Parameter(b.view(-1), requires_grad=True)\n\n    def _print_biases(self):\n        m = self.model[-1]  # Detect() module\n        for mi in m.m:  # from\n            b = mi.bias.detach().view(m.na, -1).T  # conv.bias(255) to (3,85)\n            LOGGER.info(\n                ('%6g Conv2d.bias:' + '%10.3g' * 6) % (mi.weight.shape[1], *b[:5].mean(1).tolist(), b[5:].mean()))\n\n    # def _print_weights(self):\n    #     for m in self.model.modules():\n    #         if type(m) is Bottleneck:\n    #             LOGGER.info('%10.3g' % (m.w.detach().sigmoid() * 2))  # shortcut weights\n\n    def fuse(self):  # fuse model Conv2d() + BatchNorm2d() layers\n        LOGGER.info('Fusing layers... ')\n        for m in self.model.modules():\n            if isinstance(m, (Conv, DWConv)) and hasattr(m, 'bn'):\n                m.conv = fuse_conv_and_bn(m.conv, m.bn)  # update conv\n                delattr(m, 'bn')  # remove batchnorm\n                m.forward = m.forward_fuse  # update forward\n        self.info()\n        return self\n\n    def info(self, verbose=False, img_size=640):  # print model information\n        model_info(self, verbose, img_size)\n\n    def _apply(self, fn):\n        # Apply to(), cpu(), cuda(), half() to model tensors that are not parameters or registered buffers\n        self = super()._apply(fn)\n        m = self.model[-1]  # Detect()\n        if isinstance(m, Detect):\n            m.stride = fn(m.stride)\n            m.grid = list(map(fn, m.grid))\n            if isinstance(m.anchor_grid, list):\n                m.anchor_grid = list(map(fn, m.anchor_grid))\n        return self\n\n\ndef parse_model(d, ch):  # model_dict, input_channels(3)\n    LOGGER.info(f\"\\n{'':>3}{'from':>18}{'n':>3}{'params':>10}  {'module':<40}{'arguments':<30}\")\n    anchors, nc, gd, gw = d['anchors'], d['nc'], d['depth_multiple'], d['width_multiple']\n    na = (len(anchors[0]) // 2) if isinstance(anchors, list) else anchors  # number of anchors\n    no = na * (nc + 5)  # number of outputs = anchors * (classes + 5)\n\n    layers, save, c2 = [], [], ch[-1]  # layers, savelist, ch out\n    for i, (f, n, m, args) in enumerate(d['backbone'] + d['head']):  # from, number, module, args\n        m = eval(m) if isinstance(m, str) else m  # eval strings\n        for j, a in enumerate(args):\n            try:\n                args[j] = eval(a) if isinstance(a, str) else a  # eval strings\n            except NameError:\n                pass\n\n        n = n_ = max(round(n * gd), 1) if n > 1 else n  # depth gain\n        if m in [Conv, GhostConv, Bottleneck, GhostBottleneck, SPP, SPPF, DWConv, MixConv2d, Focus, CrossConv,\n                 BottleneckCSP, C3, C3TR, C3SPP, C3Ghost]:\n            c1, c2 = ch[f], args[0]\n            if c2 != no:  # if not output\n                c2 = make_divisible(c2 * gw, 8)\n\n            args = [c1, c2, *args[1:]]\n            if m in [BottleneckCSP, C3, C3TR, C3Ghost]:\n                args.insert(2, n)  # number of repeats\n                n = 1\n        elif m is nn.BatchNorm2d:\n            args = [ch[f]]\n        elif m is Concat:\n            c2 = sum(ch[x] for x in f)\n        elif m is Detect:\n            args.append([ch[x] for x in f])\n            if isinstance(args[1], int):  # number of anchors\n                args[1] = [list(range(args[1] * 2))] * len(f)\n        elif m is Contract:\n            c2 = ch[f] * args[0] ** 2\n        elif m is Expand:\n            c2 = ch[f] // args[0] ** 2\n        else:\n            c2 = ch[f]\n\n        m_ = nn.Sequential(*(m(*args) for _ in range(n))) if n > 1 else m(*args)  # module\n        t = str(m)[8:-2].replace('__main__.', '')  # module type\n        np = sum(x.numel() for x in m_.parameters())  # number params\n        m_.i, m_.f, m_.type, m_.np = i, f, t, np  # attach index, 'from' index, type, number params\n        LOGGER.info(f'{i:>3}{str(f):>18}{n_:>3}{np:10.0f}  {t:<40}{str(args):<30}')  # print\n        save.extend(x % i for x in ([f] if isinstance(f, int) else f) if x != -1)  # append to savelist\n        layers.append(m_)\n        if i == 0:\n            ch = []\n        ch.append(c2)\n    return nn.Sequential(*layers), sorted(save)\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--cfg', type=str, default='yolov5s.yaml', help='model.yaml')\n    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')\n    parser.add_argument('--profile', action='store_true', help='profile model speed')\n    parser.add_argument('--test', action='store_true', help='test all yolo*.yaml')\n    opt = parser.parse_args()\n    opt.cfg = check_yaml(opt.cfg)  # check YAML\n    print_args(FILE.stem, opt)\n    device = select_device(opt.device)\n\n    # Create model\n    model = Model(opt.cfg).to(device)\n    model.train()\n\n    # Profile\n    if opt.profile:\n        img = torch.rand(8 if torch.cuda.is_available() else 1, 3, 640, 640).to(device)\n        y = model(img, profile=True)\n\n    # Test all models\n    if opt.test:\n        for cfg in Path(ROOT / 'models').rglob('yolo*.yaml'):\n            try:\n                _ = Model(cfg)\n            except Exception as e:\n                print(f'Error in {cfg}: {e}')\n\n    # Tensorboard (not working https://github.com/ultralytics/yolov5/issues/2898)\n    # from torch.utils.tensorboard import SummaryWriter\n    # tb_writer = SummaryWriter('.')\n    # LOGGER.info(\"Run 'tensorboard --logdir=models' to view tensorboard at http://localhost:6006/\")\n    # tb_writer.add_graph(torch.jit.trace(model, img, strict=False), [])  # add model graph\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-02-13T19:09:56.267957Z","iopub.execute_input":"2022-02-13T19:09:56.268435Z","iopub.status.idle":"2022-02-13T19:09:56.302728Z","shell.execute_reply.started":"2022-02-13T19:09:56.26839Z","shell.execute_reply":"2022-02-13T19:09:56.302054Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm -rf '/kaggle/working/yolov5/runs/val/exp/labels/'","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:24:45.480745Z","iopub.execute_input":"2022-02-13T18:24:45.481285Z","iopub.status.idle":"2022-02-13T18:24:46.145663Z","shell.execute_reply.started":"2022-02-13T18:24:45.481254Z","shell.execute_reply":"2022-02-13T18:24:46.144707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CV=True\nweights='/kaggle/input/cots-d9993-101-20220122032936/D9993-101-barrier-reef-yolov5-training-upsize-4000/best.pt'\nweights='/kaggle/input/yolos6tiles/yolov5/kaggle-Reef/exp/weights/best.pt'\nweights='/kaggle/working/best_crops_440_736.pt' #66-67\nweights='/kaggle/working/best_rect_67_enriched.pt'\nweights='/kaggle/input/barrier-reef-yolov5-training-subseq/yolov5/kaggle-Reef/exp/weights/best.pt'\nweights='/kaggle/input/barrier-reef-yolov5-subseq-area-rohit-perspective/yolov5/kaggle-Reef/exp/weights/last.pt'\n#weights='/kaggle/input/barrier-reef-yolov5-subseq-area/yolov5/kaggle-Reef/exp/weights/best.pt'\n#weights='/kaggle/input/barrier-reef-yolov5-subseq-area-nocp/yolov5/kaggle-Reef/exp/weights/best.pt'\n#weights='/kaggle/working/best.pt' #66-67\nimage_id_score={}\nfalse_neg={}\nfalse_pos={}\ntrue_neg={}\nif CV:\n    for i in [ 3600,4200]:\n\n        print(\"#######################################\\n\"*3, f'Starting Inference for image size {i}')\n        start_time = time.time()\n        !rm -rf /kaggle/working/yolov5/runs/val/exp/labels/ \n        !python val.py --data /kaggle/working/yolov5/data/reef_f1_naive.yaml\\\n            --weights {weights} \\\n            --imgsz $i\\\n            --batch 8\\\n            --conf-thres 0.1\\\n            --iou-thres 0.3\\\n            --save-txt\\\n            --augment \\\n            --save-conf\\\n            --exist-ok\n         \n        t=(time.time() - start_time)/60\n        print(f'Inference Complete in {t:.3f} minutes')\n        print('Starting Cross Validation')\n        start_time = time.time()\n        scores = []\n        for j in range(15,30,3):\n            confidence=j/100\n            gt_bboxs_list, prd_bboxs_list = [], []\n\n            count=0\n            count_fp=0\n            count_true_neg=0\n            for image_file in paths:\n                gt_bboxs = []; prd_bboxs = []\n                with open(image_file, 'r') as f:\n                    while True:\n                        r = f.readline().rstrip()\n                        if not r: break\n                        r = r.split()[1:]\n                        bbox = np.array(list(map(float, r))) \n                        gt_bboxs.append(bbox)\n\n                pred_path = '/kaggle/working/yolov5/runs/val/exp/labels/'\n                #pred_path = '/kaggle/input/eda-model-cv-check/yolov5/runs/val/exp/labels/'\n\n                pred_file = pred_path+image_file[43:]\n                \n                no_anns = True\n                if os.path.exists(pred_file):\n                    with open(pred_file, 'r') as f:\n                        while True:\n                            r = f.readline().rstrip()\n                            if not r: \n                                break\n                            r = r.split()[1:] \n                            r = [r[4], *r[:4]]\n                            conf=float(r[0])\n                            if conf>confidence: \n                                bbox = np.array(list(map(float, r)))\n                                if (bbox[3]*bbox[4]*720*1280)<50     :\n                                    #bbox[3]=bbox[3]*0.97\n                                    bbox[4]=bbox[4]*1.04\n                                    #bbox[1]=bbox[1]*1.04\n                                    bbox[2]=bbox[2]*1.02\n                                    #print('area',(bbox[3]*bbox[4]*720*1280))\n                                prd_bboxs.append(bbox)\n                                no_anns = False\n\n                if no_anns and len(gt_bboxs)!=0: \n                    false_neg[image_file[43:]]=image_file[43:]\n                    count+=1\n                if no_anns and len(gt_bboxs)==0: \n                    #false_neg[image_file[43:]]=image_file[43:]\n                    count_true_neg+=1\n                if not no_anns and len(gt_bboxs)==0: \n                    false_pos[image_file[43:]]=image_file[43:]\n                    count_fp+=1\n                if True:\n                     \n                    gt_bboxs, prd_bboxs= np.array(gt_bboxs), np.array(prd_bboxs) \n                    #if len(gt_bboxs)==0:\n                    #    gt_bboxs=np.array([[0,0,0,0]])\n                    prd_bboxs_list.append(prd_bboxs) \n                    gt_bboxs_list.append(gt_bboxs)\n                    image_id_score[image_file[43:]]=calc_f2_score([gt_bboxs], [prd_bboxs], verbose=False)\n\n            score = calc_f2_score(gt_bboxs_list, prd_bboxs_list, verbose=False)\n            scores.append([score, confidence, count])\n            if confidence%5: \n                print(f'confidence: {confidence}, images w/o anns: {count},tn count: {count_true_neg} fp count : {count_fp} total: {val_len}')\n                \n\n        best = max(scores)\n        print(f'best confidence: {best[1]}, images w/o anns: {best[2]}, total: {val_len}')\n        print(f'img size: {i}, f2 score: {best[0]}') \n        t=(time.time() - start_time)/60\n        print(f'cross validation complete in {t:.3f} minutes')\n        torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2022-02-13T19:10:07.983938Z","iopub.execute_input":"2022-02-13T19:10:07.984411Z","iopub.status.idle":"2022-02-13T19:10:59.040986Z","shell.execute_reply.started":"2022-02-13T19:10:07.984375Z","shell.execute_reply":"2022-02-13T19:10:59.039868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Seems like upsizing during inference might be causing some kind of overfit to Public LB but more experimentation (with your own augmentations) is required. \n\nYou can also use this notebook to estimate your inference time on hidden test set by multiplying time by 12500/[size of your validation folder]. For image size 3600 and val folder size 884, this came out to 1.5 hours which matched inference time on LB submission\n","metadata":{}},{"cell_type":"code","source":"#image_id_score[image_file[43:]]=calc_f2_score([gt_bboxs], [prd_bboxs], verbose=False) \n#image_id_score","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:28.305116Z","iopub.execute_input":"2022-02-10T18:46:28.305378Z","iopub.status.idle":"2022-02-10T18:46:28.309573Z","shell.execute_reply.started":"2022-02-10T18:46:28.305347Z","shell.execute_reply":"2022-02-10T18:46:28.30881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#!ls -l /kaggle/working/yolov5/runs/val/exp/labels/\n \ntry:\n    no_anns = True\n    pred_file='/kaggle/input/eda-model-cv-check/yolov5/runs/val/exp/labels/0-105.txt'\n    if os.path.exists(pred_file):\n        with open(pred_file, 'r') as f:\n            while True:\n                r = f.readline().rstrip()\n                if not r: \n                    break\n                print(r)\n                r = r.split()[1:]; r = [r[4], *r[:4]]\n                conf=float(r[0])\n                print(conf)\n                if conf>0.15: \n                    bbox = np.array(list(map(float, r)))\n                    prd_bboxs.append(bbox)\n                    no_anns = False\nexcept Exception as e:\n    print(e)","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:28.310654Z","iopub.execute_input":"2022-02-10T18:46:28.310857Z","iopub.status.idle":"2022-02-10T18:46:28.322419Z","shell.execute_reply.started":"2022-02-10T18:46:28.310831Z","shell.execute_reply":"2022-02-10T18:46:28.321913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#ls '/kaggle/working/yolov5/runs/val/exp/labels/'\n\n0.0195456*0.0316366\n ","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:28.323489Z","iopub.execute_input":"2022-02-10T18:46:28.323847Z","iopub.status.idle":"2022-02-10T18:46:28.334295Z","shell.execute_reply.started":"2022-02-10T18:46:28.323805Z","shell.execute_reply":"2022-02-10T18:46:28.333356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(false_pos)","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:28.335326Z","iopub.execute_input":"2022-02-10T18:46:28.33582Z","iopub.status.idle":"2022-02-10T18:46:28.345717Z","shell.execute_reply.started":"2022-02-10T18:46:28.335787Z","shell.execute_reply":"2022-02-10T18:46:28.344963Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_df_score=pd.DataFrame.from_dict(image_id_score, orient='index').reset_index()\npred_df_score.columns=['image_id','iou']\nif len(false_pos)!=0:\n    \n    false_pos_df=pd.DataFrame.from_dict(false_pos, orient='index').reset_index(drop=True)\n    false_pos_df.columns=['image_id' ]\n    false_pos_df.to_csv('/kaggle/working/false_pos_df.csv',index=False)\n\nfalse_neg_df=pd.DataFrame.from_dict(false_neg, orient='index').reset_index(drop=True)\nfalse_neg_df.columns=['image_id' ]","metadata":{"execution":{"iopub.status.busy":"2022-02-13T19:13:47.776395Z","iopub.execute_input":"2022-02-13T19:13:47.77685Z","iopub.status.idle":"2022-02-13T19:13:47.786812Z","shell.execute_reply.started":"2022-02-13T19:13:47.776812Z","shell.execute_reply":"2022-02-13T19:13:47.786105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_bbox_wh(annots):\n    #print(annots)\n    bboxes = [list(annot.values())[2]* list(annot.values())[3] for annot in annots]\n    return np.median(bboxes)\ndf = pd.read_csv(\"/kaggle/input/tensorflow-great-barrier-reef/train.csv\")\ndf['annotations'] = df['annotations'].apply(eval)\ndf['mean_area'] = df.annotations.progress_apply(get_bbox_wh)\ndf['area_label']=pd.cut(df.mean_area, bins=[    -1.,0,1500,2500,3500,4500,  6956., 10434., 13912., 17390., 20868., 24346.,\n        27824., 31302., 34780., 38258., 41736., 45214., 48692., 52170.],\n      labels=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18])","metadata":{"execution":{"iopub.status.busy":"2022-02-13T18:47:07.06864Z","iopub.execute_input":"2022-02-13T18:47:07.069217Z","iopub.status.idle":"2022-02-13T18:47:08.276872Z","shell.execute_reply.started":"2022-02-13T18:47:07.06918Z","shell.execute_reply":"2022-02-13T18:47:08.276112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_df_score.to_csv('/kaggle/working/pred_df_score.csv',index=False)\n\nfalse_neg_df.to_csv('/kaggle/working/false_neg_df.csv',index=False)\n","metadata":{"execution":{"iopub.status.busy":"2022-02-13T19:13:55.777552Z","iopub.execute_input":"2022-02-13T19:13:55.778397Z","iopub.status.idle":"2022-02-13T19:13:55.786531Z","shell.execute_reply.started":"2022-02-13T19:13:55.778348Z","shell.execute_reply":"2022-02-13T19:13:55.785709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_df=pd.read_csv('/kaggle/working/pred_df_score.csv')\n\npred_df['image_id']=pred_df.image_id.apply(lambda  x:x.split('.')[0])\npred_df['label']=-1\npred_df['label']=pred_df['image_id'].apply(lambda x: df[df.image_id==x].area_label.values[0] )\npred_df.groupby('label').iou.mean()","metadata":{"execution":{"iopub.status.busy":"2022-02-13T19:13:58.757526Z","iopub.execute_input":"2022-02-13T19:13:58.758316Z","iopub.status.idle":"2022-02-13T19:13:59.367345Z","shell.execute_reply.started":"2022-02-13T19:13:58.758269Z","shell.execute_reply":"2022-02-13T19:13:59.366572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! rm -rf /kaggle/working/yolo_data","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:28.378184Z","iopub.execute_input":"2022-02-10T18:46:28.381026Z","iopub.status.idle":"2022-02-10T18:46:29.8414Z","shell.execute_reply.started":"2022-02-10T18:46:28.38098Z","shell.execute_reply":"2022-02-10T18:46:29.840393Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_bbox(annots):\n    #print(annots)\n    bboxes = [list(annot.values()) for annot in annots]\n    return bboxes\n\ndef get_bbox_wh(annots):\n    #print(annots)\n    bboxes = [list(annot.values())[2]* list(annot.values())[3] for annot in annots]\n    return np.median(bboxes)\n\ndef get_bbox_w(annots):\n    #print(annots)\n    bboxes = [list(annot.values())[2]  for annot in annots]\n    return np.median(bboxes)\n\ndef get_bbox_h(annots):\n    #print(annots)\n    bboxes = [list(annot.values())[3]  for annot in annots]\n    return np.median(bboxes)\ndef get_path(row):\n    row['image_path'] = f'{TRAIN_PATH}/train_images/video_{row.video_id}/{row.video_frame}.jpg'\n    return row\ndef load_image(image_path):\n    return cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB)\n\ndef coco2yolo(image_height, image_width, bboxes):\n    \"\"\"\n    coco => [xmin, ymin, w, h]\n    yolo => [xmid, ymid, w, h] (normalized)\n    \"\"\"\n    \n    bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n    \n    # normolizinig\n    bboxes[..., [0, 2]]= bboxes[..., [0, 2]]/ image_width\n    bboxes[..., [1, 3]]= bboxes[..., [1, 3]]/ image_height\n    \n    # converstion (xmin, ymin) => (xmid, ymid)\n    bboxes[..., [0, 1]] = bboxes[..., [0, 1]] + bboxes[..., [2, 3]]/2\n    \n    return bboxes\n\ndef yolo2coco(image_height, image_width, bboxes):\n    \"\"\"\n    yolo => [xmid, ymid, w, h] (normalized)\n    coco => [xmin, ymin, w, h]\n    \n    \"\"\" \n    bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n    \n    # denormalizing\n    bboxes[..., [0, 2]]= bboxes[..., [0, 2]]* image_width\n    bboxes[..., [1, 3]]= bboxes[..., [1, 3]]* image_height\n    \n    # converstion (xmid, ymid) => (xmin, ymin) \n    bboxes[..., [0, 1]] = bboxes[..., [0, 1]] - bboxes[..., [2, 3]]/2\n    \n    return bboxes\ndef plot_one_box(x, img, color=None, label=None, line_thickness=None):\n    # Plots one bounding box on image img\n    tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1  # line/font thickness\n    color = color or [random.randint(0, 255) for _ in range(3)]\n    c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))\n    cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)\n    if label:\n        tf = max(tl - 1, 1)  # font thickness\n        t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]\n        c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3\n        cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)  # filled\n        cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [0, 0, 255], thickness=tf, lineType=cv2.LINE_AA)\n\n\n\ndef draw_bboxes(img, bboxes, classes, class_ids, colors = None, show_classes = None, bbox_format = 'yolo', class_name = False, line_thickness = 2):  \n    image = img.copy()\n    show_classes = classes if show_classes is None else show_classes\n    colors = (0, 255 ,0) if colors is None else colors\n    \n    if bbox_format == 'yolo':\n        \n        for idx in range(len(bboxes)):  \n            \n            bbox  = bboxes[idx]\n            cls   = classes[idx]\n            cls_id = class_ids[idx]\n            color = colors[cls_id] if type(colors) is list else colors\n            \n            if cls in show_classes:\n            \n                x1 = round(float(bbox[0])*image.shape[1])\n                y1 = round(float(bbox[1])*image.shape[0])\n                w  = round(float(bbox[2])*image.shape[1]/2) #w/2 \n                h  = round(float(bbox[3])*image.shape[0]/2)\n                print('Area of box',w*h)\n                voc_bbox = (x1-w, y1-h, x1+2*w, y1+2*h)#correction\n                #print('voc',voc_bbox,w,h)\n                plot_one_box(voc_bbox, \n                             image,\n                             color = color,\n                             label = cls if class_name else str(get_label(cls)),\n                             line_thickness = line_thickness)\n            \n    elif bbox_format == 'coco':\n        \n        for idx in range(len(bboxes)):  \n            \n            bbox  = bboxes[idx]\n            cls   = classes[idx]\n            cls_id = class_ids[idx]\n            color = colors[cls_id] if type(colors) is list else colors\n            \n            if cls in show_classes:            \n                x1 = int(round(bbox[0]))\n                y1 = int(round(bbox[1]))\n                w  = int(round(bbox[2]))\n                h  = int(round(bbox[3]))\n\n                voc_bbox = (x1, y1, x1+w, y1+h)\n                plot_one_box(voc_bbox, \n                             image,\n                             color = color,\n                             label = cls if class_name else str(cls_id),\n                             line_thickness = line_thickness)\n\n    elif bbox_format == 'voc_pascal':\n        \n        for idx in range(len(bboxes)):  \n            \n            bbox  = bboxes[idx]\n            cls   = classes[idx]\n            cls_id = class_ids[idx]\n            color = colors[cls_id] if type(colors) is list else colors\n            \n            if cls in show_classes: \n                x1 = int(round(bbox[0]))\n                y1 = int(round(bbox[1]))\n                x2 = int(round(bbox[2]))\n                y2 = int(round(bbox[3]))\n                voc_bbox = (x1, y1, x2, y2)\n                plot_one_box(voc_bbox, \n                             image,\n                             color = color,\n                             label = cls if class_name else str(cls_id),\n                             line_thickness = line_thickness)\n    else:\n        raise ValueError('wrong bbox format')\n\n    return image\n\nnp.random.seed(8)\ncolors = (np.random.randint(0, 255), np.random.randint(0, 255), np.random.randint(0, 255))\ncolors=(255,0,0)","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:29.843554Z","iopub.execute_input":"2022-02-10T18:46:29.843907Z","iopub.status.idle":"2022-02-10T18:46:29.884642Z","shell.execute_reply.started":"2022-02-10T18:46:29.843849Z","shell.execute_reply":"2022-02-10T18:46:29.883648Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.set_option(\"display.max_rows\", 500)","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:29.889658Z","iopub.execute_input":"2022-02-10T18:46:29.890188Z","iopub.status.idle":"2022-02-10T18:46:29.900705Z","shell.execute_reply.started":"2022-02-10T18:46:29.890151Z","shell.execute_reply":"2022-02-10T18:46:29.8999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" #!cat /kaggle/working/yolov5/runs/val/exp/labels/1-1963.txt\n#false_neg=pd.read_csv('/kaggle/input/eda-model-cv-check/false_neg_df.csv').sort_values(by='image_id')\n#false_neg[0:200]","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:29.901966Z","iopub.execute_input":"2022-02-10T18:46:29.902263Z","iopub.status.idle":"2022-02-10T18:46:29.911662Z","shell.execute_reply.started":"2022-02-10T18:46:29.902223Z","shell.execute_reply":"2022-02-10T18:46:29.910923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#!cat '/kaggle/input/eda-model-cv-check/yolov5/runs/val/exp/labels/0-4660.txt'\n","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:29.912789Z","iopub.execute_input":"2022-02-10T18:46:29.913521Z","iopub.status.idle":"2022-02-10T18:46:29.926094Z","shell.execute_reply.started":"2022-02-10T18:46:29.913491Z","shell.execute_reply":"2022-02-10T18:46:29.925502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#eval(df_train[df_train.image_id=='0-4486'].annotations.values[0])\nimage_name='107'\nlabel_name='0-107.txt'\npaths=[f'/kaggle/working/yolo_data/fold4/labels/val/{label_name}']","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:29.927286Z","iopub.execute_input":"2022-02-10T18:46:29.928049Z","iopub.status.idle":"2022-02-10T18:46:29.936605Z","shell.execute_reply.started":"2022-02-10T18:46:29.927997Z","shell.execute_reply":"2022-02-10T18:46:29.936075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n    \n    count=0\n    for image_file in paths:\n        gt_bboxs = []; prd_bboxs = []\n        with open(image_file, 'r') as f:\n            while True:\n                r = f.readline().rstrip()\n                if not r: \n                    break\n                r = r.split()[1:]\n                bbox = np.array(list(map(float, r))) \n                gt_bboxs.append(bbox)\n\n    pred_path = '/kaggle/working/yolov5/runs/val/exp/labels/'\n    pred_path='/kaggle/input/eda-model-cv-check/yolov5/runs/val/exp/labels/'\n    pred_file = pred_path+label_name\n\n    no_anns = True\n    if os.path.exists(pred_file):\n        with open(pred_file, 'r') as f:\n            while True:\n                r = f.readline().rstrip()\n                if not r: \n                    break\n                r = r.split()[1:]; \n                print(r)\n                r = [r[4], *r[:4]]\n                \n                conf=float(r[0])\n                print('conf',conf)\n                \n                if conf>0.15: \n                    bbox = np.array(list(map(float, r)))\n                    prd_bboxs.append(bbox)\n                    no_anns = False\n\n                if no_anns: \n                    count+=1\n\n    gt_bboxs, prd_bboxs= np.array(gt_bboxs), np.array(prd_bboxs)\nexcept Exception as e:\n    print('x',e)","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:29.93802Z","iopub.execute_input":"2022-02-10T18:46:29.9383Z","iopub.status.idle":"2022-02-10T18:46:29.951771Z","shell.execute_reply.started":"2022-02-10T18:46:29.938263Z","shell.execute_reply":"2022-02-10T18:46:29.951035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#!ls -l /kaggle/input/eda-model-cv-check/yolov5/runs/val/exp/labels/\n#yolo2voc(720, 1280, prd_bboxs[0,1:]) \n#prd_bboxs\n#gt_bboxs, prd_bboxs\n#gt_bboxs","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:29.953026Z","iopub.execute_input":"2022-02-10T18:46:29.95321Z","iopub.status.idle":"2022-02-10T18:46:29.962256Z","shell.execute_reply.started":"2022-02-10T18:46:29.953187Z","shell.execute_reply":"2022-02-10T18:46:29.961639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#yolo2coco(720, 1280, gt_bboxs ) \nprint((0.51211-0.016/2  )*1280,0.016406*1280)\n#df_train[df_train.image_id=='0-105']\n\n","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:29.964352Z","iopub.execute_input":"2022-02-10T18:46:29.964874Z","iopub.status.idle":"2022-02-10T18:46:29.974275Z","shell.execute_reply.started":"2022-02-10T18:46:29.96483Z","shell.execute_reply":"2022-02-10T18:46:29.973449Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#df_train[df_train.image_id=='1-1926']\n#prd_bboxs[range(len(prd_bboxs)),1:].shape,prd_bboxs.shape\n#gt_bboxs","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:29.975292Z","iopub.execute_input":"2022-02-10T18:46:29.975605Z","iopub.status.idle":"2022-02-10T18:46:29.984289Z","shell.execute_reply.started":"2022-02-10T18:46:29.975572Z","shell.execute_reply":"2022-02-10T18:46:29.983579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n    \n    names         = ['COTS']*len(gt_bboxs)\n    labels        = [0]*len(gt_bboxs)\n    fig,ax = plt.subplots(1,2,figsize=(30,20))\n    print('image_name',image_name,label_name)\n    img=load_image(f'/kaggle/input/tensorflow-great-barrier-reef/train_images/video_0/{image_name}.jpg')\n\n    #img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB )\n    print(img.shape)\n    if len(gt_bboxs)!=0:\n        \n        img2=draw_bboxes(img, gt_bboxs, names, labels, colors = colors, show_classes = None, bbox_format = 'yolo', class_name = True, line_thickness = 2) \n    ax[0].imshow(img2)\n    #img=cv2.imread('../input/tensorflow-great-barrier-reef/train_images/video_1/1926.jpg')\n    img1=load_image(f'/kaggle/input/tensorflow-great-barrier-reef/train_images/video_0/{image_name}.jpg')\n    #img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB )\n    print(img1.shape, len(prd_bboxs),prd_bboxs)\n    if len(prd_bboxs)!=0:\n        \n        names         = ['COTS']*len(prd_bboxs)\n        labels        = [0]*len(prd_bboxs)\n        img1=draw_bboxes(img1, prd_bboxs[range(len(prd_bboxs)),1:], names, labels, colors = colors, show_classes = None, \n                         bbox_format = 'yolo', class_name = True, line_thickness = 2) \n    \n    ax[1].imshow(img1)\nexcept Exception as e:\n    print(e)","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:29.985551Z","iopub.execute_input":"2022-02-10T18:46:29.985929Z","iopub.status.idle":"2022-02-10T18:46:30.425975Z","shell.execute_reply.started":"2022-02-10T18:46:29.985892Z","shell.execute_reply":"2022-02-10T18:46:30.424057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import albumentations as A\naug=A.Compose([A.RandomSizedBBoxSafeCrop(width=1280, height=704,p=0.4)]\n               ,bbox_params=A.BboxParams(format='yolo',min_area=100, min_visibility=0.1, \n                                         label_fields=['class_labels']))\n\n","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:30.427163Z","iopub.execute_input":"2022-02-10T18:46:30.427356Z","iopub.status.idle":"2022-02-10T18:46:30.432788Z","shell.execute_reply.started":"2022-02-10T18:46:30.427332Z","shell.execute_reply":"2022-02-10T18:46:30.431999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" #plt.imshow(aug(image=img, bboxes=gt_bboxs,class_labels=['0'] )['image'])","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:30.43397Z","iopub.execute_input":"2022-02-10T18:46:30.434192Z","iopub.status.idle":"2022-02-10T18:46:30.443345Z","shell.execute_reply.started":"2022-02-10T18:46:30.434165Z","shell.execute_reply":"2022-02-10T18:46:30.442729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n\n    fig,ax = plt.subplots(1,1,figsize=(70,60))\n    ax.imshow(cv2.resize(img2,(1280*3,720*3)))\nexcept:\n    print('x')","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:30.444576Z","iopub.execute_input":"2022-02-10T18:46:30.445045Z","iopub.status.idle":"2022-02-10T18:46:31.350603Z","shell.execute_reply.started":"2022-02-10T18:46:30.445013Z","shell.execute_reply":"2022-02-10T18:46:31.349761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#fig,ax = plt.subplots(1,1,figsize=(40,60))\n#ax.imshow(cv2.resize(img1,(1280*3,720*3)))","metadata":{"execution":{"iopub.status.busy":"2022-02-10T18:46:31.351742Z","iopub.execute_input":"2022-02-10T18:46:31.351981Z","iopub.status.idle":"2022-02-10T18:46:31.356237Z","shell.execute_reply.started":"2022-02-10T18:46:31.351951Z","shell.execute_reply":"2022-02-10T18:46:31.355353Z"},"trusted":true},"execution_count":null,"outputs":[]}]}