{"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 uninstall -y -q yellowbrick\n\n!pip install -q tifffile # contains tools to operate tiff-files\n!pip install -q folium==0.2.1\n!pip install -q imgaug==0.2.5\n!pip install -q opencv-python==3.4.5.20\n!pip install opencv-python-headless==4.1.2.30\n!pip install -q wget\n!pip install -q memory_profiler\n!pip install -q fpdf\n!pip install -q pycocotools\n!pip install -q fastremap\n!pip install -q natsort","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:06:38.527052Z","iopub.execute_input":"2022-08-19T17:06:38.528259Z","iopub.status.idle":"2022-08-19T17:09:03.373232Z","shell.execute_reply.started":"2022-08-19T17:06:38.528147Z","shell.execute_reply":"2022-08-19T17:09:03.372170Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.append('../input/sartorius-instance-segmentation/cellpose/cellpose')","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:03.375353Z","iopub.execute_input":"2022-08-19T17:09:03.375992Z","iopub.status.idle":"2022-08-19T17:09:03.383686Z","shell.execute_reply.started":"2022-08-19T17:09:03.375931Z","shell.execute_reply":"2022-08-19T17:09:03.382795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\nimport os\nimport tifffile\nimport imageio\nimport glob\nimport shutil\nfrom cellpose import models, io, plot\nimport glob\nimport shutil\nimport imgaug.augmenters as iaa\nimport imgaug as ia\nimport time\nimport cv2","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:03.385907Z","iopub.execute_input":"2022-08-19T17:09:03.386230Z","iopub.status.idle":"2022-08-19T17:09:10.108693Z","shell.execute_reply.started":"2022-08-19T17:09:03.386204Z","shell.execute_reply":"2022-08-19T17:09:10.107881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Original Image Dimensions\nHEIGHT = 520\nWIDTH = 704\nSHAPE = (HEIGHT, WIDTH)","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:10.110902Z","iopub.execute_input":"2022-08-19T17:09:10.111518Z","iopub.status.idle":"2022-08-19T17:09:10.116326Z","shell.execute_reply.started":"2022-08-19T17:09:10.111478Z","shell.execute_reply":"2022-08-19T17:09:10.115394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rles_to_mask(encs, shape=SHAPE):\n    \"\"\"\n    Decodes a rle.\n\n    Args:\n        encs (list of str): Rles for each class.\n        shape (tuple [2]): Mask size.\n\n    Returns:\n        np array [shape]: Mask.\n    \"\"\"\n    img = np.zeros(shape[0] * shape[1], dtype=np.uint)\n    if type(encs)==float:\n        return img\n    for m, enc in enumerate(encs):\n        if isinstance(enc, np.float) and np.isnan(enc):\n            continue\n        enc_split = enc.split()\n        for i in range(len(enc_split) // 2):\n            start = int(enc_split[2 * i]) - 1\n            length = int(enc_split[2 * i + 1])\n            img[start: start + length] = 1 + m\n    return img.reshape(shape)","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:10.117594Z","iopub.execute_input":"2022-08-19T17:09:10.118374Z","iopub.status.idle":"2022-08-19T17:09:10.127006Z","shell.execute_reply.started":"2022-08-19T17:09:10.118337Z","shell.execute_reply":"2022-08-19T17:09:10.126161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='gold'/> **Prepare data**","metadata":{}},{"cell_type":"code","source":"orig_train_dataset_folder = '../input/sartorius-cellpose-dataset/sartorius_cellpose_dataset/train'\norig_val_dataset_folder = '../input/sartorius-cellpose-dataset/sartorius_cellpose_dataset/val'","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:10.129028Z","iopub.execute_input":"2022-08-19T17:09:10.129816Z","iopub.status.idle":"2022-08-19T17:09:10.136710Z","shell.execute_reply.started":"2022-08-19T17:09:10.129790Z","shell.execute_reply":"2022-08-19T17:09:10.135789Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!mkdir './cellpose_dataset_train'\n!mkdir './cellpose_dataset_val'\n!mkdir './models'","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:10.137988Z","iopub.execute_input":"2022-08-19T17:09:10.138512Z","iopub.status.idle":"2022-08-19T17:09:13.067715Z","shell.execute_reply.started":"2022-08-19T17:09:10.138477Z","shell.execute_reply":"2022-08-19T17:09:13.066454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get ids and cell type\nsartorius_df = pd.read_csv('../input/sartorius-cell-instance-segmentation/train.csv')\nsartorius_df = sartorius_df.groupby('id').first()\nids_ct_df = sartorius_df['cell_type']","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:13.069511Z","iopub.execute_input":"2022-08-19T17:09:13.070193Z","iopub.status.idle":"2022-08-19T17:09:13.629695Z","shell.execute_reply.started":"2022-08-19T17:09:13.070150Z","shell.execute_reply":"2022-08-19T17:09:13.628850Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_img_ids = [f.split('/')[-1].replace('_img.tif', '') for f in \n                 glob.glob(os.path.join(orig_train_dataset_folder, '*img.tif'))]","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:13.631011Z","iopub.execute_input":"2022-08-19T17:09:13.631375Z","iopub.status.idle":"2022-08-19T17:09:13.779621Z","shell.execute_reply.started":"2022-08-19T17:09:13.631336Z","shell.execute_reply":"2022-08-19T17:09:13.778850Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ids_ct_df = ids_ct_df[ids_ct_df.index.isin(train_img_ids)]\nshsy5y_train_ids_ct_df = train_ids_ct_df.loc[train_ids_ct_df == 'shsy5y']\nshsy5y_remove = np.random.choice(shsy5y_train_ids_ct_df.index, 124 - (124 // 4), replace=False)","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:13.783690Z","iopub.execute_input":"2022-08-19T17:09:13.783994Z","iopub.status.idle":"2022-08-19T17:09:13.800800Z","shell.execute_reply.started":"2022-08-19T17:09:13.783968Z","shell.execute_reply":"2022-08-19T17:09:13.799814Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"astro_remove = train_ids_ct_df.loc[train_ids_ct_df == 'astro']","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:13.804102Z","iopub.execute_input":"2022-08-19T17:09:13.804517Z","iopub.status.idle":"2022-08-19T17:09:13.808778Z","shell.execute_reply.started":"2022-08-19T17:09:13.804492Z","shell.execute_reply":"2022-08-19T17:09:13.807848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cort_remove = train_ids_ct_df.loc[train_ids_ct_df == 'cort']","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:13.810179Z","iopub.execute_input":"2022-08-19T17:09:13.810778Z","iopub.status.idle":"2022-08-19T17:09:13.820230Z","shell.execute_reply.started":"2022-08-19T17:09:13.810745Z","shell.execute_reply":"2022-08-19T17:09:13.819038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rm = 0\nadd = 0\n\nfor f in glob.glob(os.path.join(orig_train_dataset_folder, '*.tif')):\n    id_ = f.split('/')[-1].split('_')[0]\n    if ('flows' not in f):\n        if ((id_ in shsy5y_remove) or \n            (id_ in astro_remove) or\n            (id_ in cort_remove)):\n            rm += 1\n        else:\n            shutil.copy(f, os.path.join('./cellpose_dataset_train', f.split('/')[-1]))","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:13.821761Z","iopub.execute_input":"2022-08-19T17:09:13.822175Z","iopub.status.idle":"2022-08-19T17:09:14.472024Z","shell.execute_reply.started":"2022-08-19T17:09:13.822150Z","shell.execute_reply":"2022-08-19T17:09:14.471193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for f in glob.glob(os.path.join(orig_val_dataset_folder, '*.tif')):\n    if 'flows' not in f:\n        shutil.copy(f, os.path.join('./cellpose_dataset_val', f.split('/')[-1]))","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:14.473479Z","iopub.execute_input":"2022-08-19T17:09:14.473856Z","iopub.status.idle":"2022-08-19T17:09:16.425239Z","shell.execute_reply.started":"2022-08-19T17:09:14.473821Z","shell.execute_reply":"2022-08-19T17:09:16.424384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_folder = './cellpose_dataset_train'\ntest_folder = './cellpose_dataset_val'","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:16.426696Z","iopub.execute_input":"2022-08-19T17:09:16.427119Z","iopub.status.idle":"2022-08-19T17:09:16.431743Z","shell.execute_reply.started":"2022-08-19T17:09:16.427083Z","shell.execute_reply":"2022-08-19T17:09:16.430844Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls {train_folder} | wc -l\n!ls {test_folder} | wc -l","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:16.433240Z","iopub.execute_input":"2022-08-19T17:09:16.433602Z","iopub.status.idle":"2022-08-19T17:09:18.423610Z","shell.execute_reply.started":"2022-08-19T17:09:16.433568Z","shell.execute_reply":"2022-08-19T17:09:18.422579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Adding mosaic astro data","metadata":{}},{"cell_type":"code","source":"for f in glob.glob('../input/sartorius-cellpose-dataset/mosaic_astro_data/mosaic_astro_data/*'):\n    shutil.copy(f, train_folder)","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:18.426209Z","iopub.execute_input":"2022-08-19T17:09:18.426868Z","iopub.status.idle":"2022-08-19T17:09:21.885003Z","shell.execute_reply.started":"2022-08-19T17:09:18.426822Z","shell.execute_reply":"2022-08-19T17:09:21.884158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls {train_folder} | wc -l\n!ls {test_folder} | wc -l","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:21.886234Z","iopub.execute_input":"2022-08-19T17:09:21.887552Z","iopub.status.idle":"2022-08-19T17:09:23.866091Z","shell.execute_reply.started":"2022-08-19T17:09:21.887512Z","shell.execute_reply":"2022-08-19T17:09:23.865007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Finish adding mosaic astro data","metadata":{}},{"cell_type":"markdown","source":"Adding mosaic cort data","metadata":{}},{"cell_type":"code","source":"for f in glob.glob('../input/sartorius-cellpose-dataset/mosaic_cort_data/mosaic_cort_data/*'):\n    shutil.copy(f, train_folder)","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:23.869178Z","iopub.execute_input":"2022-08-19T17:09:23.869519Z","iopub.status.idle":"2022-08-19T17:09:31.716630Z","shell.execute_reply.started":"2022-08-19T17:09:23.869487Z","shell.execute_reply":"2022-08-19T17:09:31.715802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls {train_folder} | wc -l\n!ls {test_folder} | wc -l","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:31.718804Z","iopub.execute_input":"2022-08-19T17:09:31.719672Z","iopub.status.idle":"2022-08-19T17:09:33.761168Z","shell.execute_reply.started":"2022-08-19T17:09:31.719631Z","shell.execute_reply":"2022-08-19T17:09:33.760155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Finish adding mosaic cort data","metadata":{}},{"cell_type":"code","source":"train_img_files = np.sort(glob.glob(os.path.join('cellpose_dataset_train', '*img.tif')))\ntrain_mask_files = np.sort(glob.glob(os.path.join('cellpose_dataset_train', '*masks.tif')))\n\nval_img_files = np.sort(glob.glob(os.path.join('cellpose_dataset_val', '*img.tif')))\nval_mask_files = np.sort(glob.glob(os.path.join('cellpose_dataset_val', \"*masks.tif\")))\n\nassert (len(train_img_files ) == len(train_mask_files)) and (len(val_img_files) == len(val_mask_files))\n\ntrain_imgs = [tifffile.imread(img_file) for img_file in tqdm(train_img_files)]\ntrain_masks = [tifffile.imread(flows_file) for flows_file in tqdm(train_mask_files)]\n\nval_imgs = [tifffile.imread(img_file) for img_file in tqdm(val_img_files)]\nval_masks = [tifffile.imread(flows_file) for flows_file in tqdm(val_mask_files)]","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:33.789808Z","iopub.execute_input":"2022-08-19T17:09:33.790149Z","iopub.status.idle":"2022-08-19T17:09:35.026825Z","shell.execute_reply.started":"2022-08-19T17:09:33.790116Z","shell.execute_reply":"2022-08-19T17:09:35.025892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <font color='gold'/> **Train**","metadata":{}},{"cell_type":"code","source":"from math import sqrt","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:35.028136Z","iopub.execute_input":"2022-08-19T17:09:35.028576Z","iopub.status.idle":"2022-08-19T17:09:35.033422Z","shell.execute_reply.started":"2022-08-19T17:09:35.028537Z","shell.execute_reply":"2022-08-19T17:09:35.032565Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cp_model_path = '../input/sartorius-weight/cellpose_221908_mosaic_astro_cort'\n#model_to_load = 'cyto' ## cyto, cyto2, nuclei\nnumber_of_epochs = 300  \nbatch_size = 8\nTraining_channel = 0 # For grayscale\nSecond_training_channel= 0 \n#learning_rate = 0.001","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:35.034659Z","iopub.execute_input":"2022-08-19T17:09:35.035421Z","iopub.status.idle":"2022-08-19T17:09:35.043353Z","shell.execute_reply.started":"2022-08-19T17:09:35.035324Z","shell.execute_reply":"2022-08-19T17:09:35.042551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from cellpose.io import logger_setup\nlogger, log_file = logger_setup()\n\ncp_model = models.CellposeModel(gpu=True, pretrained_model=cp_model_path)\n\nstart_time = time.time()\n\nmodel_path, epochs, loss_vls, val_loss_vls = cp_model.train(train_data=train_imgs, train_labels=train_masks,\n                            test_data=val_imgs, test_labels=val_masks,\n                            channels=[0, 0], save_path='./models', save_every=1, min_train_masks=5,\n                            n_epochs=number_of_epochs, \n                            model_name='cellpose_221908_mosaic_astro_cort_2')\n\nend_time = time.time()","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:09:35.044787Z","iopub.execute_input":"2022-08-19T17:09:35.045233Z","iopub.status.idle":"2022-08-19T17:27:25.012242Z","shell.execute_reply.started":"2022-08-19T17:09:35.045193Z","shell.execute_reply":"2022-08-19T17:27:25.010810Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_time = (end_time - start_time) / 3600\n\nprint('Train {} epochs took {}'.format(number_of_epochs, training_time))","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:27:25.017168Z","iopub.execute_input":"2022-08-19T17:27:25.019715Z","iopub.status.idle":"2022-08-19T17:27:25.029016Z","shell.execute_reply.started":"2022-08-19T17:27:25.019633Z","shell.execute_reply":"2022-08-19T17:27:25.028193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure(figsize=(6, 4))\n\nplt.plot(epochs, loss_vls)\nplt.plot(epochs, val_loss_vls)\nplt.legend(['loss', 'val_loss'])\n\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:27:25.030477Z","iopub.execute_input":"2022-08-19T17:27:25.031424Z","iopub.status.idle":"2022-08-19T17:27:25.279576Z","shell.execute_reply.started":"2022-08-19T17:27:25.031388Z","shell.execute_reply":"2022-08-19T17:27:25.278780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Loss: ', loss_vls[-1])\nprint('Val loss: ', val_loss_vls[-1])","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:27:25.283173Z","iopub.execute_input":"2022-08-19T17:27:25.283452Z","iopub.status.idle":"2022-08-19T17:27:25.288425Z","shell.execute_reply.started":"2022-08-19T17:27:25.283425Z","shell.execute_reply":"2022-08-19T17:27:25.287504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_path","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:27:25.290003Z","iopub.execute_input":"2022-08-19T17:27:25.290399Z","iopub.status.idle":"2022-08-19T17:27:25.302103Z","shell.execute_reply.started":"2022-08-19T17:27:25.290316Z","shell.execute_reply":"2022-08-19T17:27:25.301177Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Evaluation**","metadata":{}},{"cell_type":"markdown","source":"<a href='./models/models/cellpose_221808_rm_shsy5y'/> Download file","metadata":{}},{"cell_type":"code","source":"def rle_encode(img):\n    pixels = img.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\ntest_files = glob.glob('./cellpose_dataset_val/*_img.tif')\n#print(len(test_files))\nmodel = models.CellposeModel(gpu=True, pretrained_model=model_path)\n\nids, masks = [],[]\nfor fn in tqdm(test_files):\n    id_ = fn.split('/')[-1].replace('_img.tif','')\n    preds, flows, _ = model.eval(io.imread(fn), channels=[0,0], \n                                          augment=True, diameter=19)\n    for i in range (1, preds.max() + 1):\n        ids.append(id_)\n        masks.append(rle_encode(preds == i))\n        \npd.DataFrame({'id':ids, 'predicted':masks}).to_csv('val_predictions.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:27:25.303412Z","iopub.execute_input":"2022-08-19T17:27:25.304116Z","iopub.status.idle":"2022-08-19T17:29:23.943045Z","shell.execute_reply.started":"2022-08-19T17:27:25.304082Z","shell.execute_reply":"2022-08-19T17:29:23.942016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"width = 704\nheight = 520\nshape = [height,width]\n\ntrain_df = pd.read_csv('../input/sartorius-cell-instance-segmentation/train.csv')\ntrain_df = train_df.groupby('id').annotation.agg(list).reset_index()\n\ncellpose_predictions = pd.read_csv('val_predictions.csv')\ncellpose_predictions = cellpose_predictions.groupby('id').predicted.agg(list).reset_index()\ndf = pd.merge(train_df,cellpose_predictions,on='id')\n\nprint(df.shape)\n\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:29:23.944560Z","iopub.execute_input":"2022-08-19T17:29:23.945030Z","iopub.status.idle":"2022-08-19T17:29:24.518709Z","shell.execute_reply.started":"2022-08-19T17:29:23.944990Z","shell.execute_reply":"2022-08-19T17:29:24.517826Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"annotations = df.annotation.values\npredictions = df.predicted.values","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:29:24.520172Z","iopub.execute_input":"2022-08-19T17:29:24.520805Z","iopub.status.idle":"2022-08-19T17:29:24.526109Z","shell.execute_reply.started":"2022-08-19T17:29:24.520763Z","shell.execute_reply":"2022-08-19T17:29:24.524763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def compute_iou(labels, y_pred):\n    \"\"\"\n    Computes the IoU for instance labels and predictions.\n\n    Args:\n        labels (np array): Labels.\n        y_pred (np array): predictions\n\n    Returns:\n        np array: IoU matrix, of size true_objects x pred_objects.\n    \"\"\"\n\n    true_objects = len(np.unique(labels))\n    pred_objects = len(np.unique(y_pred))\n\n    # Compute intersection between all objects\n    intersection = np.histogram2d(\n        labels.flatten(), y_pred.flatten(), bins=(true_objects, pred_objects)\n    )[0]\n\n    # Compute areas (needed for finding the union between all objects)\n    area_true = np.histogram(labels, bins=true_objects)[0]\n    area_pred = np.histogram(y_pred, bins=pred_objects)[0]\n    area_true = np.expand_dims(area_true, -1)\n    area_pred = np.expand_dims(area_pred, 0)\n\n    # Compute union\n    union = area_true + area_pred - intersection\n    iou = intersection / union\n    \n    return iou[1:, 1:]  # exclude background\n\ndef precision_at(threshold, iou):\n    \"\"\"\n    Computes the precision at a given threshold.\n\n    Args:\n        threshold (float): Threshold.\n        iou (np array [n_truths x n_preds]): IoU matrix.\n\n    Returns:\n        int: Number of true positives,\n        int: Number of false positives,\n        int: Number of false negatives.\n    \"\"\"\n    matches = iou > threshold\n    true_positives = np.sum(matches, axis=1) >= 1  # Correct objects\n    false_negatives = np.sum(matches, axis=1) == 0  # Missed objects\n    false_positives = np.sum(matches, axis=0) == 0  # Extra objects\n    tp, fp, fn = (\n        np.sum(true_positives),\n        np.sum(false_positives),\n        np.sum(false_negatives),\n    )\n    return tp, fp, fn\n\nfrom tqdm.auto import tqdm\n\ndef iou_map(truths, preds, verbose=0):\n    \"\"\"\n    Computes the metric for the competition.\n    Masks contain the segmented pixels where each object has one value associated,\n    and 0 is the background.\n\n    Args:\n        truths (list of masks): Ground truths.\n        preds (list of masks): Predictions.\n        verbose (int, optional): Whether to print infos. Defaults to 0.\n\n    Returns:\n        float: mAP.\n    \"\"\"\n    ious = [\n        compute_iou(rles_to_mask(truth,shape), rles_to_mask(pred,shape)) \n            for truth, pred in tqdm(zip(truths, preds))\n    ]\n    \n    if verbose:\n        print(ious[0].shape)\n        print(\"Thresh\\tTP\\tFP\\tFN\\tPrec.\")\n\n    prec = []\n    for t in np.arange(0.5, 1.0, 0.05):\n        tps, fps, fns = 0, 0, 0\n        for iou in ious:\n            tp, fp, fn = precision_at(t, iou)\n            tps += tp\n            fps += fp\n            fns += fn\n\n        p = tps / (tps + fps + fns)\n        prec.append(p)\n\n        if verbose:\n            print(\"{:1.3f}\\t{}\\t{}\\t{}\\t{:1.3f}\".format(t, tps, fps, fns, p))\n\n    if verbose:\n        print(\"AP\\t-\\t-\\t-\\t{:1.3f}\".format(np.mean(prec)))\n\n    return np.mean(prec)\n\ndef rle_encode(img):\n    pixels = img.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":"2022-08-19T17:29:24.527680Z","iopub.execute_input":"2022-08-19T17:29:24.528335Z","iopub.status.idle":"2022-08-19T17:29:24.545850Z","shell.execute_reply.started":"2022-08-19T17:29:24.528299Z","shell.execute_reply":"2022-08-19T17:29:24.544999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"iou_map(annotations,predictions,verbose=1)","metadata":{"execution":{"iopub.status.busy":"2022-08-19T17:29:24.547563Z","iopub.execute_input":"2022-08-19T17:29:24.547877Z","iopub.status.idle":"2022-08-19T17:29:30.286516Z","shell.execute_reply.started":"2022-08-19T17:29:24.547853Z","shell.execute_reply":"2022-08-19T17:29:30.285692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}