{"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":"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":{}},{"cell_type":"code","source":"!pip install segmentation-models\nimport segmentation_models as sm","metadata":{"execution":{"iopub.status.busy":"2021-10-02T16:38:40.688936Z","iopub.execute_input":"2021-10-02T16:38:40.689258Z","iopub.status.idle":"2021-10-02T16:38:48.440846Z","shell.execute_reply.started":"2021-10-02T16:38:40.689204Z","shell.execute_reply":"2021-10-02T16:38:48.439992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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\")","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.status.busy":"2021-10-02T16:38:52.074671Z","iopub.execute_input":"2021-10-02T16:38:52.075022Z","iopub.status.idle":"2021-10-02T16:38:52.383923Z","shell.execute_reply.started":"2021-10-02T16:38:52.074962Z","shell.execute_reply":"2021-10-02T16:38:52.383042Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path = '../input/understanding_cloud_organization/'","metadata":{"execution":{"iopub.status.busy":"2021-10-02T16:38:57.351279Z","iopub.execute_input":"2021-10-02T16:38:57.35192Z","iopub.status.idle":"2021-10-02T16:38:57.382061Z","shell.execute_reply.started":"2021-10-02T16:38:57.351649Z","shell.execute_reply":"2021-10-02T16:38:57.378421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr = pd.read_csv(path + 'train.csv')\nprint(len(tr))\ntr.head()","metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","execution":{"iopub.status.busy":"2021-10-02T16:39:00.442274Z","iopub.execute_input":"2021-10-02T16:39:00.442615Z","iopub.status.idle":"2021-10-02T16:39:02.155893Z","shell.execute_reply.started":"2021-10-02T16:39:00.442556Z","shell.execute_reply":"2021-10-02T16:39:02.15494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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)","metadata":{"execution":{"iopub.status.busy":"2021-10-02T16:39:03.054422Z","iopub.execute_input":"2021-10-02T16:39:03.054738Z","iopub.status.idle":"2021-10-02T16:39:03.066668Z","shell.execute_reply.started":"2021-10-02T16:39:03.054681Z","shell.execute_reply":"2021-10-02T16:39:03.065686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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)","metadata":{"execution":{"iopub.status.busy":"2021-10-02T16:39:06.716948Z","iopub.execute_input":"2021-10-02T16:39:06.717304Z","iopub.status.idle":"2021-10-02T16:39:06.724294Z","shell.execute_reply.started":"2021-10-02T16:39:06.717238Z","shell.execute_reply":"2021-10-02T16:39:06.723116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_size = 256","metadata":{"execution":{"iopub.status.busy":"2021-10-02T16:39:08.249254Z","iopub.execute_input":"2021-10-02T16:39:08.249563Z","iopub.status.idle":"2021-10-02T16:39:08.253836Z","shell.execute_reply.started":"2021-10-02T16:39:08.249515Z","shell.execute_reply":"2021-10-02T16:39:08.252687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_names_all = tr['Image_Label'].apply(lambda x: x.split('_')[0]).unique()\nlen(img_names_all)","metadata":{"execution":{"iopub.status.busy":"2021-10-02T16:39:10.608271Z","iopub.execute_input":"2021-10-02T16:39:10.608584Z","iopub.status.idle":"2021-10-02T16:39:10.631494Z","shell.execute_reply.started":"2021-10-02T16:39:10.608537Z","shell.execute_reply":"2021-10-02T16:39:10.63032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Generator","metadata":{}},{"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","metadata":{"execution":{"iopub.status.busy":"2021-10-02T16:39:13.815551Z","iopub.execute_input":"2021-10-02T16:39:13.81585Z","iopub.status.idle":"2021-10-02T16:39:13.82741Z","shell.execute_reply.started":"2021-10-02T16:39:13.815801Z","shell.execute_reply":"2021-10-02T16:39:13.826367Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Model","metadata":{}},{"cell_type":"code","source":"BACKBONE = 'resnet50'\npreprocess_input = sm.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,  metrics = [\"accuracy\"])","metadata":{"execution":{"iopub.status.busy":"2021-10-02T16:39:19.460744Z","iopub.execute_input":"2021-10-02T16:39:19.461066Z","iopub.status.idle":"2021-10-02T16:39:22.198859Z","shell.execute_reply.started":"2021-10-02T16:39:19.461013Z","shell.execute_reply":"2021-10-02T16:39:22.1981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Train Model","metadata":{}},{"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()","metadata":{"execution":{"iopub.status.busy":"2021-10-02T16:39:24.446066Z","iopub.execute_input":"2021-10-02T16:39:24.446611Z","iopub.status.idle":"2021-10-02T16:39:24.452459Z","shell.execute_reply.started":"2021-10-02T16:39:24.446536Z","shell.execute_reply":"2021-10-02T16:39:24.451068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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              )","metadata":{"execution":{"iopub.status.busy":"2021-10-02T16:39:28.412501Z","iopub.execute_input":"2021-10-02T16:39:28.412834Z","iopub.status.idle":"2021-10-02T18:09:49.349798Z","shell.execute_reply.started":"2021-10-02T16:39:28.412781Z","shell.execute_reply":"2021-10-02T18:09:49.348777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gc.collect()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Read test images","metadata":{}},{"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)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Prediction","metadata":{}},{"cell_type":"code","source":"%%time\npredict = model.predict(np.asarray(test_img))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"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)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Show result of prediction","metadata":{}},{"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))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create submission file","metadata":{}},{"cell_type":"code","source":"sub = pd.read_csv( path + 'sample_submission.csv', converters={'EncodedPixels': lambda e: ' '} )\nsub['EncodedPixels'] = pred_rle\nsub.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv('submission.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}