{"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"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":9988,"databundleVersionId":868324,"sourceType":"competition"}],"dockerImageVersionId":30587,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2\nfrom PIL import Image\nimport tensorflow as tf","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:36.828799Z","iopub.execute_input":"2023-11-21T17:57:36.829422Z","iopub.status.idle":"2023-11-21T17:57:51.714945Z","shell.execute_reply.started":"2023-11-21T17:57:36.829389Z","shell.execute_reply":"2023-11-21T17:57:51.71333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CORRUPTED_FILE_NAMES = ['6384c3e78.jpg']\nIMAGE_HEIGHT, IMAGE_WIDTH = 768, 768\nBATCH_SIZE = 32\nBUFFER_SIZE = 1000\nVALIDATION_LENGTH = 2000\nSEED = 21112023\nEPOCHS = 5\nSTEPS_PER_EPOCH = 200","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:51.716757Z","iopub.execute_input":"2023-11-21T17:57:51.717355Z","iopub.status.idle":"2023-11-21T17:57:51.722678Z","shell.execute_reply.started":"2023-11-21T17:57:51.717325Z","shell.execute_reply":"2023-11-21T17:57:51.72136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ship_segmentations_v2 = pd.read_csv(\"/kaggle/input/airbus-ship-detection/train_ship_segmentations_v2.csv\", index_col = 'ImageId')\ntrain_ship_segmentations_v2","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:51.723991Z","iopub.execute_input":"2023-11-21T17:57:51.724581Z","iopub.status.idle":"2023-11-21T17:57:52.765731Z","shell.execute_reply.started":"2023-11-21T17:57:51.724547Z","shell.execute_reply":"2023-11-21T17:57:52.764311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"encoded_pixels_df = pd.DataFrame({'EncodedPixels': (train_ship_segmentations_v2['EncodedPixels'] + ' ').groupby('ImageId').sum(min_count = 1).fillna('').str.strip()})\nencoded_pixels_df","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:52.767653Z","iopub.execute_input":"2023-11-21T17:57:52.768432Z","iopub.status.idle":"2023-11-21T17:57:53.103279Z","shell.execute_reply.started":"2023-11-21T17:57:52.768403Z","shell.execute_reply":"2023-11-21T17:57:53.102222Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_image(fname, train = True):\n    return cv2.imread(('/kaggle/input/airbus-ship-detection/train_v2/' if train else '/kaggle/input/airbus-ship-detection/test_v2/') + fname) / 255.","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:53.104519Z","iopub.execute_input":"2023-11-21T17:57:53.104917Z","iopub.status.idle":"2023-11-21T17:57:53.111743Z","shell.execute_reply.started":"2023-11-21T17:57:53.10487Z","shell.execute_reply":"2023-11-21T17:57:53.1104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_mask(file_name):\n    mask = np.zeros(IMAGE_HEIGHT * IMAGE_WIDTH, dtype = bool)\n    pairs = np.array(encoded_pixels_df['EncodedPixels'][file_name].split(), dtype = int).reshape(-1, 2)\n    for position, length in pairs:\n        mask[position:position + length] = 1\n    return mask.reshape(IMAGE_WIDTH, IMAGE_HEIGHT).T\n\n#plt.imshow(get_mask('000194a2d.jpg'))\nplt.imshow(get_image('000194a2d.jpg')[..., ::-1] * (1 - get_mask('000194a2d.jpg')[..., None]))\n#plt.imshow(tf.convert_to_tensor(get_mask('000194a2d.jpg')))","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:53.113496Z","iopub.execute_input":"2023-11-21T17:57:53.113887Z","iopub.status.idle":"2023-11-21T17:57:53.699025Z","shell.execute_reply.started":"2023-11-21T17:57:53.113854Z","shell.execute_reply":"2023-11-21T17:57:53.697531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_train_pair(file_name):\n    get_image(filename), get_mask(file_name)","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:53.700059Z","iopub.execute_input":"2023-11-21T17:57:53.700369Z","iopub.status.idle":"2023-11-21T17:57:53.706372Z","shell.execute_reply.started":"2023-11-21T17:57:53.700342Z","shell.execute_reply":"2023-11-21T17:57:53.705162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_pair_generator():\n    file_names = np.setdiff1d(encoded_pixels_df.index, CORRUPTED_FILE_NAMES)\n    for file_name in file_names:\n        yield get_image(file_name), get_mask(file_name)","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:53.707412Z","iopub.execute_input":"2023-11-21T17:57:53.707748Z","iopub.status.idle":"2023-11-21T17:57:53.726861Z","shell.execute_reply.started":"2023-11-21T17:57:53.707718Z","shell.execute_reply":"2023-11-21T17:57:53.725996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = tf.data.Dataset.from_generator(\n    train_pair_generator,\n    output_signature = (\n        tf.TensorSpec(shape=(IMAGE_HEIGHT, IMAGE_WIDTH, 3), dtype = float),\n        tf.TensorSpec(shape=(IMAGE_HEIGHT, IMAGE_WIDTH,), dtype = bool),\n    )\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:53.728205Z","iopub.execute_input":"2023-11-21T17:57:53.72872Z","iopub.status.idle":"2023-11-21T17:57:53.884832Z","shell.execute_reply.started":"2023-11-21T17:57:53.72869Z","shell.execute_reply":"2023-11-21T17:57:53.883877Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Augment(tf.keras.layers.Layer):\n    def __init__(self, seed=42):\n        super().__init__()\n        # both use the same seed, so they'll make the same random changes.\n        self.augment_inputs =  tf.keras.layers.RandomFlip(seed = SEED)\n        self.augment_labels = tf.keras.layers.RandomFlip(seed = SEED)\n        \n\n    def call(self, inputs, labels):\n        inputs = self.augment_inputs(inputs)\n        labels = self.augment_labels(labels)\n        return inputs, labels","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:53.888462Z","iopub.execute_input":"2023-11-21T17:57:53.889331Z","iopub.status.idle":"2023-11-21T17:57:54.078583Z","shell.execute_reply.started":"2023-11-21T17:57:53.889289Z","shell.execute_reply":"2023-11-21T17:57:54.077221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_batches = (\n    train_dataset\n    .cache()\n    .shuffle(BUFFER_SIZE)\n    .batch(BATCH_SIZE)\n    .repeat()\n    .map(Augment())\n    .prefetch(buffer_size=tf.data.AUTOTUNE))","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:54.080362Z","iopub.execute_input":"2023-11-21T17:57:54.080958Z","iopub.status.idle":"2023-11-21T17:57:54.545867Z","shell.execute_reply.started":"2023-11-21T17:57:54.080924Z","shell.execute_reply":"2023-11-21T17:57:54.544239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Conv2DTranspose, Concatenate, Input\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.applications import VGG19\nimport keras","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:54.547518Z","iopub.execute_input":"2023-11-21T17:57:54.547871Z","iopub.status.idle":"2023-11-21T17:57:54.555942Z","shell.execute_reply.started":"2023-11-21T17:57:54.547846Z","shell.execute_reply":"2023-11-21T17:57:54.554876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def conv_block(input, num_filters):\n    x = Conv2D(num_filters, 3, padding=\"same\")(input)\n    x = BatchNormalization()(x)\n    x = Activation(\"relu\")(x)\n \n    x = Conv2D(num_filters, 3, padding=\"same\")(x)\n    x = BatchNormalization()(x)\n    x = Activation(\"relu\")(x)\n \n    return x","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:54.55727Z","iopub.execute_input":"2023-11-21T17:57:54.557627Z","iopub.status.idle":"2023-11-21T17:57:54.577222Z","shell.execute_reply.started":"2023-11-21T17:57:54.557594Z","shell.execute_reply":"2023-11-21T17:57:54.576265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def decoder_block(input, skip_features, num_filters):\n    x = Conv2DTranspose(num_filters, (2, 2), strides=2, padding=\"same\")(input)\n    x = Concatenate()([x, skip_features])\n    x = conv_block(x, num_filters)\n    return x","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:59:02.97192Z","iopub.execute_input":"2023-11-21T17:59:02.97229Z","iopub.status.idle":"2023-11-21T17:59:02.977839Z","shell.execute_reply.started":"2023-11-21T17:59:02.972259Z","shell.execute_reply":"2023-11-21T17:59:02.976512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def build_vgg19_unet(input_shape):\n    \"\"\" Input \"\"\"\n    inputs = Input(input_shape)\n \n    \"\"\" Pre-trained VGG19 Model \"\"\"\n    vgg19 = VGG19(include_top=False, weights=\"imagenet\", input_tensor=inputs)\n \n    \"\"\" Encoder \"\"\"\n    s1 = vgg19.get_layer(\"block1_conv2\").output         ## (512 x 512)\n    s2 = vgg19.get_layer(\"block2_conv2\").output         ## (256 x 256)\n    s3 = vgg19.get_layer(\"block3_conv4\").output         ## (128 x 128)\n    s4 = vgg19.get_layer(\"block4_conv4\").output         ## (64 x 64)\n \n    \"\"\" Bridge \"\"\"\n    b1 = vgg19.get_layer(\"block5_conv4\").output         ## (32 x 32)\n \n    \"\"\" Decoder \"\"\"\n    d1 = decoder_block(b1, s4, 512)                     ## (64 x 64)\n    d2 = decoder_block(d1, s3, 256)                     ## (128 x 128)\n    d3 = decoder_block(d2, s2, 128)                     ## (256 x 256)\n    d4 = decoder_block(d3, s1, 64)                      ## (512 x 512)\n \n    \"\"\" Output \"\"\"\n    outputs = Conv2D(1, 1, padding=\"same\", activation=\"sigmoid\")(d4)\n \n    model = Model(inputs, outputs, name=\"VGG19_U-Net\")\n    return model","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:59:06.869732Z","iopub.execute_input":"2023-11-21T17:59:06.870154Z","iopub.status.idle":"2023-11-21T17:59:06.879407Z","shell.execute_reply.started":"2023-11-21T17:59:06.870123Z","shell.execute_reply":"2023-11-21T17:59:06.877976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_shape = (512, 512, 3)\nmodel = build_vgg19_unet(input_shape)\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:59:10.146288Z","iopub.execute_input":"2023-11-21T17:59:10.146667Z","iopub.status.idle":"2023-11-21T17:59:15.691737Z","shell.execute_reply.started":"2023-11-21T17:59:10.146637Z","shell.execute_reply":"2023-11-21T17:59:15.690541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = build_vgg19_unet((IMAGE_HEIGHT, IMAGE_WIDTH, 3))","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:59:16.816227Z","iopub.execute_input":"2023-11-21T17:59:16.816718Z","iopub.status.idle":"2023-11-21T17:59:17.686438Z","shell.execute_reply.started":"2023-11-21T17:59:16.816694Z","shell.execute_reply":"2023-11-21T17:59:17.685342Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer='adam',\n              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:59:21.017586Z","iopub.execute_input":"2023-11-21T17:59:21.018291Z","iopub.status.idle":"2023-11-21T17:59:21.042036Z","shell.execute_reply.started":"2023-11-21T17:59:21.018257Z","shell.execute_reply":"2023-11-21T17:59:21.040166Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_history = model.fit(train_batches, epochs=EPOCHS,\n                          steps_per_epoch=STEPS_PER_EPOCH,\n                         )","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:59:21.832516Z","iopub.execute_input":"2023-11-21T17:59:21.833864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class downscale(keras.layers.Layer):\n    def __init__(self):\n        pass\n    def call(img, mask):\n        return tf.image.resize(img, [512, 512]), tf.image.resize(tf.cast(mask, dtype = float), [512, 512])\n\nclass upscale(keras.layers.Layer):\n    def __init__(self):\n        pass\n    def call(img, mask):\n        return tf.image.resize(img, [INPUT_HEIGHT, INPUT_WIDTH]), tf.image.resize(tf.cast(mask, dtype = float), [INPUT_HEIGHT, INPUT_WIDTH])","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:54.612972Z","iopub.status.idle":"2023-11-21T17:57:54.613584Z","shell.execute_reply.started":"2023-11-21T17:57:54.613305Z","shell.execute_reply":"2023-11-21T17:57:54.613333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inputs = keras.Input(shape = (INPUT_HEIGHT, INPUT_WIDTH, 3))\nouputs = downscale()(inputs)\noutputs = ","metadata":{"execution":{"iopub.status.busy":"2023-11-21T17:57:54.617129Z","iopub.status.idle":"2023-11-21T17:57:54.618405Z","shell.execute_reply.started":"2023-11-21T17:57:54.618176Z","shell.execute_reply":"2023-11-21T17:57:54.618202Z"},"trusted":true},"execution_count":null,"outputs":[]}]}