{"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":79775,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":67031,"modelId":92056}],"dockerImageVersionId":30746,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport random\nimport glob\nimport gc  # garbage collector\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nimport numpy as np\nimport cv2\n\n# tensorflow\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.layers import (Conv2D, Input, MaxPooling2D, \n                                     Dropout, concatenate, UpSampling2D, BatchNormalization, Conv2DTranspose)\nfrom tensorflow.keras.models import load_model, Model\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau, TensorBoard\nfrom tensorflow.keras import backend as K\n\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-07-20T14:38:43.189785Z","iopub.execute_input":"2024-07-20T14:38:43.190185Z","iopub.status.idle":"2024-07-20T14:39:02.494468Z","shell.execute_reply.started":"2024-07-20T14:38:43.190151Z","shell.execute_reply":"2024-07-20T14:39:02.493089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gpus = tf.config.list_physical_devices('GPU')\nif gpus:\n    try:\n        for gpu in gpus:\n            tf.config.experimental.set_memory_growth(gpu, True)\n        logical_gpus = tf.config.experimental.list_logical_devices('GPU')\n        print(len(gpus), \"Physical GPUs,\", len(logical_gpus), \"Logical GPUs\")\n    except RuntimeError as e:\n        print(e)\nelse:\n    print(\"No GPUs found. Please ensure CUDA and cuDNN are properly installed.\")","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:02.496812Z","iopub.execute_input":"2024-07-20T14:39:02.497698Z","iopub.status.idle":"2024-07-20T14:39:02.509453Z","shell.execute_reply.started":"2024-07-20T14:39:02.497651Z","shell.execute_reply":"2024-07-20T14:39:02.507951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FULL_SHAPE = (768, 768)\nNEW_SHAPE = (128, 128)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:02.511632Z","iopub.execute_input":"2024-07-20T14:39:02.512709Z","iopub.status.idle":"2024-07-20T14:39:02.542568Z","shell.execute_reply.started":"2024-07-20T14:39:02.512664Z","shell.execute_reply":"2024-07-20T14:39:02.541325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Utility functions","metadata":{}},{"cell_type":"code","source":"def image_from_path(img_dir, img_name):\n    \n    img_path = os.path.join(img_dir, img_name)\n    \n    image = cv2.imread(img_path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    image = cv2.resize(image, NEW_SHAPE)\n    image = image / 255.0  # Normalize to [0, 1]\n    \n    return np.expand_dims(image, axis=0)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:02.545883Z","iopub.execute_input":"2024-07-20T14:39:02.546248Z","iopub.status.idle":"2024-07-20T14:39:02.555847Z","shell.execute_reply.started":"2024-07-20T14:39:02.546219Z","shell.execute_reply":"2024-07-20T14:39:02.554671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load U-Net model","metadata":{}},{"cell_type":"code","source":"def create_conv2d_block(input_tensor, num_filters, kernel_size=3, batchnorm=True):\n    \"\"\"Function to add 2 convolutional layers with the parameters passed to it\"\"\"\n    \n    # 1st layer\n    x = Conv2D(filters = num_filters, kernel_size = (kernel_size, kernel_size),\\\n              kernel_initializer = 'he_normal', padding = 'same')(input_tensor)\n    \n    if batchnorm:\n        x = BatchNormalization()(x)\n        \n    x = keras.layers.Activation('relu')(x)\n    \n    # 2nd layer\n    x = Conv2D(filters = num_filters, kernel_size = (kernel_size, kernel_size),\\\n              kernel_initializer = 'he_normal', padding = 'same')(input_tensor)\n    \n    if batchnorm:\n        x = BatchNormalization()(x)\n    \n    x = keras.layers.Activation('relu')(x)\n    \n    return x","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:02.557276Z","iopub.execute_input":"2024-07-20T14:39:02.557724Z","iopub.status.idle":"2024-07-20T14:39:02.571482Z","shell.execute_reply.started":"2024-07-20T14:39:02.557689Z","shell.execute_reply":"2024-07-20T14:39:02.570134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_unet(input_shape, num_filters=16, dropout=0.1, batchnorm=True):\n    \"\"\"\n    Function to define the UNET Model\n    input_shape: (height, width, 3)\n    \"\"\"\n    \n    assert input_shape[-1] == 3  # image must have 3 channels\n    \n    # input 'layer'\n    #input_img = Input((*input_shape, 3), name='img')\n    input_img = Input(input_shape, name='img')\n    \n    # downsampling (encoder)\n    c1 = create_conv2d_block(input_img, num_filters * 1, kernel_size=3, batchnorm=batchnorm)\n    p1 = MaxPooling2D((2, 2))(c1)\n    p1 = Dropout(dropout)(p1)\n    \n    c2 = create_conv2d_block(p1, num_filters * 2, kernel_size=3, batchnorm=batchnorm)\n    p2 = MaxPooling2D((2, 2))(c2)\n    p2 = Dropout(dropout)(p2)\n    \n    c3 = create_conv2d_block(p2, num_filters * 4, kernel_size=3, batchnorm=batchnorm)\n    p3 = MaxPooling2D((2, 2))(c3)\n    p3 = Dropout(dropout)(p3)\n    \n    c4 = create_conv2d_block(p3, num_filters * 8, kernel_size=3, batchnorm=batchnorm)\n    p4 = MaxPooling2D((2, 2))(c4)\n    p4 = Dropout(dropout)(p4)\n    \n    # bottleneck\n    c5 = create_conv2d_block(p4, num_filters * 16, kernel_size=3, batchnorm=batchnorm)\n    \n    # upsampling (decoder)\n    u6 = Conv2DTranspose(num_filters * 8, (3, 3), strides=(2, 2), padding='same')(c5)\n    u6 = concatenate([u6, c4])\n    u6 = Dropout(dropout)(u6)\n    c6 = create_conv2d_block(u6, num_filters * 8, kernel_size=3, batchnorm=batchnorm)\n    \n    u7 = Conv2DTranspose(num_filters * 4, (3, 3), strides=(2, 2), padding='same')(c6)\n    u7 = concatenate([u7, c3])\n    u7 = Dropout(dropout)(u7)\n    c7 = create_conv2d_block(u7, num_filters * 4, kernel_size=3, batchnorm=batchnorm)\n    \n    u8 = Conv2DTranspose(num_filters * 2, (3, 3), strides=(2, 2), padding='same')(c7)\n    u8 = concatenate([u8, c2])\n    u8 = Dropout(dropout)(u8)\n    c8 = create_conv2d_block(u8, num_filters * 2, kernel_size=3, batchnorm=batchnorm)\n    \n    u9 = Conv2DTranspose(num_filters * 1, (3, 3), strides=(2, 2), padding='same')(c8)\n    u9 = concatenate([u9, c1])\n    u9 = Dropout(dropout)(u9)\n    c9 = create_conv2d_block(u9, num_filters * 1, kernel_size=3, batchnorm=batchnorm)\n    \n    outputs = Conv2D(1, (1, 1), activation='sigmoid')(c9)\n    model = Model(inputs=[input_img], outputs=[outputs])\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:02.572658Z","iopub.execute_input":"2024-07-20T14:39:02.573048Z","iopub.status.idle":"2024-07-20T14:39:02.593087Z","shell.execute_reply.started":"2024-07-20T14:39:02.572996Z","shell.execute_reply":"2024-07-20T14:39:02.591833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_shape = (*NEW_SHAPE, 3)\nunet_weights_path = '/kaggle/input/ship_detection_unet/tensorflow2/v1/1/model-Unet.weights.h5'\n\nunet_model = create_unet(input_shape)\nunet_model.load_weights(unet_weights_path)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:02.594477Z","iopub.execute_input":"2024-07-20T14:39:02.595000Z","iopub.status.idle":"2024-07-20T14:39:03.541685Z","shell.execute_reply.started":"2024-07-20T14:39:02.594965Z","shell.execute_reply":"2024-07-20T14:39:03.540068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Make predictions","metadata":{}},{"cell_type":"code","source":"test_images_folder_path = '/kaggle/input/airbus-ship-detection/test_v2'\ntest_images_filenames =  [os.path.basename(filename) for filename in glob.glob(test_images_folder_path + '/*')]","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:03.544735Z","iopub.execute_input":"2024-07-20T14:39:03.545596Z","iopub.status.idle":"2024-07-20T14:39:04.032823Z","shell.execute_reply.started":"2024-07-20T14:39:03.545475Z","shell.execute_reply":"2024-07-20T14:39:04.031490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(test_images_filenames), test_images_filenames[:10]","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:04.034500Z","iopub.execute_input":"2024-07-20T14:39:04.035072Z","iopub.status.idle":"2024-07-20T14:39:04.044180Z","shell.execute_reply.started":"2024-07-20T14:39:04.035022Z","shell.execute_reply":"2024-07-20T14:39:04.043039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"some_image = image_from_path(test_images_folder_path, test_images_filenames[1])\nsome_image.shape","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:04.048717Z","iopub.execute_input":"2024-07-20T14:39:04.049286Z","iopub.status.idle":"2024-07-20T14:39:04.125278Z","shell.execute_reply.started":"2024-07-20T14:39:04.049239Z","shell.execute_reply":"2024-07-20T14:39:04.124093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(some_image.squeeze(axis=0))\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:04.126938Z","iopub.execute_input":"2024-07-20T14:39:04.127445Z","iopub.status.idle":"2024-07-20T14:39:04.566210Z","shell.execute_reply.started":"2024-07-20T14:39:04.127384Z","shell.execute_reply":"2024-07-20T14:39:04.564946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_prediction(model, image):\n    threshold = 0.5\n    \n    # get probability for each pixel (-> np.ndarray)\n    prob_mask = model.predict(image).squeeze(0)\n    \n    segmentation_mask = np.zeros(prob_mask.shape)\n    # Convert probabilities to binary segmentation mask\n    segmentation_mask = (prob_mask > threshold).astype(np.uint8)\n    return segmentation_mask","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:04.567701Z","iopub.execute_input":"2024-07-20T14:39:04.568105Z","iopub.status.idle":"2024-07-20T14:39:04.574912Z","shell.execute_reply.started":"2024-07-20T14:39:04.568072Z","shell.execute_reply":"2024-07-20T14:39:04.573429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"some_image_mask = make_prediction(unet_model, some_image)","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:04.576358Z","iopub.execute_input":"2024-07-20T14:39:04.576807Z","iopub.status.idle":"2024-07-20T14:39:05.202199Z","shell.execute_reply.started":"2024-07-20T14:39:04.576766Z","shell.execute_reply":"2024-07-20T14:39:05.200689Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(ncols=2)\n\nax[0].imshow(some_image.squeeze(0))\nax[1].imshow(some_image_mask, cmap='gray')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-07-20T14:39:05.203776Z","iopub.execute_input":"2024-07-20T14:39:05.204185Z","iopub.status.idle":"2024-07-20T14:39:05.640812Z","shell.execute_reply.started":"2024-07-20T14:39:05.204131Z","shell.execute_reply":"2024-07-20T14:39:05.639458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}