{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":85240,"databundleVersionId":9622164,"sourceType":"competition"}],"dockerImageVersionId":30804,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport copy\nimport os\nimport cv2\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nfrom sklearn.model_selection import ShuffleSplit\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset,DataLoader\nfrom torch.utils.data import Subset\nimport torchvision.transforms.functional as tf\nimport torch.optim as optim\nimport torchvision\nfrom torchvision.models.detection import fasterrcnn_resnet50_fpn\nfrom torchvision.models.detection import FasterRCNN_ResNet50_FPN_Weights\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\n\n%matplotlib inline","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:17:55.153848Z","iopub.execute_input":"2024-12-04T18:17:55.155352Z","iopub.status.idle":"2024-12-04T18:17:55.185116Z","shell.execute_reply.started":"2024-12-04T18:17:55.155283Z","shell.execute_reply":"2024-12-04T18:17:55.183993Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\n# import numpy as np # linear algebra\n# import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n# import os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:17:55.187426Z","iopub.execute_input":"2024-12-04T18:17:55.187781Z","iopub.status.idle":"2024-12-04T18:17:55.197391Z","shell.execute_reply.started":"2024-12-04T18:17:55.187749Z","shell.execute_reply":"2024-12-04T18:17:55.196311Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nnp.random.seed(42)\ntorch.manual_seed(42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:17:55.199099Z","iopub.execute_input":"2024-12-04T18:17:55.199560Z","iopub.status.idle":"2024-12-04T18:17:55.219235Z","shell.execute_reply.started":"2024-12-04T18:17:55.199515Z","shell.execute_reply":"2024-12-04T18:17:55.218278Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\n\ndef create_dataframe_from_folder(image_path, label_path):\n    # Initialize a list to store data for the DataFrame\n    data = []\n\n    # Iterate over all files in the folder\n    for file in os.listdir(image_path):\n        if file.endswith((\".jpg\", \".png\", \".jpeg\")):  \n            image_file = file\n            text_file = os.path.splitext(file)[0] + \".txt\"  \n\n            # Full paths\n            image_path = os.path.join(image_path, image_file)\n            text_path = os.path.join(label_path, text_file)\n\n            # Check if the corresponding text file exists\n            if os.path.exists(text_path):\n                with open(text_path, \"r\") as f:\n                    text_data = f.read().strip().split()  \n            else:\n                text_data = [\"N/A\"]  # Handle missing text files\n\n            # Add the row to the data list\n            data.append([image_file] + text_data)\n\n    # Create a DataFrame\n    # Use \"column1\", \"column2\", ... as placeholders for text columns\n    column_names = [\"ImageID\", 'class_label','x0', 'y0', 'w', 'h']\n    df = pd.DataFrame(data, columns=column_names)\n    df['x0'] = df['x0'].astype(float)\n    df['y0'] = df['y0'].astype(float)\n    df['w'] = df['w'].astype(float)\n    df['h'] = df['h'].astype(float)\n\n    return df\n\n# Save to CSV (optional)\n# df.to_csv(\"output.csv\", index=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:17:55.220978Z","iopub.execute_input":"2024-12-04T18:17:55.221300Z","iopub.status.idle":"2024-12-04T18:17:55.232642Z","shell.execute_reply.started":"2024-12-04T18:17:55.221271Z","shell.execute_reply":"2024-12-04T18:17:55.231576Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image_path = \"/kaggle/input/dlp-object-detection/final_dlp_data/final_dlp_data/train/images\" \nlabel_path = \"/kaggle/input/dlp-object-detection/final_dlp_data/final_dlp_data/train/labels\" \n\ndf = create_dataframe_from_folder(image_path, label_path)\n\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:17:55.235465Z","iopub.execute_input":"2024-12-04T18:17:55.235889Z","iopub.status.idle":"2024-12-04T18:18:03.229903Z","shell.execute_reply.started":"2024-12-04T18:17:55.235846Z","shell.execute_reply":"2024-12-04T18:18:03.228688Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(df)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.231106Z","iopub.execute_input":"2024-12-04T18:18:03.231429Z","iopub.status.idle":"2024-12-04T18:18:03.239160Z","shell.execute_reply.started":"2024-12-04T18:18:03.231400Z","shell.execute_reply":"2024-12-04T18:18:03.238046Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# df=df[:5]\ndataframe=df\nimage_dir=\"train\"\ntest_dir=\"test\"\nmodel_weights_file=\"model.pth\"\n\ndevice=\"cuda\" if torch.cuda.is_available() else \"cpu\"\n\nbatch_size=8\nlearning_rate=0.0001\nepochs=5\n\nthreshold=0.5\niou_threshold=0.8","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.241073Z","iopub.execute_input":"2024-12-04T18:18:03.241494Z","iopub.status.idle":"2024-12-04T18:18:03.249196Z","shell.execute_reply.started":"2024-12-04T18:18:03.241438Z","shell.execute_reply":"2024-12-04T18:18:03.248028Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def center_to_min_max(box, w, h):\n    box = box.detach().numpy()\n    # print(box)\n    # print(w, h)\n    x_center, y_center, width, height = box[0]\n    # print(\"Norm\", x_center, y_center, width, height)\n\n    # Norm to pixel\n    x_center = x_center * w\n    y_center = y_center * h\n    width = width * w\n    height = height * h\n    # print(\"denorm\", x_center, y_center, width, height)\n\n    # Changing format\n    x_min = x_center - width / 2\n    y_min = y_center - height / 2\n    x_max = x_center + width / 2\n    y_max = y_center + height / 2\n    result = [x_min, y_min, x_max, y_max]\n    # print('minmax',result)\n    return torch.tensor([result])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.252231Z","iopub.execute_input":"2024-12-04T18:18:03.252592Z","iopub.status.idle":"2024-12-04T18:18:03.260419Z","shell.execute_reply.started":"2024-12-04T18:18:03.252562Z","shell.execute_reply":"2024-12-04T18:18:03.259644Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class MosquitoDataset(Dataset):\n    def __init__(self, dataframe, image_dir):\n        super().__init__()\n        self.dataframe=dataframe\n        self.img_list=sorted(self.dataframe[\"ImageID\"].unique())\n        self.img_dir=image_dir\n\n    def __len__(self):\n        return len(self.img_list)\n\n    def __getitem__(self,idx):\n        img_name=self.img_list[idx]\n        img_path=os.path.join(self.img_dir,img_name)\n        # print(img_path)\n        img=cv2.imread(img_path)\n        h, w = img.shape[:2]\n        img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)\n        img=tf.to_tensor(img)\n\n        inter=self.dataframe[self.dataframe[\"ImageID\"]==self.img_list[idx]]\n        boxes=inter[[\"x0\",\"y0\",\"w\",\"h\"]].values\n        # print(boxes)\n        boxes = center_to_min_max(torch.tensor(boxes), w, h)\n        area=boxes[:,2]*boxes[:,3]\n\n        # converting bounding box from x0y0wh format to x0y0x1y1 format\n        # boxes[:,2]=boxes[:,0]+boxes[:,2]\n        # boxes[:,3]=boxes[:,1]+boxes[:,3]\n        # print(boxes)\n\n        labels=torch.ones((boxes.shape[0]),dtype=torch.int64)\n        iscrowd=torch.zeros((boxes.shape[0]),dtype=torch.uint8)\n\n        target={}\n        target[\"boxes\"]=torch.as_tensor(boxes,dtype=torch.float32)\n        target[\"area\"]=torch.as_tensor(area,dtype=torch.float32)\n        # target[\"labels\"]=labels\n        labels = inter[['class_label']].values\n        print(labels[0][0])\n        target[\"labels\"]=torch.tensor([int(labels[0][0])], dtype=torch.int64)\n        print(target[\"labels\"].shape)\n        target[\"iscrowd\"]=iscrowd\n        target[\"id\"]=torch.tensor(idx)\n        target['height'] = torch.tensor(h)\n        target['width'] = torch.tensor(w)\n        # target['image_name'] = img_name\n        # print(img_name, target[\"boxes\"])\n        return img, target","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.261800Z","iopub.execute_input":"2024-12-04T18:18:03.262124Z","iopub.status.idle":"2024-12-04T18:18:03.276230Z","shell.execute_reply.started":"2024-12-04T18:18:03.262096Z","shell.execute_reply":"2024-12-04T18:18:03.275042Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# img_name=sorted(dataframe[\"ImageID\"].unique())[0]\n# img_path=os.path.join(image_path,img_name)\n# img=cv2.imread(img_path)\n# img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)\n# img=tf.to_tensor(img)\n\n# inter=dataframe[dataframe[\"ImageID\"]==sorted(dataframe[\"ImageID\"].unique())[0]]\n# boxes=inter[[\"x0\",\"y0\",\"w\",\"h\"]].values\n# area=boxes[:,2]*boxes[:,3]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.277525Z","iopub.execute_input":"2024-12-04T18:18:03.277870Z","iopub.status.idle":"2024-12-04T18:18:03.293039Z","shell.execute_reply.started":"2024-12-04T18:18:03.277840Z","shell.execute_reply":"2024-12-04T18:18:03.292096Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image_path","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.294544Z","iopub.execute_input":"2024-12-04T18:18:03.295020Z","iopub.status.idle":"2024-12-04T18:18:03.307758Z","shell.execute_reply.started":"2024-12-04T18:18:03.294975Z","shell.execute_reply":"2024-12-04T18:18:03.306673Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_ds=MosquitoDataset(df,image_path)\nval_ds=MosquitoDataset(df,image_path)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.309255Z","iopub.execute_input":"2024-12-04T18:18:03.310006Z","iopub.status.idle":"2024-12-04T18:18:03.327875Z","shell.execute_reply.started":"2024-12-04T18:18:03.309960Z","shell.execute_reply":"2024-12-04T18:18:03.326810Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(train_ds), len(val_ds)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.329344Z","iopub.execute_input":"2024-12-04T18:18:03.329860Z","iopub.status.idle":"2024-12-04T18:18:03.336758Z","shell.execute_reply.started":"2024-12-04T18:18:03.329814Z","shell.execute_reply":"2024-12-04T18:18:03.335867Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ss=ShuffleSplit(n_splits=1,test_size=0.2,random_state=1)\n\nindexs=range(len(train_ds))\nfor train_idx,val_idx in ss.split(indexs):\n    print(f\"Train dataset length: {len(train_idx)}\")\n    print(f\"Validation dataset length: {len(val_idx)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.337870Z","iopub.execute_input":"2024-12-04T18:18:03.338114Z","iopub.status.idle":"2024-12-04T18:18:03.354259Z","shell.execute_reply.started":"2024-12-04T18:18:03.338089Z","shell.execute_reply":"2024-12-04T18:18:03.353281Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_idx[:5]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.355442Z","iopub.execute_input":"2024-12-04T18:18:03.355765Z","iopub.status.idle":"2024-12-04T18:18:03.367338Z","shell.execute_reply.started":"2024-12-04T18:18:03.355736Z","shell.execute_reply":"2024-12-04T18:18:03.366338Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"val_idx[:5]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.372372Z","iopub.execute_input":"2024-12-04T18:18:03.372727Z","iopub.status.idle":"2024-12-04T18:18:03.379569Z","shell.execute_reply.started":"2024-12-04T18:18:03.372685Z","shell.execute_reply":"2024-12-04T18:18:03.378802Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_ds=Subset(train_ds,train_idx)\nval_ds=Subset(val_ds,val_idx)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.380917Z","iopub.execute_input":"2024-12-04T18:18:03.381254Z","iopub.status.idle":"2024-12-04T18:18:03.389487Z","shell.execute_reply.started":"2024-12-04T18:18:03.381224Z","shell.execute_reply":"2024-12-04T18:18:03.388631Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.loc[train_idx[:5]]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.390769Z","iopub.execute_input":"2024-12-04T18:18:03.391087Z","iopub.status.idle":"2024-12-04T18:18:03.409663Z","shell.execute_reply.started":"2024-12-04T18:18:03.391060Z","shell.execute_reply":"2024-12-04T18:18:03.408626Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.loc[val_idx[:5]]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.410849Z","iopub.execute_input":"2024-12-04T18:18:03.411246Z","iopub.status.idle":"2024-12-04T18:18:03.427220Z","shell.execute_reply.started":"2024-12-04T18:18:03.411197Z","shell.execute_reply":"2024-12-04T18:18:03.426154Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# df[df['ImageID']=='a47cb276-730f-4028-803f-235dae519521.jpeg']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.428746Z","iopub.execute_input":"2024-12-04T18:18:03.429146Z","iopub.status.idle":"2024-12-04T18:18:03.440068Z","shell.execute_reply.started":"2024-12-04T18:18:03.429103Z","shell.execute_reply":"2024-12-04T18:18:03.438975Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def show(img,target):\n    boxes = target['boxes']\n    w = target['width']\n    h = target['height']\n    # boxes = center_to_min_max(boxes, w, h)\n    # norm to pixel\n    # boxes[..., 0::2] = (target['width'] * boxes[..., 0::2])\n    # boxes[..., 1::2] = (target['height'] * boxes[..., 1::2])\n    \n    sample=img.permute(1,2,0).numpy().copy()\n    boxes=boxes.detach().numpy().astype(np.int32)\n    # print(boxes)\n    for box in boxes:\n        cv2.rectangle(sample,(box[0], box[1]),(box[2], box[3]),(220, 0, 0), 3)\n\n    plt.axis(\"off\");\n    plt.imshow(sample);","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.441539Z","iopub.execute_input":"2024-12-04T18:18:03.441980Z","iopub.status.idle":"2024-12-04T18:18:03.453559Z","shell.execute_reply.started":"2024-12-04T18:18:03.441936Z","shell.execute_reply":"2024-12-04T18:18:03.452730Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(8,8))\nimg, target=next(iter(train_ds))\nshow(img, target)\nplt.savefig(\"1.png\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:03.454847Z","iopub.execute_input":"2024-12-04T18:18:03.455144Z","iopub.status.idle":"2024-12-04T18:18:04.393069Z","shell.execute_reply.started":"2024-12-04T18:18:03.455115Z","shell.execute_reply":"2024-12-04T18:18:04.391963Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls -al /kaggle/input/dlp-object-detection/final_dlp_data/final_dlp_data/train/images/a47cb276-730f-4028-803f-235dae519521.jpeg","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:04.394293Z","iopub.execute_input":"2024-12-04T18:18:04.394636Z","iopub.status.idle":"2024-12-04T18:18:05.739158Z","shell.execute_reply.started":"2024-12-04T18:18:04.394578Z","shell.execute_reply":"2024-12-04T18:18:05.737696Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# file_name = f'{label_path}/a47cb276-730f-4028-803f-235dae519521.txt'\n# # print(file_name)\n# with open(file_name, encoding='utf-8') as f:\n#     data = f.read()\n#     print(data)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:05.741461Z","iopub.execute_input":"2024-12-04T18:18:05.742470Z","iopub.status.idle":"2024-12-04T18:18:05.747592Z","shell.execute_reply.started":"2024-12-04T18:18:05.742419Z","shell.execute_reply":"2024-12-04T18:18:05.746664Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def collate_fn(batch):\n    return tuple(zip(*batch))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:05.749004Z","iopub.execute_input":"2024-12-04T18:18:05.749338Z","iopub.status.idle":"2024-12-04T18:18:05.761669Z","shell.execute_reply.started":"2024-12-04T18:18:05.749311Z","shell.execute_reply":"2024-12-04T18:18:05.760741Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"batch_size=8\ntrain_dl=DataLoader(train_ds,batch_size=batch_size,shuffle=True,num_workers=2,\n                    pin_memory=True if torch.cuda.is_available else False,\n                    collate_fn=collate_fn)\nval_dl=DataLoader(val_ds,batch_size=batch_size,shuffle=False,num_workers=2,\n                  pin_memory=True if torch.cuda.is_available else False,\n                  collate_fn=collate_fn)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:05.763249Z","iopub.execute_input":"2024-12-04T18:18:05.763680Z","iopub.status.idle":"2024-12-04T18:18:05.774796Z","shell.execute_reply.started":"2024-12-04T18:18:05.763637Z","shell.execute_reply":"2024-12-04T18:18:05.773973Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# load a model pre-trained on COCO\nweights=FasterRCNN_ResNet50_FPN_Weights.DEFAULT\nmodel=fasterrcnn_resnet50_fpn(weights=weights)\n\n# replace the classifier with a new one, that has\n# num_classes which is user-defined\n# 1 class (wheat) + background\nnum_classes = 6\n\n# get number of input features for the classifier\nin_features=model.roi_heads.box_predictor.cls_score.in_features\n\n\n# replace the pre-trained head with a new one\nmodel.roi_heads.box_predictor=FastRCNNPredictor(in_channels=in_features,\n                                                num_classes=num_classes)\n\nmodel.to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:05.776172Z","iopub.execute_input":"2024-12-04T18:18:05.776464Z","iopub.status.idle":"2024-12-04T18:18:06.908184Z","shell.execute_reply.started":"2024-12-04T18:18:05.776436Z","shell.execute_reply":"2024-12-04T18:18:06.906987Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for params in model.children():\n    print(params)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:06.909563Z","iopub.execute_input":"2024-12-04T18:18:06.909996Z","iopub.status.idle":"2024-12-04T18:18:06.917495Z","shell.execute_reply.started":"2024-12-04T18:18:06.909964Z","shell.execute_reply":"2024-12-04T18:18:06.916411Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"ConvNet as fixed feature extractor: Here, we will freeze the weights for the backbone of\n   the network (resnet50 with feature pyramid network). The Regional Proposal network and\n   Region of Interest heads will be fine tuned using transfer learning.\"\"\"\n\nclassification_head=list(model.children())[-2:]\n\nfor children in list(model.children())[:-2]:\n    for params in children.parameters():\n        params.requires_grad=False\n\nparameters=[]\nfor heads in classification_head:\n    for params in heads.parameters():\n        parameters.append(params)\n\n\noptimizer=optim.Adam(parameters,lr=learning_rate)\nlr_scheduler=optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1,\n                                                  patience=8, threshold=0.0001)\n\n\nprint(classification_head)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:06.918973Z","iopub.execute_input":"2024-12-04T18:18:06.919354Z","iopub.status.idle":"2024-12-04T18:18:06.947801Z","shell.execute_reply.started":"2024-12-04T18:18:06.919312Z","shell.execute_reply":"2024-12-04T18:18:06.946661Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def get_lr(optimizer):\n    for params in optimizer.param_groups:\n        return params[\"lr\"]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:06.948969Z","iopub.execute_input":"2024-12-04T18:18:06.949322Z","iopub.status.idle":"2024-12-04T18:18:06.954425Z","shell.execute_reply.started":"2024-12-04T18:18:06.949279Z","shell.execute_reply":"2024-12-04T18:18:06.953388Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"loss_history={\"training_loss\":[],\n              \"validation_loss\":[]}\n\ntrain_len=len(train_dl.dataset)\nval_len=len(val_dl.dataset)\n\nbest_validation_loss=np.inf\nbest_weights=copy.deepcopy(model.state_dict())\n\nfor epoch in range(epochs):\n\n    training_loss=0.0\n    validation_loss=0.0\n    current_lr=get_lr(optimizer)\n\n    #During training, the model expects both the input tensors, as well as a targets\n    model.train()\n    for imgs, targets in train_dl:\n        imgs=[img.to(device) for img in imgs]\n        targets=[{k:v.to(device) for (k,v) in d.items()} for d in targets]\n\n        \"\"\"The model returns a Dict[Tensor] during training, containing the classification\n           and regression losses for both the RPN and the R-CNN.\"\"\"\n\n        loss_dict=model(imgs,targets)\n        losses=sum(loss for loss in loss_dict.values())\n        training_loss+=losses.item()\n\n        optimizer.zero_grad()\n        losses.backward()\n        optimizer.step()\n\n    with torch.no_grad():\n        for imgs, targets in val_dl:\n            imgs=[img.to(device) for img in imgs]\n            targets=[{k:v.to(device) for (k,v) in d.items()} for d in targets]\n\n            \"\"\"The model returns a Dict[Tensor] during training, containing the classification\n               and regression losses for both the RPN and the R-CNN.\"\"\"\n\n            loss_dict=model(imgs,targets)\n            losses=sum(loss for loss in loss_dict.values())\n            validation_loss+=losses.item()\n\n\n    lr_scheduler.step(validation_loss)\n    if current_lr!=get_lr(optimizer):\n        print(\"Loading best Model weights\")\n        model.load_state_dict(best_weights)\n\n    if validation_loss<best_validation_loss:\n        best_validation_loss=validation_loss\n        best_weights=copy.deepcopy(model.state_dict())\n        print(\"Updating Best Model weights\")\n\n\n    loss_history[\"training_loss\"].append(training_loss/train_len)\n    loss_history[\"validation_loss\"].append(validation_loss/val_len)\n\n    print(f\"\\n{epoch+1}/{epochs}\")\n    print(f\"Training Loss: {training_loss/train_len}\")\n    print(f\"Validation_loss: {validation_loss/val_len}\")\n    print(\"\\n\"+\"*\"*50)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T18:18:06.956392Z","iopub.execute_input":"2024-12-04T18:18:06.957149Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.lineplot(x=range(epochs),y=loss_history[\"training_loss\"],label=\"Train Losses\");\nsns.lineplot(x=range(epochs),y=loss_history[\"validation_loss\"],label=\"Validation Losses\");\nplt.title(\"Training Validation Datasets Losses Plot\");\nplt.legend();\nplt.savefig(\"3.jpg\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"torch.save(best_weights,model_weights_file)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.load_state_dict(torch.load(model_weights_file))\nmodel.to(device)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def show(img,boxes,ax,color=(255,0,0), w=32, h=32):\n    # print(boxes)\n    # norm to pixel\n    # boxes[..., 0::2] = (w * boxes[..., 0::2])\n    # boxes[..., 1::2] = (h * boxes[..., 1::2])\n\n    boxes=boxes.detach().cpu().numpy().astype(np.int32)\n    sample=img.permute(1,2,0).numpy().copy()\n\n    for box in boxes:\n        cv2.rectangle(sample,(box[0], box[1]),(box[2], box[3]),color, 5)\n\n    ax.axis(\"off\");\n    ax.imshow(sample);","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# def show(img,target):\n#     boxes = target['boxes']\n#     w = target['width']\n#     h = target['height']\n    \n#     # norm to pixel\n#     boxes[..., 0::2] = (target['width'] * boxes[..., 0::2])\n#     boxes[..., 1::2] = (target['height'] * boxes[..., 1::2])\n    \n#     sample=img.permute(1,2,0).numpy().copy()\n#     boxes=boxes.detach().numpy().astype(np.int32)\n#     for box in boxes:\n#         cv2.rectangle(sample,(box[0], box[1]),(box[2], box[3]),(220, 0, 0), 3)\n\n#     plt.axis(\"off\");\n#     plt.imshow(sample);","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"During inference, the model requires only the input tensors, and returns the\n   post-processed predictions as a List[Dict[Tensor]], one for each input image. The fields\n   of the Dict are as follows:\n   - boxes (FloatTensor[N, 4]): the predicted boxes in [x0, y0, x1, y1] format\n   - labels (Int64Tensor[N]): the predicted labels for each image\n   - scores (Tensor[N]): the scores or each prediction\"\"\"\n\nfig,axes=plt.subplots(8,2,figsize=(8,16))\nplt.subplots_adjust(wspace=0.1,hspace=0.1)\n\nimgs,targets=next(iter(train_dl))\nmodel.eval()\noutput=model([img.to(device) for img in imgs])\nfor i,idx in enumerate(range(len(imgs))):\n    img=imgs[idx]\n    predictions=output[idx]\n\n    #real bounding boxes\n    show(img,targets[idx]['boxes'],axes[i,0],color=(0,255,0), w=targets[idx]['width'], h=targets[idx]['height'])\n\n    #non-max suppression\n    #threshold=0.5\n    #iou_threshold=0.8\n    \"\"\"Non-max suppression is the final step of these object detection algorithms and is\n       used to select the most appropriate bounding box for the object.\n       The NMS takes two things into account\n        -The objectiveness score is given by the model\n        -The overlap or IOU of the bounding boxes\"\"\"\n\n    pp_boxes=predictions[\"boxes\"][predictions[\"scores\"]>=threshold]\n    scores=predictions[\"scores\"][predictions[\"scores\"]>=threshold]\n    nms=torchvision.ops.nms(pp_boxes,scores,iou_threshold=iou_threshold)\n    pp_boxes=pp_boxes[nms]\n    # print(pp_boxes)\n\n\n    show(img, pp_boxes, axes[i,1], w=targets[idx]['width'], h=targets[idx]['height']);\n\nplt.savefig(\"4.png\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Testing","metadata":{}},{"cell_type":"code","source":"model.load_state_dict(torch.load(model_weights_file))\nmodel.to(device)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class MosquitoTestDataset(Dataset):\n    def __init__(self, dataframe, image_dir):\n        super().__init__()\n        self.dataframe=dataframe\n        self.img_list=sorted(self.dataframe[\"ImageID\"].unique())\n        self.img_dir=image_dir\n\n    def __len__(self):\n        return len(self.img_list)\n\n    def __getitem__(self,idx):\n        img_name=self.img_list[idx]\n        img_path=os.path.join(self.img_dir,img_name)\n        # print(img_path)\n        img=cv2.imread(img_path)\n        h, w = img.shape[:2]\n        img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)\n        img=tf.to_tensor(img)\n        return img","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def create_test_dataframe_from_folder(image_path):\n    # Initialize a list to store data for the DataFrame\n    data = []\n\n    # Iterate over all files in the folder\n    for file in os.listdir(image_path):\n        if file.endswith((\".jpg\", \".png\", \".jpeg\")):  \n            image_file = file\n            \n            # Full paths\n            image_path = os.path.join(image_path, image_file)\n            \n            # Add the row to the data list\n            data.append([image_file])\n\n    # Create a DataFrame\n    # Use \"column1\", \"column2\", ... as placeholders for text columns\n    column_names = [\"ImageID\"]\n    df = pd.DataFrame(data, columns=column_names)\n    return df","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_image_path = \"/kaggle/input/dlp-object-detection/final_dlp_data/final_dlp_data/test/images\"\ntest_df = create_test_dataframe_from_folder(test_image_path)\ntest_df.head()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df = test_df\ntest_ds=MosquitoTestDataset(test_df, test_image_path)\ntest_dl=DataLoader(test_ds,batch_size=batch_size,shuffle=False,num_workers=2,\n                  pin_memory=True if torch.cuda.is_available else False,\n                  collate_fn=collate_fn)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(test_ds)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(test_dl)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nfrom PIL import Image\nfrom torchvision import transforms\nfrom torch.utils.data import Dataset\n\nclass ImageDataset(Dataset):\n    def __init__(self, image_dir, transform=None):\n        \"\"\"\n        Args:\n        - image_dir (str): Path to the directory containing images.\n        - transform (callable, optional): Transformation to apply to each image.\n        \"\"\"\n        self.image_dir = image_dir\n        self.image_files = [f for f in os.listdir(image_dir) if f.lower().endswith(('.jpg', '.jpeg', '.png'))]\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.image_files)\n\n    def __getitem__(self, idx):\n        img_path = os.path.join(self.image_dir, self.image_files[idx])\n        img=cv2.imread(img_path)\n        h, w = img.shape[:2]\n        img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)\n        img=tf.to_tensor(img)\n        if self.transform:\n            image = self.transform(img)\n        return img, (self.image_files[idx], h, w)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.ToTensor()  # Convert image to a tensor\n])\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torch.utils.data import DataLoader\n\n# dataset = ImageDataset(test_image_path, transform=transform)\ndataset = ImageDataset(test_image_path)\ndata_loader = DataLoader(dataset, batch_size=1, shuffle=False)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torchvision.ops import nms\n\ndef apply_nms(boxes, scores, iou_threshold=0.5):\n    \"\"\"\n    Apply Non-Maximum Suppression to filter bounding boxes.\n\n    Args:\n    - boxes (Tensor): Bounding box coordinates, shape [N, 4].\n    - scores (Tensor): Confidence scores for each box, shape [N].\n    - iou_threshold (float): IOU threshold for suppression.\n\n    Returns:\n    - indices (Tensor): Indices of the boxes to keep.\n    \"\"\"\n    indices = nms(boxes, scores, iou_threshold)\n    # print(indices)\n    return indices\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def min_max_to_center(box, w, h):\n    box = box.detach().numpy()\n    print(box)\n    print(w, h)\n    x_min, y_min, x_max, y_max = box[0]\n    print(\"Norm\", x_min, y_min, x_max, y_max)\n\n    # Norm to pixel\n    x_min = x_min * w\n    y_min = y_min * h\n    x_max = x_max * w\n    y_max = y_max * h\n    \n    print(\"denorm\", x_min, y_min, x_max, y_max)\n\n    # Changing format\n    x_center = x_min + w / 2\n    y_center = y_min + h / 2\n    result = [x_center/w, y_center/h, (x_max - x_min)/w, (y_max - y_min)/ h ]\n    print('center',result)\n    return torch.tensor([result])","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"class_map = {\n    \"aegypti\": 0,\n    \"albopictus\": 1,\n    \"anopheles\": 2,\n    \"culex\": 3,\n    \"culiseta\": 4,\n    \"japonicus/koreicus\": 5\n}\nlabel_map = {\n    0: \"aegypti\",\n    1: \"albopictus\",\n    2: \"anopheles\",\n    3: \"culex\",\n    4: \"culiseta\",\n    5: \"japonicus/koreicus\"\n}","metadata":{"execution":{"iopub.status.busy":"2024-12-04T09:47:15.483533Z","iopub.execute_input":"2024-12-04T09:47:15.483978Z","iopub.status.idle":"2024-12-04T09:47:15.517573Z","shell.execute_reply.started":"2024-12-04T09:47:15.483925Z","shell.execute_reply":"2024-12-04T09:47:15.516819Z"}}},{"cell_type":"code","source":"class_map = { \n    \"aegypti\": 0, \n    \"albopictus\": 1, \n    \"anopheles\": 2, \n    \"culex\": 3, \n    \"culiseta\": 4, \n    \"japonicus/koreicus\": 5 \n} \nlabel_map = { \n    0: \"aegypti\", \n    1: \"albopictus\", \n    2: \"anopheles\", \n    3: \"culex\", \n    4: \"culiseta\", \n    5: \"japonicus/koreicus\"\n}","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nfrom PIL import ImageDraw\n\n# Load the trained model\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel.eval()\nmodel.to(device)\n\n\n# Inference loop\nidx = 0\ncount = 5\ninference_results = []\nfor images, (file_names, height, width) in data_loader:\n    # print(images)\n    images = images.to(device)\n    with torch.no_grad():\n        predictions = model(images)\n        # print(predictions)\n        for img_tensor, preds, file_name in zip(images, predictions, file_names):\n            boxes = preds['boxes']\n            scores = preds['scores']\n            labels = preds['labels']\n            # print(\"---scores---\",scores)\n            # print(\"---labels---\",labels)\n            keep = scores >= 0\n            boxes = boxes[keep]\n            scores = scores[keep]\n            labels = labels[keep]\n            # print(\"---filtered scores---\",scores)\n            # print(\"---filtered labels---\",labels)\n            # Apply NMS\n            nms_indices = apply_nms(boxes, scores, iou_threshold)\n            print('nms', nms_indices)\n            print(\"---nms scores---\",scores[nms_indices])\n            print(\"---nms labels---\",labels[nms_indices])\n            max_idx = np.argmax(scores[nms_indices].cpu()).item()\n            # print('max_idx', max_idx)\n            filtered_boxes = boxes[max_idx]\n            x_center = (filtered_boxes[0] + filtered_boxes[2])/2\n            y_center = (filtered_boxes[1] + filtered_boxes[3])/2\n            w = filtered_boxes[2] - filtered_boxes[0]\n            h = filtered_boxes[3] - filtered_boxes[1]\n\n            box = torch.tensor([x_center.item(), y_center.item(), w.item(), h.item()])\n            box[0::2] = box[0::2] / width.item()\n            box[1::2] = box[0::2] / height.item()\n            # res.extend(box.detach().cpu().numpy())\n            # print(res)\n            output = [idx, file_names[0], label_map[labels[max_idx].item()], scores[max_idx].item()]\n            print(output)\n            output.extend(box.detach().cpu().numpy())\n            inference_results.append(output)\n            idx += 1\n            print(\"\\n\"+\"*\"*50)\n    # break\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T15:43:19.977868Z","iopub.execute_input":"2024-12-04T15:43:19.978306Z","iopub.status.idle":"2024-12-04T15:43:23.497796Z","shell.execute_reply.started":"2024-12-04T15:43:19.978263Z","shell.execute_reply":"2024-12-04T15:43:23.496567Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"result_df = pd.DataFrame(inference_results, columns=['id','ImageID', 'LabelName', 'Conf', 'xcenter', 'ycenter', 'bbx_width', 'bbx_height'])\nresult_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T15:43:23.500008Z","iopub.execute_input":"2024-12-04T15:43:23.500773Z","iopub.status.idle":"2024-12-04T15:43:23.518210Z","shell.execute_reply.started":"2024-12-04T15:43:23.500716Z","shell.execute_reply":"2024-12-04T15:43:23.517291Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"result_df.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T09:10:23.148002Z","iopub.execute_input":"2024-12-04T09:10:23.148689Z","iopub.status.idle":"2024-12-04T09:10:23.157614Z","shell.execute_reply.started":"2024-12-04T09:10:23.148649Z","shell.execute_reply":"2024-12-04T09:10:23.156826Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def submit(image_id, labels):\n    submission=pd.DataFrame(columns=['Image_ID','Label'])\n    submission['Image_ID']=image_id\n    submission['Label']=labels\n    submission.to_csv('submission.csv',index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-04T09:07:19.450276Z","iopub.status.idle":"2024-12-04T09:07:19.450553Z","shell.execute_reply.started":"2024-12-04T09:07:19.450417Z","shell.execute_reply":"2024-12-04T09:07:19.450431Z"}},"outputs":[],"execution_count":null}]}