{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom numpy import argmax\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n#for dirname, _, filenames in os.walk('/kaggle/input'):\n#    for filename in filenames:\n        #print(os.path.join(dirname, filename))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nfrom pathlib import Path\nfrom sklearn.model_selection import train_test_split\nfrom skimage.measure import label\nfrom skimage.measure import regionprops\nimport imageio\nfrom skimage.color import rgb2gray\nfrom skimage.transform import rescale, resize\nimport random\n# Tensorflow\nimport tensorflow as tf\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.layers import Input, Dense, BatchNormalization, ReLU, Conv2D, Dropout, MaxPooling2D, concatenate, UpSampling2D\nfrom tensorflow.keras.activations import softmax, sigmoid\n\nimport tensorflow.keras as keras\nimport keras.backend as K\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DATA_PATH = f'/kaggle/input/airbus-ship-detection/'\nfor x in os.listdir(DATA_PATH):\n    print(x)\n    \nTRAINING_CSV = f'{DATA_PATH}/train_ship_segmentations_v2.csv'\nTRAINING_IMAGES_PATH = f'{DATA_PATH}/train_v2/'\nTEST_IMAGES_PATH = f'{DATA_PATH}/test_v2/'\n\n\nOUTPUT_PATH = f'/kaggle/output'\n\nPath(OUTPUT_PATH).mkdir(exist_ok=True)\nfor x in os.listdir(OUTPUT_PATH):\n    print(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class AirbusImage(object):\n    images_path = TRAINING_IMAGES_PATH\n    def __init__(self, imageId, data):\n        self.imageId = imageId\n        self.image = None\n        image_data = data.loc[data['ImageId'] == self.imageId, 'EncodedPixels'].tolist()\n        self.flat_masks, self.masks, self.labels, self.boxes = self.__create_boats_data(image_data)\n\n    def __rle_decode_flatten(self, mask_rle):\n        shape=(768, 768)\n        s = mask_rle.split()\n        starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]\n        starts -= 1\n        ends = starts + lengths\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        return img\n\n    def __rle_decode(self, mask_rle):\n        shape=(768, 768)\n        flat_mask = self.__rle_decode_flatten(mask_rle)\n        return flat_mask.reshape(shape).T\n\n    def __create_boats_data(self, data):\n        masks = []\n        flat_masks = []\n        labels = []\n        boxes = []\n        if data != [-1]:\n            for encoded_mask in data:\n                img_mask = self.__rle_decode(encoded_mask)\n                flat_masks.append(self.__rle_decode_flatten(encoded_mask))\n                masks.append(img_mask)\n                img_label = label(img_mask)\n                labels.append(img_label)\n                img_box = regionprops(img_label)[0].bbox\n                boxes.append(img_box)\n        return flat_masks, masks, labels, boxes\n\n    def get_image(self):        \n        image = rgb2gray(imageio.imread(f'{TRAINING_IMAGES_PATH}/{self.imageId}'))\n        #image_resized = resize(image, (512, 512), anti_aliasing=True)\n        #image_resized = np.reshape(image_resized, (512, 512, 1))\n        image_resized = resize(image, (256, 256), anti_aliasing=True)\n        image_resized = np.reshape(image_resized, (256, 256, 1))\n        return image_resized\n\n    def get_flat_grey_image(self):\n        gray_image = rgb2gray(imageio.imread(f'{TRAINING_IMAGES_PATH}/{self.imageId}'))\n        flat_gray_image = [item for sublist in gray_image for item in sublist]\n        return flat_gray_image\n    \n    def get_masks(self):\n        return self.masks\n\n    def get_united_masks(self):\n        united_mask = self.get_flat_united_mask()\n        united_mask = np.reshape(united_mask, (768, 768)).T\n        united_mask = resize(united_mask, (256, 256), anti_aliasing=True)\n        return united_mask\n    \n    def get_flat_masks(self):\n        return self.flat_masks\n\n    def get_flat_united_mask(self):\n        unite_mask = np.zeros(768 * 768, dtype=np.uint8)\n        for mask in self.flat_masks:\n            unite_mask += mask\n        return unite_mask\n    \n    def get_boxes(self):\n        return self.boxes\n\n    def get_labels(self):\n        return self.labels\n    \n    def get_height(self):\n        return 768\n    \n    def get_width(self):\n        return 768\n    \n    def get_encoded_jpg(self):\n        with tf.gfile.GFile(f'{TRAINING_IMAGES_PATH}/{self.imageId}', 'rb') as fid:\n            encoded_jpg = fid.read()\n        return encoded_jpg","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from skimage.draw import rectangle_perimeter\n\ndata = pd.read_csv(TRAINING_CSV).fillna(-1)\nimage_name = 'c8b051d24.jpg'\nimage = AirbusImage(image_name, data)\n\nimg = image.get_image()\nmasks = image.get_masks()\n#print(masked_image.shape)\nunified_mask = image.get_united_masks()\n\nfig=plt.figure(figsize=(20, 10))\nax = fig.add_subplot(1, 3, 1)\nimg = np.reshape(img, (256, 256))\nplt.imshow(img)\nax = fig.add_subplot(1, 3, 2)\nplt.imshow(unified_mask)\nax = fig.add_subplot(1, 3, 3)\nplt.imshow(unified_mask)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_dataset_X_y(chosen_image, full_dataset):\n    X_data = []\n    y_data = []\n    c = 0\n    for index, image_id in chosen_image.items():\n        #print(image_id)\n        img_obj = AirbusImage(image_id, full_dataset)\n        X_data.append(tf.convert_to_tensor(img_obj.get_image()/255, dtype=tf.float32))\n        mask = img_obj.get_united_masks()\n        y_data.append(tf.convert_to_tensor(mask, dtype=tf.bool))\n        c += 1\n        if c % 50 == 0:\n            print(c)\n    print('Converting to tensor')\n    X_data = tf.convert_to_tensor(X_data)\n    y_data = tf.convert_to_tensor(y_data)#, dtype=tf.float32)\n    y_data = keras.utils.to_categorical(y_data, 2)\n    print('End converting to tensor')\n    return X_data, y_data\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_data = pd.read_csv(TRAINING_CSV).dropna()\nimage_data = image_data.reset_index(drop=True)\n\nimages_name = image_data['ImageId']\nimages_name = images_name.drop_duplicates()\nimages_name = images_name.sample(frac=1) # shuffle\nprint(f'Original images with data {images_name.shape}')\n#print(images_name.head())\n#images_to_use, images_discarded = train_test_split(images_name, test_size=0.995)\n#images_to_use, images_discarded = train_test_split(images_name, test_size=0.97)\nimages_to_use, images_discarded = train_test_split(images_name, test_size=0.95)\nprint(f'After reducing the size {images_to_use.shape}')\ntrain_df, test_df = train_test_split(images_to_use, test_size=0.3)\nprint(f'Training data shape: {train_df.shape}')\nprint(f'Test data shape: {test_df.shape}')\n\nX_train, y_train = get_dataset_X_y(train_df, image_data)\nX_test, y_test = get_dataset_X_y(test_df, image_data)\n\nprint(f'Shape of element 0 of X {X_train[0].shape}')\nprint(f'Shape of element 0 of y {y_train[0].shape}')\n#print(X_train)\nprint(y_train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def customLoss(yTrue, yPred):\n    weights = {0: 1, 1:155}\n    diff = yTrue - yPred\n\n    onesCondition = K.cast(K.equal(yTrue, 0.), tf.float32) * weights[0]\n    zeroCondition = K.cast(K.not_equal(yTrue, 0.), tf.float32) * weights[1]\n    weighted_tensor = onesCondition + zeroCondition\n    \n    diff = diff * weighted_tensor\n    loss = K.mean(K.abs(diff))\n    #print(loss)\n    return loss\n\nsol = customLoss(tf.convert_to_tensor([0., 0., 0., 0.], dtype=tf.float32), tf.convert_to_tensor([0.,0.,0.,1.], dtype=tf.float32))\nsol\n#print(sol)\n#print(sol.gradient())\n#tf.gradients(sol)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def oneHotcustomLoss(yTrue, yPred):\n    #weights = {0: 1, 1:155}\n    weighted = (K.argmax(yTrue) * 500) + 1\n    #print(weighted)\n    return tf.losses.binary_crossentropy(yTrue, yPred) * K.cast(weighted, tf.float32)\n\n#K.argmax(y_train[4])\ntrue = tf.convert_to_tensor([[[1, 0],[0, 1],[1, 0]]], tf.float32)\n#pred = tf.convert_to_tensor([[[0, 1],[1, 0],[0, 1]]], tf.float32)\npred = tf.convert_to_tensor([[[0.5, 0.5],[1, 0],[0, 1]]], tf.float32)\n\noneHotcustomLoss(true, pred)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import keras.backend as K\nfrom keras.optimizers import Adam\nfrom keras.losses import binary_crossentropy\n\n## intersection over union\ndef IoU(y_true, y_pred, eps=1e-6):\n    intersection = K.sum(y_true * y_pred, axis=[1,2,3])\n    union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3]) - intersection\n    return K.mean( (intersection + eps) / (union + eps), axis=0)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import keras.backend as K\nfrom keras.optimizers import Adam\nfrom keras.losses import binary_crossentropy\ndef dice_coef(y_true, y_pred, smooth=1):\n    intersection = K.sum(y_true * y_pred, axis=[1,2,3])\n    union = K.sum(y_true, axis=[1,2,3]) + K.sum(y_pred, axis=[1,2,3])\n    return K.mean( (2. * intersection + smooth) / (union + smooth), axis=0)\ndef dice_p_bce(in_gt, in_pred):\n    return 1e-3*binary_crossentropy(in_gt, in_pred) - dice_coef(in_gt, in_pred)\ndef true_positive_rate(y_true, y_pred):\n    return K.sum(K.flatten(y_true)*K.flatten(K.round(y_pred)))/K.sum(y_true)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"n_classes = 2\n\nimg_input = Input(shape=(256, 256, 1))\n\n# Encoder\nconv1 = Conv2D(64, (3, 3), activation='relu', padding='same')(img_input)\nconv1 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv1)\npool1 = MaxPooling2D((2, 2))(conv1)\n\nconv2 = Conv2D(128, (3, 3), activation='relu', padding='same')(pool1)\nconv2 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv2)\npool2 = MaxPooling2D((2, 2))(conv2)\n\nconv3 = Conv2D(256, (3, 3), activation='relu', padding='same')(pool2)\nconv3 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv3)\npool3 = MaxPooling2D((2, 2))(conv3)\n\nconv4 = Conv2D(512, (3, 3), activation='relu', padding='same')(pool3)\nconv4 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv4)\npool4 = MaxPooling2D((2, 2))(conv4)\n\n# Dencoder\nconv5 = Conv2D(1024, (3, 3), activation='relu', padding='same')(pool4)\nconv5 = Conv2D(1024, (3, 3), activation='relu', padding='same')(conv5)\nup1 = concatenate([UpSampling2D((2, 2))(conv5), conv4], axis=-1)\n\nconv6 = Conv2D(512, (3, 3), activation='relu', padding='same')(up1)\nconv6 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv6)\nup2 = concatenate([UpSampling2D((2, 2))(conv6), conv3], axis=-1)\n\nconv7 = Conv2D(256, (3, 3), activation='relu', padding='same')(up2)\nconv7 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv7)\nup3 = concatenate([UpSampling2D((2, 2))(conv7), conv2], axis=-1)\n\nconv8 = Conv2D(128, (3, 3), activation='relu', padding='same')(up3)\nconv8 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv8)\nup4 = concatenate([UpSampling2D((2, 2))(conv8), conv1], axis=-1)\n\n# Output\nconv9 = Conv2D(64, (3, 3), activation='relu', padding='same')(up4)\nconv9 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv9)\nconv9 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv9)\nconv9 = Conv2D(n_classes, (3, 3), activation='relu', padding='same')(conv9)\n\n\nout = softmax(conv9)\n\nmodel = keras.Model(inputs=img_input, outputs=out, name=\"AirbusCNN\")\n\nmodel.summary()\n\nmodel.compile(optimizer='adam',\n              #loss=WeightedBinaryCrossEntropy(pos_weight=0.5, weight = 2, from_logits=True),\n              loss=oneHotcustomLoss,\n              #loss=dice_p_bce,\n              #loss=IoU,\n              metrics = ['acc'])\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(X_train, y_train,\n              batch_size=32,\n              epochs=15,\n              shuffle=True,\n              callbacks = [keras.callbacks.EarlyStopping(patience=5)],\n              validation_data=(X_test, y_test))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_prediction(num_predictions):\n    print(f'Predictions of {num_predictions} images')\n    fig=plt.figure(figsize=(20, (num_predictions/6 * 25)))\n    for i in range(0, num_predictions):\n        image_num = random.randint(0,X_test.shape[0])\n        print(f'Preparing prediction {i+1}. Choosen image number {image_num}')\n        img = X_test[image_num] #np.reshape(X_test[image_num], (768, 768, 3))\n        img = np.reshape(img, (256, 256))\n        \n        real_mask = argmax(y_test[image_num], axis=2)\n        #real_mask = y_test[image_num]\n        print('Going to do a prediction')\n        prediction = model.predict(np.array([X_test[image_num]]))\n        print('Prediction done')\n        predicted_mask = argmax(prediction[0], axis=2)\n        #predicted_mask = np.reshape(prediction[0], (256, 256))\n\n        \n        ax = fig.add_subplot(num_predictions, 3, 1 + (i*3))\n        ax.axis('off')\n        plt.imshow(img)\n        ax = fig.add_subplot(num_predictions, 3, 2 + (i*3))\n        ax.axis('off')\n        print(real_mask.shape)\n        plt.imshow(real_mask)\n        ax = fig.add_subplot(num_predictions, 3, 3 + (i*3))\n        ax.axis('off')\n        plt.imshow(predicted_mask)\n    plt.show()\n\nplot_prediction(16)\n\n\n#y_test[1]\n#argmax(y_test[1], axis=2)","execution_count":null,"outputs":[]}],"metadata":{"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"}},"nbformat":4,"nbformat_minor":4}