{"cells":[{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":false},"cell_type":"code","source":"!pip install tensorflow-gpu==1.14.0 --quiet\n!pip install keras==2.2.4 --quiet","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"from cloud_images_segmentation_utillity_script import *\nfrom keras.models import load_model\n\n!pip install tta-wrapper --quiet\n\nseed = 0\nseed_everything(seed)\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"train = pd.read_csv('../input/understanding_cloud_organization/train.csv')\nsubmission = pd.read_csv('../input/understanding_cloud_organization/sample_submission.csv')\n\n# Preprocecss data\ntrain['image'] = train['Image_Label'].apply(lambda x: x.split('_')[0])\ntrain['label'] = train['Image_Label'].apply(lambda x: x.split('_')[1])\nsubmission['image'] = submission['Image_Label'].apply(lambda x: x.split('_')[0])\ntest = pd.DataFrame(submission['image'].unique(), columns=['image'])\n\n# Create one column for each mask\ntrain_df = pd.pivot_table(train, index=['image'], values=['EncodedPixels'], columns=['label'], aggfunc=np.min).reset_index()\ntrain_df.columns = ['image', 'Fish_mask', 'Flower_mask', 'Gravel_mask', 'Sugar_mask']\n\nprint('Compete set samples:', len(train_df))\nprint('Test samples:', len(submission))\n\ndisplay(train.head())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Train and validation split"},{"metadata":{"trusted":false},"cell_type":"code","source":"X_train, X_val = train_test_split(train_df, test_size=0.2, random_state=seed)\nX_train['set'] = 'train'\nX_val['set'] = 'validation'\ntest['set'] = 'test'\n\nprint('Train samples: ', len(X_train))\nprint('Validation samples: ', len(X_val))","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"BACKBONE = 'resnet18'\nBATCH_SIZE = 16\nEPOCHS = 40\nLEARNING_RATE = 1e-3\nHEIGHT = 384\nWIDTH = 480\nCHANNELS = 3\nN_CLASSES = 4\nES_PATIENCE = 5\nRLROP_PATIENCE = 3\nDECAY_DROP = 0.2\nmodel_path = 'uNet_%s_%sx%s.h5' % (BACKBONE, HEIGHT, WIDTH)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"preprocessing = sm.get_preprocessing(BACKBONE)\n\naugmentation = albu.Compose([albu.HorizontalFlip(p=0.5),\n                             albu.HorizontalFlip(p=0.7),\n                             albu.HorizontalFlip(p=1.0),\n                             albu.VerticalFlip(p=1.0),\n                             #albu.JpegCompression(quality_lower=0, quality_upper=1),\n                             #albu.Blur(blur_limit=50),\n                             albu.VerticalFlip(p=0.5),\n                             albu.VerticalFlip(p=0.7),\n                             albu.GridDistortion(p=0.5),\n                             #albu.RandomBrightness(limit = 0.2),\n                             albu.ShiftScaleRotate(rotate_limit=0, scale_limit = 0.5, shift_limit=0.1, border_mode = 0 ,p=0.5),\n                             #albu.ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.2, rotate_limit=45, p=0.2),\n                            ])","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"train_base_path = '../input/understanding_cloud_organization/train_images/'\ntest_base_path = '../input/understanding_cloud_organization/test_images/'\ntrain_images_dest_path = 'base_dir/train_images/'\nvalidation_images_dest_path = 'base_dir/validation_images/'\ntest_images_dest_path = 'base_dir/test_images/'\n\n# Making sure directories don't exist\nif os.path.exists(train_images_dest_path):\n    shutil.rmtree(train_images_dest_path)\nif os.path.exists(validation_images_dest_path):\n    shutil.rmtree(validation_images_dest_path)\nif os.path.exists(test_images_dest_path):\n    shutil.rmtree(test_images_dest_path)\n    \n# Creating train, validation and test directories\nos.makedirs(train_images_dest_path)\nos.makedirs(validation_images_dest_path)\nos.makedirs(test_images_dest_path)\n\ndef preprocess_data(df, HEIGHT=HEIGHT, WIDTH=WIDTH):\n    '''\n    This function needs to be defined here, because it will be called with no arguments, \n    and must have the default parameters from the beggining of the notebook (HEIGHT and WIDTH)\n    '''\n    df = df.reset_index()\n    for i in range(df.shape[0]):\n        item = df.iloc[i]\n        image_id = item['image']\n        item_set = item['set']\n        if item_set == 'train':\n            preprocess_image(image_id, train_base_path, train_images_dest_path, HEIGHT, WIDTH)\n        if item_set == 'validation':\n            preprocess_image(image_id, train_base_path, validation_images_dest_path, HEIGHT, WIDTH)\n        if item_set == 'test':\n            preprocess_image(image_id, test_base_path, test_images_dest_path, HEIGHT, WIDTH)\n\n# Pre-procecss train set\npre_process_set(X_train, preprocess_data)\n\n# Pre-procecss validation set\npre_process_set(X_val, preprocess_data)\n\n# Pre-procecss test set\npre_process_set(test, preprocess_data)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"train_generator = DataGenerator(\n                  directory=train_images_dest_path,\n                  dataframe=X_train,\n                  target_df=train,\n                  batch_size=BATCH_SIZE,\n                  target_size=(HEIGHT, WIDTH),\n                  n_channels=CHANNELS,\n                  n_classes=N_CLASSES,\n                  preprocessing=preprocessing,\n                  augmentation=augmentation,\n                  seed=seed)\n\nvalid_generator = DataGenerator(\n                  directory=validation_images_dest_path,\n                  dataframe=X_val,\n                  target_df=train,\n                  batch_size=BATCH_SIZE, \n                  target_size=(HEIGHT, WIDTH),\n                  n_channels=CHANNELS,\n                  n_classes=N_CLASSES,\n                  preprocessing=preprocessing,\n                  seed=seed)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"model = sm.Unet(backbone_name=BACKBONE, \n                encoder_weights='imagenet',\n                classes=N_CLASSES,\n                activation='sigmoid',\n                input_shape=(HEIGHT, WIDTH, CHANNELS))\n\ncheckpoint = ModelCheckpoint(model_path, monitor='val_loss', mode='min', save_best_only=True, save_weights_only=True)\nes = EarlyStopping(monitor='val_loss', mode='min', patience=ES_PATIENCE, restore_best_weights=True, verbose=1)\nrlrop = ReduceLROnPlateau(monitor='val_loss', mode='min', patience=RLROP_PATIENCE, factor=DECAY_DROP, min_lr=1e-6, verbose=1)\n\nmetric_list = [dice_coef, sm.metrics.iou_score]\ncallback_list = [checkpoint, es, rlrop]\noptimizer = RAdam(learning_rate=LEARNING_RATE, warmup_proportion=0.1)\n\nmodel.compile(optimizer=optimizer, loss=sm.losses.bce_dice_loss, metrics=metric_list)\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"STEP_SIZE_TRAIN = len(X_train)//BATCH_SIZE\nSTEP_SIZE_VALID = len(X_val)//BATCH_SIZE\n\nhistory = model.fit_generator(generator=train_generator,\n                              steps_per_epoch=STEP_SIZE_TRAIN,\n                              validation_data=valid_generator,\n                              validation_steps=STEP_SIZE_VALID,\n                              callbacks=callback_list,\n                              epochs=EPOCHS,\n                              verbose=2).history","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"plot_metrics(history, metric_list=['loss', 'dice_coef', 'iou_score'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"class_names = ['Fish  ', 'Flower', 'Gravel', 'Sugar ']\nbest_tresholds = [.5, .5, .5, .35]\nbest_masks = [25000, 20000, 22500, 15000]\n\nfor index, name in enumerate(class_names):\n    print('%s treshold=%.2f mask size=%d' % (name, best_tresholds[index], best_masks[index]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"train_metrics = get_metrics(model, train, X_train, train_images_dest_path, best_tresholds, best_masks, seed=seed, preprocessing=preprocessing, set_name='Train')\ndisplay(train_metrics)\n\nvalidation_metrics = get_metrics(model, train, X_val, validation_images_dest_path, best_tresholds, best_masks, seed=seed, preprocessing=preprocessing, set_name='Validation')\ndisplay(validation_metrics)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"from tta_wrapper import tta_segmentation\n\nmodel = tta_segmentation(model, h_flip=True, v_flip=True, h_shift=(-10, 10), v_shift=(-10, 10), merge='mean')","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"test_df = []\n\nfor i in range(0, test.shape[0], 300):\n    batch_idx = list(range(i, min(test.shape[0], i + 300)))\n    batch_set = test[batch_idx[0]: batch_idx[-1]+1]\n    \n    test_generator = DataGenerator(\n                      directory=test_images_dest_path,\n                      dataframe=batch_set,\n                      target_df=submission,\n                      batch_size=1, \n                      target_size=(HEIGHT, WIDTH),\n                      n_channels=CHANNELS,\n                      n_classes=N_CLASSES,\n                      preprocessing=preprocessing,\n                      seed=seed,\n                      mode='predict',\n                      shuffle=False)\n    \n    preds = model.predict_generator(test_generator)\n\n    for index, b in enumerate(batch_idx):\n        filename = test['image'].iloc[b]\n        image_df = submission[submission['image'] == filename].copy()\n        pred_masks = preds[index, ].round().astype(int)\n        pred_rles = build_rles(pred_masks, reshape=(350, 525))\n        image_df['EncodedPixels'] = pred_rles\n\n        ### Post procecssing\n        pred_masks_post = preds[index, ].astype('float32') \n        for class_index in range(N_CLASSES):\n            pred_mask = pred_masks_post[...,class_index]\n            pred_mask = post_process(pred_mask, threshold=best_tresholds[class_index], min_size=best_masks[class_index])\n            pred_masks_post[...,class_index] = pred_mask\n\n        pred_rles_post = build_rles(pred_masks_post, reshape=(350, 525))\n        image_df['EncodedPixels_post'] = pred_rles_post\n        ###\n        \n        test_df.append(image_df)\n\nsub_df = pd.concat(test_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"submission_df = sub_df[['Image_Label' ,'EncodedPixels']]\nsubmission_df.to_csv('submission.csv', index=False)\ndisplay(submission_df.head())","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"submission_df_post = sub_df[['Image_Label' ,'EncodedPixels_post']]\nsubmission_df_post.columns = ['Image_Label' ,'EncodedPixels']\nsubmission_df_post.to_csv('submission_post.csv', index=False)\ndisplay(submission_df_post.head())","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Cleaning created directories\nif os.path.exists(train_images_dest_path):\n    shutil.rmtree(train_images_dest_path)\nif os.path.exists(validation_images_dest_path):\n    shutil.rmtree(validation_images_dest_path)\nif os.path.exists(test_images_dest_path):\n    shutil.rmtree(test_images_dest_path)","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"}},"nbformat":4,"nbformat_minor":1}