{"cells":[{"metadata":{},"cell_type":"markdown","source":"WIP:\n    * 512 dataset (done)\n    * cross validation\n    * Remove class 14 (done)\n    * 2 class filter\n    * 1 x 1 bbox trick\n    * Prediction code\n\n* CutMix + Mixup\n* Cosine annealing scheduler"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import pandas as pd\nimport os\nimport numpy as np\nimport shutil\nimport ast\nfrom sklearn import model_selection\nfrom tqdm import tqdm\nimport wandb\nfrom sklearn.model_selection import GroupKFold\nfrom IPython.display import Image, clear_output  # to display images\nfrom os import listdir\nfrom os.path import isfile\nfrom glob import glob\nimport yaml\n# clear_output()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TRAIN_LABELS_PATH = './vinbigdata/labels/train'\nVAL_LABELS_PATH = './vinbigdata/labels/val'\nTRAIN_IMAGES_PATH = './vinbigdata/images/train' #12000\nVAL_IMAGES_PATH = './vinbigdata/images/val' #3000\nExternal_DIR = '../input/vinbigdata-512-image-dataset/vinbigdata/train' # 15000\nos.makedirs(TRAIN_LABELS_PATH, exist_ok = True)\nos.makedirs(VAL_LABELS_PATH, exist_ok = True)\nos.makedirs(TRAIN_IMAGES_PATH, exist_ok = True)\nos.makedirs(VAL_IMAGES_PATH, exist_ok = True)\nsize = 512","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv('../input/vinbigdata-512-image-dataset/vinbigdata/train.csv')\ndf = df[df.class_id!=14].reset_index(drop = True)\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df['x_min'] = df.apply(lambda row: (row.x_min)/row.width, axis = 1)*float(size)\ndf['y_min'] = df.apply(lambda row: (row.y_min)/row.height, axis = 1)*float(size)\ndf['x_max'] = df.apply(lambda row: (row.x_max)/row.width, axis =1)*float(size)\ndf['y_max'] = df.apply(lambda row: (row.y_max)/row.height, axis =1)*float(size)\n\n# calculation x-mid, y-mid, width and hight of the bounding box for yolo\ndf['x_mid'] = df.apply(lambda row: (row.x_max+row.x_min)/2, axis =1)\ndf['y_mid'] = df.apply(lambda row: (row.y_max+row.y_min)/2, axis =1)\n\ndf['w'] = df.apply(lambda row: (row.x_max-row.x_min), axis =1)\ndf['h'] = df.apply(lambda row: (row.y_max-row.y_min), axis =1)\n\ndf['x_mid'] /= float(size)\ndf['y_mid'] /= float(size)\n\ndf['w'] /= float(size)\ndf['h'] /= float(size)\n\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# df_train, df_valid = model_selection.train_test_split(df, test_size=0.2, random_state=42, shuffle=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# cross validation\ngkf  = GroupKFold(n_splits = 5)\ndf['fold'] = -1\nfor fold, (train_idx, val_idx) in enumerate(gkf.split(df, groups = df.image_id.tolist())):\n    df.loc[val_idx, 'fold'] = fold\nval_df = df[df['fold']==4]\nval_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# <class> <x_center> <y_center> <width> <height>\ndef preproccess_data(df, labels_path, images_path):\n    for column, row in tqdm(df.iterrows(), total=len(df)):\n        attributes = row[['class_id','x_mid','y_mid','w','h']].values\n        attributes = np.array(attributes)\n        np.savetxt(os.path.join(labels_path, f\"{row['image_id']}.txt\"),\n                   [attributes], fmt = ['%d', '%f', '%f', '%f', '%f'])\n        shutil.copy(os.path.join('/kaggle/input/vinbigdata-512-image-dataset/vinbigdata/train', f\"{row['image_id']}.png\"),images_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preproccess_data(df, TRAIN_LABELS_PATH, TRAIN_IMAGES_PATH)\npreproccess_data(val_df, VAL_LABELS_PATH, VAL_IMAGES_PATH)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!git clone https://github.com/ultralytics/yolov5.git","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"classes = [ 'Aortic enlargement',\n            'Atelectasis',\n            'Calcification',\n            'Cardiomegaly',\n            'Consolidation',\n            'ILD',\n            'Infiltration',\n            'Lung Opacity',\n            'Nodule/Mass',\n            'Other lesion',\n            'Pleural effusion',\n            'Pleural thickening',\n            'Pneumothorax',\n            'Pulmonary fibrosis']\n\ndata = dict(\n    train =  '../vinbigdata/images/train',\n    val   =  '../vinbigdata/images/val',\n    nc    = 14,\n    names = classes\n    )\n\nwith open('./yolov5/vinbigdata.yaml', 'w') as outfile:\n    yaml.dump(data, outfile, default_flow_style=False)\n    \nf = open('./yolov5/vinbigdata.yaml', 'r')\nprint('\\nyaml:')\nprint(f.read())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def run_fold(fold):\n    print(f\"Starting fold {fold}\")\n    trn_idx = df[df['fold'] != fold].index\n    val_idx = val_df[val_df['fold'] == fold].index\n#     preprocess\n#    run train .py\n\n    \n    print(f\"Completed Fold {fold} in {round(time.time()-start, 2)} seconds\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%cd ./yolov5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -U -r requirements.txt\n!pip install pycocotools>=2.0 seaborn>=0.11.0 pandas thop\nclear_output()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# b39dd18eed49a73a53fccd7b684ea7ecaed75b08\nwandb.login()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!python train.py --img 512 --batch 16 --epochs 100 --data ./vinbigdata.yaml --cfg models/yolov5x.yaml --weights yolov5x.pt --cache --name vin","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# !python train.py --resume","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dir = f'/kaggle/input/vinbigdata-{size}-image-dataset/vinbigdata/test'\nweights_dir = './runs/train/vin3/weights/best.pt'\nos.listdir('./runs/train/vin3/weights')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!python detect.py --weights $weights_dir\\\n--img 512\\\n--conf 0.15\\\n--iou 0.4\\\n--source $test_dir\\\n--save-txt --save-conf --exist-ok","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def yolo2voc(image_height, image_width, bboxes):\n    \"\"\"\n    yolo => [xmid, ymid, w, h] (normalized)\n    voc  => [x1, y1, x2, y1]\n    \n    \"\"\" \n    bboxes = bboxes.copy().astype(float) # otherwise all value will be 0 as voc_pascal dtype is np.int\n    \n    bboxes[..., [0, 2]] = bboxes[..., [0, 2]]* image_width\n    bboxes[..., [1, 3]] = bboxes[..., [1, 3]]* image_height\n    \n    bboxes[..., [0, 1]] = bboxes[..., [0, 1]] - bboxes[..., [2, 3]]/2\n    bboxes[..., [2, 3]] = bboxes[..., [0, 1]] + bboxes[..., [2, 3]]\n    \n    return bboxes","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_ids = []\nPredictionStrings = []\ntest_df = pd.read_csv(f'/kaggle/input/vinbigdata-{size}-image-dataset/vinbigdata/test.csv')\n\nfor file_path in tqdm(glob('runs/detect/exp/labels/*txt')):\n    image_id = file_path.split('/')[-1].split('.')[0] # extract image id\n    w, h = test_df.loc[test_df.image_id==image_id,['width', 'height']].values[0]\n    f = open(file_path, 'r')\n    data = np.array(f.read().replace('\\n', ' ').strip().split(' ')).astype(np.float32).reshape(-1, 6)\n    data = data[:, [0, 5, 1, 2, 3, 4]]\n    bboxes = list(np.round(np.concatenate((data[:, :2], np.round(yolo2voc(h, w, data[:, 2:]))), axis =1).reshape(-1), 1).astype(str))\n    for idx in range(len(bboxes)):\n        bboxes[idx] = str(int(float(bboxes[idx]))) if idx%6!=1 else bboxes[idx]\n    image_ids.append(image_id)\n    PredictionStrings.append(' '.join(bboxes))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip uninstall pandas\n!pip install pandas==1.1.5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_df = pd.DataFrame({'image_id':image_ids,\n                        'PredictionString':PredictionStrings})\nsub_df = pd.merge(test_df, pred_df, on = 'image_id', how = 'left').fillna(\"14 1 0 0 1 1\")\nsub_df = sub_df[['image_id', 'PredictionString']]\nsub_df.to_csv('/kaggle/working/submission.csv',index = False)\nsub_df.tail()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}