{"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":30699,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# :הקדמות","metadata":{}},{"cell_type":"code","source":"!pip install torch torchvision\n\nimport torch\nimport torchvision\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport os\n\n# Check if GPU is available\nif torch.cuda.is_available():\n    device = torch.device('cuda')\n    print(\"CUDA is available. Using GPU.\")\nelse:\n    device = torch.device('cpu')\n    print(\"CUDA is not available. Using CPU.\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-08-16T12:54:54.259316Z","iopub.execute_input":"2024-08-16T12:54:54.259818Z","iopub.status.idle":"2024-08-16T12:55:26.743414Z","shell.execute_reply.started":"2024-08-16T12:54:54.259779Z","shell.execute_reply":"2024-08-16T12:55:26.741854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# important library:","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport random\nfrom PIL import Image , ImageDraw \nfrom collections import Counter\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nimport torch\nimport torchvision\nfrom torchvision import transforms as T\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\nimport random\nfrom PIL import Image\nimport os\nfrom sklearn.model_selection import train_test_split\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\n\n","metadata":{"execution":{"iopub.status.busy":"2024-08-16T13:12:55.958496Z","iopub.execute_input":"2024-08-16T13:12:55.958913Z","iopub.status.idle":"2024-08-16T13:12:55.965670Z","shell.execute_reply.started":"2024-08-16T13:12:55.958881Z","shell.execute_reply":"2024-08-16T13:12:55.964566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# load the dataset:","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/global-wheat-detection/train.csv')\nprint(\"Training Data Loaded\")\nprint(f\"Number of training images: {train_df['image_id'].nunique()}\")\nprint(f\"Number of bounding boxes: {len(train_df)}\")\n\n# Display a sample of the data\nprint(train_df.head())","metadata":{"execution":{"iopub.status.busy":"2024-08-16T13:09:19.387821Z","iopub.execute_input":"2024-08-16T13:09:19.388242Z","iopub.status.idle":"2024-08-16T13:09:19.616034Z","shell.execute_reply.started":"2024-08-16T13:09:19.388209Z","shell.execute_reply":"2024-08-16T13:09:19.614587Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#  Exploratory Data Analysis (understand the data):","metadata":{}},{"cell_type":"markdown","source":"**show some photos to see that the data has loaded succesfully:**","metadata":{}},{"cell_type":"code","source":"def display_random_images(df, image_folder, num_images=5):\n    # Get a random sample of image IDs\n    random_image_ids = random.sample(list(df['image_id'].unique()), num_images)\n\n    for image_id in random_image_ids:\n        # Load the image\n        image_path = os.path.join(image_folder, f\"{image_id}.jpg\")\n        image = Image.open(image_path)\n\n        # Get the bounding boxes for this image\n        image_data = df[df['image_id'] == image_id]\n        bboxes = image_data['bbox'].tolist()\n\n        # Plot the image\n        fig, ax = plt.subplots(1, figsize=(12, 12))\n        ax.imshow(image)\n        \n        # Add the bounding boxes\n        for bbox in bboxes:\n            bbox = [float(x) for x in bbox.strip('[]').split(',')]\n            rect = patches.Rectangle((bbox[0], bbox[1]), bbox[2], bbox[3], linewidth=2, edgecolor='r', facecolor='none')\n            ax.add_patch(rect)\n\n        plt.title(f\"Image ID: {image_id}\")\n        plt.show()\n\n# Assuming your images are in a folder called 'train' in the current directory\nimage_folder = '/kaggle/input/global-wheat-detection/train'\ndisplay_random_images(train_df, image_folder, num_images=5)\n","metadata":{"execution":{"iopub.status.busy":"2024-08-16T13:12:59.515762Z","iopub.execute_input":"2024-08-16T13:12:59.516183Z","iopub.status.idle":"2024-08-16T13:13:05.183397Z","shell.execute_reply.started":"2024-08-16T13:12:59.516144Z","shell.execute_reply":"2024-08-16T13:13:05.181903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**see the bounding boxes distribution in the photos:**","metadata":{}},{"cell_type":"code","source":"# Number of unique images\nprint(f\"Number of unique images: {train_df['image_id'].nunique()}\")\n\n# Number of bounding boxes per image\nbbox_counts = train_df.groupby('image_id').size()\nprint(f\"Average number of bounding boxes per image: {bbox_counts.mean()}\")\n\n# Plot distribution of bounding boxes per image\nplt.figure(figsize=(10,6))\nbbox_counts.plot(kind='hist', bins=30, title='Distribution of Bounding Boxes per Image')\nplt.xlabel('Number of Bounding Boxes')\nplt.ylabel('Frequency')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-08-16T13:09:21.004403Z","iopub.execute_input":"2024-08-16T13:09:21.004814Z","iopub.status.idle":"2024-08-16T13:09:21.332833Z","shell.execute_reply.started":"2024-08-16T13:09:21.004782Z","shell.execute_reply":"2024-08-16T13:09:21.331640Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Preprocessing:","metadata":{}},{"cell_type":"code","source":"# Keep a copy of the original DataFrame\noriginal_train_df = train_df.copy()\n\n# Function to split the data correctly\ndef split_data(df):\n    unique_image_ids = df['image_id'].unique()\n    \n    # Split the data into training and validation sets\n    train_ids, valid_ids = train_test_split(unique_image_ids, test_size=0.2, random_state=42)\n\n    train_df = df[df['image_id'].isin(train_ids)]\n    valid_df = df[df['image_id'].isin(valid_ids)]\n\n    return train_df, valid_df, unique_image_ids, train_ids, valid_ids\n\n# Reset the DataFrame to the original before each split\ntrain_df, valid_df, unique_image_ids, train_ids, valid_ids = split_data(original_train_df.copy())\n\n# Print the results of the split\nprint(f\"Total unique image IDs: {len(unique_image_ids)}\")\nprint(f\"Training image IDs: {len(train_ids)}\")\nprint(f\"Validation image IDs: {len(valid_ids)}\")\nprint(f\"Training set size: {len(train_df)}\")\nprint(f\"Validation set size: {len(valid_df)}\")\n","metadata":{"execution":{"iopub.status.busy":"2024-08-16T13:09:24.118845Z","iopub.execute_input":"2024-08-16T13:09:24.119231Z","iopub.status.idle":"2024-08-16T13:09:24.179387Z","shell.execute_reply.started":"2024-08-16T13:09:24.119201Z","shell.execute_reply":"2024-08-16T13:09:24.178235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model Selection and Implementation:","metadata":{}},{"cell_type":"code","source":"from torchvision.models.detection import fasterrcnn_resnet50_fpn\n\n# Load a pre-trained Faster R-CNN model\nmodel = fasterrcnn_resnet50_fpn(pretrained=True)\n\n# Replace the classifier with a new one for wheat detection (2 classes: wheat, background)\nnum_classes = 2  # Wheat and background\nin_features = model.roi_heads.box_predictor.cls_score.in_features\nmodel.roi_heads.box_predictor = torchvision.models.detection.faster_rcnn.FastRCNNPredictor(in_features, num_classes)\n\nmodel = model.to(device)\n\nprint(\"Model initialized and ready for training.\")\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training:","metadata":{}},{"cell_type":"code","source":"import torch.optim as optim\nfrom torch.utils.data import DataLoader\n\n# Define optimizer and loss function\noptimizer = optim.Adam(model.parameters(), lr=0.001)\n\n# Sample training loop\nnum_epochs = 10\nfor epoch in range(num_epochs):\n    print(f\"Starting epoch {epoch+1}/{num_epochs}\")\n    \n    # Set the model to training mode\n    model.train()\n    running_loss = 0.0\n    \n    for i, (images, targets) in enumerate(train_loader):\n        images = [image.to(device) for image in images]\n        targets = [{k: v.to(device) for k, v in t.items()} for t in targets]\n\n        # Zero the gradients\n        optimizer.zero_grad()\n\n        # Forward pass\n        loss_dict = model(images, targets)\n        losses = sum(loss for loss in loss_dict.values())\n        \n        # Backward pass\n        losses.backward()\n        optimizer.step()\n\n        running_loss += losses.item()\n        \n        # Debug statement for progress monitoring\n        if i % 10 == 0:\n            print(f\"Batch {i}, Loss: {losses.item()}\")\n\n    print(f\"Epoch {epoch+1} finished, Average Loss: {running_loss/len(train_loader)}\")\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Save and Test the Model","metadata":{}},{"cell_type":"code","source":"# Save the trained model\ntorch.save(model.state_dict(), 'fasterrcnn_wheat_detection.pth')\nprint(\"Model saved successfully.\")\n\n# Test the model on a few validation images\nmodel.eval()\nwith torch.no_grad():\n    for i, (images, targets) in enumerate(valid_loader):\n        images = [image.to(device) for image in images]\n        outputs = model(images)\n        \n        # Visualize results or print debug information\n        print(f\"Output for image {i}: {outputs}\")\n        break\n","metadata":{},"execution_count":null,"outputs":[]}]}