{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Import libraries","metadata":{}},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings('ignore')\n\nimport pandas as pd \nimport numpy as np \nimport matplotlib.pyplot as plt\nfrom PIL import Image, ImageDraw, ImageEnhance\nimport albumentations as albu\nimport cv2\nimport os \nimport glob as gb \nfrom tqdm.auto import tqdm \n\nimport tensorflow as tf \nfrom tensorflow import keras \nfrom keras.models import Model\nfrom tensorflow.keras.losses import BinaryCrossentropy , MSE\nfrom tensorflow.keras.layers import Conv2D , BatchNormalization , LeakyReLU\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.metrics import Precision, Recall","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:40:28.176782Z","iopub.execute_input":"2023-08-30T13:40:28.177319Z","iopub.status.idle":"2023-08-30T13:40:32.040074Z","shell.execute_reply.started":"2023-08-30T13:40:28.177275Z","shell.execute_reply":"2023-08-30T13:40:32.039039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gpus = tf.config.experimental.list_physical_devices('GPU')\nfor gpu in gpus:\n    print(\"Name:\", gpu.name, \"  Type:\", gpu.device_type)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:40:32.042574Z","iopub.execute_input":"2023-08-30T13:40:32.043423Z","iopub.status.idle":"2023-08-30T13:40:32.150236Z","shell.execute_reply.started":"2023-08-30T13:40:32.043376Z","shell.execute_reply":"2023-08-30T13:40:32.149022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.test.is_gpu_available()","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:40:32.151959Z","iopub.execute_input":"2023-08-30T13:40:32.152434Z","iopub.status.idle":"2023-08-30T13:40:33.175445Z","shell.execute_reply.started":"2023-08-30T13:40:32.152390Z","shell.execute_reply":"2023-08-30T13:40:33.174409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load data","metadata":{}},{"cell_type":"code","source":"labels = pd.read_csv('../input/global-wheat-detection/train.csv')\nlabels.head()","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:40:33.177108Z","iopub.execute_input":"2023-08-30T13:40:33.177523Z","iopub.status.idle":"2023-08-30T13:40:33.387633Z","shell.execute_reply.started":"2023-08-30T13:40:33.177489Z","shell.execute_reply":"2023-08-30T13:40:33.386621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def group_boxes(group) : \n    boundaries = group['bbox'].str.split(',',expand=True)\n    boundaries[0] = boundaries[0].str.slice(start=1)\n    boundaries[3] = boundaries[3].str.slice(stop=-1)\n    \n    return boundaries.values.astype(float)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:40:33.391775Z","iopub.execute_input":"2023-08-30T13:40:33.392687Z","iopub.status.idle":"2023-08-30T13:40:33.399450Z","shell.execute_reply.started":"2023-08-30T13:40:33.392650Z","shell.execute_reply":"2023-08-30T13:40:33.397938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = labels.groupby('image_id').apply(group_boxes)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:40:33.401810Z","iopub.execute_input":"2023-08-30T13:40:33.402636Z","iopub.status.idle":"2023-08-30T13:40:38.629755Z","shell.execute_reply.started":"2023-08-30T13:40:33.402599Z","shell.execute_reply":"2023-08-30T13:40:38.627023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels[0][0:5]","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:40:38.632612Z","iopub.execute_input":"2023-08-30T13:40:38.633838Z","iopub.status.idle":"2023-08-30T13:40:38.642797Z","shell.execute_reply.started":"2023-08-30T13:40:38.633700Z","shell.execute_reply":"2023-08-30T13:40:38.641787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_image_idx = np.unique(labels.index.values)[0:3363]\nval_image_idx = np.unique(labels.index.values)[3363:3373]","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:40:38.644484Z","iopub.execute_input":"2023-08-30T13:40:38.645216Z","iopub.status.idle":"2023-08-30T13:40:38.663659Z","shell.execute_reply.started":"2023-08-30T13:40:38.645181Z","shell.execute_reply":"2023-08-30T13:40:38.662690Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_image(image_id) : \n    image = Image.open('../input/global-wheat-detection/train/' + image_id + \".jpg\")\n    image = image.resize((256,256))\n    \n    return np.asarray(image)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:40:38.664970Z","iopub.execute_input":"2023-08-30T13:40:38.665424Z","iopub.status.idle":"2023-08-30T13:40:38.675140Z","shell.execute_reply.started":"2023-08-30T13:40:38.665391Z","shell.execute_reply":"2023-08-30T13:40:38.674146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_pixels = {} \ntrain_labels = {} \n\nfor image_id in tqdm(train_image_idx) : \n    train_pixels[image_id] = load_image(image_id) \n    train_labels[image_id] = labels[image_id].copy() / 4","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:40:38.676448Z","iopub.execute_input":"2023-08-30T13:40:38.676997Z","iopub.status.idle":"2023-08-30T13:41:45.082071Z","shell.execute_reply.started":"2023-08-30T13:40:38.676964Z","shell.execute_reply":"2023-08-30T13:41:45.081010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_pixels = {} \nval_labels = {} \nfor image_id in tqdm(val_image_idx) : \n    val_pixels[image_id] = load_image(image_id) \n    val_labels[image_id] = labels[image_id].copy() / 4","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:45.083759Z","iopub.execute_input":"2023-08-30T13:41:45.084405Z","iopub.status.idle":"2023-08-30T13:41:45.316268Z","shell.execute_reply.started":"2023-08-30T13:41:45.084370Z","shell.execute_reply":"2023-08-30T13:41:45.315128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Create bounding boxes","metadata":{}},{"cell_type":"code","source":"def draw_bboxes(image_id , bboxes) : \n    image = Image.open('../input/global-wheat-detection/train/' + image_id + \".jpg\")\n    image = image.resize((256,256)) \n    \n    draw = ImageDraw.Draw(image) \n    \n    for bbox in bboxes : \n        draw_bbox(draw,bbox) \n        \n    return np.asarray(image) \n\ndef draw_bbox(draw , bbox) : \n    x , y , width , height = bbox \n    draw.rectangle([x , y , x+width , y+height] , width = 2 , outline = 'red')","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:26:29.530135Z","iopub.execute_input":"2023-08-30T15:26:29.531080Z","iopub.status.idle":"2023-08-30T15:26:29.537883Z","shell.execute_reply.started":"2023-08-30T15:26:29.531044Z","shell.execute_reply":"2023-08-30T15:26:29.536883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_images(image_idx , bboxes) : \n    pixels = [] \n    \n    for image_id in image_idx : \n        pixels.append(\n            draw_bboxes(image_id , bboxes[image_id])\n        )\n        \n    num_of_images = len(image_idx) \n    \n    fig,axes = plt.subplots(1,num_of_images ,figsize=(5 * num_of_images, 5 * num_of_images) )\n    \n    for i , image_pixels in enumerate(pixels) : \n        axes[i].imshow(image_pixels)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:26:32.547400Z","iopub.execute_input":"2023-08-30T15:26:32.547772Z","iopub.status.idle":"2023-08-30T15:26:32.554499Z","shell.execute_reply.started":"2023-08-30T15:26:32.547742Z","shell.execute_reply":"2023-08-30T15:26:32.553234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_images(train_image_idx[0:4] , train_labels)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:26:35.206291Z","iopub.execute_input":"2023-08-30T15:26:35.206731Z","iopub.status.idle":"2023-08-30T15:26:36.377681Z","shell.execute_reply.started":"2023-08-30T15:26:35.206694Z","shell.execute_reply":"2023-08-30T15:26:36.376788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tiny_bboxes = []\n\nfor i, image_id in enumerate(train_image_idx):\n    for label in train_labels[image_id]:\n        if label[2] * label[3] <= 10 and label[2] * label[3] != 0:\n            tiny_bboxes.append(i)\n\n            \nprint(str(len(tiny_bboxes)) + ' tiny bounding boxes found')","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:46.577714Z","iopub.execute_input":"2023-08-30T13:41:46.578039Z","iopub.status.idle":"2023-08-30T13:41:46.718689Z","shell.execute_reply.started":"2023-08-30T13:41:46.578009Z","shell.execute_reply":"2023-08-30T13:41:46.717575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"huge_bboxes = []\n\nfor i, image_id in enumerate(train_image_idx):\n    for label in train_labels[image_id]:\n        if label[2] * label[3] > 8000:\n            huge_bboxes.append(i)\n\n            \nprint(str(len(huge_bboxes)) + ' huge bounding boxes found')","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:46.720345Z","iopub.execute_input":"2023-08-30T13:41:46.720709Z","iopub.status.idle":"2023-08-30T13:41:46.852267Z","shell.execute_reply.started":"2023-08-30T13:41:46.720676Z","shell.execute_reply":"2023-08-30T13:41:46.851206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_images(train_image_idx[562:566], train_labels)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:26:54.043618Z","iopub.execute_input":"2023-08-30T15:26:54.044007Z","iopub.status.idle":"2023-08-30T15:26:55.316919Z","shell.execute_reply.started":"2023-08-30T15:26:54.043976Z","shell.execute_reply":"2023-08-30T15:26:55.316065Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def clean_labels(train_image_ids, train_labels):\n    good_labels = {}\n    \n    for i, image_id in enumerate(train_image_ids):\n        good_labels[image_id] = []\n        \n        for j, label in enumerate(train_labels[image_id]):\n\n            # remove huge bbox\n            if label[2] * label[3] > 8000 and i not in [1079, 1371, 2020]:\n                continue\n\n            # remove tiny bbox\n            elif label[2] < 5 or label[3] < 5:\n                continue\n                \n            else:\n                good_labels[image_id].append(\n                    train_labels[image_id][j]\n                )\n                \n    return good_labels\n\ntrain_labels = clean_labels(train_image_idx, train_labels)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:47.495612Z","iopub.execute_input":"2023-08-30T13:41:47.496421Z","iopub.status.idle":"2023-08-30T13:41:47.792923Z","shell.execute_reply.started":"2023-08-30T13:41:47.496381Z","shell.execute_reply":"2023-08-30T13:41:47.791929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_images(train_image_idx[562:566], train_labels)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:27:15.792123Z","iopub.execute_input":"2023-08-30T15:27:15.792539Z","iopub.status.idle":"2023-08-30T15:27:17.026104Z","shell.execute_reply.started":"2023-08-30T15:27:15.792508Z","shell.execute_reply":"2023-08-30T15:27:17.025227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data pipeline","metadata":{}},{"cell_type":"code","source":"class DataGenerator(tf.keras.utils.Sequence) : \n    def __init__(self , image_ids , image_pixels , labels = None , batch_size = 1 , shuffle= False , augment = False) : \n        self.image_ids = image_ids \n        self.image_pixels = image_pixels \n        self.labels = labels \n        self.batch_size = batch_size \n        self.shuffle = shuffle \n        self.augment = augment \n        self.on_epoch_end()\n        \n        self.image_grid = self.form_image_grid() \n        \n    def form_image_grid(self) : \n        image_grid = np.zeros((32,32,4)) \n            \n        cell = [0 , 0 , 256 / 32 , 256 / 32] \n            \n        for i in range(0 , 32) : \n            for j in range(0 , 32) : \n                image_grid[i,j] = cell \n                    \n                cell[0] = cell[0] + cell[2] \n                    \n            cell[0] = 0 \n            cell[1] = cell[1] + cell[3] \n                \n        return image_grid\n        \n        \n    def __len__(self) : \n        return int(np.floor(len(self.image_ids) / self.batch_size))\n    \n    def on_epoch_end(self):\n        self.indexes = np.arange(len(self.image_ids))\n\n        if self.shuffle == True:\n            np.random.shuffle(self.indexes) ","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:48.442876Z","iopub.execute_input":"2023-08-30T13:41:48.443851Z","iopub.status.idle":"2023-08-30T13:41:48.456146Z","shell.execute_reply.started":"2023-08-30T13:41:48.443815Z","shell.execute_reply":"2023-08-30T13:41:48.455133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DataGenerator.train_augmentations = albu.Compose([\n        albu.RandomSizedCrop(\n            min_max_height=(200, 200), \n            height=256, \n            width=256, \n            p=0.8\n        ),\n        albu.OneOf([\n            albu.Flip(),\n            albu.RandomRotate90(),\n        ], p=1),\n        albu.OneOf([\n            albu.HueSaturationValue(),\n            albu.RandomBrightnessContrast()\n        ], p=1),\n        albu.OneOf([\n            albu.GaussNoise(),\n            albu.GlassBlur(),\n            albu.ISONoise(),\n            albu.MultiplicativeNoise(),\n        ], p=0.5),\n        albu.Cutout(\n            num_holes=8, \n            max_h_size=16, \n            max_w_size=16, \n            fill_value=0, \n            p=0.5\n        ),\n        albu.CLAHE(p=1),\n        albu.ToGray(p=1),\n    ], \n    bbox_params={'format': 'coco', 'label_fields': ['labels']})\n\nDataGenerator.val_augmentations = albu.Compose([\n    albu.CLAHE(p=1),\n    albu.ToGray(p=1),\n])","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:48.458030Z","iopub.execute_input":"2023-08-30T13:41:48.458486Z","iopub.status.idle":"2023-08-30T13:41:48.473017Z","shell.execute_reply.started":"2023-08-30T13:41:48.458456Z","shell.execute_reply":"2023-08-30T13:41:48.472078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def __getitem__(self, index):\n    indexes = self.indexes[index * self.batch_size:(index + 1) * self.batch_size]\n\n    batch_ids = [self.image_ids[i] for i in indexes]\n\n    X, y = self.__data_generation(batch_ids)\n\n    return X, y\n\n\ndef __data_generation(self, batch_ids):\n    X, y = [], []\n\n    # Generate data\n    for i, image_id in enumerate(batch_ids):\n        pixels = self.image_pixels[image_id]\n        bboxes = self.labels[image_id]\n\n        if self.augment:     \n            pixels, bboxes = self.augment_image(pixels, bboxes)\n        else:\n            pixels = self.contrast_image(pixels)\n            bboxes = self.form_label_grid(bboxes)\n\n        X.append(pixels)\n        y.append(bboxes)\n\n    return np.array(X), np.array(y)\n\n\ndef augment_image(self, pixels, bboxes):\n    bbox_labels = np.ones(len(bboxes))\n\n    aug_result = self.train_augmentations(image=pixels, bboxes=bboxes, labels=bbox_labels)\n\n    bboxes = self.form_label_grid(aug_result['bboxes'])\n\n    return np.array(aug_result['image']) / 255, bboxes\n\n\ndef contrast_image(self, pixels):        \n    aug_result = self.val_augmentations(image=pixels)\n    return np.array(aug_result['image']) / 255\n\n\nDataGenerator.__getitem__ = __getitem__\nDataGenerator.__data_generation = __data_generation\nDataGenerator.augment_image = augment_image\nDataGenerator.contrast_image = contrast_image","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:48.474308Z","iopub.execute_input":"2023-08-30T13:41:48.474729Z","iopub.status.idle":"2023-08-30T13:41:48.488833Z","shell.execute_reply.started":"2023-08-30T13:41:48.474696Z","shell.execute_reply":"2023-08-30T13:41:48.487856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def form_label_grid(self, bboxes):\n    label_grid = np.zeros((32, 32, 10))\n\n    for i in range(0, 32):\n        for j in range(0, 32):\n            cell = self.image_grid[i,j]\n            label_grid[i,j] = self.rect_intersect(cell, bboxes)\n\n    return label_grid\n\n\ndef rect_intersect(self, cell, bboxes): \n    cell_x, cell_y, cell_width, cell_height = cell\n    cell_x_max = cell_x + cell_width \n    cell_y_max = cell_y + cell_height\n    \n    anchor_one = np.array([0, 0, 0, 0, 0])\n    anchor_two = np.array([0, 0, 0, 0, 0])\n\n    # check all boxes\n    for bbox in bboxes:\n        box_x, box_y, box_width, box_height = bbox\n        box_x_centre = box_x + (box_width / 2)\n        box_y_centre = box_y + (box_height / 2)\n\n        if(box_x_centre >= cell_x and box_x_centre < cell_x_max and box_y_centre >= cell_y and box_y_centre < cell_y_max):\n            \n            if anchor_one[0] == 0:\n                anchor_one = self.yolo_shape(\n                    [box_x, box_y, box_width, box_height], \n                    [cell_x, cell_y, cell_width, cell_height]\n                )\n            \n            elif anchor_two[0] == 0:\n                anchor_two = self.yolo_shape(\n                    [box_x, box_y, box_width, box_height], \n                    [cell_x, cell_y, cell_width, cell_height]\n                )\n                \n            else:\n                break\n\n    return np.concatenate((anchor_one, anchor_two), axis=None)\n\n\ndef yolo_shape(self, box, cell):\n    box_x, box_y, box_width, box_height = box\n    cell_x, cell_y, cell_width, cell_height = cell\n\n    # top left x,y to centre x,y\n    box_x = box_x + (box_width / 2)\n    box_y = box_y + (box_height / 2)\n\n    # offset bbox x,y to cell x,y\n    box_x = (box_x - cell_x) / cell_width\n    box_y = (box_y - cell_y) / cell_height\n\n    # bbox width,height relative to cell width,height\n    box_width = box_width / 256\n    box_height = box_height / 256\n\n    return [1, box_x, box_y, box_width, box_height]\n\n\nDataGenerator.form_label_grid = form_label_grid\nDataGenerator.rect_intersect = rect_intersect\nDataGenerator.yolo_shape = yolo_shape","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:48.491706Z","iopub.execute_input":"2023-08-30T13:41:48.492009Z","iopub.status.idle":"2023-08-30T13:41:48.505930Z","shell.execute_reply.started":"2023-08-30T13:41:48.491984Z","shell.execute_reply":"2023-08-30T13:41:48.504921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator = DataGenerator(\n    train_image_idx,\n    train_pixels,\n    train_labels, \n    batch_size=6, \n    shuffle=True,\n    augment=True\n)\n\nval_generator = DataGenerator(\n    val_image_idx, \n    val_pixels,\n    val_labels, \n    batch_size=10,\n    shuffle=False,\n    augment=False\n)\n\nimage_grid = train_generator.image_grid","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:48.507259Z","iopub.execute_input":"2023-08-30T13:41:48.507856Z","iopub.status.idle":"2023-08-30T13:41:48.521793Z","shell.execute_reply.started":"2023-08-30T13:41:48.507822Z","shell.execute_reply":"2023-08-30T13:41:48.521124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_train_sample , y_train_sample = next(iter(train_generator))","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:48.522809Z","iopub.execute_input":"2023-08-30T13:41:48.523889Z","iopub.status.idle":"2023-08-30T13:41:49.045534Z","shell.execute_reply.started":"2023-08-30T13:41:48.523854Z","shell.execute_reply":"2023-08-30T13:41:49.044526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"The size of the training generator is : {train_generator.__len__()} batches of {train_generator.batch_size}\")","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:49.047121Z","iopub.execute_input":"2023-08-30T13:41:49.047508Z","iopub.status.idle":"2023-08-30T13:41:49.053589Z","shell.execute_reply.started":"2023-08-30T13:41:49.047474Z","shell.execute_reply":"2023-08-30T13:41:49.052590Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axis = plt.subplots(2, 3, figsize=(20, 5))\nfor i, ax in enumerate(axis.flat):\n    img = x_train_sample[i]\n    ax.imshow(img)\n    ax.set(title = 'Train Image')\n    ax.axis('off')\n        ","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:28:03.795983Z","iopub.execute_input":"2023-08-30T15:28:03.796369Z","iopub.status.idle":"2023-08-30T15:28:04.492332Z","shell.execute_reply.started":"2023-08-30T15:28:03.796338Z","shell.execute_reply":"2023-08-30T15:28:04.491148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_val_sample , y_val_sample = next(iter(val_generator))","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:49.666388Z","iopub.execute_input":"2023-08-30T13:41:49.667011Z","iopub.status.idle":"2023-08-30T13:41:50.698355Z","shell.execute_reply.started":"2023-08-30T13:41:49.666978Z","shell.execute_reply":"2023-08-30T13:41:50.697346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"The size of the validation generator is : {val_generator.__len__()} batches of {val_generator.batch_size}\")","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:50.699728Z","iopub.execute_input":"2023-08-30T13:41:50.700329Z","iopub.status.idle":"2023-08-30T13:41:50.706593Z","shell.execute_reply.started":"2023-08-30T13:41:50.700293Z","shell.execute_reply":"2023-08-30T13:41:50.705473Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axis = plt.subplots(2, 5, figsize=(20, 5))\nfor i, ax in enumerate(axis.flat):\n    img = x_val_sample[i]\n    ax.imshow(img)\n    ax.set(title = 'Val Image')\n    ax.axis('off')\n        ","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:28:13.024037Z","iopub.execute_input":"2023-08-30T15:28:13.024509Z","iopub.status.idle":"2023-08-30T15:28:14.194323Z","shell.execute_reply.started":"2023-08-30T15:28:13.024471Z","shell.execute_reply":"2023-08-30T15:28:14.193433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Build our model ","metadata":{}},{"cell_type":"code","source":"def YOLOV3(in_channels , out_channels) : \n    inputs = keras.Input(shape = in_channels) \n    \n    x = Conv2D(32 , (3,3) , strides = (1,1) , padding = 'same')(inputs)\n    x = BatchNormalization()(x) \n    x= LeakyReLU(alpha=0.1)(x) \n    \n    # block 1 \n    \n    x = Conv2D(64,(3,3) , strides = (1,1) , padding = 'same')(x)\n    x = BatchNormalization()(x)\n    x= LeakyReLU(alpha=0.1)(x)\n    \n    PreviousBlock = x \n    \n    for i in range(2) : \n        x = Conv2D(32,(3,3) , strides = (1,1) , padding = 'same')(x)\n        x = BatchNormalization()(x)\n        x= LeakyReLU(alpha=0.1)(x)\n        \n        x = Conv2D(64,(3,3) , strides = (1,1) , padding = 'same')(x)\n        x = BatchNormalization()(x)\n        x= LeakyReLU(alpha=0.1)(x)\n        \n        x = keras.layers.Add()([PreviousBlock,x])\n        x = LeakyReLU(alpha=0.1)(x)\n        \n        PreviousBlock = x\n        \n        \n    \n    # block 2 \n    \n    x = Conv2D(128 , (3,3) , strides = (1,1) , padding = 'same')(x)\n    x = BatchNormalization()(x) \n    x= LeakyReLU(alpha=0.1)(x)\n    \n    PreviousBlock = x\n    \n    for i in range(2) : \n        x = Conv2D(64,(3,3) , strides = (1,1) , padding = 'same')(x)\n        x = BatchNormalization()(x)\n        x= LeakyReLU(alpha=0.1)(x)\n        \n        x = Conv2D(128,(3,3) , strides = (1,1) , padding = 'same')(x)\n        x = BatchNormalization()(x)\n        x= LeakyReLU(alpha=0.1)(x)\n        \n        x = keras.layers.Add()([PreviousBlock,x])\n        x = LeakyReLU(alpha=0.1)(x)\n        \n        PreviousBlock = x\n    \n    \n    # block3 \n    \n    x = Conv2D(256 , (3,3) , strides = (2,2) , padding = 'same')(x) \n    x = BatchNormalization()(x)\n    x= LeakyReLU(alpha=0.1)(x)\n    \n    PreviousBlock = x\n    \n    for i in range(8) : \n        x = Conv2D(128,(3,3) , strides = (1,1) , padding = 'same')(x)\n        x = BatchNormalization()(x)\n        x= LeakyReLU(alpha=0.1)(x)\n        \n        x = Conv2D(256,(3,3) , strides = (1,1) , padding = 'same')(x)\n        x = BatchNormalization()(x)\n        x= LeakyReLU(alpha=0.1)(x)\n        \n        x = keras.layers.Add()([PreviousBlock,x])\n        x = LeakyReLU(alpha=0.1)(x)\n        \n        PreviousBlock = x\n        \n        \n    # block 4 \n    \n    x = Conv2D(512 , (3,3) , strides = (2,2) , padding = 'same')(x) \n    x = BatchNormalization()(x)\n    x= LeakyReLU(alpha=0.1)(x)\n    \n    PreviousBlock = x\n    \n    for i in range(8) : \n        x = Conv2D(256,(3,3) , strides = (1,1) , padding = 'same')(x)\n        x = BatchNormalization()(x)\n        x= LeakyReLU(alpha=0.1)(x)\n        \n        x = Conv2D(512,(3,3) , strides = (1,1) , padding = 'same')(x)\n        x = BatchNormalization()(x)\n        x= LeakyReLU(alpha=0.1)(x)\n        \n        x = keras.layers.Add()([PreviousBlock,x])\n        x = LeakyReLU(alpha=0.1)(x)\n        \n        PreviousBlock = x\n        \n        \n        \n    # block 5 \n    \n    x = Conv2D(1024 , (3,3) , strides = (2,2) , padding = 'same')(x) \n    x = BatchNormalization()(x)\n    x= LeakyReLU(alpha=0.1)(x)\n    \n    PreviousBlock = x\n    \n    for i in range(8) : \n        x = Conv2D(512,(3,3) , strides = (1,1) , padding = 'same')(x)\n        x = BatchNormalization()(x)\n        x= LeakyReLU(alpha=0.1)(x)\n        \n        x = Conv2D(1024,(3,3) , strides = (1,1) , padding = 'same')(x)\n        x = BatchNormalization()(x)\n        x= LeakyReLU(alpha=0.1)(x)\n        \n        x = keras.layers.Add()([PreviousBlock,x])\n        x = LeakyReLU(alpha=0.1)(x)\n        \n        PreviousBlock = x\n        \n        \n    # output layer \n    \n    x = Conv2D(512 , (3,3) , strides = (1,1) , padding = 'same')(x) \n    x = BatchNormalization()(x)\n    x= LeakyReLU(alpha=0.1)(x)\n    \n    x = Conv2D(256 , (3,3) , strides = (1,1) , padding = 'same')(x) \n    x = BatchNormalization()(x)\n    x= LeakyReLU(alpha=0.1)(x)\n    \n    x = Conv2D(128 , (3,3) , strides = (1,1) , padding = 'same')(x) \n    x = BatchNormalization()(x)\n    x= LeakyReLU(alpha=0.1)(x)\n    \n    \n    outputs = Conv2D(out_channels , (1,1) , strides = (1,1) , padding='same' , activation = 'sigmoid')(x)\n    \n    \n    model = Model(inputs , outputs)\n    \n    return model ","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:51.784365Z","iopub.execute_input":"2023-08-30T13:41:51.784744Z","iopub.status.idle":"2023-08-30T13:41:51.819221Z","shell.execute_reply.started":"2023-08-30T13:41:51.784713Z","shell.execute_reply":"2023-08-30T13:41:51.818070Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"keras.backend.clear_session()","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:51.821192Z","iopub.execute_input":"2023-08-30T13:41:51.821633Z","iopub.status.idle":"2023-08-30T13:41:51.843702Z","shell.execute_reply.started":"2023-08-30T13:41:51.821598Z","shell.execute_reply":"2023-08-30T13:41:51.842766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = YOLOV3(in_channels=(256, 256,3), out_channels=10)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:51.845328Z","iopub.execute_input":"2023-08-30T13:41:51.845674Z","iopub.status.idle":"2023-08-30T13:41:53.772306Z","shell.execute_reply.started":"2023-08-30T13:41:51.845641Z","shell.execute_reply":"2023-08-30T13:41:53.771332Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:53.773602Z","iopub.execute_input":"2023-08-30T13:41:53.773957Z","iopub.status.idle":"2023-08-30T13:41:54.347440Z","shell.execute_reply.started":"2023-08-30T13:41:53.773923Z","shell.execute_reply":"2023-08-30T13:41:54.346681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"keras.utils.plot_model(model, show_shapes=True)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:54.348459Z","iopub.execute_input":"2023-08-30T13:41:54.348814Z","iopub.status.idle":"2023-08-30T13:41:57.612604Z","shell.execute_reply.started":"2023-08-30T13:41:54.348781Z","shell.execute_reply":"2023-08-30T13:41:57.611050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_mask(y_true):\n    anchor_one_mask = tf.where(\n        y_true[:,:,:,0] == 0, \n        0.5, \n        5.0\n    )\n    \n    anchor_two_mask = tf.where(\n        y_true[:,:,:,5] == 0, \n        0.5, \n        5.0\n    )\n    \n    bboxes_mask = tf.concat(\n        [anchor_one_mask,anchor_two_mask],\n        axis=0\n    )\n    \n    return bboxes_mask","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:57.614434Z","iopub.execute_input":"2023-08-30T13:41:57.615000Z","iopub.status.idle":"2023-08-30T13:41:57.621141Z","shell.execute_reply.started":"2023-08-30T13:41:57.614967Z","shell.execute_reply":"2023-08-30T13:41:57.620242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def custom_loss(y_true, y_pred):\n    binary_crossentropy = prob_loss = BinaryCrossentropy(\n        reduction= keras.losses.Reduction.SUM_OVER_BATCH_SIZE\n    )\n    \n    prob_loss = binary_crossentropy(\n        tf.concat([y_true[:,:,:,0], y_true[:,:,:,5]], axis=0), \n        tf.concat([y_pred[:,:,:,0], y_pred[:,:,:,5]], axis=0)\n    )\n    \n    xy_loss = MSE(\n        tf.concat([y_true[:,:,:,1:3], y_true[:,:,:,6:8]], axis=0), \n        tf.concat([y_pred[:,:,:,1:3], y_pred[:,:,:,6:8]], axis=0)\n    )\n    \n    wh_loss = MSE(\n        tf.concat([y_true[:,:,:,3:5], y_true[:,:,:,8:10]], axis=0), \n        tf.concat([y_pred[:,:,:,3:5], y_pred[:,:,:,8:10]], axis=0)\n    )\n    \n    bboxes_mask = get_mask(y_true)\n    \n    xy_loss = xy_loss * bboxes_mask\n    wh_loss = wh_loss * bboxes_mask\n    \n    return prob_loss + xy_loss + wh_loss","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:57.622445Z","iopub.execute_input":"2023-08-30T13:41:57.622969Z","iopub.status.idle":"2023-08-30T13:41:57.636266Z","shell.execute_reply.started":"2023-08-30T13:41:57.622939Z","shell.execute_reply":"2023-08-30T13:41:57.634904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train our model","metadata":{}},{"cell_type":"code","source":"model.compile(\n    optimizer= Adam(learning_rate=0.0001) , \n    loss = custom_loss\n)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:57.637673Z","iopub.execute_input":"2023-08-30T13:41:57.638226Z","iopub.status.idle":"2023-08-30T13:41:57.677611Z","shell.execute_reply.started":"2023-08-30T13:41:57.638194Z","shell.execute_reply":"2023-08-30T13:41:57.676546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 10","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:57.679083Z","iopub.execute_input":"2023-08-30T13:41:57.679498Z","iopub.status.idle":"2023-08-30T13:41:57.683883Z","shell.execute_reply.started":"2023-08-30T13:41:57.679466Z","shell.execute_reply":"2023-08-30T13:41:57.682917Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with tf.device(\"/GPU:0\") : \n    history = model.fit_generator(\n    train_generator , \n    validation_data= val_generator , \n    epochs = epochs \n)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T13:41:57.685351Z","iopub.execute_input":"2023-08-30T13:41:57.685983Z","iopub.status.idle":"2023-08-30T15:04:56.288154Z","shell.execute_reply.started":"2023-08-30T13:41:57.685952Z","shell.execute_reply":"2023-08-30T15:04:56.287119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Make predictions","metadata":{}},{"cell_type":"code","source":"def prediction_to_bbox(bboxes, image_grid):    \n    bboxes = bboxes.copy()\n    \n    im_width = (image_grid[:,:,2] * 32)\n    im_height = (image_grid[:,:,3] * 32)\n    \n    # descale x,y\n    bboxes[:,:,1] = (bboxes[:,:,1] * image_grid[:,:,2]) + image_grid[:,:,0]\n    bboxes[:,:,2] = (bboxes[:,:,2] * image_grid[:,:,3]) + image_grid[:,:,1]\n    bboxes[:,:,6] = (bboxes[:,:,6] * image_grid[:,:,2]) + image_grid[:,:,0]\n    bboxes[:,:,7] = (bboxes[:,:,7] * image_grid[:,:,3]) + image_grid[:,:,1]\n    \n    # descale width,height\n    bboxes[:,:,3] = bboxes[:,:,3] * im_width \n    bboxes[:,:,4] = bboxes[:,:,4] * im_height\n    bboxes[:,:,8] = bboxes[:,:,8] * im_width \n    bboxes[:,:,9] = bboxes[:,:,9] * im_height\n    \n    # centre x,y to top left x,y\n    bboxes[:,:,1] = bboxes[:,:,1] - (bboxes[:,:,3] / 2)\n    bboxes[:,:,2] = bboxes[:,:,2] - (bboxes[:,:,4] / 2)\n    bboxes[:,:,6] = bboxes[:,:,6] - (bboxes[:,:,8] / 2)\n    bboxes[:,:,7] = bboxes[:,:,7] - (bboxes[:,:,9] / 2)\n    \n    # width,heigth to x_max,y_max\n    bboxes[:,:,3] = bboxes[:,:,1] + bboxes[:,:,3]\n    bboxes[:,:,4] = bboxes[:,:,2] + bboxes[:,:,4]\n    bboxes[:,:,8] = bboxes[:,:,6] + bboxes[:,:,8]\n    bboxes[:,:,9] = bboxes[:,:,7] + bboxes[:,:,9]\n    \n    return bboxes","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:10:50.753890Z","iopub.execute_input":"2023-08-30T15:10:50.754316Z","iopub.status.idle":"2023-08-30T15:10:50.769211Z","shell.execute_reply.started":"2023-08-30T15:10:50.754282Z","shell.execute_reply":"2023-08-30T15:10:50.767962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def non_max_suppression(predictions, top_n):\n    probabilities = np.concatenate((predictions[:,:,0].flatten(), predictions[:,:,5].flatten()), axis=None)\n    \n    first_anchors = predictions[:,:,1:5].reshape((32*32, 4))\n    second_anchors = predictions[:,:,6:10].reshape((32*32, 4))\n    \n    bboxes = np.concatenate(\n        (first_anchors,second_anchors),\n        axis=0\n    )\n    \n    bboxes = switch_x_y(bboxes)\n    bboxes, probabilities = select_top(probabilities, bboxes, top_n=top_n)\n    bboxes = switch_x_y(bboxes)\n    \n    return bboxes\n\n\ndef switch_x_y(bboxes):\n    x1 = bboxes[:,0].copy()\n    y1 = bboxes[:,1].copy()\n    x2 = bboxes[:,2].copy()\n    y2 = bboxes[:,3].copy()\n    \n    bboxes[:,0] = y1\n    bboxes[:,1] = x1\n    bboxes[:,2] = y2\n    bboxes[:,3] = x2\n    \n    return bboxes\n\n\ndef select_top(probabilities, boxes, top_n=10):\n    top_indices = tf.image.non_max_suppression(\n        boxes = boxes, \n        scores = probabilities, \n        max_output_size = top_n, \n        iou_threshold = 0.3,\n        score_threshold = 0.3\n    )\n    \n    top_indices = top_indices.numpy()\n    \n    return boxes[top_indices], probabilities[top_indices]","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:10:54.423902Z","iopub.execute_input":"2023-08-30T15:10:54.424295Z","iopub.status.idle":"2023-08-30T15:10:54.436039Z","shell.execute_reply.started":"2023-08-30T15:10:54.424264Z","shell.execute_reply":"2023-08-30T15:10:54.435101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def process_predictions(predictions, image_ids, image_grid):\n    bboxes = {}\n    \n    for i, image_id in enumerate(image_ids):\n        predictions[i] = prediction_to_bbox(predictions[i], image_grid)\n        bboxes[image_id] = non_max_suppression(predictions[i], top_n=100)\n        \n        # back to coco shape\n        bboxes[image_id][:,2:4] = bboxes[image_id][:,2:4] - bboxes[image_id][:,0:2]\n    \n    return bboxes","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:10:59.193915Z","iopub.execute_input":"2023-08-30T15:10:59.194311Z","iopub.status.idle":"2023-08-30T15:10:59.200835Z","shell.execute_reply.started":"2023-08-30T15:10:59.194280Z","shell.execute_reply":"2023-08-30T15:10:59.199838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with tf.device(\"/GPU:0\") : \n    val_predictions = model.predict(val_generator)\n    val_predictions = process_predictions(val_predictions, val_image_idx, image_grid)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:11:02.180923Z","iopub.execute_input":"2023-08-30T15:11:02.182078Z","iopub.status.idle":"2023-08-30T15:11:06.088434Z","shell.execute_reply.started":"2023-08-30T15:11:02.182033Z","shell.execute_reply":"2023-08-30T15:11:06.086565Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_images(val_image_idx[0:8], val_predictions)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:25:30.603884Z","iopub.execute_input":"2023-08-30T15:25:30.604287Z","iopub.status.idle":"2023-08-30T15:25:33.197043Z","shell.execute_reply.started":"2023-08-30T15:25:30.604254Z","shell.execute_reply":"2023-08-30T15:25:33.195454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluate model ","metadata":{}},{"cell_type":"code","source":"print(f\"The training loss is : {history.history['loss'][-1]:0.3f}\\n\\n\")\nprint(f\"The validation loss is : {history.history['val_loss'][-1]:0.3f}\")","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:15:12.724608Z","iopub.execute_input":"2023-08-30T15:15:12.724971Z","iopub.status.idle":"2023-08-30T15:15:12.730390Z","shell.execute_reply.started":"2023-08-30T15:15:12.724936Z","shell.execute_reply":"2023-08-30T15:15:12.729358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history.history['loss'] , label='training_loss')\nplt.plot(history.history['val_loss'] , label='val_loss')\nplt.title('Training/Validation loss over Epochs')\nplt.xlabel('Epochs')\nplt.ylabel('loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:17:44.904017Z","iopub.execute_input":"2023-08-30T15:17:44.904494Z","iopub.status.idle":"2023-08-30T15:17:45.328625Z","shell.execute_reply.started":"2023-08-30T15:17:44.904447Z","shell.execute_reply":"2023-08-30T15:17:45.327720Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predict on test images","metadata":{}},{"cell_type":"code","source":"test_image_ids = os.listdir('/kaggle/input/global-wheat-detection/test/')\ntest_image_ids = [image_id[:-4] for image_id in test_image_ids]","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:18:50.190141Z","iopub.execute_input":"2023-08-30T15:18:50.190546Z","iopub.status.idle":"2023-08-30T15:18:50.204900Z","shell.execute_reply.started":"2023-08-30T15:18:50.190515Z","shell.execute_reply":"2023-08-30T15:18:50.203807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_predictions = []\n\nfor i, image_id in enumerate(test_image_ids):\n    image = Image.open('/kaggle/input/global-wheat-detection/test/' + image_id + \".jpg\")\n    image = image.resize((256, 256))            \n\n    pixels = np.asarray(image)\n\n    val_augmentations = albu.Compose([\n        albu.CLAHE(p=1),\n        albu.ToGray(p=1)\n    ])\n\n    aug_result = val_augmentations(image=pixels)\n    pixels = np.array(aug_result['image']) / 255\n    \n    pixels = np.expand_dims(pixels, axis=0)\n    \n    bboxes = model.predict(pixels)\n\n    test_predictions.append(bboxes)\n    \ntest_predictions = np.concatenate(test_predictions)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:19:25.583592Z","iopub.execute_input":"2023-08-30T15:19:25.583960Z","iopub.status.idle":"2023-08-30T15:19:29.070978Z","shell.execute_reply.started":"2023-08-30T15:19:25.583931Z","shell.execute_reply":"2023-08-30T15:19:29.069978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_predictions = process_predictions(test_predictions, test_image_ids, image_grid)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:19:43.369139Z","iopub.execute_input":"2023-08-30T15:19:43.369638Z","iopub.status.idle":"2023-08-30T15:19:43.398003Z","shell.execute_reply.started":"2023-08-30T15:19:43.369600Z","shell.execute_reply":"2023-08-30T15:19:43.397091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def test_draw_bboxes(image_id , bboxes) : \n    image = Image.open('/kaggle/input/global-wheat-detection/test/' + image_id + \".jpg\")\n    image = image.resize((256,256)) \n    \n    draw = ImageDraw.Draw(image) \n    \n    for bbox in bboxes : \n        draw_bbox(draw,bbox) \n        \n    return np.asarray(image) ","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:24:25.582147Z","iopub.execute_input":"2023-08-30T15:24:25.583187Z","iopub.status.idle":"2023-08-30T15:24:25.589367Z","shell.execute_reply.started":"2023-08-30T15:24:25.583141Z","shell.execute_reply":"2023-08-30T15:24:25.588243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_test_images(image_idx , bboxes) : \n    pixels = [] \n    \n    for image_id in image_idx : \n        pixels.append(\n            test_draw_bboxes(image_id , bboxes[image_id])\n        )\n        \n    num_of_images = len(image_idx) \n    \n    fig,axes = plt.subplots(1,num_of_images ,figsize=(5 * num_of_images, 5 * num_of_images) )\n    \n    for i , image_pixels in enumerate(pixels) : \n        axes[i].imshow(image_pixels)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:24:30.672893Z","iopub.execute_input":"2023-08-30T15:24:30.673297Z","iopub.status.idle":"2023-08-30T15:24:30.679738Z","shell.execute_reply.started":"2023-08-30T15:24:30.673266Z","shell.execute_reply":"2023-08-30T15:24:30.678699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_test_images(test_image_ids[0:8], test_predictions)","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:25:04.201691Z","iopub.execute_input":"2023-08-30T15:25:04.202061Z","iopub.status.idle":"2023-08-30T15:25:07.092902Z","shell.execute_reply.started":"2023-08-30T15:25:04.202030Z","shell.execute_reply":"2023-08-30T15:25:07.091429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save_weights('wheat_detection_model')","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:28:56.438807Z","iopub.execute_input":"2023-08-30T15:28:56.439214Z","iopub.status.idle":"2023-08-30T15:29:04.302668Z","shell.execute_reply.started":"2023-08-30T15:28:56.439160Z","shell.execute_reply":"2023-08-30T15:29:04.301648Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save(\"Wheat Detection.h5\")","metadata":{"execution":{"iopub.status.busy":"2023-08-30T15:30:08.725585Z","iopub.execute_input":"2023-08-30T15:30:08.725950Z","iopub.status.idle":"2023-08-30T15:30:11.693161Z","shell.execute_reply.started":"2023-08-30T15:30:08.725923Z","shell.execute_reply":"2023-08-30T15:30:11.691305Z"},"trusted":true},"execution_count":null,"outputs":[]}],"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"}}