{"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":9988,"databundleVersionId":868324,"sourceType":"competition"},{"sourceId":7728801,"sourceType":"datasetVersion","datasetId":4515877}],"dockerImageVersionId":30646,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Importing necessary libraries\n\nimport numpy as np \nimport pandas as pd \nimport os\nimport matplotlib.pyplot as plt\n\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nimport cv2\n\nfrom PIL import Image\nfrom sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:27:52.573028Z","iopub.execute_input":"2024-03-05T19:27:52.573477Z","iopub.status.idle":"2024-03-05T19:27:52.579925Z","shell.execute_reply.started":"2024-03-05T19:27:52.573445Z","shell.execute_reply":"2024-03-05T19:27:52.578678Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_ids = pd.read_csv(\"/kaggle/input/airbus-ship-detection/train_ship_segmentations_v2.csv\")\n\n# delete corrupted file\ncorrupted_filenames = ['6384c3e78.jpg']\nimage_ids = image_ids[~image_ids['ImageId'].isin(corrupted_filenames)]\n\nimage_ids['EncodedPixels'] = image_ids['EncodedPixels'].fillna('')\nimage_ids['ImageId'] = image_ids['ImageId'].astype(str)\n\n# uncomment to look at image_ids\n#image_ids.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:27:53.577782Z","iopub.execute_input":"2024-03-05T19:27:53.579111Z","iopub.status.idle":"2024-03-05T19:27:54.595699Z","shell.execute_reply.started":"2024-03-05T19:27:53.579060Z","shell.execute_reply":"2024-03-05T19:27:54.594376Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# one-hot encoding mask\ndef one_hot(a, num_classes=2):\n    return np.squeeze(np.eye(num_classes)[a])\n\n# preprocessing function for images and masks\ndef preprocessing(img_id, img_f='/kaggle/input/airbus-ship-detection/train_v2', augment=True, shape=(768, 768), target_size=(256, 256)): \n    \n    img_id = str(img_id)\n    encoded_mask = image_ids[image_ids['ImageId'] == img_id].iloc[0]['EncodedPixels']\n    \n    # decoding rle to mask\n    if not pd.isna(encoded_mask):\n        encoded_pixels = np.array(encoded_mask.split(), dtype=int)\n        starts = encoded_pixels[::2] - 1\n        ends = starts + encoded_pixels[1::2]\n        img = np.zeros(shape[0] * shape[1], dtype=np.uint8)\n        for lo, hi in zip(starts, ends):\n            img[lo:hi] = 1\n            \n        input_mask = img.reshape(shape).T\n        input_mask = cv2.resize(input_mask, target_size, interpolation=cv2.INTER_AREA)\n        input_mask = np.expand_dims(input_mask, axis=2) \n    else:\n        input_mask = np.zeros(target_size + (1,), dtype=np.int8)\n    one_hot_mask = one_hot(input_mask)\n    mask_tensor = tf.convert_to_tensor(one_hot_mask, dtype=tf.float32)\n    \n    image = cv2.imread(os.path.join(img_f, img_id))\n    image = tf.image.resize(image, target_size)\n    \n    # Image augmentation\n    if augment:\n        data_gen_args = dict(\n        rotation_range=30,\n        width_shift_range=0.1,\n        height_shift_range=0.1,\n        shear_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True,\n        vertical_flip=True,\n        fill_mode='reflect')\n\n    image_datagen = ImageDataGenerator(**data_gen_args)\n    \n    image_np = image.numpy()\n    mask_np = mask_tensor.numpy()\n    \n    # Apply augmentation to NumPy array\n    image_np = image_datagen.random_transform(image_np, seed=42)\n    mask_np = image_datagen.random_transform(mask_np, seed=42)\n    \n    # Convert NumPy array back to TensorFlow tensor\n    image = tf.convert_to_tensor(image_np, dtype=tf.float32)\n    mask_tensor = tf.convert_to_tensor(mask_np, dtype=tf.float32)\n    \n    image = tf.cast(image, dtype=tf.float32) / 255.0\n    \n    return image, mask_tensor","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:27:54.598144Z","iopub.execute_input":"2024-03-05T19:27:54.598642Z","iopub.status.idle":"2024-03-05T19:27:54.615430Z","shell.execute_reply.started":"2024-03-05T19:27:54.598602Z","shell.execute_reply":"2024-03-05T19:27:54.614127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image, mask_tensor = preprocessing('000155de5.jpg')\nmask_tensor.shape\n\nplt.imshow(mask_tensor[:, :, 1])","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:27:59.720451Z","iopub.execute_input":"2024-03-05T19:27:59.720890Z","iopub.status.idle":"2024-03-05T19:28:00.066140Z","shell.execute_reply.started":"2024-03-05T19:27:59.720855Z","shell.execute_reply":"2024-03-05T19:28:00.065078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(image)","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:00.723541Z","iopub.execute_input":"2024-03-05T19:28:00.724232Z","iopub.status.idle":"2024-03-05T19:28:01.068799Z","shell.execute_reply.started":"2024-03-05T19:28:00.724198Z","shell.execute_reply":"2024-03-05T19:28:01.067509Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# creating a list of images for training \n\nimg_with_ships = image_ids[image_ids['EncodedPixels'] != ''].sample(n=25000)\nimg_without_ships = image_ids[image_ids['EncodedPixels'] == ''].sample(n=15000)\nimage_ids_less = pd.concat([img_with_ships, img_without_ships])\n\nlen(image_ids_less)\n\n# deviding images into train and validation\ntrain_data, val_data = train_test_split(image_ids_less, test_size=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:02.308056Z","iopub.execute_input":"2024-03-05T19:28:02.308636Z","iopub.status.idle":"2024-03-05T19:28:02.453932Z","shell.execute_reply.started":"2024-03-05T19:28:02.308593Z","shell.execute_reply":"2024-03-05T19:28:02.452827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# preprocessing train dataset\ntrain_images_dataset = tf.data.Dataset.from_tensor_slices(train_data['ImageId'])\ntrain_images = train_images_dataset.map(lambda x: tf.py_function(preprocessing, [x], [tf.float32, tf.float32]), num_parallel_calls=tf.data.AUTOTUNE)\n\n'''train_images = train_images.map(lambda img, mask: (img, mask), \n                                num_parallel_calls=tf.data.AUTOTUNE,\n                                deterministic=False)'''\n# ensuring necessary shape\ntrain_images = train_images.map(lambda img, mask: (tf.ensure_shape(img, (256, 256, 3)), tf.ensure_shape(mask, (256, 256, 2))),\n                                num_parallel_calls=tf.data.AUTOTUNE)\n# prepairing training batches \ntrain_images = train_images.shuffle(256, reshuffle_each_iteration=True)\ntraining_batches = train_images.batch(32)\ntraining_batches = training_batches.repeat()\ntraining_batches = training_batches.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)\n\n# shape of training batches\nprint(training_batches.element_spec)","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:03.705432Z","iopub.execute_input":"2024-03-05T19:28:03.706152Z","iopub.status.idle":"2024-03-05T19:28:03.755631Z","shell.execute_reply.started":"2024-03-05T19:28:03.706111Z","shell.execute_reply":"2024-03-05T19:28:03.754303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# preprocessing val dataset\nval_images_dataset = tf.data.Dataset.from_tensor_slices(val_data['ImageId'])\nval_images = val_images_dataset.map(lambda x: tf.py_function(preprocessing, [x], [tf.float32, tf.float32]), num_parallel_calls=tf.data.AUTOTUNE)\n\n'''val_images = val_images.map(lambda img, mask: (img, mask), \n                                num_parallel_calls=tf.data.AUTOTUNE,\n                                deterministic=False)'''\n# ensuring necessary shape\nval_images = val_images.map(lambda img, mask: (tf.ensure_shape(img, (256, 256, 3)), tf.ensure_shape(mask, (256, 256, 2))),\n                                num_parallel_calls=tf.data.AUTOTUNE)\n\n# prepairing val batches\nval_images = val_images.shuffle(256, reshuffle_each_iteration=True)\nval_batches = val_images.batch(32)\n\n# shape of val batches\nprint(val_images.element_spec)","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:04.424545Z","iopub.execute_input":"2024-03-05T19:28:04.425018Z","iopub.status.idle":"2024-03-05T19:28:04.468933Z","shell.execute_reply.started":"2024-03-05T19:28:04.424982Z","shell.execute_reply":"2024-03-05T19:28:04.467503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Defining a Unet model\n\n# convolutional part of an encoder block\ndef conv2d_block(input_tensor, n_filters, kernel_size = 3):\n    x = input_tensor\n    \n    for i in range(2):\n        x = tf.keras.layers.Conv2D(filters = n_filters, \n         kernel_size = (kernel_size, kernel_size), padding='same')(x)\n\n        x = tf.keras.layers.Activation('relu')(x)\n    return x\n\n# encoder block itself\ndef encoder_block(inputs, n_filters, pool_size, dropout):\n    f = conv2d_block(inputs, n_filters=n_filters)\n    p = tf.keras.layers.MaxPooling2D(pool_size)(f)\n    p = tf.keras.layers.Dropout(dropout)(p)\n\n    return f, p\n\n# encoder part of the model\ndef encoder(inputs):\n    f1, p1 = encoder_block(inputs, n_filters=64, pool_size=(2,2), dropout=0.3)\n    f2, p2 = encoder_block(p1, n_filters=128, pool_size=(2,2), dropout=0.3)\n    f3, p3 = encoder_block(p2, n_filters=256, pool_size=(2,2), dropout=0.3)\n    f4, p4 = encoder_block(p3, n_filters=512, pool_size=(2,2), dropout=0.3)\n    return p4, (f1, f2, f3, f4)","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:05.986468Z","iopub.execute_input":"2024-03-05T19:28:05.986882Z","iopub.status.idle":"2024-03-05T19:28:05.999596Z","shell.execute_reply.started":"2024-03-05T19:28:05.986851Z","shell.execute_reply":"2024-03-05T19:28:05.998092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# bottleneck of the moodel\ndef bottleneck(inputs):\n    bottle_neck = conv2d_block(inputs, n_filters=1024)\n    return bottle_neck","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:07.357796Z","iopub.execute_input":"2024-03-05T19:28:07.358814Z","iopub.status.idle":"2024-03-05T19:28:07.363195Z","shell.execute_reply.started":"2024-03-05T19:28:07.358758Z","shell.execute_reply":"2024-03-05T19:28:07.362318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# decoder block of the model\ndef decoder_block(inputs, conv_output, n_filters, kernel_size, strides, dropout):\n    u = tf.keras.layers.Conv2DTranspose(n_filters, kernel_size, strides = strides, \n    padding = 'same')(inputs)\n    c = tf.keras.layers.concatenate([u, conv_output])\n    c = tf.keras.layers.Dropout(dropout)(c)\n    c = conv2d_block(c, n_filters, kernel_size=3)\n    return c\n\n# decoder part of the model\ndef decoder(inputs, convs):\n    f1, f2, f3, f4 = convs\n    c6 = decoder_block(inputs, f4, n_filters=512, kernel_size=(3,3), strides=(2,2), dropout=0.3)\n    c7 = decoder_block(c6, f3, n_filters=256, kernel_size=(3,3), strides=(2,2), dropout=0.3)\n    c8 = decoder_block(c7, f2, n_filters=128, kernel_size=(3,3), strides=(2,2), dropout=0.3)\n    c9 = decoder_block(c8, f1, n_filters=64, kernel_size=(3,3), strides=(2,2), dropout=0.3)\n    outputs = tf.keras.layers.Conv2D(2, (1, 1), activation='softmax')(c9)\n    return outputs\n\n# joining everything into Unet model\ndef unet():\n    inputs = tf.keras.layers.Input(shape=(256,256,3))\n    encoder_output, convs = encoder(inputs)\n    \n    bottle_neck = bottleneck(encoder_output)\n    \n    outputs = decoder(bottle_neck, convs)\n    model = tf.keras.Model(inputs=inputs, outputs=outputs)\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:08.406290Z","iopub.execute_input":"2024-03-05T19:28:08.407129Z","iopub.status.idle":"2024-03-05T19:28:08.418891Z","shell.execute_reply.started":"2024-03-05T19:28:08.407084Z","shell.execute_reply":"2024-03-05T19:28:08.417987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = unet()","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:09.575416Z","iopub.execute_input":"2024-03-05T19:28:09.576124Z","iopub.status.idle":"2024-03-05T19:28:10.467135Z","shell.execute_reply.started":"2024-03-05T19:28:09.576089Z","shell.execute_reply":"2024-03-05T19:28:10.465867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# function for calculating dice score\ndef class_wise_metrics(y_true, y_pred):\n\n    class_wise_dice_score = []\n    \n    smoothing_factor = 0.00001\n\n    for i in range(n_classes):\n        intersection = np.sum((y_pred == i) * (y_true == i))\n        y_true_area = np.sum((y_true == i))\n        y_pred_area = np.sum((y_pred == i))\n        combined_area = y_true_area + y_pred_area\n\n    dice_score =  2 * ((intersection) / (combined_area + smoothing_factor))\n    class_wise_dice_score.append(dice_score)\n\n    return class_wise_dice_score","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:11.306538Z","iopub.execute_input":"2024-03-05T19:28:11.306999Z","iopub.status.idle":"2024-03-05T19:28:11.316084Z","shell.execute_reply.started":"2024-03-05T19:28:11.306961Z","shell.execute_reply":"2024-03-05T19:28:11.314585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#training model\n\nfrom keras.optimizers import RMSprop\n\n# defining parameters \nepochs = 5\nbatch_size = 32\ndataset_size = tf.data.Dataset.from_tensor_slices(train_data['ImageId']).cardinality().numpy()\n\nmodel.compile(loss=tf.keras.losses.BinaryCrossentropy(), optimizer=RMSprop(lr=0.001), metrics=['accuracy'])\n\n\nmodel_history = model.fit(training_batches,\n                          epochs=epochs,\n                          steps_per_epoch=dataset_size // batch_size,\n                          validation_data=val_batches)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# saving weigths of model\n\nmodel.save_weights('model_weights.h5')","metadata":{"execution":{"iopub.status.busy":"2024-02-28T21:25:39.443493Z","iopub.execute_input":"2024-02-28T21:25:39.443841Z","iopub.status.idle":"2024-02-28T21:25:39.697658Z","shell.execute_reply.started":"2024-02-28T21:25:39.443812Z","shell.execute_reply":"2024-02-28T21:25:39.696801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# uncomment to load weights\n\nmodel.load_weights('/kaggle/input/model-weights-h5/model_weights.h5')","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:14.202923Z","iopub.execute_input":"2024-03-05T19:28:14.203346Z","iopub.status.idle":"2024-03-05T19:28:15.742820Z","shell.execute_reply.started":"2024-03-05T19:28:14.203315Z","shell.execute_reply":"2024-03-05T19:28:15.741786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_path = '/kaggle/input/airbus-ship-detection/test_v2/009bc4be5.jpg'\nimg = cv2.imread(img_path)\nimage = tf.image.resize(img, (256, 256))\nimage = tf.expand_dims(image, axis=0)\nimage = tf.cast(image, dtype=tf.float32) / 255.0\n\nprediction = model.predict(image)","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:18.103454Z","iopub.execute_input":"2024-03-05T19:28:18.103866Z","iopub.status.idle":"2024-03-05T19:28:19.632790Z","shell.execute_reply.started":"2024-03-05T19:28:18.103835Z","shell.execute_reply":"2024-03-05T19:28:19.631846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prediction.shape","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:21.104296Z","iopub.execute_input":"2024-03-05T19:28:21.104700Z","iopub.status.idle":"2024-03-05T19:28:21.112364Z","shell.execute_reply.started":"2024-03-05T19:28:21.104669Z","shell.execute_reply":"2024-03-05T19:28:21.111241Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(img)","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:24.107234Z","iopub.execute_input":"2024-03-05T19:28:24.107719Z","iopub.status.idle":"2024-03-05T19:28:24.534327Z","shell.execute_reply.started":"2024-03-05T19:28:24.107683Z","shell.execute_reply":"2024-03-05T19:28:24.533061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prediction_single = prediction[0]\n\nprediction_class = tf.argmax(prediction_single, axis=-1)\n\nplt.imshow(prediction_class)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:28:26.818429Z","iopub.execute_input":"2024-03-05T19:28:26.818877Z","iopub.status.idle":"2024-03-05T19:28:27.021398Z","shell.execute_reply.started":"2024-03-05T19:28:26.818843Z","shell.execute_reply":"2024-03-05T19:28:27.020335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''test_folder = '/kaggle/input/airbus-ship-detection/test_v2'\n\ntest_images = [images for images in os.listdir(test_folder)]'''","metadata":{"execution":{"iopub.status.busy":"2024-03-01T20:05:14.979258Z","iopub.execute_input":"2024-03-01T20:05:14.979673Z","iopub.status.idle":"2024-03-01T20:05:14.993856Z","shell.execute_reply.started":"2024-03-01T20:05:14.979622Z","shell.execute_reply":"2024-03-01T20:05:14.993102Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Function that converts mask to rle\ndef mask_to_rle(img, shape=(768, 768)):\n    \"\"\"\n    :param img: numpy 4D array, (batch_size, height, width, channels)\n           shape: (height, width) dimensions of the image \n    :return: run length encoded pixels as string formated\n    \"\"\"\n    \n    img = img[0, :, :, 1]\n    \n    img = img.astype('float32')\n    img = cv2.resize(img, shape, interpolation=cv2.INTER_AREA)\n    img = np.stack(np.vectorize(lambda x: 0 if x < 0.1 else 1)(img), axis=1)\n    pixels = img.T.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:30:30.063529Z","iopub.execute_input":"2024-03-05T19:30:30.064477Z","iopub.status.idle":"2024-03-05T19:30:30.073924Z","shell.execute_reply.started":"2024-03-05T19:30:30.064436Z","shell.execute_reply":"2024-03-05T19:30:30.072486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Making predictions on test dataset \n\ntest_folder = '/kaggle/input/airbus-ship-detection/test_v2'\ntarget_size=(256, 256)\n\ntest_submission = pd.DataFrame(columns=['ImageId', 'EncodedPixels'])\n\nfor img in os.listdir(test_folder):\n    img_path = os.path.join(test_folder, img)\n    \n    image = cv2.imread(img_path)\n    image = tf.image.resize(image, target_size)\n    image = tf.expand_dims(image, axis=0)\n    image = tf.cast(image, dtype=tf.float32) / 255.0\n    pred = model.predict(image)\n    rle = mask_to_rle(pred)\n    \n    test_submission.loc[len(test_submission)] = [img, rle]","metadata":{"execution":{"iopub.status.busy":"2024-03-05T19:30:31.288348Z","iopub.execute_input":"2024-03-05T19:30:31.288770Z","iopub.status.idle":"2024-03-05T19:30:37.098719Z","shell.execute_reply.started":"2024-03-05T19:30:31.288739Z","shell.execute_reply":"2024-03-05T19:30:37.097133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_submission.head(10)","metadata":{"execution":{"iopub.status.busy":"2024-03-01T21:52:17.923051Z","iopub.execute_input":"2024-03-01T21:52:17.923642Z","iopub.status.idle":"2024-03-01T21:52:17.934408Z","shell.execute_reply.started":"2024-03-01T21:52:17.923615Z","shell.execute_reply":"2024-03-01T21:52:17.933404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_submission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-03-01T21:47:01.682283Z","iopub.execute_input":"2024-03-01T21:47:01.682653Z","iopub.status.idle":"2024-03-01T21:47:08.657210Z","shell.execute_reply.started":"2024-03-01T21:47:01.682624Z","shell.execute_reply":"2024-03-01T21:47:08.656217Z"},"trusted":true},"execution_count":null,"outputs":[]}]}