{"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":"!pip install -q segmentation-models-pytorch==0.1.3 albumentations==0.4.6 torchmetrics","metadata":{"id":"Z54s-kObkWR6","outputId":"06b86a2b-acdf-4301-8932-2518c183b00c","execution":{"iopub.status.busy":"2022-01-11T08:07:47.622911Z","iopub.execute_input":"2022-01-11T08:07:47.623485Z","iopub.status.idle":"2022-01-11T08:08:06.610677Z","shell.execute_reply.started":"2022-01-11T08:07:47.623351Z","shell.execute_reply":"2022-01-11T08:08:06.609654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport cv2\nimport pdb\nimport time\nimport warnings\nimport random\nimport numpy as np\nimport pandas as pd\nfrom tqdm import tqdm_notebook as tqdm\nfrom torch.optim.lr_scheduler import ReduceLROnPlateau\nfrom sklearn.model_selection import KFold\nimport torch\nimport torch.nn as nn\nfrom torch.nn import functional as F\nimport torch.optim as optim\nimport torch.backends.cudnn as cudnn\nfrom torch.utils.data import DataLoader, Dataset, sampler\nfrom matplotlib import pyplot as plt\nfrom albumentations import (HorizontalFlip, ShiftScaleRotate, Normalize, Resize, Compose, GaussNoise)\nfrom torchmetrics import MetricCollection, Accuracy, Precision, Recall, F1\nfrom albumentations.pytorch import ToTensorV2\nfrom torchmetrics import IoU\nimport torch\nimport collections.abc as container_abcs\ntorch._six.container_abcs = container_abcs\nimport segmentation_models_pytorch as smp\nfrom torch.utils.data import random_split\nwarnings.filterwarnings(\"ignore\")","metadata":{"id":"4uePlLXeE5B_","execution":{"iopub.status.busy":"2022-01-11T08:08:06.614305Z","iopub.execute_input":"2022-01-11T08:08:06.614861Z","iopub.status.idle":"2022-01-11T08:08:18.370784Z","shell.execute_reply.started":"2022-01-11T08:08:06.614813Z","shell.execute_reply":"2022-01-11T08:08:18.369833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SAMPLE_SUBMISSION  = '../input/sartorius-cell-instance-segmentation/sample_submission.csv'\nTRAIN_CSV = \"../input/sartorius-cell-instance-segmentation/train.csv\"\nTRAIN_PATH = \"../input/sartorius-cell-instance-segmentation/train\"\nTEST_PATH = \"../input/sartorius-cell-instance-segmentation/test\"\n\nRESNET_MEAN = (0.485, 0.456, 0.406)\nRESNET_STD = (0.229, 0.224, 0.225)\n\n# (336, 336)\nIMAGE_RESIZE = (224, 224)\n\nLEARNING_RATE = 5e-4\nEPOCHS = 10","metadata":{"id":"gJXh0a2uE5CA","execution":{"iopub.status.busy":"2022-01-11T08:08:18.373043Z","iopub.execute_input":"2022-01-11T08:08:18.373354Z","iopub.status.idle":"2022-01-11T08:08:18.384054Z","shell.execute_reply.started":"2022-01-11T08:08:18.373311Z","shell.execute_reply":"2022-01-11T08:08:18.381634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_decode(mask_rle, shape, color=1):\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    '''\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.float32)\n    for lo, hi in zip(starts, ends):\n        img[lo : hi] = color\n    return img.reshape(shape)\n\n\ndef build_masks(df_train, image_id, input_shape):\n    height, width = input_shape\n    labels = df_train[df_train[\"id\"] == image_id][\"annotation\"].tolist()\n    mask = np.zeros((height, width))\n    for label in labels:\n        mask += rle_decode(label, shape=(height, width))\n    mask = mask.clip(0, 1)\n    return mask","metadata":{"id":"BC9kLGi3E5CC","execution":{"iopub.status.busy":"2022-01-11T08:08:18.387078Z","iopub.execute_input":"2022-01-11T08:08:18.387715Z","iopub.status.idle":"2022-01-11T08:08:18.405339Z","shell.execute_reply.started":"2022-01-11T08:08:18.387671Z","shell.execute_reply":"2022-01-11T08:08:18.404389Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CellDataset(Dataset):\n    def __init__(self, df):\n        self.df = df\n        self.base_path = TRAIN_PATH\n        self.transforms = Compose([Resize(IMAGE_RESIZE[0], IMAGE_RESIZE[1]),  ToTensorV2()])\n        self.gb = self.df.groupby('id')\n        self.image_ids = df.id.unique().tolist()\n\n    def __getitem__(self, idx):\n        image_id = self.image_ids[idx]\n        df = self.gb.get_group(image_id)\n        annotations = df['annotation'].tolist()\n        image_path = os.path.join(self.base_path, image_id + \".png\")\n        image = cv2.imread(image_path).astype('float32')\n        mask = build_masks(df_train, image_id, input_shape=(520, 704))\n        mask = (mask >= 1).astype('float32')\n        augmented = self.transforms(image=image, mask=mask)\n        image = augmented['image']\n        mask = augmented['mask']\n        return image, mask.reshape((1, IMAGE_RESIZE[0], IMAGE_RESIZE[1]))\n\n    def __len__(self):\n        return len(self.image_ids)","metadata":{"id":"_ST9JH6bE5CD","execution":{"iopub.status.busy":"2022-01-11T08:08:18.409075Z","iopub.execute_input":"2022-01-11T08:08:18.409917Z","iopub.status.idle":"2022-01-11T08:08:18.422291Z","shell.execute_reply.started":"2022-01-11T08:08:18.409841Z","shell.execute_reply":"2022-01-11T08:08:18.421042Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class TestCellDataset(Dataset):\n    def __init__(self):\n        self.test_path = TEST_PATH\n        \n        # I am not sure if they adapt the sample submission csv or only the test folder\n        # I am using the test folders as the ground truth for the images to predict, which should be always right\n        # The sample csv is ignored\n        self.image_ids = [f[:-4]for f in os.listdir(self.test_path)]\n        self.num_samples = len(self.image_ids)\n        self.transform = Compose([Resize(IMAGE_RESIZE[0], IMAGE_RESIZE[1]), Normalize(mean=RESNET_MEAN, std=RESNET_STD, p=1), ToTensorV2()])\n\n    def __getitem__(self, idx):\n        image_id = self.image_ids[idx]\n        path = os.path.join(self.test_path, image_id + \".png\")\n        image = cv2.imread(path)\n        image = self.transform(image=image)['image']\n        return {'image': image, 'id': image_id}\n\n    def __len__(self):\n        return self.num_samples","metadata":{"id":"rbhewkt2E5CI","execution":{"iopub.status.busy":"2022-01-11T08:08:18.423532Z","iopub.execute_input":"2022-01-11T08:08:18.423997Z","iopub.status.idle":"2022-01-11T08:08:18.434035Z","shell.execute_reply.started":"2022-01-11T08:08:18.423938Z","shell.execute_reply":"2022-01-11T08:08:18.433072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv(TRAIN_CSV)\ndf_train.head()","metadata":{"id":"ZbQ8y_74vHin","outputId":"ea2f6622-edfd-45c1-e6e6-ed4b2e266d20","execution":{"iopub.status.busy":"2022-01-11T08:08:18.435726Z","iopub.execute_input":"2022-01-11T08:08:18.436239Z","iopub.status.idle":"2022-01-11T08:08:18.991086Z","shell.execute_reply.started":"2022-01-11T08:08:18.436193Z","shell.execute_reply":"2022-01-11T08:08:18.990073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds = CellDataset(df_train)\nds_submit = TestCellDataset()\nimage, mask = ds[1]\nimage.shape, mask.shape","metadata":{"id":"NRzNAobDE5CE","outputId":"af24c46f-f120-45b0-d8ab-cdd3449b9bf2","execution":{"iopub.status.busy":"2022-01-11T08:08:18.992872Z","iopub.execute_input":"2022-01-11T08:08:18.993409Z","iopub.status.idle":"2022-01-11T08:08:19.199753Z","shell.execute_reply.started":"2022-01-11T08:08:18.993360Z","shell.execute_reply":"2022-01-11T08:08:19.198862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_train, ds_test = random_split(ds, [int(len(ds)*0.7), len(ds)- int(len(ds)*0.7)])","metadata":{"id":"JV2OzilTsGd6","execution":{"iopub.status.busy":"2022-01-11T08:09:21.875261Z","iopub.execute_input":"2022-01-11T08:09:21.875553Z","iopub.status.idle":"2022-01-11T08:09:21.881563Z","shell.execute_reply.started":"2022-01-11T08:09:21.875513Z","shell.execute_reply":"2022-01-11T08:09:21.880354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"im = torch.stack([image[0],image[1], image[2]], dim = 2)\nplt.imshow(im/im.max())\nplt.show()\nplt.imshow(mask[0], cmap = 'bone')\nplt.show()","metadata":{"id":"EO_WPkmdE5CE","outputId":"b5216862-c255-4110-af31-cf74ed6f8a1b","execution":{"iopub.status.busy":"2022-01-11T08:09:23.043863Z","iopub.execute_input":"2022-01-11T08:09:23.044575Z","iopub.status.idle":"2022-01-11T08:09:23.574788Z","shell.execute_reply.started":"2022-01-11T08:09:23.044519Z","shell.execute_reply":"2022-01-11T08:09:23.573833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dl_train = DataLoader(ds_train, batch_size=8, num_workers=4, pin_memory=True, shuffle=False)\ndl_test = DataLoader(ds_test, batch_size=8, shuffle=False, num_workers=4, pin_memory=True)\ndl_test2 = DataLoader(ds_submit, batch_size=8, shuffle=False, num_workers=4, pin_memory=True)","metadata":{"id":"4AXJmM8kE5CE","execution":{"iopub.status.busy":"2022-01-11T08:09:24.664745Z","iopub.execute_input":"2022-01-11T08:09:24.665076Z","iopub.status.idle":"2022-01-11T08:09:24.671756Z","shell.execute_reply.started":"2022-01-11T08:09:24.665040Z","shell.execute_reply":"2022-01-11T08:09:24.670451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = smp.Unet(\"efficientnet-b0\", encoder_weights=\"imagenet\", activation=None)","metadata":{"id":"hT-f6WMkE5CH","execution":{"iopub.status.busy":"2022-01-11T08:09:25.662090Z","iopub.execute_input":"2022-01-11T08:09:25.662415Z","iopub.status.idle":"2022-01-11T08:09:26.658320Z","shell.execute_reply.started":"2022-01-11T08:09:25.662382Z","shell.execute_reply":"2022-01-11T08:09:26.657278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SMOOTH = 1e-6\n\ndef iou(outputs: torch.Tensor, labels: torch.Tensor):\n    # You can comment out this line if you are passing tensors of equal shape\n    # But if you are passing output from UNet or something it will most probably\n    # be with the BATCH x 1 x H x W shape\n    outputs = outputs.squeeze(1)  # BATCH x 1 x H x W => BATCH x H x W\n    \n    intersection = (outputs & labels).float().sum((1, 2))  # Will be zero if Truth=0 or Prediction=0\n    union = (outputs | labels).float().sum((1, 2))         # Will be zzero if both are 0\n    \n    iou = (intersection + SMOOTH) / (union + SMOOTH)  # We smooth our devision to avoid 0/0\n    \n    thresholded = torch.clamp(20 * (iou - 0.5), 0, 10).ceil() / 10  # This is equal to comparing with thresolds\n    \n    return thresholded  # Or thresholded.mean() if you are interested in average across the batch","metadata":{"id":"Hrx-TBAOwY6A","execution":{"iopub.status.busy":"2022-01-11T08:09:29.834027Z","iopub.execute_input":"2022-01-11T08:09:29.834378Z","iopub.status.idle":"2022-01-11T08:09:29.842601Z","shell.execute_reply.started":"2022-01-11T08:09:29.834347Z","shell.execute_reply":"2022-01-11T08:09:29.841025Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","metadata":{"id":"5roeFn-Bk6sk","execution":{"iopub.status.busy":"2022-01-11T08:09:49.882221Z","iopub.execute_input":"2022-01-11T08:09:49.882526Z","iopub.status.idle":"2022-01-11T08:09:49.888063Z","shell.execute_reply.started":"2022-01-11T08:09:49.882480Z","shell.execute_reply":"2022-01-11T08:09:49.886745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_metrics = MetricCollection([Accuracy(), Precision(num_classes=1, average='micro'), Recall(num_classes=1, average='micro'), F1(average='micro')]).to(device)\ntest_metrics = MetricCollection([Accuracy(), Precision(num_classes=1, average='micro'), Recall(num_classes=1, average='micro'), F1(average='micro')]).to(device)","metadata":{"id":"yxzyKlvELPfq","execution":{"iopub.status.busy":"2022-01-11T08:09:50.940718Z","iopub.execute_input":"2022-01-11T08:09:50.941642Z","iopub.status.idle":"2022-01-11T08:09:50.964538Z","shell.execute_reply.started":"2022-01-11T08:09:50.941588Z","shell.execute_reply":"2022-01-11T08:09:50.963598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def dice_loss(input, target):\n    input = torch.sigmoid(input)\n    smooth = 1.0\n    iflat = input.view(-1)\n    tflat = target.view(-1)\n    intersection = (iflat * tflat).sum()\n    return ((2.0 * intersection + smooth) / (iflat.sum() + tflat.sum() + smooth))\n\n\nclass FocalLoss(nn.Module):\n    def __init__(self, gamma):\n        super().__init__()\n        self.gamma = gamma\n\n    def forward(self, input, target):\n        if not (target.size() == input.size()):\n            raise ValueError(\"Target size ({}) must be the same as input size ({})\"\n                             .format(target.size(), input.size()))\n        max_val = (-input).clamp(min=0)\n        loss = input - input * target + max_val + \\\n            ((-max_val).exp() + (-input - max_val).exp()).log()\n        invprobs = F.logsigmoid(-input * (target * 2.0 - 1.0))\n        loss = (invprobs * self.gamma).exp() * loss\n        return loss.mean()\n    \nclass MixedLoss(nn.Module):\n    def __init__(self, alpha, gamma):\n        super().__init__()\n        self.alpha = alpha\n        self.focal = FocalLoss(gamma)\n\n    def forward(self, input, target):\n        loss = self.alpha*self.focal(input, target) - torch.log(dice_loss(input, target))\n        return loss.mean()","metadata":{"execution":{"iopub.status.busy":"2022-01-11T08:10:05.571149Z","iopub.execute_input":"2022-01-11T08:10:05.571526Z","iopub.status.idle":"2022-01-11T08:10:05.584760Z","shell.execute_reply.started":"2022-01-11T08:10:05.571491Z","shell.execute_reply":"2022-01-11T08:10:05.583455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.set_default_tensor_type(\"torch.cuda.FloatTensor\")\nn_batches = len(dl_train)\n\nmodel.cuda()\nmodel.train()\n\ncriterion = MixedLoss(10.0, 2.0)\noptimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)\n\nfor epoch in range(1,EPOCHS + 1):\n    #print(f\"Starting epoch: {epoch} / {EPOCHS}\")\n    running_loss = 0.0\n    optimizer.zero_grad()\n    Dice_loss = 0\n    for batch_idx, tr_batch in enumerate(dl_train):        \n        # Predict\n        tr_images, tr_masks = tr_batch\n        tr_images, tr_masks = tr_images.cuda(), tr_masks.cuda()\n        outputs = model(tr_images)\n        loss = criterion(outputs, tr_masks)\n        \n        loss.backward()\n        optimizer.step()\n        optimizer.zero_grad()\n        running_loss += loss.item()\n        train_metric = train_metrics(torch.sigmoid(outputs.flatten()), tr_masks.flatten().type(torch.int))\n    with torch.no_grad():\n        for batch_idx, ts_batch in enumerate(dl_test): \n          ts_images, ts_masks = ts_batch\n          ts_images, ts_masks = ts_images.cuda(), ts_masks.cuda()\n          preds = model(ts_images)\n          test_metric = test_metrics(torch.sigmoid(preds.flatten()), ts_masks.flatten().type(torch.int))\n    test_results = test_metrics.compute()\n    train_results = train_metrics.compute()\n    epoch_loss = running_loss / n_batches\n    print(f\"Epoch: {epoch} - Train Loss {epoch_loss:.4f} - Train Metrics:{train_results} - Test Metrics:{test_results}\")\n    train_metrics.reset()\n    test_metrics.reset()\n   # print(f\"Epoch: {epoch} - Train: Loss {epoch_loss:.4f} Dice {Dice_loss:.4f}\")","metadata":{"id":"OAKo068mE5CH","outputId":"575247f0-70b7-434e-ca7a-4a7358114391","execution":{"iopub.status.busy":"2022-01-11T08:10:06.244148Z","iopub.execute_input":"2022-01-11T08:10:06.244768Z","iopub.status.idle":"2022-01-11T08:11:16.194216Z","shell.execute_reply.started":"2022-01-11T08:10:06.244735Z","shell.execute_reply":"2022-01-11T08:11:16.190616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def post_process(probability, threshold=0.5, min_size=300):\n    mask = cv2.threshold(probability, threshold, 1, cv2.THRESH_BINARY)[1]\n    num_component, component = cv2.connectedComponents(mask.astype(np.uint8))\n    predictions = []\n    for c in range(1, num_component):\n        p = (component == c)\n        if p.sum() > min_size:\n            a_prediction = np.zeros((520, 704), np.float32)\n            a_prediction[p] = 1\n            predictions.append(a_prediction)\n    return predictions\n\n# Stolen from: https://www.kaggle.com/arunamenon/cell-instance-segmentation-unet-eda\n# Run-length encoding stolen from https://www.kaggle.com/rakhlin/fast-run-length-encoding-python\n# Modified by me\ndef rle_encoding(x):\n    dots = np.where(x.flatten() == 1)[0]\n    run_lengths = []\n    prev = -2\n    for b in dots:\n        if (b>prev+1): run_lengths.extend((b + 1, 0))\n        run_lengths[-1] += 1\n        prev = b\n    return ' '.join(map(str, run_lengths))","metadata":{"id":"v8Dj-cet91Yo","execution":{"iopub.status.busy":"2022-01-11T08:11:19.842195Z","iopub.execute_input":"2022-01-11T08:11:19.842551Z","iopub.status.idle":"2022-01-11T08:11:19.853561Z","shell.execute_reply.started":"2022-01-11T08:11:19.842517Z","shell.execute_reply":"2022-01-11T08:11:19.852359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.read_csv(SAMPLE_SUBMISSION)","metadata":{"id":"-M-X2SIc93db","outputId":"86cbf6ac-4805-4830-d9c3-0ae6670f0cab","execution":{"iopub.status.busy":"2022-01-11T08:11:21.080231Z","iopub.execute_input":"2022-01-11T08:11:21.080558Z","iopub.status.idle":"2022-01-11T08:11:21.101973Z","shell.execute_reply.started":"2022-01-11T08:11:21.080512Z","shell.execute_reply":"2022-01-11T08:11:21.101060Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def check_is_run_length(mask_rle):\n    if not mask_rle:\n        return True\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    start_prev = starts[0]\n    ok = True\n    for start in starts[1:]:\n        ok = ok and start > start_prev\n        start_prev = start\n        if not ok:\n            return False\n    return True\n\ndef create_empty_submission():\n    fs = os.listdir(\"../input/sartorius-cell-instance-segmentation/test\")\n    df = pd.DataFrame([(f[:-4], \"\") for f in fs], columns=['id', 'predicted'])\n    df.to_csv(\"submission.csv\", index=False)","metadata":{"id":"sNaxYzrX971T","execution":{"iopub.status.busy":"2022-01-11T08:11:21.946562Z","iopub.execute_input":"2022-01-11T08:11:21.946907Z","iopub.status.idle":"2022-01-11T08:11:21.955912Z","shell.execute_reply.started":"2022-01-11T08:11:21.946876Z","shell.execute_reply":"2022-01-11T08:11:21.954883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ts_image, ts_label= batch.values()","metadata":{"execution":{"iopub.status.busy":"2022-01-11T08:12:09.927790Z","iopub.execute_input":"2022-01-11T08:12:09.928907Z","iopub.status.idle":"2022-01-11T08:12:09.934748Z","shell.execute_reply.started":"2022-01-11T08:12:09.928850Z","shell.execute_reply":"2022-01-11T08:12:09.933245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ts_label","metadata":{"execution":{"iopub.status.busy":"2022-01-11T08:12:12.145725Z","iopub.execute_input":"2022-01-11T08:12:12.146096Z","iopub.status.idle":"2022-01-11T08:12:12.159446Z","shell.execute_reply.started":"2022-01-11T08:12:12.146053Z","shell.execute_reply":"2022-01-11T08:12:12.158382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\n\nsubmission = []\nfor i, batch in enumerate(tqdm(dl_test2)):\n    ts_image, ts_label= batch.values()\n    preds = torch.sigmoid(model(ts_image.cuda()))\n    preds = preds.detach().cpu().numpy()[:, 0, :, :] # (batch_size, 1, size, size) -> (batch_size, size, size)\n    for image_id, probability_mask in zip(ts_label, preds):\n        try:\n            #if probability_mask.shape != IMAGE_RESIZE:\n            #    probability_mask = cv2.resize(probability_mask, dsize=IMAGE_RESIZE, interpolation=cv2.INTER_LINEAR)\n            probability_mask = cv2.resize(probability_mask, dsize=(704, 520), interpolation=cv2.INTER_LINEAR)\n            predictions = post_process(probability_mask)\n            for prediction in predictions:\n                #plt.imshow(prediction)\n                #plt.show()\n                try:\n                    submission.append((image_id, rle_encoding(prediction)))\n                except:\n                    print(\"Error in RL encoding\")\n        except Exception as e:\n            print(f\"Exception for img: {image_id}: {e}\")\n        \n        # Fill images with no predictions\n        image_ids = [img_id for img_id, preds in submission]\n        if image_id not in image_ids:\n            submission.append((image_id, \"\"))\n            \ndf_submission = pd.DataFrame(submission, columns=['id', 'predicted'])\ndf_submission.to_csv('submission.csv', index=False)\n\nif df_submission['predicted'].apply(check_is_run_length).mean() != 1:\n    print(\"Check run lenght failed\")\n    create_empty_submission()","metadata":{"id":"d5oQYdXMwaSa","outputId":"15f01f5c-3f0f-4b44-815b-3cd4dab095b8","execution":{"iopub.status.busy":"2022-01-11T08:12:48.846240Z","iopub.execute_input":"2022-01-11T08:12:48.847123Z","iopub.status.idle":"2022-01-11T08:12:49.343426Z","shell.execute_reply.started":"2022-01-11T08:12:48.847085Z","shell.execute_reply":"2022-01-11T08:12:49.342516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission","metadata":{"execution":{"iopub.status.busy":"2022-01-11T08:12:59.007830Z","iopub.execute_input":"2022-01-11T08:12:59.008744Z","iopub.status.idle":"2022-01-11T08:12:59.019159Z","shell.execute_reply.started":"2022-01-11T08:12:59.008706Z","shell.execute_reply":"2022-01-11T08:12:59.018226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}