{"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":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import KFold, StratifiedKFold\nfrom glob import glob\nimport albumentations as A\nimport cv2\nimport os\nimport shutil\nfrom tqdm import tqdm\nimport torch\nimport ruamel.yaml\nfrom pathlib import Path","metadata":{"execution":{"iopub.status.busy":"2023-10-10T08:24:02.087118Z","iopub.execute_input":"2023-10-10T08:24:02.087456Z","iopub.status.idle":"2023-10-10T08:24:02.112486Z","shell.execute_reply.started":"2023-10-10T08:24:02.087430Z","shell.execute_reply":"2023-10-10T08:24:02.111655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = 'cuda' if torch.cuda.is_available() else 'cpu'\ndevice","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-10-10T08:19:35.761745Z","iopub.execute_input":"2023-10-10T08:19:35.762690Z","iopub.status.idle":"2023-10-10T08:19:35.792962Z","shell.execute_reply.started":"2023-10-10T08:19:35.762648Z","shell.execute_reply":"2023-10-10T08:19:35.792144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def alter_yaml(input_yaml: str, changes: dict, output_yaml: str = None) -> None:\n    \"\"\"\n\n    :param input_yaml: yaml file you want to alter\n    :param changes: dict with variables you want to change. Example: {'path': '/test', 'force_plot': False}\n    :param output_yaml: optional output yaml file. If None, the input yaml is overwritten\n    :return:\n    \"\"\"\n    yaml = ruamel.yaml.YAML()\n    yaml.preserve_quotes = True\n    yaml.default_flow_style = True\n    with open(input_yaml , errors=\"ignore\") as fp:\n        data = yaml.load(fp)\n        for key, value in changes.items():\n            data[key] = value\n\n    if output_yaml is not None:\n        yaml.dump(data, Path(f'{output_yaml}'))\n    else:\n        yaml.dump(data, Path(f'{input_yaml}'))","metadata":{"execution":{"iopub.status.busy":"2023-10-10T08:19:36.949722Z","iopub.execute_input":"2023-10-10T08:19:36.950564Z","iopub.status.idle":"2023-10-10T08:19:36.956644Z","shell.execute_reply.started":"2023-10-10T08:19:36.950534Z","shell.execute_reply":"2023-10-10T08:19:36.955634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"marking = pd.read_csv('/kaggle/input/global-wheat-detection/train.csv')\nimage_ids = marking.image_id.unique()\n\n# create folds for cross validation\nkf = KFold(n_splits=5, shuffle=True, random_state=42)\nfor i, fold in enumerate(kf.split(image_ids)):\n    marking.loc[marking.image_id.isin(image_ids[fold[1]]), 'fold'] = i\n\n# extract bounding box columns\nbboxs = np.stack(marking['bbox'].apply(lambda x: np.fromstring(x[1:-1], sep=',')))\nfor i, column in enumerate(['x', 'y', 'w', 'h']):\n    marking[column] = bboxs[:,i]\n\nmarking.head()","metadata":{"execution":{"iopub.status.busy":"2023-10-10T08:19:37.924195Z","iopub.execute_input":"2023-10-10T08:19:37.924514Z","iopub.status.idle":"2023-10-10T08:19:38.625041Z","shell.execute_reply.started":"2023-10-10T08:19:37.924488Z","shell.execute_reply":"2023-10-10T08:19:38.624127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# clone the yolov7 repository from github and install requirements. This implementation is based on Pytorch\n!git clone 'https://github.com/WongKinYiu/yolov7.git'\n\n!cd yolov7\n!pip install -qr /kaggle/working/yolov7/requirements.txt","metadata":{"execution":{"iopub.status.busy":"2023-10-10T08:19:44.743606Z","iopub.execute_input":"2023-10-10T08:19:44.743917Z","iopub.status.idle":"2023-10-10T08:19:51.962841Z","shell.execute_reply.started":"2023-10-10T08:19:44.743891Z","shell.execute_reply":"2023-10-10T08:19:51.961735Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create input file structure\nos.mkdir('/kaggle/working/train')\nos.mkdir('/kaggle/working/val')\nos.mkdir('/kaggle/working/train/images')\nos.mkdir('/kaggle/working/train/labels')\nos.mkdir('/kaggle/working/val/images')\nos.mkdir('/kaggle/working/val/labels')","metadata":{"execution":{"iopub.status.busy":"2023-10-10T08:20:02.560492Z","iopub.execute_input":"2023-10-10T08:20:02.561222Z","iopub.status.idle":"2023-10-10T08:20:02.566913Z","shell.execute_reply.started":"2023-10-10T08:20:02.561188Z","shell.execute_reply":"2023-10-10T08:20:02.566107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# split into training and validation data\nfold_nr = 0\ntrain_marking = marking[marking.fold !=fold_nr]\nval_marking = marking[marking.fold ==fold_nr]\n\n# populate train folders\nimage_ids = train_marking.image_id.unique()\nfor image_id in tqdm(image_ids):\n    #copy image\n    src = f'/kaggle/input/global-wheat-detection/train/{image_id}.jpg'\n    dst = f'/kaggle/working/train/images/{image_id}.jpg'\n    shutil.copyfile(src, dst)\n    \n    #create txt file\n    selection = train_marking[train_marking.image_id==image_id]\n    \n    with open(f'/kaggle/working/train/labels/{image_id}.txt', 'w') as f:\n        for i, row in selection.iterrows():\n            x, y, width, height = row[['x', 'y', 'w', 'h']]/1024\n            line = f'0 {x} {y} {width} {height}'\n            f.write(line)\n            f.write('\\n')\n\n# populate validation folders           \nimage_ids = val_marking.image_id.unique()\nfor image_id in tqdm(image_ids):\n    #copy image\n    src = f'/kaggle/input/global-wheat-detection/train/{image_id}.jpg'\n    dst = f'/kaggle/working/val/images/{image_id}.jpg'\n    shutil.copyfile(src, dst)\n    \n    #create label txt file\n    selection = train_marking[train_marking.image_id==image_id]\n    \n    with open(f'/kaggle/working/val/labels/{image_id}.txt', 'w') as f:\n        for i, row in selection.iterrows():\n            x, y, width, height = row[['x', 'y', 'w', 'h']]/1024\n            line = f'0 {x} {y} {width} {height}'\n            f.write(line)\n            f.write('\\n')","metadata":{"execution":{"iopub.status.busy":"2023-10-10T08:20:02.569079Z","iopub.execute_input":"2023-10-10T08:20:02.569718Z","iopub.status.idle":"2023-10-10T08:23:10.434533Z","shell.execute_reply.started":"2023-10-10T08:20:02.569688Z","shell.execute_reply":"2023-10-10T08:23:10.433492Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#download weights\n!wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt","metadata":{"execution":{"iopub.status.busy":"2023-10-10T08:23:26.555962Z","iopub.execute_input":"2023-10-10T08:23:26.556642Z","iopub.status.idle":"2023-10-10T08:23:29.635885Z","shell.execute_reply.started":"2023-10-10T08:23:26.556611Z","shell.execute_reply":"2023-10-10T08:23:29.634807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create configuration yamls\nos.mkdir('/kaggle/working/yolov7/training_configuration')\n\ninput_yaml = \"/kaggle/working/yolov7/cfg/training/yolov7.yaml\"\noutput_yaml = \"/kaggle/working/yolov7/training_configuration/yolov7.yaml\"\nchanges = {'nc': 1}\nalter_yaml(input_yaml, changes, output_yaml)\n\ninput_yaml = \"/kaggle/working/yolov7/data/coco.yaml\"\noutput_yaml = \"/kaggle/working/yolov7/training_configuration/data.yaml\"\nchanges = {'nc': 1,\n          'train': '/kaggle/working/train',\n          'val': '/kaggle/working/val',\n          'names': [ 'wheat' ]}\nalter_yaml(input_yaml, changes, output_yaml)\n\ninput_yaml = \"/kaggle/working/yolov7/data/hyp.scratch.custom.yaml\"\noutput_yaml = \"/kaggle/working/yolov7/training_configuration/hyp.scratch.custom.yaml\"\nchanges = {}\nalter_yaml(input_yaml, changes, output_yaml)","metadata":{"execution":{"iopub.status.busy":"2023-10-10T08:24:35.377651Z","iopub.execute_input":"2023-10-10T08:24:35.377978Z","iopub.status.idle":"2023-10-10T08:24:35.532314Z","shell.execute_reply.started":"2023-10-10T08:24:35.377951Z","shell.execute_reply":"2023-10-10T08:24:35.531460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train\n!wandb disabled\n!python '/kaggle/working/yolov7/train.py' --epochs 10 --device 0 --batch-size 4 --data '/kaggle/working/yolov7/training_configuration/data.yaml' --img 1024 1024 --cfg '/kaggle/working/yolov7/training_configuration/yolov7.yaml' --weights '/kaggle/working/yolov7.pt' --name wheat_detection --hyp '/kaggle/working/yolov7/training_configuration/hyp.scratch.custom.yaml'","metadata":{"execution":{"iopub.status.busy":"2023-10-10T08:24:51.990879Z","iopub.execute_input":"2023-10-10T08:24:51.991246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load model\npath = '/kaggle/working/runs/train/wheat_detection/weights/best.pt'\nmodel = torch.hub.load(\"WongKinYiu/yolov7\",\"custom\",f\"{path}\",trust_repo=True)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# inference on test images and create submission file\nwith open(f'submission.txt', 'w') as f:\n    f.write('image_id,PredictionString')\n    f.write('\\n')\n    \n    for image_path in test_image_paths:\n        image_id = image_path.split('/')[-1][:-4]\n        print(image_id)\n        results_string = f'{image_id} '\n        image = cv2.imread(image_path)\n        \n        results = model(image)\n        results = results.pandas().xyxy\n        results = results[0]\n        \n        results[['xmin', 'ymin', 'xmax', 'ymax']] = results[['xmin', 'ymin', 'xmax', 'ymax']].astype(int)\n        results['width'] = results['xmax'] - results['xmin']\n        results['height'] = results['ymax'] - results['ymin']\n        \n        for i, row in results.iterrows():\n            bbox_results_string = f'{row.confidence} {row.xmin} {row.ymin} {row.width} {row.height} '\n            results_string = results_string + bbox_results_string\n        f.write(results_string)\n        f.write('\\n')","metadata":{},"execution_count":null,"outputs":[]}]}