{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Airbus Ship Detection"},{"metadata":{},"cell_type":"markdown","source":"In this kernel, we will create a model that will help us detect ships in a sattelite image. Our task is to locate the ships in the image and put an aligned bounding box around them. Ships can differ in size and some images may not even have ships."},{"metadata":{},"cell_type":"markdown","source":"**train_ship_segmentation_v2.csv**: This file contains the [Run Length Encoded](https://en.wikipedia.org/wiki/Run-length_encoding) Masks of ships in the image."},{"metadata":{"trusted":true},"cell_type":"code","source":"# Importing Libraries\n\n# Provides OS realted functions\nimport os \n\n# For Image Manipulation\nfrom skimage.data import imread\nfrom skimage.morphology import label\n\n# For Data Manipulation and Analysis\nimport pandas as pd\nimport numpy as np\n\n# Deep Learning Library\nfrom keras.models import *\nfrom keras.layers import *\nfrom keras.optimizers import *\n\n# Other utilities\nimport random\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.model_selection import train_test_split","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Directories Paths\ninput_dir = '../input/'\ntrain_dir = '../input/train_v2/'\ntest_dir = '../input/test_v2/'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Reading Training Data\ntrain_df = pd.read_csv(input_dir+'train_ship_segmentations_v2.csv')\n\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Removing Bug Images\ntrain_df = train_df[train_df['ImageId'] != '6384c3e78.jpg']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Removing 10000 non-ship Images\ndef area_isnull(x):\n    if x == x:\n        return 0\n    else:\n        return 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['isnan'] = train_df['EncodedPixels'].apply(area_isnull)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = train_df.sort_values('isnan', ascending=False)\ntrain_df = train_df.iloc[100000:]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['isnan'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"These are some helper functions that will help in calculating the ship area and will group them by imageId"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Helper Functions\ndef rle_to_mask(rle_list, SHAPE):\n    tmp_flat = np.zeros(SHAPE[0]*SHAPE[1])\n    if len(rle_list) == 1:\n        mask = np.reshape(tmp_flat, SHAPE).T\n    else:\n        strt = rle_list[::2]\n        length = rle_list[1::2]\n        for i,v in zip(strt,length):\n            tmp_flat[(int(i)-1):(int(i)-1)+int(v)] = 255\n        mask = np.reshape(tmp_flat, SHAPE).T\n    return mask","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def calc_area_for_rle(rle_str):\n    rle_list = [int(x) if x.isdigit() else x for x in str(rle_str).split()]\n    if len(rle_list) == 1:\n        return 0\n    else:\n        area = np.sum(rle_list[1::2])\n        return area","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['area'] = train_df[\"EncodedPixels\"].apply(calc_area_for_rle)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df_isship = train_df[train_df['area'] > 0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df_isship.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df_smallarea = train_df_isship['area'][train_df_isship['area'] < 10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df_smallarea.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df_smallarea.shape[0]/train_df_isship.shape[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_gp = train_df.groupby('ImageId').sum()\ntrain_gp = train_gp.reset_index()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_gp.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Now we will set the class for ship area"},{"metadata":{"trusted":true},"cell_type":"code","source":"def calc_class(area):\n    area = area / (768*768)\n    if area == 0:\n        return 0\n    elif area < 0.005:\n        return 1\n    elif area < 0.015:\n        return 2\n    elif area < 0.025:\n        return 3\n    elif area < 0.035:\n        return 4\n    elif area < 0.045:\n        return 5\n    else:\n        return 6","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_gp['class'] = train_gp['area'].apply(calc_class)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_gp['class'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Splitting data into train and validation set"},{"metadata":{"trusted":true},"cell_type":"code","source":"train, val = train_test_split(train_gp, test_size=0.01, stratify=train_gp['class'].tolist())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_isship_list = train['ImageId'][train['isnan']==0].tolist()\ntrain_isship_list = random.sample(train_isship_list, len(train_isship_list))\ntrain_nanship_list = train['ImageId'][train['isnan']==1].tolist()\ntrain_nanship_list = random.sample(train_nanship_list, len(train_nanship_list))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# data generator\n\ndef mygenerator(isship_list, nanship_list, batch_size, cap_num):\n    train_img_names_nanship = isship_list[:cap_num]\n    train_img_names_isship = nanship_list[:cap_num]\n    k = 0\n    while True:\n        if k+batch_size//2 >= cap_num:\n            k = 0\n        batch_img_names_nan = train_img_names_nanship[k:k+batch_size//2]\n        batch_img_names_is = train_img_names_isship[k:k+batch_size//2]\n        batch_img = []\n        batch_mask = []\n        for name in batch_img_names_nan:\n            tmp_img = imread(train_dir + name)\n            batch_img.append(tmp_img)\n            mask_list = train_df['EncodedPixels'][train_df['ImageId'] == name].tolist()\n            one_mask = np.zeros((768, 768, 1))\n            for item in mask_list:\n                rle_list = str(item).split()\n                tmp_mask = rle_to_mask(rle_list, (768, 768))\n                one_mask[:,:,0] += tmp_mask\n            batch_mask.append(one_mask)\n        for name in batch_img_names_is:\n            tmp_img = imread(train_dir + name)\n            batch_img.append(tmp_img)\n            mask_list = train_df['EncodedPixels'][train_df['ImageId'] == name].tolist()\n            one_mask = np.zeros((768, 768, 1))\n            for item in mask_list:\n                rle_list = str(item).split()\n                tmp_mask = rle_to_mask(rle_list, (768, 768))\n                one_mask[:,:,0] += tmp_mask\n            batch_mask.append(one_mask)\n        img = np.stack(batch_img, axis=0)\n        mask = np.stack(batch_mask, axis=0)\n        img = img / 255.0\n        mask = mask / 255.0\n        k += batch_size//2\n        yield img, mask\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 2\nCAP_NUM = min(len(train_isship_list),len(train_nanship_list))\ndatagen = mygenerator(train_isship_list, train_nanship_list, batch_size=BATCH_SIZE, cap_num=CAP_NUM)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Creat"},{"metadata":{"trusted":true},"cell_type":"code","source":"inputs = Input(shape=(768,768,3))\nconv0 = Conv2D(8, 3, activation='relu', padding='same', kernel_initializer='he_normal')(inputs)\nconv0 = BatchNormalization()(conv0)\nconv0 = Conv2D(8, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv0)\nconv0 = BatchNormalization()(conv0)\n\ncomp0 = AveragePooling2D((6,6))(conv0)\nconv1 = Conv2D(16, 3, activation='relu', padding='same', kernel_initializer='he_normal')(comp0)\nconv1 = BatchNormalization()(conv1)\nconv1 = Conv2D(16, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv1)\nconv1 = BatchNormalization()(conv1)\nconv1 = Dropout(0.4)(conv1)\n\npool1 = MaxPooling2D(pool_size=(2,2))(conv1)\nconv2 = Conv2D(32, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool1)\nconv2 = BatchNormalization()(conv2)\nconv2 = Conv2D(32, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv2)\nconv2 = BatchNormalization()(conv2)\nconv2 = Dropout(0.4)(conv2)\n\npool2 = MaxPooling2D(pool_size=(2,2))(conv2)\nconv3 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool2)\nconv3 = BatchNormalization()(conv3)\nconv3 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv3)\nconv3 = BatchNormalization()(conv3)\nconv3 = Dropout(0.4)(conv3)\n\npool3 = MaxPooling2D(pool_size=(2,2))(conv3)\nconv4 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool3)\nconv4 = BatchNormalization()(conv4)\nconv4 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv4)\nconv4 = BatchNormalization()(conv4)\nconv4 = Dropout(0.4)(conv4)\n\npool4 = MaxPooling2D(pool_size=(2,2))(conv4)\nconv5 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(pool4)\nconv5 = BatchNormalization()(conv5)\nconv5 = Conv2D(256, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv5)\nconv5 = BatchNormalization()(conv5)\n\nupcv6 = UpSampling2D(size=(2,2))(conv5)\nupcv6 = Conv2D(128, 2, activation='relu', padding='same', kernel_initializer='he_normal')(upcv6)\nupcv6 = BatchNormalization()(upcv6)\nmrge6 = concatenate([conv4, upcv6], axis=3)\nconv6 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(mrge6)\nconv6 = BatchNormalization()(conv6)\nconv6 = Conv2D(128, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv6)\nconv6 = BatchNormalization()(conv6)\n\nupcv7 = UpSampling2D(size=(2,2))(conv6)\nupcv7 = Conv2D(64, 2, activation='relu', padding='same', kernel_initializer='he_normal')(upcv7)\nupcv7 = BatchNormalization()(upcv7)\nmrge7 = concatenate([conv3, upcv7], axis=3)\nconv7 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(mrge7)\nconv7 = BatchNormalization()(conv7)\nconv7 = Conv2D(64, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv7)\nconv7 = BatchNormalization()(conv7)\n\nupcv8 = UpSampling2D(size=(2,2))(conv7)\nupcv8 = Conv2D(32, 2, activation='relu', padding='same', kernel_initializer='he_normal')(upcv8)\nupcv8 = BatchNormalization()(upcv8)\nmrge8 = concatenate([conv2, upcv8], axis=3)\nconv8 = Conv2D(32, 3, activation='relu', padding='same', kernel_initializer='he_normal')(mrge8)\nconv8 = BatchNormalization()(conv8)\nconv8 = Conv2D(32, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv8)\nconv8 = BatchNormalization()(conv8)\n\nupcv9 = UpSampling2D(size=(2,2))(conv8)\nupcv9 = Conv2D(16, 2, activation='relu', padding='same', kernel_initializer='he_normal')(upcv9)\nupcv9 = BatchNormalization()(upcv9)\nmrge9 = concatenate([conv1, upcv9], axis=3)\nconv9 = Conv2D(16, 3, activation='relu', padding='same', kernel_initializer='he_normal')(mrge9)\nconv9 = BatchNormalization()(conv9)\nconv9 = Conv2D(16, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv9)\nconv9 = BatchNormalization()(conv9)\n\ndcmp10 = UpSampling2D((6,6), interpolation='bilinear')(conv9)\nmrge10 = concatenate([dcmp10, conv0], axis=3)\nconv10 = Conv2D(16, 3, activation='relu', padding='same', kernel_initializer='he_normal')(mrge10)\nconv10 = BatchNormalization()(conv10)\nconv10 = Conv2D(8, 3, activation='relu', padding='same', kernel_initializer='he_normal')(conv10)\nconv10 = BatchNormalization()(conv10)\nconv11 = Conv2D(1, 1, activation='sigmoid')(conv10)\n\nmodel = Model(inputs=inputs, outputs=conv11)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer='adam', loss='binary_crossentropy')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit_generator(datagen, steps_per_epoch = 500, epochs = 10)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}