{"cells":[{"metadata":{},"cell_type":"markdown","source":"### Very simple started code using Keras.\n\nChangelog:\n* V1: predict only 1 class (LB: 0.417)\n* V2, V3, V4: error\n* V5: predict 4 classes\n* V6, V7: model changed from pretrained VGG16 to U-net model from this excellent kernel - https://www.kaggle.com/xhlulu/satellite-clouds-yet-another-u-net-boilerplate\n* V9: model changed to pretrained IceptionResNetV2\n* V10: model changed to pretrained EfficientNetB4\n* V12: model changed to pretrained ResNet50\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install segmentation-models\nimport segmentation_models as sm","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","trusted":true},"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nimport pandas as pd\nimport os\nimport random\nfrom tqdm import tqdm_notebook\nimport cv2\nimport gc\n\nimport albumentations as albu\nimport keras\nfrom keras import backend as K\nfrom keras.models import Model\nfrom keras.layers import Input, UpSampling2D, Conv2D, Activation\nfrom keras.layers.convolutional import Conv2D, Conv2DTranspose\nfrom keras.layers.pooling import MaxPooling2D\nfrom keras.layers.merge import concatenate\nfrom keras.losses import binary_crossentropy\nfrom keras.callbacks import Callback, ModelCheckpoint\nfrom keras import optimizers\n\nfrom sklearn.model_selection import train_test_split\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path = '../input/understanding_cloud_organization/'","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"tr = pd.read_csv(path + 'train.csv')\nprint(len(tr))\ntr.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def rle2mask(rle, imgshape):\n    width = imgshape[0]\n    height= imgshape[1]\n    \n    mask= np.zeros( width*height ).astype(np.uint8)\n    \n    array = np.asarray([int(x) for x in rle.split()])\n    starts = array[0::2]\n    lengths = array[1::2]\n\n    current_position = 0\n    for index, start in enumerate(starts):\n        mask[int(start):int(start+lengths[index])] = 1\n        current_position += lengths[index]\n        \n    return np.flipud( np.rot90( mask.reshape(height, width), k=1 ) )\n\ndef mask2rle(img):\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)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def dice_loss(y_true, y_pred):\n    smooth = 1.\n    y_true_f = K.flatten(y_true)\n    y_pred_f = K.flatten(y_pred)\n    intersection = y_true_f * y_pred_f\n    score = (2. * K.sum(intersection) + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)\n    return 1. - score\n\ndef bce_dice_loss(y_true, y_pred):\n    return binary_crossentropy(y_true, y_pred) + dice_loss(y_true, y_pred)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_size = 256","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_names_all = tr['Image_Label'].apply(lambda x: x.split('_')[0]).unique()\nlen(img_names_all)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Generator"},{"metadata":{"trusted":true},"cell_type":"code","source":"new_ep = False\ndef keras_generator(batch_size):  \n    global new_ep\n    while True:   \n        \n        x_batch = []\n        y_batch = []        \n        for _ in range(batch_size):                         \n            if new_ep == True:\n                img_names =  img_names_all\n                new_ep = False\n            \n            fn = img_names[random.randrange(0, len(img_names))]                                       \n\n            img = cv2.imread(path + 'train_images/'+ fn)\n            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)                       \n            masks = []\n            for rle in tr[tr['Image_Label'].apply(lambda x: x.split('_')[0]) == fn]['EncodedPixels']:                \n                if pd.isnull(rle):\n                    mask = np.zeros((img_size, img_size))\n                else:\n                    mask = rle2mask(rle, img.shape)\n                    mask = cv2.resize(mask, (img_size, img_size))\n                masks.append(mask)                                        \n            img = cv2.resize(img, (img_size, img_size))            \n            x_batch += [img]\n            y_batch += [masks] \n\n            img_names = img_names[img_names != fn]   \n        \n        x_batch = np.array(x_batch)\n        y_batch = np.transpose(np.array(y_batch), (0, 2, 3, 1))        \n\n        yield x_batch, y_batch","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"BACKBONE = 'resnet50'\npreprocess_input = sm.backbones.get_preprocessing(BACKBONE)\n\nmodel = sm.Unet(\n           encoder_name=BACKBONE, \n           classes=4,\n           activation='sigmoid',\n           input_shape=(img_size, img_size, 3))\n\nmodel.compile(optimizer=optimizers.Adam(lr=9e-3), loss=bce_dice_loss)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Train Model"},{"metadata":{"trusted":false},"cell_type":"code","source":"class EpochBegin(keras.callbacks.Callback):\n    def on_epoch_begin (self, epoch, logs={}):\n        global new_ep\n        new_ep = True\nEpoch_Begin_Clb = EpochBegin()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"%%time\nbatch_size = 16\nmodel.fit_generator(keras_generator(batch_size),\n              steps_per_epoch=200,                    \n              epochs=20,                    \n              verbose=1,\n              callbacks=[Epoch_Begin_Clb]\n              )","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"gc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Read test images"},{"metadata":{"trusted":false},"cell_type":"code","source":"%%time\n\ntest_img = []\ntestfiles=os.listdir(path + 'test_images/')\nfor fn in tqdm_notebook(testfiles):     \n        img = cv2.imread( path + 'test_images/'+fn )\n        img = cv2.resize(img,(img_size,img_size))       \n        test_img.append(img)\nlen(test_img)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Prediction"},{"metadata":{"trusted":false},"cell_type":"code","source":"%%time\npredict = model.predict(np.asarray(test_img))","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"%%time\npred_rle = []\nfor img in predict:      \n    img = cv2.resize(img, (525, 350))\n    tmp = np.copy(img)\n    tmp[tmp<np.mean(img)] = 0\n    tmp[tmp>0] = 1\n    for i in range(tmp.shape[-1]):\n        pred_rle.append(mask2rle(tmp[:,:,i]))\nlen(pred_rle)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"#### Show result of prediction"},{"metadata":{"trusted":false},"cell_type":"code","source":"fig, axs = plt.subplots(5, figsize=(20, 20))\naxs[0].imshow(cv2.resize(plt.imread(path + 'test_images/' + testfiles[0]),(525, 350)))\nfor i in range(4):\n    axs[i+1].imshow(rle2mask(pred_rle[i], img.shape))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Create submission file"},{"metadata":{"trusted":false},"cell_type":"code","source":"sub = pd.read_csv( path + 'sample_submission.csv', converters={'EncodedPixels': lambda e: ' '} )\nsub['EncodedPixels'] = pred_rle\nsub.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"sub.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.6"},"widgets":{"application/vnd.jupyter.widget-state+json":{"state":{"1503a2b6439042469f1b87daea37153b":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"44e7b26a8ec543f18fdd51febe9f1680":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"4b4182749d204a1dad4d8bccc35320ee":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_44e7b26a8ec543f18fdd51febe9f1680","placeholder":"​","style":"IPY_MODEL_1503a2b6439042469f1b87daea37153b","value":"100% 3698/3698 [02:20&lt;00:00, 26.34it/s]"}},"67184fe55e39450eb0c142a2a83ccd11":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"IntProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"IntProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_b5b6557ad4a84f9f8a8bc31f6e38b7a5","max":3698,"min":0,"orientation":"horizontal","style":"IPY_MODEL_c438217e76ee44a0bb6c287f2b028db9","value":3698}},"6f53904ae22245f4aba71dfd78771f8a":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_67184fe55e39450eb0c142a2a83ccd11","IPY_MODEL_4b4182749d204a1dad4d8bccc35320ee"],"layout":"IPY_MODEL_95b5f1ef72614b41863c8c16adcc0fdd"}},"95b5f1ef72614b41863c8c16adcc0fdd":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"b5b6557ad4a84f9f8a8bc31f6e38b7a5":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"c438217e76ee44a0bb6c287f2b028db9":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}}},"version_major":2,"version_minor":0}}},"nbformat":4,"nbformat_minor":1}