{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport os\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport tensorflow as tf\nfrom skimage.io import imread, imshow\nfrom skimage.transform import resize\nimport math","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:11.001492Z","iopub.execute_input":"2022-08-27T19:32:11.002944Z","iopub.status.idle":"2022-08-27T19:32:17.425588Z","shell.execute_reply.started":"2022-08-27T19:32:11.002858Z","shell.execute_reply":"2022-08-27T19:32:17.424566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.config.list_physical_devices('GPU')\n\nfrom tensorflow.python.client import device_lib\n\ndevice_lib.list_local_devices()\n\ntf.test.is_built_with_cuda()","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:17.431255Z","iopub.execute_input":"2022-08-27T19:32:17.434153Z","iopub.status.idle":"2022-08-27T19:32:20.270238Z","shell.execute_reply.started":"2022-08-27T19:32:17.434114Z","shell.execute_reply":"2022-08-27T19:32:20.269250Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.style.use('seaborn-notebook')\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:20.271871Z","iopub.execute_input":"2022-08-27T19:32:20.276399Z","iopub.status.idle":"2022-08-27T19:32:20.283964Z","shell.execute_reply.started":"2022-08-27T19:32:20.276359Z","shell.execute_reply":"2022-08-27T19:32:20.282829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SEED = 42\nos.environ['PYTHONHASHSEED'] = str(SEED)\nnp.random.seed(SEED)","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:20.287097Z","iopub.execute_input":"2022-08-27T19:32:20.287946Z","iopub.status.idle":"2022-08-27T19:32:20.294943Z","shell.execute_reply.started":"2022-08-27T19:32:20.287907Z","shell.execute_reply":"2022-08-27T19:32:20.293841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_dir = '../input/airbus-ship-detection'\ntrain_dir = os.path.join(data_dir, 'train_v2')\ntest_dir = os.path.join(data_dir, 'test_v2')","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:20.297493Z","iopub.execute_input":"2022-08-27T19:32:20.298882Z","iopub.status.idle":"2022-08-27T19:32:20.308361Z","shell.execute_reply.started":"2022-08-27T19:32:20.298845Z","shell.execute_reply":"2022-08-27T19:32:20.307110Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Ground truth masks are provided in run-length encoding format (*rle_encode* and *rle_decode* functions are taken from [here](https://www.kaggle.com/code/paulorzp/run-length-encode-and-decode/script)).","metadata":{}},{"cell_type":"code","source":"# ref.: https://www.kaggle.com/stainsby/fast-tested-rle\ndef rle_encode(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\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)\n\ndef rle_decode(mask_rle, shape=(768, 768)):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (height,width) of array to return \n    Returns numpy array, 1 - mask, 0 - background\n    '''\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.reshape(shape).T\n\n#ref.: https://www.kaggle.com/code/kmader/baseline-u-net-model-part-1/notebook\ndef masks_as_image(in_mask_list):\n    # Take the individual ship masks and create a single mask array for all ships\n    all_masks = np.zeros((768, 768), dtype = np.int16)\n    #if isinstance(in_mask_list, list):\n    for mask in in_mask_list:\n        if isinstance(mask, str):\n            all_masks += rle_decode(mask)\n    return np.expand_dims(all_masks, -1)\n\ndef masks_together(in_mask_list):\n    # Take the individual ship masks and create a single mask array for all ships\n    all_masks = np.zeros((768, 768), dtype = np.int16)\n    #if isinstance(in_mask_list, list):\n    for mask in in_mask_list:\n        if isinstance(mask, str):\n            all_masks += rle_decode(mask)\n    return rle_encode(np.expand_dims(all_masks, -1))","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:20.310202Z","iopub.execute_input":"2022-08-27T19:32:20.311210Z","iopub.status.idle":"2022-08-27T19:32:20.327345Z","shell.execute_reply.started":"2022-08-27T19:32:20.311167Z","shell.execute_reply":"2022-08-27T19:32:20.326131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## First let's look at our dataset starting with masks for training data.","metadata":{}},{"cell_type":"code","source":"masks = pd.read_csv(os.path.join(data_dir, 'train_ship_segmentations_v2.csv'))\nmasks.head(10)","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:20.331558Z","iopub.execute_input":"2022-08-27T19:32:20.331866Z","iopub.status.idle":"2022-08-27T19:32:21.445481Z","shell.execute_reply.started":"2022-08-27T19:32:20.331827Z","shell.execute_reply":"2022-08-27T19:32:21.444324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"masks['ImageId'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:21.447018Z","iopub.execute_input":"2022-08-27T19:32:21.448028Z","iopub.status.idle":"2022-08-27T19:32:21.573920Z","shell.execute_reply.started":"2022-08-27T19:32:21.447973Z","shell.execute_reply":"2022-08-27T19:32:21.572928Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"masks[masks['ImageId'] == '099177963.jpg']","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:21.575339Z","iopub.execute_input":"2022-08-27T19:32:21.577424Z","iopub.status.idle":"2022-08-27T19:32:21.604088Z","shell.execute_reply.started":"2022-08-27T19:32:21.577378Z","shell.execute_reply":"2022-08-27T19:32:21.602984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Pictures with NaN as EncodedPixels value are those without ship on the picture.","metadata":{}},{"cell_type":"code","source":"ships = masks.copy()","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:21.609451Z","iopub.execute_input":"2022-08-27T19:32:21.609741Z","iopub.status.idle":"2022-08-27T19:32:21.619871Z","shell.execute_reply.started":"2022-08-27T19:32:21.609714Z","shell.execute_reply":"2022-08-27T19:32:21.618922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Run-length encoding of empty mask would be just empty string.","metadata":{}},{"cell_type":"code","source":"rle_encode(np.zeros((768, 768, 1))) == ''","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:21.621426Z","iopub.execute_input":"2022-08-27T19:32:21.621771Z","iopub.status.idle":"2022-08-27T19:32:21.635825Z","shell.execute_reply.started":"2022-08-27T19:32:21.621737Z","shell.execute_reply":"2022-08-27T19:32:21.634562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"That's why we will replace all NaNs in *masks* dictionary with empty strings.","metadata":{}},{"cell_type":"code","source":"masks = masks.fillna('')\nmasks","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:21.637102Z","iopub.execute_input":"2022-08-27T19:32:21.637364Z","iopub.status.idle":"2022-08-27T19:32:21.686119Z","shell.execute_reply.started":"2022-08-27T19:32:21.637333Z","shell.execute_reply":"2022-08-27T19:32:21.684973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now let's figure out distribution of ships on those images.","metadata":{}},{"cell_type":"code","source":"ships['HasShipNum'] = (~(ships['EncodedPixels'].isnull())).astype('int')\nships.head(5)","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:21.687758Z","iopub.execute_input":"2022-08-27T19:32:21.688160Z","iopub.status.idle":"2022-08-27T19:32:21.718566Z","shell.execute_reply.started":"2022-08-27T19:32:21.688124Z","shell.execute_reply":"2022-08-27T19:32:21.717526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ships = ships.groupby('ImageId').sum().reset_index()\n\nships.head(5)","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:21.720030Z","iopub.execute_input":"2022-08-27T19:32:21.720460Z","iopub.status.idle":"2022-08-27T19:32:21.874868Z","shell.execute_reply.started":"2022-08-27T19:32:21.720421Z","shell.execute_reply":"2022-08-27T19:32:21.873991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ships.plot.hist(bins=np.arange(10))","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:21.876198Z","iopub.execute_input":"2022-08-27T19:32:21.876633Z","iopub.status.idle":"2022-08-27T19:32:22.148505Z","shell.execute_reply.started":"2022-08-27T19:32:21.876596Z","shell.execute_reply":"2022-08-27T19:32:22.147614Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"There is a huge class imbalance in our data, there are much more pictures with no ship then of any other amount of ships. Now let's check images themselves for corrupted ones.","metadata":{}},{"cell_type":"markdown","source":"Finally I will drop all images under 0.0035 quantile in image size (they have no useful for model information).","metadata":{}},{"cell_type":"code","source":"im_name = 'ffff6e525.jpg'\nim = imread(os.path.join(train_dir, im_name))\nfig = plt.figure()\nfig.add_subplot(2, 2, 1)\nplt.imshow(im)\nplt.title(im_name)\nfig.add_subplot(2, 2, 2)\nplt.imshow(masks_as_image(masks[masks['ImageId'] == im_name]['EncodedPixels']))\nplt.title(im_name)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:22.150073Z","iopub.execute_input":"2022-08-27T19:32:22.150406Z","iopub.status.idle":"2022-08-27T19:32:22.531880Z","shell.execute_reply.started":"2022-08-27T19:32:22.150371Z","shell.execute_reply":"2022-08-27T19:32:22.530912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"im_name = 'c8e722430.jpg'\nim = imread(os.path.join(train_dir, im_name))\nfig = plt.figure()\nfig.add_subplot(2, 2, 1)\nplt.imshow(im)\nplt.title(im_name)\nfig.add_subplot(2, 2, 2)\nplt.imshow(masks_as_image(masks[masks['ImageId'] == im_name]['EncodedPixels']))\nplt.title(im_name)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:22.533454Z","iopub.execute_input":"2022-08-27T19:32:22.533784Z","iopub.status.idle":"2022-08-27T19:32:22.894906Z","shell.execute_reply.started":"2022-08-27T19:32:22.533751Z","shell.execute_reply":"2022-08-27T19:32:22.894027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain_ships, valid_ships = train_test_split(ships, test_size=0.3, stratify=ships['HasShipNum'], random_state=SEED)","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:22.897112Z","iopub.execute_input":"2022-08-27T19:32:22.897697Z","iopub.status.idle":"2022-08-27T19:32:23.084667Z","shell.execute_reply.started":"2022-08-27T19:32:22.897659Z","shell.execute_reply":"2022-08-27T19:32:23.082905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now we will undersample pictures with 0 ships so that our dataset would become more balanced.","metadata":{}},{"cell_type":"code","source":"train_ships['HasShipNum'].plot.hist()","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:23.086940Z","iopub.execute_input":"2022-08-27T19:32:23.087595Z","iopub.status.idle":"2022-08-27T19:32:23.419631Z","shell.execute_reply.started":"2022-08-27T19:32:23.087557Z","shell.execute_reply":"2022-08-27T19:32:23.418642Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ships['HasShipNum'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:23.421182Z","iopub.execute_input":"2022-08-27T19:32:23.421828Z","iopub.status.idle":"2022-08-27T19:32:23.432220Z","shell.execute_reply.started":"2022-08-27T19:32:23.421774Z","shell.execute_reply":"2022-08-27T19:32:23.431291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def undersample_zeros(data):\n    zeros = data[data['HasShipNum'] == 0].sample(n=30_000, random_state = SEED)\n    nonzeros = data[data['HasShipNum'] != 0]\n    return pd.concat((nonzeros, zeros))","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:23.433839Z","iopub.execute_input":"2022-08-27T19:32:23.434454Z","iopub.status.idle":"2022-08-27T19:32:23.444779Z","shell.execute_reply.started":"2022-08-27T19:32:23.434418Z","shell.execute_reply":"2022-08-27T19:32:23.443902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ships = undersample_zeros(train_ships)\nvalid_ships = undersample_zeros(valid_ships)\ntrain_ships['HasShipNum'].plot.hist(bins=np.arange(10))","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:23.446274Z","iopub.execute_input":"2022-08-27T19:32:23.446860Z","iopub.status.idle":"2022-08-27T19:32:23.715710Z","shell.execute_reply.started":"2022-08-27T19:32:23.446819Z","shell.execute_reply":"2022-08-27T19:32:23.714563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"(train_ships['HasShipNum'] > 0).astype(int).value_counts().plot.bar()","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:23.720116Z","iopub.execute_input":"2022-08-27T19:32:23.720699Z","iopub.status.idle":"2022-08-27T19:32:23.903952Z","shell.execute_reply.started":"2022-08-27T19:32:23.720661Z","shell.execute_reply":"2022-08-27T19:32:23.902916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now dataset is a bit more balanced in terms of amount of ships on photos.","metadata":{}},{"cell_type":"markdown","source":"Now let's test how resizing pictures to 512 * 512 will impact quality of picture.","metadata":{}},{"cell_type":"code","source":"im_name = 'c8e722430.jpg'\nim = imread(os.path.join(train_dir, im_name))\nfig = plt.figure()\nfig.add_subplot(2, 2, 1)\nplt.imshow(im)\nplt.title(im_name)\nfig.add_subplot(2, 2, 2)\nrs = resize(im, (512, 512, 3))\nplt.imshow(rs)\nplt.title(im_name + \" (resized to 512 * 512)\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:23.905474Z","iopub.execute_input":"2022-08-27T19:32:23.905822Z","iopub.status.idle":"2022-08-27T19:32:24.333785Z","shell.execute_reply.started":"2022-08-27T19:32:23.905787Z","shell.execute_reply":"2022-08-27T19:32:24.332933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Range of values on original pic: \", np.min(im), np.max(im))\nprint(\"Range of values on resized pic: \", np.min(rs), np.max(rs))","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:24.335381Z","iopub.execute_input":"2022-08-27T19:32:24.335728Z","iopub.status.idle":"2022-08-27T19:32:24.346581Z","shell.execute_reply.started":"2022-08-27T19:32:24.335686Z","shell.execute_reply":"2022-08-27T19:32:24.345130Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"No need for normalizing layer (all pixels / 256) in NN later as resize function already normalizes pixel range. ","metadata":{}},{"cell_type":"markdown","source":"Train and val sets take quite a lot of memory so let's write Sequence for then using in training.","metadata":{}},{"cell_type":"code","source":"class AirBusSequence(tf.keras.utils.Sequence):\n\n    def __init__(self, images_set, masks_set, batch_size):\n        \"\"\"Init function for Sequence\n\n        Args:\n            images_set (np.ndarray): Array of names of images in format ****.jpg\n            masks_set (pd.DataFrame): DataFrame with column of picture names and masks encoded in RLE format\n            batch_size (_type_): _description_\n        \"\"\"\n        self.images, self.masks = images_set, masks_set\n        self.batch_size = batch_size\n\n    def __len__(self):\n        return math.ceil(len(self.images) / self.batch_size)\n\n    def __getitem__(self, idx):\n        batch_images = self.images[idx * self.batch_size:(idx + 1) * self.batch_size]\n        # we get masks using utilitary function masks_as_image from dataframe of all masks\n        return (\n                np.array([\n                        resize(\n                            imread(os.path.join(train_dir, file_name)), \n                            (512, 512, 3))\n                        for file_name in batch_images]), \n                np.array([\n                    resize(masks_as_image(\n                            self.masks[self.masks['ImageId'] == im_name]['EncodedPixels']), \n                        (512, 512, 1))\n                        for im_name in batch_images\n                ])\n                )","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:24.348783Z","iopub.execute_input":"2022-08-27T19:32:24.349445Z","iopub.status.idle":"2022-08-27T19:32:25.651399Z","shell.execute_reply.started":"2022-08-27T19:32:24.349408Z","shell.execute_reply":"2022-08-27T19:32:25.650422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class AirBusSequence(tf.keras.utils.Sequence):\n\n    def __init__(self, images_set, masks_set, batch_size):\n        \"\"\"Init function for Sequence\n\n        Args:\n            images_set (np.ndarray): Array of names of images in format ****.jpg\n            masks_set (pd.DataFrame): Array of masks encoded in RLE format\n            batch_size (_type_): _description_\n        \"\"\"\n        self.images, self.masks = images_set, masks_set\n        self.batch_size = batch_size\n\n    def __len__(self):\n        return math.ceil(len(self.images) / self.batch_size)\n\n    def __getitem__(self, idx):\n        batch_images = self.images[idx * self.batch_size:(idx + 1) * self.batch_size]\n        batch_masks = self.masks[idx * self.batch_size:(idx + 1) * self.batch_size]\n        # we get masks using utilitary function masks_as_image from dataframe of all masks\n        return (\n                np.array([\n                        resize(\n                            imread(os.path.join(train_dir, file_name)), \n                            (512, 512, 3))\n                        for file_name in batch_images]), \n                np.array([\n                    resize(masks_as_image(\n                            mask_rle), \n                        (512, 512, 1))\n                        for mask_rle in batch_masks\n                ])\n                )","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_HEIGHT = 512\nIMG_WIDTH = 512\nIMG_CHANNELS = 3","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:25.652716Z","iopub.execute_input":"2022-08-27T19:32:25.653111Z","iopub.status.idle":"2022-08-27T19:32:25.660093Z","shell.execute_reply.started":"2022-08-27T19:32:25.653063Z","shell.execute_reply":"2022-08-27T19:32:25.659062Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.models import Model, load_model\nfrom keras.layers import Input\nfrom keras.layers.core import Dropout, Lambda\nfrom keras.layers.convolutional import Conv2D, Conv2DTranspose\nfrom keras.layers.pooling import MaxPooling2D\nfrom keras.layers import concatenate\nfrom keras.callbacks import EarlyStopping, ModelCheckpoint\nfrom keras import backend as K","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:25.668652Z","iopub.execute_input":"2022-08-27T19:32:25.668978Z","iopub.status.idle":"2022-08-27T19:32:25.678102Z","shell.execute_reply.started":"2022-08-27T19:32:25.668946Z","shell.execute_reply":"2022-08-27T19:32:25.676968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def 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)","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:25.679414Z","iopub.execute_input":"2022-08-27T19:32:25.679866Z","iopub.status.idle":"2022-08-27T19:32:25.691199Z","shell.execute_reply.started":"2022-08-27T19:32:25.679824Z","shell.execute_reply":"2022-08-27T19:32:25.690214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inputs = Input((IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS))\n\ns = Lambda(lambda x: x / 255) (inputs)\n\nc1 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (s)\nc1 = Dropout(0.1) (c1)\nc1 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c1)\np1 = MaxPooling2D((2, 2)) (c1)\n\nc2 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p1)\nc2 = Dropout(0.1) (c2)\nc2 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c2)\np2 = MaxPooling2D((2, 2)) (c2)\n\nc3 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p2)\nc3 = Dropout(0.2) (c3)\nc3 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c3)\np3 = MaxPooling2D((2, 2)) (c3)\n\nc4 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p3)\nc4 = Dropout(0.2) (c4)\nc4 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c4)\np4 = MaxPooling2D(pool_size=(2, 2)) (c4)\n\nc5 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p4)\nc5 = Dropout(0.3) (c5)\nc5 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c5)\n\nu6 = Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same') (c5)\nu6 = concatenate([u6, c4])\nc6 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (u6)\nc6 = Dropout(0.2) (c6)\nc6 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c6)\n\nu7 = Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same') (c6)\nu7 = concatenate([u7, c3])\nc7 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (u7)\nc7 = Dropout(0.2) (c7)\nc7 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c7)\n\nu8 = Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same') (c7)\nu8 = concatenate([u8, c2])\nc8 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (u8)\nc8 = Dropout(0.1) (c8)\nc8 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c8)\n\nu9 = Conv2DTranspose(16, (2, 2), strides=(2, 2), padding='same') (c8)\nu9 = concatenate([u9, c1], axis=3)\nc9 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (u9)\nc9 = Dropout(0.1) (c9)\nc9 = Conv2D(16, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c9)\n\noutputs = Conv2D(1, (1, 1), activation='sigmoid') (c9)\n\nmodel = Model(inputs=[inputs], outputs=[outputs])\n\nmodel.compile(optimizer='adam', loss='binary_crossentropy', metrics=[dice_coef])\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:25.692747Z","iopub.execute_input":"2022-08-27T19:32:25.693245Z","iopub.status.idle":"2022-08-27T19:32:26.346690Z","shell.execute_reply.started":"2022-08-27T19:32:25.693210Z","shell.execute_reply":"2022-08-27T19:32:26.345676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 32","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:32:59.004600Z","iopub.execute_input":"2022-08-27T19:32:59.005223Z","iopub.status.idle":"2022-08-27T19:32:59.012705Z","shell.execute_reply.started":"2022-08-27T19:32:59.005172Z","shell.execute_reply":"2022-08-27T19:32:59.010322Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"filepath = \"model.h5\"\n\nearlystopper = EarlyStopping(patience=5, verbose=1)\n\ncheckpoint = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, \n                             save_best_only=True, mode='min')\n\ncallbacks_list = [earlystopper, checkpoint]\n\nhistory = model.fit(AirBusSequence(np.array(train_ships['ImageId']), masks, BATCH_SIZE), \n                    validation_data=AirBusSequence(np.array(valid_ships['ImageId']), masks, BATCH_SIZE), \n                    epochs=50, \n                    callbacks=callbacks_list)","metadata":{"execution":{"iopub.status.busy":"2022-08-27T19:33:01.104675Z","iopub.execute_input":"2022-08-27T19:33:01.105152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}