{"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":"# About\nFor the Efn-B7 adding part, I've sorted them for you to easier to read. For the result, I've just changed some hyperparameters then got 0.001 increasing on LB. Copy and Edit from [here](https://www.kaggle.com/aristotelisch/efnb7-classification-model-added-to-cellwise-infer) ([@aristotelisch](https://www.kaggle.com/aristotelisch)). **Please be noted, I'm not going to submit this kernel as my final selection. It's all for having fun here.**\n\n*ORIGINAL NOTEBOOK CREATED BY [DARIEN SCHETTLER](https://www.kaggle.com/dschettler8845) (classification added by [Alien](https://www.kaggle.com/h053473666))*\n\n## Training\n- [HPA Eff-B7 Train (All) 4 Channels](https://www.kaggle.com/chienhsianghung/hpa-eff-b7-train-all-4-channels)\n- [HPA Models](https://www.kaggle.com/chienhsianghung/hpa-models)","metadata":{}},{"cell_type":"markdown","source":"# Imports","metadata":{"papermill":{"duration":0.0173,"end_time":"2021-01-31T11:44:38.723672","exception":false,"start_time":"2021-01-31T11:44:38.706372","status":"completed"},"tags":[]}},{"cell_type":"code","source":"!pip install /kaggle/input/kerasapplications -q\n!pip install /kaggle/input/efficientnet-keras-source-code/ -q --no-deps","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Cell Segmentator Tool\nprint(\"\\n... INSTALLING AND IMPORTING CELL-PROFILER TOOL (HPACELLSEG) ...\\n\")\ntry:\n    import hpacellseg.cellsegmentator as cellsegmentator\n    from hpacellseg.utils import label_cell\nexcept:\n    !pip install -q \"/kaggle/input/pycocotools/pycocotools-2.0-cp37-cp37m-linux_x86_64.whl\"\n    !pip install -q \"/kaggle/input/hpapytorchzoozip/pytorch_zoo-master\"\n    !pip install -q \"/kaggle/input/hpacellsegmentatormaster/HPA-Cell-Segmentation-master\"\n    import hpacellseg.cellsegmentator as cellsegmentator\n    from hpacellseg.utils import label_cell\n\nprint(\"\\n... OTHER IMPORTS STARTING ...\\n\")\nprint(\"\\n\\tVERSION INFORMATION\")\n\n# Machine Learning and Data Science Imports\nimport tensorflow as tf; print(f\"\\t\\t– TENSORFLOW VERSION: {tf.__version__}\");\nimport pandas as pd; pd.options.mode.chained_assignment = None;\nimport numpy as np; print(f\"\\t\\t– NUMPY VERSION: {np.__version__}\");\nimport torch\n\nimport pandas as pd\nimport os\n\nimport efficientnet.tfkeras as efn\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\n\n# Built In Imports\nfrom collections import Counter\nfrom datetime import datetime\nimport multiprocessing\nfrom glob import glob\nimport warnings\nimport requests\nimport imageio\nimport IPython\nimport urllib\nimport zipfile\nimport pickle\nimport random\nimport shutil\nimport string\nimport math\nimport tqdm\nimport time\nimport gzip\nimport sys\nimport ast\nimport csv; csv.field_size_limit(sys.maxsize)\nimport io\nimport os\nimport gc\nimport re\n\n# Visualization Imports\nfrom matplotlib.colors import ListedColormap\nimport matplotlib.patches as patches\nimport plotly.graph_objects as go\nimport matplotlib.pyplot as plt\nfrom tqdm.notebook import tqdm\nimport plotly.express as px\nimport seaborn as sns\nfrom PIL import Image\nimport matplotlib; print(f\"\\t\\t– MATPLOTLIB VERSION: {matplotlib.__version__}\");\nimport plotly\nimport PIL\nimport cv2\n\n# Submission Imports\nfrom pycocotools import _mask as coco_mask\nimport typing as t\nimport base64\nimport zlib\n\n# PRESETS\nLBL_NAMES = [\"Nucleoplasm\", \"Nuclear Membrane\", \"Nucleoli\", \"Nucleoli Fibrillar Center\", \"Nuclear Speckles\", \"Nuclear Bodies\", \"Endoplasmic Reticulum\", \"Golgi Apparatus\", \"Intermediate Filaments\", \"Actin Filaments\", \"Microtubules\", \"Mitotic Spindle\", \"Centrosome\", \"Plasma Membrane\", \"Mitochondria\", \"Aggresome\", \"Cytosol\", \"Vesicles\", \"Negative\"]\nINT_2_STR = {x:LBL_NAMES[x] for x in np.arange(19)}\nINT_2_STR_LOWER = {k:v.lower().replace(\" \", \"_\") for k,v in INT_2_STR.items()}\nSTR_2_INT_LOWER = {v:k for k,v in INT_2_STR_LOWER.items()}\nSTR_2_INT = {v:k for k,v in INT_2_STR.items()}\nFIG_FONT = dict(family=\"Helvetica, Arial\", size=14, color=\"#7f7f7f\")\nLABEL_COLORS = [px.colors.label_rgb(px.colors.convert_to_RGB_255(x)) for x in sns.color_palette(\"Spectral\", len(LBL_NAMES))]\nLABEL_COL_MAP = {str(i):x for i,x in enumerate(LABEL_COLORS)}\n\nprint(\"\\n\\n... IMPORTS COMPLETE ...\\n\")\n\n##### THIS IS FOR PROTOTYPING AND PUBLIC LB PROBING #####\nONLY_PUBLIC = True\n##### THIS IS FOR PROTOTYPING AND PUBLIC LB PROBING#####\n\nif ONLY_PUBLIC:\n    print(\"\\n... ONLY INFERRING ON PUBLIC TEST DATA (USING PRE-PROCESSED DF) ...\\n\")\nelse:\n    # Stop Tensorflow From Eating All The Memory\n    gpus = tf.config.experimental.list_physical_devices('GPU')\n    if gpus:\n        try:\n            # Currently, memory growth needs to be the same across GPUs\n            for gpu in gpus:\n                tf.config.experimental.set_memory_growth(gpu, True)\n            logical_gpus = tf.config.experimental.list_logical_devices('GPU')\n            print(len(gpus), \"... Physical GPUs,\", len(logical_gpus), \"Logical GPUs ...\\n\")\n        except RuntimeError as e:\n            # Memory growth must be set before GPUs have been initialized\n            print(e)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Focal Loss","metadata":{}},{"cell_type":"code","source":"!cp -r ../input/focallosstensorflowstablefromartemmavrin/focal-loss-master/* ./\n!pip install ./focal-loss-master/","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from focal_loss import BinaryFocalLoss  # Used by the model here: https://www.kaggle.com/aristotelisch/hpa-classification-efnb7-train-13cc0d.\n\ndef binary_focal_loss(gamma=2, alpha=0.25):\n    \"\"\"\n    Binary form of focal loss.\n         Focal loss for binary classification problems\n    \n    focal_loss(p_t) = -alpha_t * (1 - p_t)**gamma * log(p_t)\n        where p = sigmoid(x), p_t = p or 1 - p depending on if the label is 1 or 0, respectively.\n    References:\n        https://arxiv.org/pdf/1708.02002.pdf\n    Usage:\n     model.compile(loss=[binary_focal_loss(alpha=.25, gamma=2)], metrics=[\"accuracy\"], optimizer=adam)\n    \"\"\"\n    alpha = tf.constant(alpha, dtype=tf.float32)\n    gamma = tf.constant(gamma, dtype=tf.float32)\n\n    def binary_focal_loss_fixed(y_true, y_pred):\n        \"\"\"\n        y_true shape need be (None,1)\n        y_pred need be compute after sigmoid\n        \"\"\"\n        y_true = tf.cast(y_true, tf.float32)\n        alpha_t = y_true*alpha + (K.ones_like(y_true)-y_true)*(1-alpha)\n    \n        p_t = y_true*y_pred + (K.ones_like(y_true)-y_true)*(K.ones_like(y_true)-y_pred) + K.epsilon()\n        focal_loss = - alpha_t * K.pow((K.ones_like(y_true)-p_t),gamma) * K.log(p_t)\n        return K.mean(focal_loss)\n    return binary_focal_loss_fixed","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1 BACKGROUND INFORMATION","metadata":{"papermill":{"duration":0.019977,"end_time":"2021-01-31T11:45:56.098171","exception":false,"start_time":"2021-01-31T11:45:56.078194","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"<h3 style=\"text-align: font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\">1.1 APPROACH OVERVIEW</h3>\n\n---\n\n**TRAINING**\n\n1. Identify slide-level images containing only one label\n2. Segment slide-level images (get RLEs for all cells in all applicable slide-level images)\n3. Crop RGBY image around each cell\n4. Pad each RGBY tile to be square\n5. Resize each RGBY tile to be (256px by 256px)\n6. TBD ---> Filter the images based on certain additional factors to obtain a better training dataset\n7. Seperate the channels and store as seperate datasets\n8. Augment the dataset (rotation, flipping (horizontal and vertical), minor-skew)\n9. Train a model to classify these tile-level images accurately\n\n---\n\n**INFERENCE**\n\n1. Use CellSegmentator to do instance segmentation on images in test-dataset\n2. Record this mask in the appropriate format for later submission\n3. Crop RGBY image around each cell\n4. Pad each RGBY tile to be square\n5. Resize each RGBY tile to be (256px by 256px)\n6. Infer on each slide \n7. Combine cell-level classification with segmentation as RLE when submitting","metadata":{}},{"cell_type":"markdown","source":"<h3 style=\"text-align: font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\">1.2 VISUAL HELPER</h3>\n\n---","metadata":{}},{"cell_type":"markdown","source":"\n\n![basic_idea_graph](https://i.ibb.co/y6YfBzN/basic-idea.png)","metadata":{}},{"cell_type":"markdown","source":"# 2 NOTEBOOK SETUP","metadata":{"papermill":{"duration":0.020391,"end_time":"2021-01-31T11:45:56.263882","exception":false,"start_time":"2021-01-31T11:45:56.243491","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# Define paths to nucleus and cell models for the cellsegmentator class\nNUC_MODEL = '/kaggle/input/hpacellsegmentatormodelweights/dpn_unet_nuclei_v1.pth'\nCELL_MODEL = '/kaggle/input/hpacellsegmentatormodelweights/dpn_unet_cell_3ch_v1.pth'\n\nB2_CELL_CLSFR_DIR = \"/kaggle/input/hpa-models/HPA - Cellwise Classification TRAINING/ebnet_b2_wdensehead/ckpt-0007-0.0901.ckpt\"\n\n# Define the path to the competition data directory\nDATA_DIR = \"/kaggle/input/hpa-single-cell-image-classification\"\n\n# Define the paths to the training and testing tfrecord and \n# image folders respectively for the competition data\nTEST_IMG_DIR = os.path.join(DATA_DIR, \"test\")\n\n# Capture all the relevant full image paths for the competition dataset\nTEST_IMG_PATHS = sorted([os.path.join(TEST_IMG_DIR, f_name) for f_name in os.listdir(TEST_IMG_DIR)])\nprint(f\"... The number of testing images is {len(TEST_IMG_PATHS)}\" \\\n      f\"\\n\\t--> i.e. {len(TEST_IMG_PATHS)//4} 4-channel images ...\")\n\n# Define paths to the relevant csv files\nPUB_SS_CSV = \"/kaggle/input/hpa-sample-submission-with-extra-metadata/updated_sample_submission.csv\"\nSWAP_SS_CSV = os.path.join(DATA_DIR, \"sample_submission.csv\")\n\n# Create the relevant dataframe objects\nss_df = pd.read_csv(SWAP_SS_CSV)\n\n# Test Time Augmentation Information\nDO_TTA = True\nTTA_REPEATS = 8\n\n# helps us control whether this is the full submission or just the initial pass\nIS_DEMO = len(ss_df)==559\nIS_DEMO=False\nif IS_DEMO:\n    ss_df_1 = ss_df.drop_duplicates(\"ImageWidth\", keep=\"first\")\n    ss_df_2 = ss_df.drop_duplicates(\"ImageWidth\", keep=\"last\")\n    ss_df = pd.concat([ss_df_1, ss_df_2])\n    del ss_df_1; del ss_df_2; gc.collect();\n    print(\"\\n\\nSAMPLE SUBMISSION DATAFRAME\\n\\n\")\n    display(ss_df)\nelse:\n    print(\"\\n\\nSAMPLE SUBMISSION DATAFRAME\\n\\n\")\n    display(ss_df)\n    \n# If demo-submission/display we only do a subset of the data\nif ONLY_PUBLIC:\n    pub_ss_df = pd.read_csv(PUB_SS_CSV)\n    \n    if IS_DEMO:\n        pub_ss_df_1 = pub_ss_df.drop_duplicates(\"ImageWidth\", keep=\"first\")\n        pub_ss_df_2 = pub_ss_df.drop_duplicates(\"ImageWidth\", keep=\"last\")\n        pub_ss_df = pd.concat([pub_ss_df_1, pub_ss_df_2])\n        \n    pub_ss_df.mask_rles = pub_ss_df.mask_rles.apply(lambda x: ast.literal_eval(x))\n    pub_ss_df.mask_bboxes = pub_ss_df.mask_bboxes.apply(lambda x: ast.literal_eval(x))\n    pub_ss_df.mask_sub_rles = pub_ss_df.mask_sub_rles.apply(lambda x: ast.literal_eval(x))\n    \n    print(\"\\n\\nTEST DATAFRAME W/ MASKS\\n\\n\")\n    display(pub_ss_df)    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3 HELPER FUNCTIONS","metadata":{"papermill":{"duration":0.022604,"end_time":"2021-01-31T11:45:58.224086","exception":false,"start_time":"2021-01-31T11:45:58.201482","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def binary_mask_to_ascii(mask, mask_val=1):\n    \"\"\"Converts a binary mask into OID challenge encoding ascii text.\"\"\"\n    mask = np.where(mask==mask_val, 1, 0).astype(np.bool)\n    \n    # check input mask --\n    if mask.dtype != np.bool:\n        raise ValueError(f\"encode_binary_mask expects a binary mask, received dtype == {mask.dtype}\")\n\n    mask = np.squeeze(mask)\n    if len(mask.shape) != 2:\n        raise ValueError(f\"encode_binary_mask expects a 2d mask, received shape == {mask.shape}\")\n\n    # convert input mask to expected COCO API input --\n    mask_to_encode = mask.reshape(mask.shape[0], mask.shape[1], 1)\n    mask_to_encode = mask_to_encode.astype(np.uint8)\n    mask_to_encode = np.asfortranarray(mask_to_encode)\n\n    # RLE encode mask --\n    encoded_mask = coco_mask.encode(mask_to_encode)[0][\"counts\"]\n\n    # compress and base64 encoding --\n    binary_str = zlib.compress(encoded_mask, zlib.Z_BEST_COMPRESSION)\n    base64_str = base64.b64encode(binary_str)\n    return base64_str.decode()\n\n\ndef rle_encoding(img, mask_val=1):\n    \"\"\"\n    Turns our masks into RLE encoding to easily store them\n    and feed them into models later on\n    https://en.wikipedia.org/wiki/Run-length_encoding\n    \n    Args:\n        img (np.array): Segmentation array\n        mask_val (int): Which value to use to create the RLE\n        \n    Returns:\n        RLE string\n    \n    \"\"\"\n    dots = np.where(img.T.flatten() == mask_val)[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        \n    return ' '.join([str(x) for x in run_lengths])\n\n\ndef rle_to_mask(rle_string, height, width):\n    \"\"\" Convert RLE sttring into a binary mask \n    \n    Args:\n        rle_string (rle_string): Run length encoding containing \n            segmentation mask information\n        height (int): Height of the original image the map comes from\n        width (int): Width of the original image the map comes from\n    \n    Returns:\n        Numpy array of the binary segmentation mask for a given cell\n    \"\"\"\n    rows,cols = height,width\n    rle_numbers = [int(num_string) for num_string in rle_string.split(' ')]\n    rle_pairs = np.array(rle_numbers).reshape(-1,2)\n    img = np.zeros(rows*cols,dtype=np.uint8)\n    for index,length in rle_pairs:\n        index -= 1\n        img[index:index+length] = 255\n    img = img.reshape(cols,rows)\n    img = img.T\n    return img\n\n\ndef decode_img(img, img_size=(224,224), testing=False):\n    \"\"\"TBD\"\"\"\n    \n    # convert the compressed string to a 3D uint8 tensor\n    if not testing:\n        # resize the image to the desired size\n        img = tf.image.decode_png(img, channels=1)\n        return tf.cast(tf.image.resize(img, img_size), tf.uint8)\n    else:\n        return tf.image.decode_png(img, channels=1)\n        \n\n    \ndef preprocess_path_ds(rp, gp, bp, yp, lbl, n_classes=19, img_size=(224,224), combine=True, drop_yellow=True):\n    \"\"\" TBD \"\"\"\n    \n    ri = decode_img(tf.io.read_file(rp), img_size)\n    gi = decode_img(tf.io.read_file(gp), img_size)\n    bi = decode_img(tf.io.read_file(bp), img_size)\n    yi = decode_img(tf.io.read_file(yp), img_size)\n\n    if combine and drop_yellow:\n        return tf.stack([ri[..., 0], gi[..., 0], bi[..., 0]], axis=-1), tf.one_hot(lbl, n_classes, dtype=tf.uint8)\n    elif combine:\n        return tf.stack([ri[..., 0], gi[..., 0], bi[..., 0], yi[..., 0]], axis=-1), tf.one_hot(lbl, n_classes, dtype=tf.uint8)\n    elif drop_yellow:\n        return ri, gi, bi, tf.one_hot(lbl, n_classes, dtype=tf.uint8)\n    else:\n        return ri, gi, bi, yi, tf.one_hot(lbl, n_classes, dtype=tf.uint8)        \n    \n    \ndef create_pred_col(row):\n    \"\"\" Simple function to return the correct prediction string\n    \n    We will want the original public test dataframe submission when it is \n    available. However, we will use the swapped inn submission dataframe\n    when it is not.\n    \n    Args:\n        row (pd.Series): A row in the dataframe\n    \n    Returns:\n        The prediction string\n    \"\"\"\n    if pd.isnull(row.PredictionString_y):\n        return row.PredictionString_x\n    else:\n        return row.PredictionString_y\n    \n    \ndef load_image(img_id, img_dir, testing=False, only_public=False):\n    \"\"\" Load An Image Using ID and Directory Path - Composes 4 Individual Images \"\"\"\n    if only_public:\n        return_axis = -1\n        clr_list = [\"red\", \"green\", \"blue\"]\n    else:\n        return_axis = 0\n        clr_list = [\"red\", \"green\", \"blue\", \"yellow\"]\n    \n    if not testing:\n        rgby = [\n            np.asarray(Image.open(os.path.join(img_dir, img_id+f\"_{c}.png\")), np.uint8) \\\n            for c in [\"red\", \"green\", \"blue\", \"yellow\"]\n        ]\n        return np.stack(rgby, axis=-1)\n    else:\n        # This is for cellsegmentator\n        return np.stack(\n            [np.asarray(decode_img(tf.io.read_file(os.path.join(img_dir, img_id+f\"_{c}.png\")), testing=True), np.uint8)[..., 0] \\\n             for c in clr_list], axis=return_axis,\n        )\n        \n\n\ndef plot_rgb(arr, figsize=(12,12)):\n    \"\"\" Plot 3 Channel Microscopy Image \"\"\"\n    plt.figure(figsize=figsize)\n    plt.title(f\"RGB Composite Image\", fontweight=\"bold\")\n    plt.imshow(arr)\n    plt.axis(False)\n    plt.show()\n    \n    \ndef convert_rgby_to_rgb(arr):\n    \"\"\" Convert a 4 channel (RGBY) image to a 3 channel RGB image.\n    \n    Advice From Competition Host/User: lnhtrang\n\n    For annotation (by experts) and for the model, I guess we agree that individual \n    channels with full range px values are better. \n    In annotation, we toggled the channels. \n    For visualization purpose only, you can try blending the channels. \n    For example, \n        - red = red + yellow\n        - green = green + yellow/2\n        - blue=blue.\n        \n    Args:\n        arr (numpy array): The RGBY, 4 channel numpy array for a given image\n    \n    Returns:\n        RGB Image\n    \"\"\"\n    \n    rgb_arr = np.zeros_like(arr[..., :-1])\n    rgb_arr[..., 0] = arr[..., 0]\n    rgb_arr[..., 1] = arr[..., 1]+arr[..., 3]/2\n    rgb_arr[..., 2] = arr[..., 2]\n    \n    return rgb_arr\n    \n    \ndef plot_ex(arr, figsize=(20,6), title=None, plot_merged=True, rgb_only=False):\n    \"\"\" Plot 4 Channels Side by Side \"\"\"\n    if plot_merged and not rgb_only:\n        n_images=5 \n    elif plot_merged and rgb_only:\n        n_images=4\n    elif not plot_merged and rgb_only:\n        n_images=4\n    else:\n        n_images=3\n    plt.figure(figsize=figsize)\n    if type(title) == str:\n        plt.suptitle(title, fontsize=20, fontweight=\"bold\")\n\n    for i, c in enumerate([\"Red Channel – Microtubles\", \"Green Channel – Protein of Interest\", \"Blue - Nucleus\", \"Yellow – Endoplasmic Reticulum\"]):\n        if not rgb_only:\n            ch_arr = np.zeros_like(arr[..., :-1])        \n        else:\n            ch_arr = np.zeros_like(arr)\n        if c in [\"Red Channel – Microtubles\", \"Green Channel – Protein of Interest\", \"Blue - Nucleus\"]:\n            ch_arr[..., i] = arr[..., i]\n        else:\n            if rgb_only:\n                continue\n            ch_arr[..., 0] = arr[..., i]\n            ch_arr[..., 1] = arr[..., i]\n        plt.subplot(1,n_images,i+1)\n        plt.title(f\"{c.title()}\", fontweight=\"bold\")\n        plt.imshow(ch_arr)\n        plt.axis(False)\n        \n    if plot_merged:\n        plt.subplot(1,n_images,n_images)\n        \n        if rgb_only:\n            plt.title(f\"Merged RGB\", fontweight=\"bold\")\n            plt.imshow(arr)\n        else:\n            plt.title(f\"Merged RGBY into RGB\", fontweight=\"bold\")\n            plt.imshow(convert_rgby_to_rgb(arr))\n        plt.axis(False)\n        \n    plt.tight_layout(rect=[0, 0.2, 1, 0.97])\n    plt.show()\n    \n    \ndef flatten_list_of_lists(l_o_l, to_string=False):\n    if not to_string:\n        return [item for sublist in l_o_l for item in sublist]\n    else:\n        return [str(item) for sublist in l_o_l for item in sublist]\n\n\ndef create_segmentation_maps(list_of_image_lists, segmentator, batch_size=8):\n    \"\"\" Function to generate segmentation maps using CellSegmentator tool \n    \n    Args:\n        list_of_image_lists (list of lists):\n            - [[micro-tubules(red)], [endoplasmic-reticulum(yellow)], [nucleus(blue)]]\n        batch_size (int): Batch size to use in generating the segmentation masks\n        \n    Returns:\n        List of lists containing RLEs for all the cells in all images\n    \"\"\"\n    \n    all_mask_rles = {}\n    for i in tqdm(range(0, len(list_of_image_lists[0]), batch_size), total=len(list_of_image_lists[0])//batch_size):\n        \n        # Get batch of images\n        sub_images = [img_channel_list[i:i+batch_size] for img_channel_list in list_of_image_lists] # 0.000001 seconds\n\n        # Do segmentation\n        cell_segmentations = segmentator.pred_cells(sub_images)\n        nuc_segmentations = segmentator.pred_nuclei(sub_images[2])\n\n        # post-processing\n        for j, path in enumerate(sub_images[0]):\n            img_id = path.replace(\"_red.png\", \"\").rsplit(\"/\", 1)[1]\n            nuc_mask, cell_mask = label_cell(nuc_segmentations[j], cell_segmentations[j])\n            new_name = os.path.basename(path).replace('red','mask')\n            all_mask_rles[img_id] = [rle_encoding(cell_mask, mask_val=k) for k in range(1, np.max(cell_mask)+1)]\n    return all_mask_rles\n\n\ndef get_img_list(img_dir, return_ids=False, sub_n=None):\n    \"\"\" Get image list in the format expected by the CellSegmentator tool \"\"\"\n    if sub_n is None:\n        sub_n=len(glob(img_dir + '/' + f'*_red.png'))\n    if return_ids:\n        images = [sorted(glob(img_dir + '/' + f'*_{c}.png'))[:sub_n] for c in [\"red\", \"yellow\", \"blue\"]]\n        return [x.replace(\"_red.png\", \"\").rsplit(\"/\", 1)[1] for x in images[0]], images\n    else:\n        return [sorted(glob(img_dir + '/' + f'*_{c}.png'))[:sub_n] for c in [\"red\", \"yellow\", \"blue\"]]\n    \n    \ndef get_contour_bbox_from_rle(rle, width, height, return_mask=True,):\n    \"\"\" Get bbox of contour as `xmin ymin xmax ymax`\n    \n    Args:\n        rle (rle_string): Run length encoding containing \n            segmentation mask information\n        height (int): Height of the original image the map comes from\n        width (int): Width of the original image the map comes from\n    \n    Returns:\n        Numpy array for a cell bounding box coordinates\n    \"\"\"\n    mask = rle_to_mask(rle, height, width).copy()\n    cnts = grab_contours(\n        cv2.findContours(\n            mask, \n            cv2.RETR_EXTERNAL, \n            cv2.CHAIN_APPROX_SIMPLE\n        ))\n    x,y,w,h = cv2.boundingRect(cnts[0])\n    \n    if return_mask:\n        return (x,y,x+w,y+h), mask\n    else:\n        return (x,y,x+w,y+h)\n    \n\ndef get_contour_bbox_from_raw(raw_mask):\n    \"\"\" Get bbox of contour as `xmin ymin xmax ymax`\n    \n    Args:\n        raw_mask (nparray): Numpy array containing segmentation mask information\n    \n    Returns:\n        Numpy array for a cell bounding box coordinates\n    \"\"\"\n    cnts = grab_contours(\n        cv2.findContours(\n            raw_mask, \n            cv2.RETR_EXTERNAL, \n            cv2.CHAIN_APPROX_SIMPLE\n        ))\n    xywhs = [cv2.boundingRect(cnt) for cnt in cnts]\n    xys = [(xywh[0], xywh[1], xywh[0]+xywh[2], xywh[1]+xywh[3]) for xywh in xywhs]\n    return sorted(xys, key=lambda x: (x[1], x[0]))\n\n\ndef pad_to_square(a):\n    \"\"\" Pad an array `a` evenly until it is a square \"\"\"\n    if a.shape[1]>a.shape[0]: # pad height\n        n_to_add = a.shape[1]-a.shape[0]\n        top_pad = n_to_add//2\n        bottom_pad = n_to_add-top_pad\n        a = np.pad(a, [(top_pad, bottom_pad), (0, 0), (0, 0)], mode='constant')\n\n    elif a.shape[0]>a.shape[1]: # pad width\n        n_to_add = a.shape[0]-a.shape[1]\n        left_pad = n_to_add//2\n        right_pad = n_to_add-left_pad\n        a = np.pad(a, [(0, 0), (left_pad, right_pad), (0, 0)], mode='constant')\n    else:\n        pass\n    return a\n\n\ndef cut_out_cells(rgby, rles, resize_to=(256,256), square_off=True, return_masks=False, from_raw=True):\n    \"\"\" Cut out the cells as padded square images \n    \n    Args:\n        rgby (np.array): 4 Channel image to be cut into tiles\n        rles (list of RLE strings): List of run length encoding containing \n            segmentation mask information\n        resize_to (tuple of ints, optional): The square dimension to resize the image to\n        square_off (bool, optional): Whether to pad the image to a square or not\n        \n    Returns:\n        list of square arrays representing squared off cell images\n    \"\"\"\n    w,h = rgby.shape[:2]\n    contour_bboxes = [get_contour_bbox(rle, w, h, return_mask=return_masks) for rle in rles]\n    if return_masks:\n        masks = [x[-1] for x in contour_bboxes]\n        contour_bboxes = [x[:-1] for x in contour_bboxes]\n    \n    arrs = [rgby[bbox[1]:bbox[3], bbox[0]:bbox[2], ...] for bbox in contour_bboxes]\n    if square_off:\n        arrs = [pad_to_square(arr) for arr in arrs]\n        \n    if resize_to is not None:\n        arrs = [\n            cv2.resize(pad_to_square(arr).astype(np.float32), \n                       resize_to, \n                       interpolation=cv2.INTER_CUBIC) \\\n            for arr in arrs\n        ]\n    if return_masks:\n        return arrs, masks\n    else:\n        return arrs\n\n\ndef grab_contours(cnts):\n    # if the length the contours tuple returned by cv2.findContours\n    # is '2' then we are using either OpenCV v2.4, v4-beta, or\n    # v4-official\n    if len(cnts) == 2:\n        cnts = cnts[0]\n\n    # if the length of the contours tuple is '3' then we are using\n    # either OpenCV v3, v4-pre, or v4-alpha\n    elif len(cnts) == 3:\n        cnts = cnts[1]\n\n    # otherwise OpenCV has changed their cv2.findContours return\n    # signature yet again and I have no idea WTH is going on\n    else:\n        raise Exception((\"Contours tuple must have length 2 or 3, \"\n            \"otherwise OpenCV changed their cv2.findContours return \"\n            \"signature yet again. Refer to OpenCV's documentation \"\n            \"in that case\"))\n\n    # return the actual contours array\n    return cnts\n\n\ndef preprocess_row(img_id, img_w, img_h, combine=True, drop_yellow=True):\n    \"\"\" TBD \"\"\"\n\n    rp = os.path.join(TEST_IMG_DIR, img_id+\"_red.png\")\n    gp = os.path.join(TEST_IMG_DIR, img_id+\"_green.png\")\n    bp = os.path.join(TEST_IMG_DIR, img_id+\"_blue.png\")\n    yp = os.path.join(TEST_IMG_DIR, img_id+\"_yellow.png\")\n    \n    ri = decode_img(tf.io.read_file(rp), (img_w, img_h), testing=True)\n    gi = decode_img(tf.io.read_file(gp), (img_w, img_h), testing=True)\n    bi = decode_img(tf.io.read_file(bp), (img_w, img_h), testing=True)\n\n    if not drop_yellow:\n        yi = decode_img(tf.io.read_file(yp), (img_w, img_h), testing=True)\n\n    if combine and drop_yellow:\n        return tf.stack([ri[..., 0], gi[..., 0], bi[..., 0]], axis=-1)\n    elif combine:\n        return tf.stack([ri[..., 0], gi[..., 0], bi[..., 0], yi[..., 0]], axis=-1)\n    elif drop_yellow:\n        return ri, gi, bi\n    else:\n        return ri, gi, bi, yi\n\n    \ndef plot_predictions(img, masks, preds, confs=None, fill_alpha=0.3, lbl_as_str=True):\n    # Initialize\n    FONT = cv2.FONT_HERSHEY_SIMPLEX; FONT_SCALE = 0.7; FONT_THICKNESS = 2; FONT_LINE_TYPE = cv2.LINE_AA;\n    COLORS = [[round(y*255) for y in x] for x in sns.color_palette(\"Spectral\", len(LBL_NAMES))]\n    to_plot = img.copy()\n    cntr_img = img.copy()\n    if confs==None:\n        confs = [None,]*len(masks)\n\n    cnts = grab_contours(\n        cv2.findContours(\n            masks, \n            cv2.RETR_EXTERNAL, \n            cv2.CHAIN_APPROX_SIMPLE\n        ))\n    cnts = sorted(cnts, key=lambda x: (cv2.boundingRect(x)[1], cv2.boundingRect(x)[0]))\n        \n    for c, pred, conf in zip(cnts, preds, confs):\n        # We can only display one color so we pick the first\n        color = COLORS[pred[0]]\n        if not lbl_as_str:\n            classes = \"CLS=[\"+\",\".join([str(p) for p in pred])+\"]\"\n        else:\n            classes = \", \".join([INT_2_STR[p] for p in pred])\n        M = cv2.moments(c)\n        cx = int(M['m10']/M['m00'])\n        cy = int(M['m01']/M['m00'])\n        \n        text_width, text_height = cv2.getTextSize(classes, FONT, FONT_SCALE, FONT_THICKNESS)[0]\n        \n        # Border and fill\n        cv2.drawContours(to_plot, [c], contourIdx=-1, color=[max(0, x-40) for x in color], thickness=10)\n        cv2.drawContours(cntr_img, [c], contourIdx=-1, color=(color), thickness=-1)\n        \n        # Text\n        cv2.putText(to_plot, classes, (cx-text_width//2,cy-text_height//2),\n                    FONT, FONT_SCALE, [min(255, x+40) for x in color], FONT_THICKNESS, FONT_LINE_TYPE)\n    \n    cv2.addWeighted(cntr_img, fill_alpha, to_plot, 1-fill_alpha, 0, to_plot)\n    plt.figure(figsize=(16,16))\n    plt.imshow(to_plot)\n    plt.axis(False)\n    plt.show()\n    \ndef tta(original_img_batch, repeats=4):\n    \"\"\" Perform test time augmentation \"\"\"\n    tta_img_batches = [original_img_batch,]\n\n    for i in range(repeats):\n        # create new image batch (tf automatically deep copies)\n        img_batch = original_img_batch\n        \n        SEED = tf.random.uniform((2,), minval=0, maxval=100, dtype=tf.dtypes.int32)\n        K = tf.random.uniform((1,), minval=0, maxval=4, dtype=tf.dtypes.int32)[0]\n\n        img_batch = tf.image.stateless_random_flip_left_right(img_batch, SEED)\n        img_batch = tf.image.stateless_random_flip_up_down(img_batch, SEED)\n        img_batch = tf.image.rot90(img_batch, K)\n\n        img_batch = tf.image.stateless_random_saturation(img_batch, 0.9, 1.1, SEED)\n        img_batch = tf.image.stateless_random_brightness(img_batch, 0.075, SEED)\n        img_batch = tf.image.stateless_random_contrast(img_batch, 0.9, 1.1, SEED)    \n        tta_img_batches.append(img_batch)\n    \n    return tta_img_batches","metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","execution":{"iopub.execute_input":"2021-01-31T11:45:58.303779Z","iopub.status.busy":"2021-01-31T11:45:58.291581Z","iopub.status.idle":"2021-01-31T11:46:01.296299Z","shell.execute_reply":"2021-01-31T11:46:01.295762Z"},"papermill":{"duration":3.049332,"end_time":"2021-01-31T11:46:01.296459","exception":false,"start_time":"2021-01-31T11:45:58.247127","status":"completed"},"tags":[],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 4 INFERENCE LOOP","metadata":{"papermill":{"duration":0.026161,"end_time":"2021-01-31T11:46:01.349387","exception":false,"start_time":"2021-01-31T11:46:01.323226","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"<h3 style=\"text-align: font-family: Verdana; font-size: 20px; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; letter-spacing: 2px; color: navy; background-color: #ffffff;\">4.1 LOAD THE MODEL</h3>\n\n---\n\n* Load the models\n* Define the parameters\n* Make subset dataframes\n* Initialize","metadata":{"papermill":{"duration":0.030494,"end_time":"2021-01-31T11:46:03.144496","exception":false,"start_time":"2021-01-31T11:46:03.114002","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# Load inference model\ninference_model = tf.keras.models.load_model(B2_CELL_CLSFR_DIR)\n\n# Parameters\nIMAGE_SIZES = [1728, 2048, 3072, 4096]\nBATCH_SIZE = 32\nCONF_THRESH = 0.0\nTILE_SIZE = (224,224)\n\n\n# Switch what we will be actually infering on\nif ONLY_PUBLIC:\n    # Make subset dataframes\n    predict_df_1728 = pub_ss_df[pub_ss_df.ImageWidth==IMAGE_SIZES[0]]\n    predict_df_2048 = pub_ss_df[pub_ss_df.ImageWidth==IMAGE_SIZES[1]]\n    predict_df_3072 = pub_ss_df[pub_ss_df.ImageWidth==IMAGE_SIZES[2]]\n    predict_df_4096 = pub_ss_df[pub_ss_df.ImageWidth==IMAGE_SIZES[3]]\nelse:\n    # Load Segmentator\n    segmentator = cellsegmentator.CellSegmentator(NUC_MODEL, CELL_MODEL, scale_factor=0.275, padding=True)\n    \n    # Make subset dataframes\n    predict_df_1728 = ss_df[ss_df.ImageWidth==IMAGE_SIZES[0]]\n    predict_df_2048 = ss_df[ss_df.ImageWidth==IMAGE_SIZES[1]]\n    predict_df_3072 = ss_df[ss_df.ImageWidth==IMAGE_SIZES[2]]\n    predict_df_4096 = ss_df[ss_df.ImageWidth==IMAGE_SIZES[3]]\n\n\npredict_ids_1728 = predict_df_1728.ID.to_list()\npredict_ids_2048 = predict_df_2048.ID.to_list()\npredict_ids_3072 = predict_df_3072.ID.to_list()\npredict_ids_4096 = predict_df_4096.ID.to_list()","metadata":{"execution":{"iopub.execute_input":"2021-01-31T11:46:03.219768Z","iopub.status.busy":"2021-01-31T11:46:03.214645Z","iopub.status.idle":"2021-01-31T11:46:03.482199Z","shell.execute_reply":"2021-01-31T11:46:03.481322Z"},"papermill":{"duration":0.307114,"end_time":"2021-01-31T11:46:03.482374","exception":false,"start_time":"2021-01-31T11:46:03.17526","status":"completed"},"tags":[],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4.2 INFER","metadata":{"papermill":{"duration":0.02683,"end_time":"2021-01-31T11:46:01.403131","exception":false,"start_time":"2021-01-31T11:46:01.376301","status":"completed"},"tags":[]}},{"cell_type":"code","source":"predictions = []\nsub_df = pd.DataFrame(columns=[\"ID\"], data=predict_ids_1728+predict_ids_2048+predict_ids_3072+predict_ids_4096)\n\n# #### STEP TIMING FOR 1728x1728 IMAGES FOR EFFNETB0 ON 128x128 CROPS ####\n#  0:\t 1.03042 seconds\n#  1:\t 8.14935 seconds\n#  2:\t 0.00002 seconds\n#  3:\t 29.9057 seconds\n#  4:\t 1.30675 seconds\n#  5:\t 0.01442 seconds\n#  6:\t 0.26723 seconds\n#  7:\t 4.10871 seconds\n#  8:\t 0.00108 seconds\n#  9:\t 0.00066 seconds\n# 10:\t 0.00015 seconds\nfor size_idx, submission_ids in enumerate([predict_ids_1728, predict_ids_2048, predict_ids_3072, predict_ids_4096]):\n    size = IMAGE_SIZES[size_idx]\n    if submission_ids==[]:\n        print(f\"\\n...SKIPPING SIZE {size} AS THERE ARE NO IMAGE IDS ...\\n\")\n        continue\n    else:\n        print(f\"\\n...WORKING ON IMAGE IDS FOR SIZE {size} ...\\n\")\n    for i in tqdm(range(0, len(submission_ids), BATCH_SIZE), total=int(np.ceil(len(submission_ids)/BATCH_SIZE))):\n        \n        # Step 0: Get batch of images as numpy arrays\n        batch_rgby_images = [\n            load_image(ID, TEST_IMG_DIR, testing=True, only_public=ONLY_PUBLIC) \\\n            for ID in submission_ids[i:(i+BATCH_SIZE)]\n        ]\n        \n        if ONLY_PUBLIC:\n            # Step 1: Get Bounding Boxes\n            batch_cell_bboxes = pub_ss_df[pub_ss_df.ID.isin(submission_ids[i:(i+BATCH_SIZE)])].mask_bboxes.values\n            \n            # Step 2: Get RGB Images (which are actually just labelled as RGBY)\n            batch_rgb_images = batch_rgby_images\n            \n            # Step 3: Get Submission RLEs\n            submission_rles = pub_ss_df[pub_ss_df.ID.isin(submission_ids[i:(i+BATCH_SIZE)])].mask_sub_rles.values\n            \n            # Optional Step: Get the Masks\n            if IS_DEMO:\n                batch_masks = [\n                    sum([rle_to_mask(mask, size, size) for mask in batch]) \\\n                    for batch in pub_ss_df[pub_ss_df.ID.isin(submission_ids[i:(i+BATCH_SIZE)])].mask_rles.values\n                ]\n                \n            \n        else:\n            # Step 1: Do Prediction On Batch\n            cell_segmentations = segmentator.pred_cells([[rgby_image[j] for rgby_image in batch_rgby_images] for j in [0, 3, 2]])\n            nuc_segmentations = segmentator.pred_nuclei([rgby_image[2] for rgby_image in batch_rgby_images])\n\n            # Step 2: Perform Cell Labelling on Batch\n            batch_masks = [label_cell(nuc_seg, cell_seg)[1].astype(np.uint8) for nuc_seg, cell_seg in zip(nuc_segmentations, cell_segmentations)]\n\n            # Step 3: Reshape the RGBY Images so They Are Channels Last Across the Batch\n            batch_rgb_images = [rgby_image.transpose(1,2,0)[..., :-1] for rgby_image in batch_rgby_images]\n\n            # Step 4: Get Bounding Boxes For All Cells in All Images in Batch\n            batch_cell_bboxes = [get_contour_bbox_from_raw(mask) for mask in batch_masks]\n            \n            # Step 5: Generate Submission RLEs For the Batch\n            submission_rles = [[binary_mask_to_ascii(mask, mask_val=cell_id) for cell_id in range(1, mask.max()+1)] for mask in batch_masks]\n    \n        # Step 6: Cut Out, Pad to Square, and Resize to 224x224\n        batch_cell_tiles = [[\n            cv2.resize(\n                pad_to_square(\n                    rgb_image[bbox[1]:bbox[3], bbox[0]:bbox[2], ...]), \n                TILE_SIZE, interpolation=cv2.INTER_CUBIC) for bbox in bboxes] \n            for bboxes, rgb_image in zip(batch_cell_bboxes, batch_rgb_images)\n        ]\n\n        # Step 7: (OPTIONAL) Test Time Augmentation\n        if DO_TTA:\n            tta_batch_cell_tiles = [tta(tf.cast(ct, dtype=tf.float32), repeats=TTA_REPEATS) for ct in batch_cell_tiles]\n        else:\n            batch_cell_tiles = [tf.cast(ct, dtype=tf.float32) for ct in batch_cell_tiles]\n        \n        # Step 8: Perform Inference \n        if DO_TTA:\n            tta_batch_o_preds = [[inference_model.predict(ct) for ct in bct] for bct in tta_batch_cell_tiles]\n            batch_o_preds = [tf.keras.layers.Average()(tta_o_preds).numpy() for tta_o_preds in tta_batch_o_preds]\n        else:\n            batch_o_preds = [inference_model.predict(cell_tiles) for cell_tiles in batch_cell_tiles]\n            \n        # Step 9: Post-Process\n        batch_confs = [[pred[np.where(pred>CONF_THRESH)] for pred in o_preds] for o_preds in batch_o_preds]\n        batch_preds = [[np.where(pred>CONF_THRESH)[0] for pred in o_preds] for o_preds in batch_o_preds]\n\n        for j, preds in enumerate(batch_preds):\n            for k in range(len(preds)):\n                if preds[k].size==0:\n                    batch_preds[j][k]=np.array([18,])\n                    batch_confs[j][k]=np.array([1-np.max(batch_o_preds[j][k]),])\n        \n        # Optional Viz Step\n        if IS_DEMO:\n            print(\"\\n... DEMO IMAGES ...\\n\")\n            for rgb_images, masks, preds, confs in zip(batch_rgb_images, batch_masks, batch_preds, batch_confs):\n                plot_predictions(rgb_images, masks, preds, confs=confs, fill_alpha=0.2, lbl_as_str=True)\n\n        \n        # Step 10: Format Predictions To Create Prediction String Easily\n        submission_rles = [flatten_list_of_lists([[m,]*len(p) for m, p in zip(masks, preds)]) for masks, preds in zip(submission_rles, batch_preds)]\n        batch_preds = [flatten_list_of_lists(preds, to_string=True) for preds in batch_preds]\n        batch_confs = [[f\"{conf:.4f}\" for cell_confs in confs for conf in cell_confs] for confs in batch_confs]\n        \n        # Step 11: Save Predictions to Be Added to Dataframe At The End\n        predictions.extend([\" \".join(flatten_list_of_lists(zip(*[preds,confs,masks]))) for preds, confs, masks in zip(batch_preds, batch_confs, submission_rles)])\nsub_df[\"PredictionString\"] = predictions\n\nprint(\"\\n... TEST DATAFRAME ...\\n\")\ndisplay(sub_df.head(3))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 5 SUBMIT","metadata":{}},{"cell_type":"code","source":"ss_df = ss_df.merge(sub_df, how=\"left\", on=\"ID\")\nss_df[\"PredictionString\"] = ss_df.apply(create_pred_col, axis=1)\nss_df = ss_df.drop(columns=[\"PredictionString_x\", \"PredictionString_y\"])\n#ss_df.to_csv(\"/kaggle/working/submission.csv\", index=False)\ndisplay(ss_df)\n\ntorch.cuda.empty_cache()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 6 BLENDING","metadata":{}},{"cell_type":"code","source":"def auto_select_accelerator():\n    try:\n        tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n        tf.config.experimental_connect_to_cluster(tpu)\n        tf.tpu.experimental.initialize_tpu_system(tpu)\n        strategy = tf.distribute.experimental.TPUStrategy(tpu)\n        print(\"Running on TPU:\", tpu.master())\n    except ValueError:\n        strategy = tf.distribute.get_strategy()\n    print(f\"Running on {strategy.num_replicas_in_sync} replicas\")\n\n    return strategy\n\n\ndef build_decoder(with_labels=True, target_size=(300, 300), ext='jpg'):\n    \n    def decode(path):\n        file_bytes = tf.io.read_file(path)\n        if ext == 'png':\n            img = tf.image.decode_png(file_bytes, channels=3)\n        elif ext in ['jpg', 'jpeg']:\n            img = tf.image.decode_jpeg(file_bytes, channels=3)\n        else:\n            raise ValueError(\"Image extension not supported\")\n        img = tf.cast(img, tf.float32) / 255.0\n        img = tf.image.resize(img, target_size)\n        return img\n    \n    def decode_with_labels(path, label):\n        return decode(path), label\n\n    return decode_with_labels if with_labels else decode\n\n\ndef build_augmenter(with_labels=True):\n    \n    def augment(img):\n        img = tf.image.random_flip_left_right(img)\n        img = tf.image.random_flip_up_down(img)\n        return img\n    \n    def augment_with_labels(img, label):\n        return augment(img), label\n    \n    return augment_with_labels if with_labels else augment\n\n\ndef build_dataset(paths, labels=None, bsize=32, cache=True,\n                  decode_fn=None, augment_fn=None,\n                  augment=True, repeat=True, shuffle=1024, \n                  cache_dir=\"\"):\n    if cache_dir != \"\" and cache is True:\n        os.makedirs(cache_dir, exist_ok=True)\n    if decode_fn is None:\n        decode_fn = build_decoder(labels is not None)\n    if augment_fn is None:\n        augment_fn = build_augmenter(labels is not None)\n\n    AUTO = tf.data.experimental.AUTOTUNE\n    slices = paths if labels is None else (paths, labels)\n\n    dset = tf.data.Dataset.from_tensor_slices(slices)\n    dset = dset.map(decode_fn, num_parallel_calls=AUTO)\n    dset = dset.cache(cache_dir) if cache else dset\n    dset = dset.map(augment_fn, num_parallel_calls=AUTO) if augment else dset\n    dset = dset.repeat() if repeat else dset\n    dset = dset.shuffle(shuffle) if shuffle else dset\n    dset = dset.batch(bsize).prefetch(AUTO)\n\n    return dset","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"HPA_MODELS = False\nCOMPETITION_NAME = \"hpa-single-cell-image-classification\"\nstrategy = auto_select_accelerator()\nBATCH_SIZE = strategy.num_replicas_in_sync * 16\n\nIMSIZE = (224, 240, 260, 300, 380, 456, 528, 600, 720)\n\nload_dir = f\"/kaggle/input/{COMPETITION_NAME}/\"\nsub_df = pd.read_csv('../input/hpa-single-cell-image-classification/sample_submission.csv')\nsub_df = sub_df.drop(sub_df.columns[1:],axis=1)\nfor i in range(19):\n    sub_df[f'{i}'] = pd.Series(np.zeros(sub_df.shape[0]))\n\nif HPA_MODELS:\n    colours = ['blue', 'green', 'red', 'yellow']\n    sub_dfs = []\n    for colour in colours:\n        test_paths = load_dir + \"/test/\" + sub_df['ID'] + '_' + colour + '.png' # Start making individul label\n        label_cols = sub_df.columns[1:] # Get the multi-labels\n\n        test_decoder = build_decoder(with_labels=False, target_size=(IMSIZE[-1], IMSIZE[-1]))\n        dtest = build_dataset(\n            test_paths, bsize=BATCH_SIZE, repeat=False, \n            shuffle=False, augment=False, cache=False,\n            decode_fn=test_decoder\n        )\n\n        with strategy.scope():\n            model = tf.keras.models.load_model(\n                f'../input/hpa-models/effb7_individual_model_{colour}.h5'\n            )\n\n        model.summary()\n        sub_df[label_cols] = model.predict(dtest, verbose=1)\n        sub_dfs.append(sub_df)\n\n        # if colour == 'green':\n        # sub_df = pd.concat((sub_df.ID, (sub_dfs[0].iloc[:, 1:] + sub_dfs[1].iloc[:, 1:])/2), axis=1)\n        # break\n\n        if colour == 'yellow':\n            sub_df = pd.concat((sub_df.ID, (\n            sub_dfs[0].iloc[:, 1:] + sub_dfs[1].iloc[:, 1:] + sub_dfs[2].iloc[:, 1:] + sub_dfs[3].iloc[:, 1:]\n            )/4), axis=1)\nelse:\n    test_paths = load_dir + \"/test/\" + sub_df['ID'] + '_' + 'green' + '.png' # Start making individul label\n    label_cols = sub_df.columns[1:] # Get the multi-labels\n\n    test_decoder = build_decoder(with_labels=False, target_size=(IMSIZE[-1], IMSIZE[-1]))\n    dtest = build_dataset(\n        test_paths, bsize=BATCH_SIZE, repeat=False, \n        shuffle=False, augment=False, cache=False,\n        decode_fn=test_decoder\n    )\n\n    with strategy.scope():\n        model = tf.keras.models.load_model('../input/hpa-models/HPA classification efnb7 train 13cc0d 20/model_green.h5')\n\n    model.summary()\n    sub_df[label_cols] = model.predict(dtest, verbose=1)\n\nss_df = pd.merge(ss_df, sub_df, on = 'ID', how = 'left')\n\nfor row in range(ss_df.shape[0]):\n    pred = ss_df.loc[row,'PredictionString']\n    pred_split = pred.split()\n    for j in range(int(len(pred_split)/3)):        \n        for k in range(19):\n            if int(pred_split[ 3*j ]) == k:\n                p = pred_split[ 3*j + 1 ]               \n                pred_split[ 3*j + 1 ] = str( ss_df.loc[row, f'{k}']*0.6 + float(p)*0.4 )\n    ss_df.loc[row,'PredictionString'] = ' '.join(pred_split)\n\nss_df = ss_df[['ID','ImageWidth','ImageHeight','PredictionString']]\nss_df.to_csv('submission.csv',index = False)\n\nprint(f'HPA_MODELS = {HPA_MODELS}')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ss_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}