{"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":"# Download YOLOV5 and create our workspace ","metadata":{}},{"cell_type":"code","source":"\n%cd /kaggle\n!rm -rf tmp\n!mkdir tmp\n%cd tmp","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:46.400819Z","iopub.execute_input":"2021-07-13T10:11:46.401462Z","iopub.status.idle":"2021-07-13T10:11:48.048554Z","shell.execute_reply.started":"2021-07-13T10:11:46.401417Z","shell.execute_reply":"2021-07-13T10:11:48.047229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ls ../","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:48.051085Z","iopub.execute_input":"2021-07-13T10:11:48.051575Z","iopub.status.idle":"2021-07-13T10:11:48.816742Z","shell.execute_reply.started":"2021-07-13T10:11:48.051518Z","shell.execute_reply":"2021-07-13T10:11:48.815466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Download YOLOv5\n\n# !git clone https://github.com/ultralytics/yolov5  # clone repo\n\n%cp -R /kaggle/input/yolov5-for-siim-covid19/yolov5 /kaggle/tmp\n%cd yolov5\n# %pip install -qr requirements.txt #install dependencies\n%cp -R /kaggle/input/requirements-for-siim-covid19/requirements.txt  /kaggle/tmp/yolov5\n\n%cd ../\nimport torch\n\nprint(f\"Setup complete. Using torch {torch.__version__} ({torch.cuda.get_device_properties(0).name if torch.cuda.is_available() else 'CPU'})\")","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:48.819312Z","iopub.execute_input":"2021-07-13T10:11:48.819701Z","iopub.status.idle":"2021-07-13T10:11:50.426692Z","shell.execute_reply.started":"2021-07-13T10:11:48.819661Z","shell.execute_reply":"2021-07-13T10:11:50.425458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !ls ../kaggle/tmp\n# !ls /kaggle/input/yolov5-for-siim-covid19/yolov5\n# !ls /kaggle/input/../input/requirements-for-siim-covid19\n# !ls /kaggle/input\n# !ls tmp","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:50.428718Z","iopub.execute_input":"2021-07-13T10:11:50.429049Z","iopub.status.idle":"2021-07-13T10:11:50.435213Z","shell.execute_reply.started":"2021-07-13T10:11:50.429013Z","shell.execute_reply":"2021-07-13T10:11:50.433091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !pip install -q --upgrade wandb\n# !pip install --upgrade wanb==0.9.7\n# #Login\n# import wandb\n# wandb.login()","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:50.436585Z","iopub.execute_input":"2021-07-13T10:11:50.436879Z","iopub.status.idle":"2021-07-13T10:11:50.452477Z","shell.execute_reply.started":"2021-07-13T10:11:50.436842Z","shell.execute_reply":"2021-07-13T10:11:50.451660Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Import packages ","metadata":{}},{"cell_type":"code","source":"# Necessary/extra dependencies. \nimport os\nimport gc\nimport cv2\nimport numpy as np\nimport pandas as pd\nfrom tqdm import tqdm\nfrom shutil import copyfile\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nimport wandb\n#customize iPython writefile so we can write variables\nfrom IPython.core.magic import register_line_cell_magic\n\n@register_line_cell_magic\ndef writetemplate(line, cell):\n    with open(line, 'w') as f:\n        f.write(cell.format(**globals()))","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:50.453923Z","iopub.execute_input":"2021-07-13T10:11:50.454274Z","iopub.status.idle":"2021-07-13T10:11:50.463958Z","shell.execute_reply.started":"2021-07-13T10:11:50.454194Z","shell.execute_reply":"2021-07-13T10:11:50.463154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Hyperparameters","metadata":{}},{"cell_type":"code","source":"TRAIN_PATH = 'input/siim-covid19-resized-to-256px-jpg/train/'\nIMG_SIZE = 256\nBATCH_SIZE = 16\nEPOCHS = 10","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:50.465138Z","iopub.execute_input":"2021-07-13T10:11:50.465435Z","iopub.status.idle":"2021-07-13T10:11:50.477492Z","shell.execute_reply.started":"2021-07-13T10:11:50.465407Z","shell.execute_reply":"2021-07-13T10:11:50.476561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prepare Dataset","metadata":{}},{"cell_type":"markdown","source":"* Create train_validation split\n* Create required `/dataset`\n* Create `data.yaml` file needed to train the model\n* Create bounding box coordinates in the required YOLO format","metadata":{}},{"cell_type":"code","source":"# Everything is done from /kaggle directory\n%cd /kaggle\n#Load image level csv file\ndf = pd.read_csv('input/siim-covid19-detection/train_image_level.csv')\n\n#Modify values in the id column\ndf['id'] = df.apply(lambda row:row.id.split('_')[0],axis=1)\n\n# Add absolute path\ndf['path'] = df.apply(lambda row:TRAIN_PATH+row.id+'.jpg',axis=1)\n\n#get image level labels\ndf['image_level'] = df.apply(lambda row:row.label.split(' ')[0], axis=1)\ndf.head(5)\n","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:50.480070Z","iopub.execute_input":"2021-07-13T10:11:50.480562Z","iopub.status.idle":"2021-07-13T10:11:50.860600Z","shell.execute_reply.started":"2021-07-13T10:11:50.480529Z","shell.execute_reply":"2021-07-13T10:11:50.859858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load meta.csv file\n# Original dimensions are required to scale the bounding box coordinates appropriately.\n\nmeta_df = pd.read_csv('input/siim-covid19-resized-to-256px-jpg/meta.csv')\ntrain_meta_df = meta_df.loc[meta_df.split=='train']\ntrain_meta_df=train_meta_df.drop('split',axis=1)\ntrain_meta_df.columns=['id','dim0','dim1']\n\ntrain_meta_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:50.862230Z","iopub.execute_input":"2021-07-13T10:11:50.862642Z","iopub.status.idle":"2021-07-13T10:11:50.891122Z","shell.execute_reply.started":"2021-07-13T10:11:50.862610Z","shell.execute_reply":"2021-07-13T10:11:50.890395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#merge train df\ndf = df.merge(train_meta_df,on='id',how='left')\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:50.892254Z","iopub.execute_input":"2021-07-13T10:11:50.892648Z","iopub.status.idle":"2021-07-13T10:11:50.915753Z","shell.execute_reply.started":"2021-07-13T10:11:50.892618Z","shell.execute_reply":"2021-07-13T10:11:50.914870Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train & Validation set split","metadata":{}},{"cell_type":"code","source":"train_df, valid_df = train_test_split(df, test_size=0.2, random_state = 710, stratify=df.image_level.values)\n\n\n# train_df.assign(split = \"train\")\n# valid_df.assign(split = \"valid\")\n\ntrain_df.loc[:,\"split\"]='train'\nvalid_df.loc[:,\"split\"]='valid'\n\ndf = pd.concat([train_df, valid_df]).reset_index(drop=True)\n","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:50.916956Z","iopub.execute_input":"2021-07-13T10:11:50.917447Z","iopub.status.idle":"2021-07-13T10:11:50.950312Z","shell.execute_reply.started":"2021-07-13T10:11:50.917415Z","shell.execute_reply":"2021-07-13T10:11:50.949236Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'Size of dataset: {len(df)}, training images: {len(train_df)}. validation images: {len(valid_df)}')\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:50.951983Z","iopub.execute_input":"2021-07-13T10:11:50.952468Z","iopub.status.idle":"2021-07-13T10:11:50.971358Z","shell.execute_reply.started":"2021-07-13T10:11:50.952418Z","shell.execute_reply":"2021-07-13T10:11:50.970217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.makedirs('tmp/covid/images/train',exist_ok=True)\nos.makedirs('tmp/covid/images/valid',exist_ok=True)\n\n\nos.makedirs('tmp/covid/labels/train',exist_ok=True)\nos.makedirs('tmp/covid/labels/valid',exist_ok=True)\n\n!ls tmp/covid/images","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:50.972975Z","iopub.execute_input":"2021-07-13T10:11:50.973302Z","iopub.status.idle":"2021-07-13T10:11:51.726478Z","shell.execute_reply.started":"2021-07-13T10:11:50.973263Z","shell.execute_reply":"2021-07-13T10:11:51.725205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in tqdm(range(len(df))):\n    row=df.loc[i]\n    if row.split=='train':\n        copyfile(row.path, f'tmp/covid/images/train/{row.id}.jpg')\n    else:\n        copyfile(row.path, f'tmp/covid/images/valid/{row.id}.jpg')","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:51.728385Z","iopub.execute_input":"2021-07-13T10:11:51.728732Z","iopub.status.idle":"2021-07-13T10:11:58.942160Z","shell.execute_reply.started":"2021-07-13T10:11:51.728697Z","shell.execute_reply":"2021-07-13T10:11:58.940893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Create `.YAML` file","metadata":{}},{"cell_type":"code","source":"import yaml\n\ndata_yaml=dict(\n    train='../covid/images/train',\n    val='../covid/images/valid',\n    nc=2,\n    names=['none','opacity'])\n\n#write yaml file\nwith open('tmp/yolov5/data/data.yaml','w') as outfile:\n    yaml.dump(data_yaml,outfile,default_flow_style=True)\n\n%cat tmp/yolov5/data/data.yaml","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:58.943861Z","iopub.execute_input":"2021-07-13T10:11:58.944205Z","iopub.status.idle":"2021-07-13T10:11:59.726703Z","shell.execute_reply.started":"2021-07-13T10:11:58.944152Z","shell.execute_reply":"2021-07-13T10:11:59.725234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prepare Bounding Box Coordinated for YOLOv5","metadata":{}},{"cell_type":"code","source":"# Get the raw rounding box by parsing the row value of the label column\n\ndef get_bbox(row):\n    bboxes=[]\n    bbox=[]\n    for i,l in enumerate(row.label.split(' ')):\n        if (i%6==0)|(i%6==1):\n            continue\n        bbox.append(float(l))\n        if (i%6==5):\n            bboxes.append(bbox)\n            bbox=[]\n    return bboxes\n\n#Scale the bounding boxes according to the size of the resized image\n\ndef scale_bbox(row, bboxes):\n    # Get scaling factor\n    \n    scale_x = IMG_SIZE/row.dim1\n    scale_y= IMG_SIZE/row.dim0\n    \n    scaled_bboxes=[]\n    \n    for bbox in bboxes:\n        x = int(np.round(bbox[0]*scale_x,4))\n        y = int(np.round(bbox[1]*scale_y,4))\n        x1=int(np.round(bbox[2]*scale_x,4))\n        y1=int(np.round(bbox[2]*scale_y,4))\n    \n        scaled_bboxes.append([x,y,x1,y1])\n        \n        \n    return scaled_bboxes\n\n# convert the bounding boxes into YOLO format\n\ndef get_yolo_format_bbox(img_w,img_h,bboxes):\n    yolo_boxes=[]\n    for bbox in bboxes:\n        w=bbox[2]-bbox[0]\n        h=bbox[3]-bbox[1]\n        xc=bbox[0]+int(np.round(w/2)) # mid point of height and width\n        yc=bbox[1]+int(np.round(h/2))\n        #normalization?\n        yolo_boxes.append([xc/img_w,yc/img_h,w/img_w,h/img_h])\n    \n    return yolo_boxes","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:59.728613Z","iopub.execute_input":"2021-07-13T10:11:59.728949Z","iopub.status.idle":"2021-07-13T10:11:59.744850Z","shell.execute_reply.started":"2021-07-13T10:11:59.728915Z","shell.execute_reply":"2021-07-13T10:11:59.743568Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# prepare the txt files for the bounding box\n\nfor i in tqdm(range(len(df))):\n    row = df.loc[i]\n    \n    #get image id\n    img_id=row.id\n    split=row.split\n    label=row.image_level\n    \n    if row.split=='train':\n        file_name=f'tmp/covid/labels/train/{row.id}.txt'\n    \n    else:\n        file_name=f'tmp/covid/labels/valid/{row.id}.txt'\n        \n        \n    if label=='opacity':\n        \n        #Get bboxes\n        bboxes = get_bbox(row)\n        # Scale bounding boxes\n        scale_bboxes = scale_bbox(row,bboxes)\n        \n        # Format for YOLOv5\n        yolo_bboxes=get_yolo_format_bbox(IMG_SIZE,IMG_SIZE,scale_bboxes)\n        \n        with open(file_name,'w') as f:\n            for bbox in yolo_bboxes:\n                bbox=[1]+bbox\n                bbox=[str(i) for i in bbox]\n                bbox = ' '.join(bbox)\n                f.write(bbox)\n                f.write('\\n')\n        \n        \n        ","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:11:59.746876Z","iopub.execute_input":"2021-07-13T10:11:59.747318Z","iopub.status.idle":"2021-07-13T10:12:03.055348Z","shell.execute_reply.started":"2021-07-13T10:11:59.747278Z","shell.execute_reply":"2021-07-13T10:12:03.054274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd tmp/yolov5/","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:12:03.056747Z","iopub.execute_input":"2021-07-13T10:12:03.057068Z","iopub.status.idle":"2021-07-13T10:12:03.065538Z","shell.execute_reply.started":"2021-07-13T10:12:03.057037Z","shell.execute_reply":"2021-07-13T10:12:03.063834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !python train.py --img {IMG_SIZE} \\\n#                  --batch {BATCH_SIZE} \\\n#                  --epochs {EPOCHS} \\\n#                  --data data.yaml \\\n#                  --weights yolov5s.pt \\\n#                  --save_period 1\\\n#                  --project kaggle-siim-covid","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:12:03.067785Z","iopub.execute_input":"2021-07-13T10:12:03.068371Z","iopub.status.idle":"2021-07-13T10:12:03.197602Z","shell.execute_reply.started":"2021-07-13T10:12:03.068317Z","shell.execute_reply":"2021-07-13T10:12:03.196321Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# cd /kaggle/tmp/yolov5/kaggle-siim-covid/exp/weights/\n%ls","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:12:03.199306Z","iopub.execute_input":"2021-07-13T10:12:03.199646Z","iopub.status.idle":"2021-07-13T10:12:03.958819Z","shell.execute_reply.started":"2021-07-13T10:12:03.199594Z","shell.execute_reply":"2021-07-13T10:12:03.957561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # import wandb\n# iimport wandb\n# run = wandb.init()\n# artifact = run.use_artifact('andernzhu/kaggle-siim-covid/run_3a0jaej5_model:v9', type='model')\n# artifact_dir = artifact.download()","metadata":{"_kg_hide-input":false,"execution":{"iopub.status.busy":"2021-07-13T10:12:03.961033Z","iopub.execute_input":"2021-07-13T10:12:03.961537Z","iopub.status.idle":"2021-07-13T10:12:03.966412Z","shell.execute_reply.started":"2021-07-13T10:12:03.961485Z","shell.execute_reply":"2021-07-13T10:12:03.965344Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ls /kaggle/tmp/yolov5","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:12:03.967717Z","iopub.execute_input":"2021-07-13T10:12:03.968016Z","iopub.status.idle":"2021-07-13T10:12:04.724717Z","shell.execute_reply.started":"2021-07-13T10:12:03.967987Z","shell.execute_reply":"2021-07-13T10:12:04.723476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TEST_PATH = '/kaggle/input/siim-covid19-resized-to-256px-jpg/test/' # absolute path","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:12:04.728807Z","iopub.execute_input":"2021-07-13T10:12:04.729159Z","iopub.status.idle":"2021-07-13T10:12:04.733797Z","shell.execute_reply.started":"2021-07-13T10:12:04.729122Z","shell.execute_reply":"2021-07-13T10:12:04.732837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"MODEL_PATH = '/kaggle/input/best-model/317a481ae22f8b127f462ec81d721bea'","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:12:04.735713Z","iopub.execute_input":"2021-07-13T10:12:04.736100Z","iopub.status.idle":"2021-07-13T10:12:04.747803Z","shell.execute_reply.started":"2021-07-13T10:12:04.736050Z","shell.execute_reply":"2021-07-13T10:12:04.746767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cd /kaggle/tmp/yolov5","metadata":{"execution":{"iopub.status.busy":"2021-07-13T10:12:04.749595Z","iopub.execute_input":"2021-07-13T10:12:04.750106Z","iopub.status.idle":"2021-07-13T10:12:04.761564Z","shell.execute_reply.started":"2021-07-13T10:12:04.750062Z","shell.execute_reply":"2021-07-13T10:12:04.760383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!python detect.py --weights {MODEL_PATH} \\\n                  --source {TEST_PATH} \\\n                  --img {IMG_SIZE} \\\n                  --conf 0.281 \\\n                  --iou-thres 0.5 \\\n                  --max-det 3 \\\n                  --save-txt \\\n                  --save-conf","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-07-13T10:12:04.763299Z","iopub.execute_input":"2021-07-13T10:12:04.763708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PRED_PATH = 'runs/detect/exp/labels'\n# !ls {PRED_PATH}\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualize predicted coordinates.\n%cat runs/detect/exp2/labels/ffb8115a304c.txt","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prediction_files = os.listdir(PRED_PATH)\nprint('Number of test images predicted as opaque: ', len(prediction_files))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Generate the submission `.csv` file","metadata":{}},{"cell_type":"code","source":"# The submisison requires xmin, ymin, xmax, ymax format. \n# YOLOv5 returns x_center, y_center, width, height\ndef correct_bbox_format(bboxes):\n    correct_bboxes = []\n    for b in bboxes:\n        xc, yc = int(np.round(b[0]*IMG_SIZE)), int(np.round(b[1]*IMG_SIZE))\n        w, h = int(np.round(b[2]*IMG_SIZE)), int(np.round(b[3]*IMG_SIZE))\n\n        xmin = xc - int(np.round(w/2))\n        xmax = xc + int(np.round(w/2))\n        ymin = yc - int(np.round(h/2))\n        ymax = yc + int(np.round(h/2))\n        \n        correct_bboxes.append([xmin, xmax, ymin, ymax])\n        \n    return correct_bboxes\n\n# Read the txt file generated by YOLOv5 during inference and extract \n# confidence and bounding box coordinates.\ndef get_conf_bboxes(file_path):\n    confidence = []\n    bboxes = []\n    with open(file_path, 'r') as file:\n        for line in file:\n            preds = line.strip('\\n').split(' ')\n            preds = list(map(float, preds))\n            confidence.append(preds[-1])\n            bboxes.append(preds[1:-1])\n    return confidence, bboxes\n        ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Read the submission file\n\nsub_df=pd.read_csv('/kaggle/input/siim-covid19-detection/sample_submission.csv')\nsub_df.tail()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prediction loop for submission\npredictions = []\n\nfor i in tqdm(range(len(sub_df))):\n    row = sub_df.loc[i]\n    id_name = row.id.split('_')[0]\n    id_level = row.id.split('_')[-1]\n    \n    if id_level == 'study':\n        # do study-level classification\n        predictions.append(\"Negative 1 0 0 1 1\") # dummy prediction\n        \n    elif id_level == 'image':\n        # we can do image-level classification here.\n        # also we can rely on the object detector's classification head.\n        # for this example submisison we will use YOLO's classification head. \n        # since we already ran the inference we know which test images belong to opacity.\n        if f'{id_name}.txt' in prediction_files:\n            # opacity label\n            confidence, bboxes = get_conf_bboxes(f'{PRED_PATH}/{id_name}.txt')\n            bboxes = correct_bbox_format(bboxes)\n            pred_string = ''\n            for j, conf in enumerate(confidence):\n                pred_string += f'opacity {conf} ' + ' '.join(map(str, bboxes[j])) + ' '\n            predictions.append(pred_string[:-1]) \n        else:\n            predictions.append(\"None 1 0 0 1 1\") ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df['PredictionString'] = predictions\nsub_df.to_csv('submission.csv', index=False)\nsub_df.tail()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%mv submission.csv /kaggle/working\n# %mv /kaggle/tmp/yolov5/requirements.txt /kaggle/working\n%ls /kaggle/working ","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}