{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport cv2\nimport zlib\nimport base64\nimport argparse\nimport numpy as np\nimport pandas as pd\nimport torch  # 1.7.0\nimport torchvision.transforms as transforms\nfrom collections import OrderedDict\n\nos.chdir('/kaggle/input')\nos.getcwd()\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\nfrom hpacellseg import cellsegmentator\nfrom hpacellseg.utils import label_cell\nfrom pycocotools import _mask as coco_mask","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class HPA_test(torch.utils.data.Dataset):\n    ''' Dateset class for PyTorch dataloader.\n\n    '''\n    def __init__(self, root, name, cells, transform):\n        super(HPA_test, self).__init__()\n        self.root = root\n        self.name = name\n        self.cell_list = cells\n        self.transform = transform\n        channel_list = ['blue', 'green', 'red', 'yellow']\n        channels = [cv2.imread(os.path.join(root, 'test', f'{name}_{ch}.png'), cv2.IMREAD_UNCHANGED) for ch in channel_list]\n        self.image = np.stack(channels, axis=-1)\n\n    def __getitem__(self, index):\n        # Get patch.\n        encoded_mask, min_h, max_h, min_w, max_w = self.cell_list[index]\n        sub_mask = coco_mask.decode(encoded_mask).astype(np.uint16)\n        patch = (self.image * sub_mask)[min_h: max_h, min_w: max_w]\n        patch = (patch / 65536).astype(np.float32)\n\n        h, w = patch.shape[:2]\n        delta = int(abs(h-w)/2)\n        _pad_list = ((0,0),(delta, delta),(0,0)) if h > w else ((delta, delta),(0,0),(0,0))\n        patch = np.pad(patch, _pad_list, constant_values=0)\n        patch=cv2.resize(patch,(256,256))\n        # Get mask string.\n        rle_str = encoded_mask[0]['counts']\n        binary_str = zlib.compress(rle_str, zlib.Z_BEST_COMPRESSION)\n        mask_str = base64.b64encode(binary_str).decode()\n\n#         if self.transform is not None:\n#             patch = self.transform(patch)\n        patch = np.array(patch, np.float32).transpose(2, 0, 1)\n        return patch, mask_str\n\n    def __len__(self):\n        return len(self.cell_list)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class HPA_image_test(torch.utils.data.Dataset):\n    ''' Dateset class for PyTorch dataloader.\n\n    '''\n\n    def __init__(self, root, names, transform):\n        super(HPA_image_test, self).__init__()\n        self.root = root\n        self.name_list = names\n        self.transform = transform\n\n    def __getitem__(self, index):\n        # Load channels.\n        name = self.name_list[index]\n        channel_list = ['blue', 'green', 'red', 'yellow']\n        channels = [cv2.imread(os.path.join(self.root, 'test', f'{name}_{ch}.png'), cv2.IMREAD_UNCHANGED) for ch in\n                    channel_list]\n\n        # Get image.\n        image = np.stack(channels, axis=-1)\n        max_value = 256 ** ((image.dtype == np.uint16) + 1) - 1\n        image = (image / max_value).astype(np.float32)\n\n        if self.transform is not None:\n            image = self.transform(image)\n        return image, name\n\n    def __len__(self):\n        return len(self.name_list)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def cell_segmentation(df, data_dir, model_dir, save_dir):\n    ''' Cell segmentation for HPA dataset.\n\n    # Arguments\n        data_dir  (str): Directory to load data.\n        save_dir  (str): Directory to save cell-level masks.\n        model_dir (str): Directory to load models.\n        df  (DataFrame): Sameple Submission.\n    '''\n    # Load segmentation model.\n    nuclei_model = os.path.join(model_dir, 'nuclei-model.pth')\n    cell_model = os.path.join(model_dir, 'cell-model.pth')\n    segmentator = cellsegmentator.CellSegmentator(\n        nuclei_model,\n        cell_model,\n        scale_factor=0.25,\n        device='cuda',\n        padding=True,\n        multi_channel_model=True,\n    )\n\n    # Load data list.\n    image_list = list(df['ID'])\n    cell_level_masks = {}\n\n    # Set batch size.\n    batch_size = 24\n\n    for index in range(0, len(image_list), batch_size):\n        # Initialize data path.\n        sub_image_list = image_list[index: index + batch_size]\n        mt = [os.path.join(data_dir, 'test', f'{img}_red.png') for img in sub_image_list]\n        er = [img.replace('red', 'yellow') for img in mt]\n        nu = [img.replace('red', 'blue') for img in mt]\n\n        # Model inference.\n        nuclei_segmentations = segmentator.pred_nuclei(nu)\n        cell_segmentations = segmentator.pred_cells([mt, er, nu])\n\n        for i, name in enumerate(sub_image_list):\n            # Label cells.\n            _, cell_mask = label_cell(nuclei_segmentations[i], cell_segmentations[i])\n\n            # Save cell masks.\n            cell_level_masks[name] = []\n            for c in range(cell_mask.max()):\n                # Get cell region.\n                sub_mask = (cell_mask == (c + 1))\n                h_pos, w_pos = np.where(sub_mask)\n                min_h, max_h = h_pos.min(), h_pos.max()\n                min_w, max_w = w_pos.min(), w_pos.max()\n\n                # Encode mask.\n                encoded_mask = coco_mask.encode(np.asfortranarray(np.expand_dims(sub_mask, axis=-1)))\n                cell_level_masks[name].append([encoded_mask, min_h, max_h, min_w, max_w])\n\n        # Display progress.\n        total = (len(image_list) - 1) // batch_size + 1\n        print(' Progress: %5d / %5d\\r' % (index // batch_size + 1, total), end='')\n\n    # Save results.\n    torch.save(cell_level_masks, os.path.join(save_dir, 'test_cell_masks.t7'))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def image_classification(df, data_dir, save_dir):\n\n    model = EfficientNet.from_name('efficientnet-b7', num_classes=18)\n    model._change_in_channels(4)\n    model = My_EModel(model, num_classes=18).cuda()\n    model = torch.nn.DataParallel(model)\n\n    # Load model weights.\n\n    model.load_state_dict(torch.load(os.path.join('xxx.pth'))))\n\n    model.eval()\n    model = tta.ClassificationTTAWrapper(model, tta.aliases.d4_transform(), merge_mode='mean')\n\n    # Define transforms for dataset.\n    input_size = EfficientNet.get_image_size('efficientnet-b7')\n    test_transform = transforms.Compose([\n        transforms.ToTensor(),\n        transforms.Resize((input_size, input_size)),\n    ])\n\n    name_list = list(df['ID'])\n    test_set = HPA_image_test(data_dir, name_list, test_transform)\n    test_loader = torch.utils.data.DataLoader(\n        test_set,\n        batch_size=16,\n        shuffle=False,\n        pin_memory=True,\n        num_workers=4,\n    )\n\n    # Model inference.\n    image_level_pred = {}\n    with torch.no_grad():\n        for batch_idx, (inputs, names) in enumerate(test_loader):\n            # Forward propagation.\n            inputs = inputs.cuda()\n            outputs = model(inputs)\n            predicts = outputs.sigmoid()\n\n            # Record predictions.\n            for predict, name in zip(predicts, names):\n                predict = predict.cpu().numpy()\n                predict = np.append(predict, 1 - predict.max())\n                image_level_pred[name] = predict\n                # image_level_pred[name] = predict\n\n            # Display progress.\n            print(' Progress: %5d / %5d\\r' % (batch_idx + 1, len(test_loader)), end='')\n    torch.save(image_level_pred, os.path.join(save_dir, 'xxx.t7'))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def cell_classification(df, data_dir, model_dir, save_dir):\n    ''' Cell classification for HPA dataset.\n\n    # Arguments\n        data_dir  (str): Directory to load data.\n        save_dir  (str): Directory to save submission file.\n        model_dir (str): Directory to load models.\n        df  (DataFrame): Sameple Submission.\n    '''\n    # Initialize classification model.\n    model = Net(num_class=18)\n    \n    model = torch.nn.DataParallel(model)\n    model=model.cuda()\n\n    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n    # Load model weights.\n    checkpoint = torch.load(r'/kaggle/input/cell-image-18-fold0/checkpoint_HPA_014_0.67812.t7')['model']\n\n#     new_state_dict = OrderedDict()\n#     for k,v in checkpoint.items():\n#         name = k[7:]\n#         new_state_dict[name] = v\n\n    model.load_state_dict(checkpoint,strict=True)\n#     model.to(device)\n    model.eval()\n\n    # Define transforms for dataset.\n#     input_size = EfficientNet.get_image_size('efficientnet-b3')\n    test_transform = transforms.Compose([\n        transforms.ToTensor(),\n        transforms.Resize((256, 256)), \n        # transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n    ])\n\n    # Load cell-level masks.\n    cell_level_masks = torch.load(os.path.join(save_dir, 'test_cell_masks.t7'),map_location=device)\n\n    with torch.no_grad():\n        for index, row in df.iterrows():\n            # Load cells.\n            name = row.ID\n            test_set = HPA_test(data_dir, name, cell_level_masks[name], test_transform)\n            test_loader = torch.utils.data.DataLoader(\n                test_set, \n                batch_size=128,\n                shuffle=False,\n                pin_memory=True,\n                num_workers=16,\n            )\n\n            # Model inference.\n            pred_str = []\n            for batch_idx, (inputs, masks) in enumerate(test_loader):\n                # Forward propagation.\n                inputs = inputs.to(device)\n                #pred_tmp = []\n                #for ckpt in os.listdir(model_dir):\n                #    checkpoint = torch.load(os.path.join(model_dir, ckpt),map_location=device)\n                #    model.load_state_dict(checkpoint['model'])\n                #    model = model.to(device)\n                #    model.eval()\n                #    outputs = model(inputs)\n                #    pred_tmp.append(outputs.sigmoid())\n\n                #predicts = torch.mean(torch.stack(pred_tmp, axis=1), axis=1)\n                #predicts = torch.max(torch.stack(pred_tmp, axis=1), axis=1)[0]\n                outputs = model(inputs)\n                predicts = outputs.sigmoid()\n\n                # Record predictions.\n                for predict, mask in zip(predicts, masks):\n                    predict = predict.tolist()\n                    predict.append(1 - max(predict))\n                    #pdp = pd.Series(predict)\n                    #for c, score in pdp.nlargest(4).items():\n                    for c, score in enumerate(predict):\n                        pred_str.append(f' {c} {score} {mask}')\n            df.loc[index, 'PredictionString'] = ' '.join(pred_str)\n            print(' Progress: %5d / %5d\\r' % (index + 1, len(df)), end='')\n\n    # Save submission file.\n    df.to_csv(os.path.join(save_dir, 'submission.csv'), index=False)\n    print(df)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_dir = '/kaggle/input/hpa-single-cell-image-classification/'\nseg_dir  = '/kaggle/input/segmodel'\ncls_dir  = '/kaggle/input/hpamodelseb4focal/'\nsave_dir = '/kaggle/working/'\n\ndf = pd.read_csv(os.path.join(data_dir, 'sample_submission.csv'))\nif len(df) == 559:\n    df = df[:4]\ncell_segmentation(df, data_dir, seg_dir, save_dir)\nimage_classification(df, data_dir, cls_dir, save_dir)\nprint('ssue')\ncell_classification(df, data_dir, cls_dir, save_dir)","metadata":{},"execution_count":null,"outputs":[]}]}