{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":19989,"databundleVersionId":1160143,"sourceType":"competition"}],"dockerImageVersionId":30733,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"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\nimport numpy as np # linear algebra\nimport 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\nimport os\nfor 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","execution":{"iopub.status.busy":"2024-06-15T07:22:35.689353Z","iopub.execute_input":"2024-06-15T07:22:35.689759Z","iopub.status.idle":"2024-06-15T07:22:40.968129Z","shell.execute_reply.started":"2024-06-15T07:22:35.689726Z","shell.execute_reply":"2024-06-15T07:22:40.966139Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <b> Importing Required Libraries:","metadata":{}},{"cell_type":"code","source":"# Standard library imports\nimport os  # For handling file paths\nimport random  # For generating random numbers\nfrom collections import Counter  # For counting hashable objects\n\n# Third-party imports\nimport numpy as np  # For numerical operations\nimport pandas as pd  # For data manipulation and analysis\nfrom PIL import Image, ImageDraw  # For image handling and drawing\nimport matplotlib.pyplot as plt  # For plotting\nfrom sklearn.model_selection import train_test_split  # For splitting data into training and testing sets\n\n# PyTorch imports\nimport torch  # For tensor operations and neural networks\nimport torchvision  # For computer vision tasks\n\n# Torchvision imports\nfrom torchvision import transforms as T  # For data transformations\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor  # For Faster R-CNN model","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:32:37.868032Z","iopub.execute_input":"2024-06-15T07:32:37.868856Z","iopub.status.idle":"2024-06-15T07:32:43.205486Z","shell.execute_reply.started":"2024-06-15T07:32:37.868818Z","shell.execute_reply":"2024-06-15T07:32:43.204506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <b> Loading the Training Dataset","metadata":{}},{"cell_type":"code","source":"train =  pd.read_csv('/kaggle/input/global-wheat-detection/train.csv')\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:34:20.159951Z","iopub.execute_input":"2024-06-15T07:34:20.160793Z","iopub.status.idle":"2024-06-15T07:34:20.445402Z","shell.execute_reply.started":"2024-06-15T07:34:20.16076Z","shell.execute_reply":"2024-06-15T07:34:20.444477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### <b> Splliting the bbox column to x1,y1,w,h","metadata":{}},{"cell_type":"code","source":"coord = pd.DataFrame(list(train.bbox.apply(lambda x : x[1:-1].split(\",\")).values),columns=[\"x1\",\"y1\",\"w\",\"h\"])","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:37:09.813799Z","iopub.execute_input":"2024-06-15T07:37:09.814206Z","iopub.status.idle":"2024-06-15T07:37:10.359298Z","shell.execute_reply.started":"2024-06-15T07:37:09.81418Z","shell.execute_reply":"2024-06-15T07:37:10.358413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.concat([train,coord],axis=1)\ndf","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:37:27.508668Z","iopub.execute_input":"2024-06-15T07:37:27.509496Z","iopub.status.idle":"2024-06-15T07:37:27.544513Z","shell.execute_reply.started":"2024-06-15T07:37:27.509457Z","shell.execute_reply":"2024-06-15T07:37:27.54344Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### <b> Making the values of the columns numeric values: ","metadata":{}},{"cell_type":"code","source":"df['x1']=pd.to_numeric(df['x1'])\ndf['y1']=pd.to_numeric(df['y1'])\ndf['w']=pd.to_numeric(df['w'])\ndf['h']=pd.to_numeric(df['h'])","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:38:54.460056Z","iopub.execute_input":"2024-06-15T07:38:54.460775Z","iopub.status.idle":"2024-06-15T07:38:54.866665Z","shell.execute_reply.started":"2024-06-15T07:38:54.460736Z","shell.execute_reply":"2024-06-15T07:38:54.865862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <b> Calcualte the y2,x2 :","metadata":{}},{"cell_type":"code","source":"df['x2']=df['x1']+df['w']\ndf['y2']=df['y1']+df['h']","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:39:41.522099Z","iopub.execute_input":"2024-06-15T07:39:41.523086Z","iopub.status.idle":"2024-06-15T07:39:41.53132Z","shell.execute_reply.started":"2024-06-15T07:39:41.523049Z","shell.execute_reply":"2024-06-15T07:39:41.530403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:39:45.842168Z","iopub.execute_input":"2024-06-15T07:39:45.842538Z","iopub.status.idle":"2024-06-15T07:39:45.869744Z","shell.execute_reply.started":"2024-06-15T07:39:45.842507Z","shell.execute_reply":"2024-06-15T07:39:45.868839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### <b> Dropping unnecessary column:","metadata":{}},{"cell_type":"code","source":"df.drop(['bbox','width','height','w','h','source'],axis=1,inplace=True)","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:41:06.536387Z","iopub.execute_input":"2024-06-15T07:41:06.536817Z","iopub.status.idle":"2024-06-15T07:41:06.552212Z","shell.execute_reply.started":"2024-06-15T07:41:06.536784Z","shell.execute_reply":"2024-06-15T07:41:06.551261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:41:14.922618Z","iopub.execute_input":"2024-06-15T07:41:14.922997Z","iopub.status.idle":"2024-06-15T07:41:14.936393Z","shell.execute_reply.started":"2024-06-15T07:41:14.922968Z","shell.execute_reply":"2024-06-15T07:41:14.935416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Take the unique ids of the images:","metadata":{}},{"cell_type":"code","source":"unique_imgs=df.image_id.unique()\nunique_imgs","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:42:17.223612Z","iopub.execute_input":"2024-06-15T07:42:17.223985Z","iopub.status.idle":"2024-06-15T07:42:17.244123Z","shell.execute_reply.started":"2024-06-15T07:42:17.223957Z","shell.execute_reply":"2024-06-15T07:42:17.243214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Make custom class for preparing the data:","metadata":{}},{"cell_type":"code","source":"# Define a custom dataset class inheriting from torch.utils.data.Dataset\nclass custDat(torch.utils.data.Dataset):\n    def __init__(self, df, unique_imgs, indices):\n        \"\"\"\n        Initialize the dataset with a DataFrame, a list of unique image names, and indices.\n        \n        Args:\n            df (pd.DataFrame): DataFrame containing image IDs and bounding box information.\n            unique_imgs (list): List of unique image names.\n            indices (list): List of indices to be used for accessing the dataset.\n        \"\"\"\n        self.df = df  # DataFrame containing image and bounding box data\n        self.unique_imgs = unique_imgs  # List of unique image names\n        self.indices = indices  # Indices for accessing the images in the dataset\n    \n    def __len__(self):\n        \"\"\"\n        Return the length of the dataset.\n        \n        Returns:\n            int: Number of samples in the dataset.\n        \"\"\"\n        return len(self.indices)  # Length of the dataset based on the indices\n    \n    def __getitem__(self, idx):\n        \"\"\"\n        Get an item from the dataset at the specified index.\n        \n        Args:\n            idx (int): Index of the item to be fetched.\n        \n        Returns:\n            tuple: Tuple containing the image tensor and the target dictionary.\n        \"\"\"\n        # Get the image name using the index\n        image_name = self.unique_imgs[self.indices[idx]]\n        \n        # Get the bounding boxes for the image\n        boxes = self.df[self.df.image_id == image_name].values[:, 1:].astype(\"float\")\n        \n        # Open the image and convert it to RGB format\n        img = Image.open(\"../input/global-wheat-detection/train/\" + image_name + \".jpg\").convert('RGB')\n        \n        # Create labels tensor with value 1 for each bounding box\n        labels = torch.ones(boxes.shape[0], dtype=torch.int64)\n        \n        # Create the target dictionary containing boxes and labels\n        target = {}\n        target[\"boxes\"] = torch.tensor(boxes)  # Bounding boxes as a tensor\n        target[\"label\"] = labels  # Labels as a tensor\n        \n        # Return the image converted to a tensor and the target dictionary\n        return T.ToTensor()(img), target","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:46:15.826186Z","iopub.execute_input":"2024-06-15T07:46:15.826615Z","iopub.status.idle":"2024-06-15T07:46:15.840735Z","shell.execute_reply.started":"2024-06-15T07:46:15.826578Z","shell.execute_reply":"2024-06-15T07:46:15.839679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Spit the data int train and validation:","metadata":{}},{"cell_type":"code","source":"train_inds , val_inds =train_test_split(range(unique_imgs.shape[0]),test_size=0.1)","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:47:57.44116Z","iopub.execute_input":"2024-06-15T07:47:57.441582Z","iopub.status.idle":"2024-06-15T07:47:57.448715Z","shell.execute_reply.started":"2024-06-15T07:47:57.441538Z","shell.execute_reply":"2024-06-15T07:47:57.447528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def custom_collate(data):\n    return data","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:48:10.234934Z","iopub.execute_input":"2024-06-15T07:48:10.235311Z","iopub.status.idle":"2024-06-15T07:48:10.239519Z","shell.execute_reply.started":"2024-06-15T07:48:10.235281Z","shell.execute_reply":"2024-06-15T07:48:10.238557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Need for custom_collate in Object Detection\nHandling Variable Number of Annotations:\n\nIn object detection, each image can have a different number of objects, and consequently, a different number of annotations (bounding boxes). The default collate function in PyTorch (default_collate) expects each sample in the batch to have the same shape, which is not the case here.\nMaintaining Data Structure:\n\nThe custom_collate function helps maintain the structure of the data when it is batched together. Specifically, it returns the data as a list of tuples, where each tuple contains an image tensor and its corresponding target dictionary. This structure is essential for the Faster R-CNN model, which expects a list of such tuples as input.\nAvoiding Collate Errors:\n\nWithout a custom collate function, the DataLoader might try to convert the list of dictionaries (targets) into a single tensor, which would fail due to the variable number of bounding boxes per image.","metadata":{}},{"cell_type":"markdown","source":"Input: data is a list of tuples. Each tuple contains:\n\nAn image tensor (e.g., T.ToTensor()(img)).\nA target dictionary (e.g., target with keys \"boxes\" and \"labels\").\nOutput: The same list of tuples is returned without any modification.","metadata":{}},{"cell_type":"markdown","source":"# Call the data loader to prepare it to the model:","metadata":{}},{"cell_type":"code","source":"train_dl = torch.utils.data.DataLoader(custDat(df,unique_imgs,train_inds),\n                                       batch_size=16,\n                                       shuffle=True,\n                                       collate_fn=custom_collate,\n                                       pin_memory=True if torch.cuda.is_available() else False)\nval_dl = torch.utils.data.DataLoader(custDat(df,unique_imgs,val_inds),\n                                     batch_size=8,\n                                     shuffle=True,\n                                     collate_fn=custom_collate,\n                                     pin_memory=True if torch.cuda.is_available() else False)","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:49:24.913072Z","iopub.execute_input":"2024-06-15T07:49:24.913494Z","iopub.status.idle":"2024-06-15T07:49:24.943556Z","shell.execute_reply.started":"2024-06-15T07:49:24.913461Z","shell.execute_reply":"2024-06-15T07:49:24.942392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Modeling:","metadata":{}},{"cell_type":"code","source":"model = torchvision.models.detection.fasterrcnn_resnet50_fpn(weights=True)","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:49:57.949532Z","iopub.execute_input":"2024-06-15T07:49:57.950175Z","iopub.status.idle":"2024-06-15T07:49:59.94012Z","shell.execute_reply.started":"2024-06-15T07:49:57.950143Z","shell.execute_reply":"2024-06-15T07:49:59.938843Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:50:30.421745Z","iopub.execute_input":"2024-06-15T07:50:30.422121Z","iopub.status.idle":"2024-06-15T07:50:30.431414Z","shell.execute_reply.started":"2024-06-15T07:50:30.422091Z","shell.execute_reply":"2024-06-15T07:50:30.43047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_classes=2","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:50:48.760807Z","iopub.execute_input":"2024-06-15T07:50:48.761196Z","iopub.status.idle":"2024-06-15T07:50:48.767044Z","shell.execute_reply.started":"2024-06-15T07:50:48.761166Z","shell.execute_reply":"2024-06-15T07:50:48.76625Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"in_features=model.roi_heads.box_predictor.cls_score.in_features\nmodel.roi_heads.box_predictor =  FastRCNNPredictor(in_features,num_classes)\nmodel","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:51:20.136407Z","iopub.execute_input":"2024-06-15T07:51:20.13721Z","iopub.status.idle":"2024-06-15T07:51:20.148281Z","shell.execute_reply.started":"2024-06-15T07:51:20.137179Z","shell.execute_reply":"2024-06-15T07:51:20.147472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:51:41.781191Z","iopub.execute_input":"2024-06-15T07:51:41.781565Z","iopub.status.idle":"2024-06-15T07:51:41.786368Z","shell.execute_reply.started":"2024-06-15T07:51:41.781522Z","shell.execute_reply":"2024-06-15T07:51:41.785364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:51:49.225779Z","iopub.execute_input":"2024-06-15T07:51:49.226634Z","iopub.status.idle":"2024-06-15T07:51:49.232437Z","shell.execute_reply.started":"2024-06-15T07:51:49.226598Z","shell.execute_reply":"2024-06-15T07:51:49.231486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer = torch.optim.SGD(model.parameters(),lr=0.001,momentum=0.9,weight_decay=0.005)\nnum_epochs=5","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:52:01.061011Z","iopub.execute_input":"2024-06-15T07:52:01.061448Z","iopub.status.idle":"2024-06-15T07:52:01.07095Z","shell.execute_reply.started":"2024-06-15T07:52:01.061414Z","shell.execute_reply":"2024-06-15T07:52:01.068576Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### train the model with 5 epochs and prin the loss:","metadata":{}},{"cell_type":"code","source":"# Move the model to the specified device (CPU or GPU)\nmodel.to(device)\n\n# Loop over the number of epochs\nfor epoch in range(num_epochs):\n    epoch_loss = 0  # Initialize the loss for the current epoch\n    \n    # Loop over the data in the training DataLoader\n    for data in train_dl:\n        imgs = []  # List to store the images\n        targets = []  # List to store the target dictionaries\n        \n        # Loop over each data sample in the batch\n        for d in data:\n            # Append the image tensor to the imgs list and move it to the device\n            imgs.append(d[0].to(device))\n            \n            # Create a target dictionary for the current sample\n            targ = {}\n            # Move the bounding boxes tensor to the device\n            targ['boxes'] = d[1]['boxes'].to(device)\n            # Move the labels tensor to the device\n            targ['labels'] = d[1]['label'].to(device)\n            \n            # Append the target dictionary to the targets list\n            targets.append(targ)\n        \n        # Perform a forward pass through the model and get the loss dictionary\n        loss_dict = model(imgs, targets)\n        \n        # Sum all the losses in the loss dictionary to get the total loss\n        loss = sum(v for v in loss_dict.values())\n        \n        # Add the loss for the current batch to the epoch loss, converting it to a numpy value\n        epoch_loss += loss.cpu().detach().numpy()\n        \n        # Zero the gradients of the optimizer\n        optimizer.zero_grad()\n        \n        # Backpropagate the loss\n        loss.backward()\n        \n        # Update the model parameters\n        optimizer.step()\n    \n    # Print the total loss for the current epoch\n    print(epoch_loss)","metadata":{"execution":{"iopub.status.busy":"2024-06-15T07:53:05.808484Z","iopub.execute_input":"2024-06-15T07:53:05.808921Z","iopub.status.idle":"2024-06-15T08:17:29.147199Z","shell.execute_reply.started":"2024-06-15T07:53:05.808892Z","shell.execute_reply":"2024-06-15T08:17:29.146195Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Evaluate the model","metadata":{}},{"cell_type":"code","source":"model.eval()\ndata = iter(val_dl).__next__()","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:14.874287Z","iopub.execute_input":"2024-06-15T08:18:14.874676Z","iopub.status.idle":"2024-06-15T08:18:15.276565Z","shell.execute_reply.started":"2024-06-15T08:18:14.874644Z","shell.execute_reply":"2024-06-15T08:18:15.275744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img= data[0][0]\nboxes=data[0][1]['boxes']\nlabels=data[0][1]['label']","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:19.47313Z","iopub.execute_input":"2024-06-15T08:18:19.473887Z","iopub.status.idle":"2024-06-15T08:18:19.47876Z","shell.execute_reply.started":"2024-06-15T08:18:19.473855Z","shell.execute_reply":"2024-06-15T08:18:19.477609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"output = model([img.to(device)])","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:22.814981Z","iopub.execute_input":"2024-06-15T08:18:22.815358Z","iopub.status.idle":"2024-06-15T08:18:22.929164Z","shell.execute_reply.started":"2024-06-15T08:18:22.815327Z","shell.execute_reply":"2024-06-15T08:18:22.928108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- output os the evaluation:","metadata":{}},{"cell_type":"code","source":"output","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:25.122796Z","iopub.execute_input":"2024-06-15T08:18:25.123518Z","iopub.status.idle":"2024-06-15T08:18:25.169625Z","shell.execute_reply.started":"2024-06-15T08:18:25.123486Z","shell.execute_reply":"2024-06-15T08:18:25.168733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"out_bbox=output[0]['boxes']\nout_scores=output[0]['scores']","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:27.002789Z","iopub.execute_input":"2024-06-15T08:18:27.003715Z","iopub.status.idle":"2024-06-15T08:18:27.009131Z","shell.execute_reply.started":"2024-06-15T08:18:27.003662Z","shell.execute_reply":"2024-06-15T08:18:27.00793Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"keep = torchvision.ops.nms(out_bbox,out_scores,0.45)","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:27.842756Z","iopub.execute_input":"2024-06-15T08:18:27.843119Z","iopub.status.idle":"2024-06-15T08:18:27.847917Z","shell.execute_reply.started":"2024-06-15T08:18:27.843088Z","shell.execute_reply":"2024-06-15T08:18:27.846948Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"out_bbox.shape , keep.shape","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:29.192953Z","iopub.execute_input":"2024-06-15T08:18:29.193347Z","iopub.status.idle":"2024-06-15T08:18:29.199251Z","shell.execute_reply.started":"2024-06-15T08:18:29.193317Z","shell.execute_reply":"2024-06-15T08:18:29.198417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- prediction detection:","metadata":{}},{"cell_type":"code","source":"im = (img.permute(1,2,0).cpu().detach().numpy()*255).astype('uint8')\nim","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:31.312713Z","iopub.execute_input":"2024-06-15T08:18:31.313072Z","iopub.status.idle":"2024-06-15T08:18:31.324354Z","shell.execute_reply.started":"2024-06-15T08:18:31.313046Z","shell.execute_reply":"2024-06-15T08:18:31.323382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vsample = Image.fromarray(im)\ndraw = ImageDraw.Draw(vsample)\nfor box in boxes :\n    draw.rectangle(list(box),fill=None,outline='red')\nvsample","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:32.610743Z","iopub.execute_input":"2024-06-15T08:18:32.611729Z","iopub.status.idle":"2024-06-15T08:18:33.097743Z","shell.execute_reply.started":"2024-06-15T08:18:32.611693Z","shell.execute_reply":"2024-06-15T08:18:33.096395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Save the model state\ntorch.save(model.state_dict(), 'modified_fasterrcnn_resnet50_fpn.pth')","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:33.874638Z","iopub.execute_input":"2024-06-15T08:18:33.874979Z","iopub.status.idle":"2024-06-15T08:18:34.115346Z","shell.execute_reply.started":"2024-06-15T08:18:33.874954Z","shell.execute_reply":"2024-06-15T08:18:34.114582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\ndata = iter(val_dl).__next__()\n\nimg= data[0][0]\nboxes=data[0][1]['boxes']\nlabels=data[0][1]['label']\n\noutput = model([img.to(device)])\n\nout_bbox=output[0]['boxes']\nout_scores=output[0]['scores']\n\nkeep = torchvision.ops.nms(out_bbox,out_scores,0.45)\n\nout_bbox.shape , keep.shape\nim = (img.permute(1,2,0).cpu().detach().numpy()*255).astype('uint8')\n\nvsample = Image.fromarray(im)\ndraw = ImageDraw.Draw(vsample)\nfor box in boxes :\n    draw.rectangle(list(box),fill=None,outline='red')\nvsample","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:43.3813Z","iopub.execute_input":"2024-06-15T08:18:43.381658Z","iopub.status.idle":"2024-06-15T08:18:44.318278Z","shell.execute_reply.started":"2024-06-15T08:18:43.38163Z","shell.execute_reply":"2024-06-15T08:18:44.316902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\ndata = iter(val_dl).__next__()\n\nimg= data[0][0]\nboxes=data[0][1]['boxes']\nlabels=data[0][1]['label']\n\noutput = model([img.to(device)])\n\nout_bbox=output[0]['boxes']\nout_scores=output[0]['scores']\n\nkeep = torchvision.ops.nms(out_bbox,out_scores,0.45)\n\nout_bbox.shape , keep.shape\nim = (img.permute(1,2,0).cpu().detach().numpy()*255).astype('uint8')\n\nvsample = Image.fromarray(im)\ndraw = ImageDraw.Draw(vsample)\nfor box in boxes :\n    draw.rectangle(list(box),fill=None,outline='red')\nvsample","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:46.254462Z","iopub.execute_input":"2024-06-15T08:18:46.254829Z","iopub.status.idle":"2024-06-15T08:18:47.062134Z","shell.execute_reply.started":"2024-06-15T08:18:46.254802Z","shell.execute_reply":"2024-06-15T08:18:47.060789Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load the saved model","metadata":{}},{"cell_type":"code","source":"import torch\nimport torchvision\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\n\n# Function to create the model and replace the classifier head\ndef create_model(num_classes):\n    # Load a pre-trained model\n    model = torchvision.models.detection.fasterrcnn_resnet50_fpn(weights=False)\n    \n    # Get the number of input features for the classifier\n    in_features = model.roi_heads.box_predictor.cls_score.in_features\n    \n    # Replace the pre-trained head with a new one (adjusting for the number of classes)\n    model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)\n    \n    return model\n\n# Specify the number of classes (1 class + background)\nnum_classes = 2\n\n# Create a model instance\nmodel2 = create_model(num_classes)\n\n# Load the saved model state dictionary\nmodel2.load_state_dict(torch.load('/kaggle/working/modified_fasterrcnn_resnet50_fpn.pth'))\n\n# Move the model to the specified device\ndevice = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\nmodel2.to(device)\n\n# Now the model is ready to be used for inference or further training","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:18:57.890931Z","iopub.execute_input":"2024-06-15T08:18:57.891279Z","iopub.status.idle":"2024-06-15T08:18:59.495725Z","shell.execute_reply.started":"2024-06-15T08:18:57.891253Z","shell.execute_reply":"2024-06-15T08:18:59.494834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model2.eval()\ndata = iter(val_dl).__next__()\n\nimg= data[0][0]\nboxes=data[0][1]['boxes']\nlabels=data[0][1]['label']\n\noutput = model([img.to(device)])\n\nout_bbox=output[0]['boxes']\nout_scores=output[0]['scores']\n\nkeep = torchvision.ops.nms(out_bbox,out_scores,0.45)\n\nout_bbox.shape , keep.shape\nim = (img.permute(1,2,0).cpu().detach().numpy()*255).astype('uint8')\n\nvsample = Image.fromarray(im)\ndraw = ImageDraw.Draw(vsample)\nfor box in boxes :\n    draw.rectangle(list(box),fill=None,outline='red')\nvsample","metadata":{"execution":{"iopub.status.busy":"2024-06-15T08:19:08.523167Z","iopub.execute_input":"2024-06-15T08:19:08.523573Z","iopub.status.idle":"2024-06-15T08:19:09.521345Z","shell.execute_reply.started":"2024-06-15T08:19:08.523515Z","shell.execute_reply":"2024-06-15T08:19:09.517732Z"},"trusted":true},"execution_count":null,"outputs":[]}]}