{"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":"This is my first time participating in a segmentation task competition.\nPlease point out any problems with my code in the comments, as I want to make my code better.\nAlso, please feel free to ask me any questions you may have.\n\n\nMy code is to divide a 65 channel image into several 512*512 blocks and infer block by block.\nI don't want to train on blocks that have all 0 mask values.","metadata":{}},{"cell_type":"code","source":"import socket\nimport sys\n\n\nis_train = _dh != [\"/kaggle/working\"]\n\n\nNB = \"exp0006\"\nHOST = \"54a2c6eb5b61\"\n\n\nNB, HOST","metadata":{"papermill":{"duration":0.112207,"end_time":"2021-09-27T02:54:59.505937","exception":false,"start_time":"2021-09-27T02:54:59.393730","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:02.743822Z","iopub.execute_input":"2023-03-19T04:52:02.744830Z","iopub.status.idle":"2023-03-19T04:52:02.770732Z","shell.execute_reply.started":"2023-03-19T04:52:02.744792Z","shell.execute_reply":"2023-03-19T04:52:02.769613Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!nvidia-smi","metadata":{"papermill":{"duration":0.021702,"end_time":"2021-09-27T02:54:59.551604","exception":false,"start_time":"2021-09-27T02:54:59.529902","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:02.773132Z","iopub.execute_input":"2023-03-19T04:52:02.773836Z","iopub.status.idle":"2023-03-19T04:52:03.773584Z","shell.execute_reply.started":"2023-03-19T04:52:02.773799Z","shell.execute_reply":"2023-03-19T04:52:03.772285Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nimport gc\nimport glob\nimport math\nimport os\nimport pickle\nimport random\nimport shutil\nimport warnings\nfrom collections import OrderedDict\nfrom pathlib import Path\n\nimport albumentations as albu\nimport cv2\nimport matplotlib.pyplot as plt\n\n# import mlflow\nimport numpy as np\nimport pandas as pd\nimport timm\nimport torch\nimport torch.optim as optim\n#from logzero import logger\nfrom sklearn.metrics import accuracy_score, f1_score, mean_squared_error, roc_auc_score\nfrom sklearn.model_selection import KFold, StratifiedGroupKFold, StratifiedKFold\nfrom torch import nn\nfrom torch.utils.data import DataLoader, Dataset\nfrom tqdm import tqdm\n\nwarnings.simplefilter(\"ignore\")\n\nif is_train:\n    ROOT_DIR = Path(\"../\")\n    DATA_DIR = ROOT_DIR / \"data\"\n    OUTPUT_DIR = ROOT_DIR / \"output\"\n    CP_DIR = OUTPUT_DIR\nelse:\n    ROOT_DIR = Path(\"../\")\n    DATA_DIR = Path(\"/kaggle/input/vesuvius-challenge-ink-detection\")\n    OUTPUT_DIR = Path(\"./\")\n    CP_DIR = Path(\"/kaggle/input/ink-model/\")\n\n\ndef to_pickle(filename, obj):\n    with open(filename, mode=\"wb\") as f:\n        pickle.dump(obj, f)\n\n\ndef unpickle(filename):\n    with open(filename, mode=\"rb\") as fo:\n        p = pickle.load(fo)\n    return p","metadata":{"papermill":{"duration":6.891314,"end_time":"2021-09-27T02:55:06.464626","exception":false,"start_time":"2021-09-27T02:54:59.573312","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:03.777117Z","iopub.execute_input":"2023-03-19T04:52:03.777442Z","iopub.status.idle":"2023-03-19T04:52:08.103583Z","shell.execute_reply.started":"2023-03-19T04:52:03.777408Z","shell.execute_reply":"2023-03-19T04:52:08.102402Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"papermill":{"duration":0.030687,"end_time":"2021-09-27T02:55:06.518944","exception":false,"start_time":"2021-09-27T02:55:06.488257","status":"completed"},"tags":[]},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"papermill":{"duration":0.029823,"end_time":"2021-09-27T02:55:06.571004","exception":false,"start_time":"2021-09-27T02:55:06.541181","status":"completed"},"tags":[]},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import multiprocessing\n\nprint(\"cpu count:\", multiprocessing.cpu_count())\n\n\nclass Config:\n    N_FOLD = 5\n    RANDOM_SATE = 42\n    LR = 1.0e-05\n    MAX_LR = 1.0e-5\n    PATIENCE = 15\n    EPOCH = 8\n    BATCH_SIZE = 8\n    IMG_SIZE = 512\n    NUM_WORKERS = multiprocessing.cpu_count()\n\n\ndef seed_everything(seed=1234):\n    random.seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n\n\nseed_everything(seed=Config.RANDOM_SATE)","metadata":{"papermill":{"duration":0.038449,"end_time":"2021-09-27T02:55:06.632933","exception":false,"start_time":"2021-09-27T02:55:06.594484","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:08.108059Z","iopub.execute_input":"2023-03-19T04:52:08.108356Z","iopub.status.idle":"2023-03-19T04:52:08.121854Z","shell.execute_reply.started":"2023-03-19T04:52:08.108324Z","shell.execute_reply":"2023-03-19T04:52:08.120809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"glob.glob(str(DATA_DIR / \"*\"))","metadata":{"papermill":{"duration":0.030289,"end_time":"2021-09-27T02:55:06.780933","exception":false,"start_time":"2021-09-27T02:55:06.750644","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:08.123180Z","iopub.execute_input":"2023-03-19T04:52:08.123617Z","iopub.status.idle":"2023-03-19T04:52:08.133992Z","shell.execute_reply.started":"2023-03-19T04:52:08.123578Z","shell.execute_reply":"2023-03-19T04:52:08.132587Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle(img, thr=0.5):\n    flat_img = img.flatten()\n    flat_img = np.where(flat_img > thr, 1, 0).astype(np.uint8)\n\n    starts = np.array((flat_img[:-1] == 0) & (flat_img[1:] == 1))\n    ends = np.array((flat_img[:-1] == 1) & (flat_img[1:] == 0))\n    starts_ix = np.where(starts)[0] + 2\n    ends_ix = np.where(ends)[0] + 2\n    lengths = ends_ix - starts_ix\n\n    return starts_ix, lengths\n\n\ndef concat_tile(im_list_2d):\n    return cv2.vconcat([cv2.hconcat(im_list_h) for im_list_h in im_list_2d])","metadata":{"execution":{"iopub.status.busy":"2023-03-19T04:52:08.135889Z","iopub.execute_input":"2023-03-19T04:52:08.136256Z","iopub.status.idle":"2023-03-19T04:52:08.143386Z","shell.execute_reply.started":"2023-03-19T04:52:08.136219Z","shell.execute_reply":"2023-03-19T04:52:08.142214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load Data","metadata":{}},{"cell_type":"code","source":"if is_train:\n\n    img1 = []\n    for i in tqdm(range(65)):\n        img1.append(cv2.imread(str(DATA_DIR / f\"train/1/surface_volume/{i:02}.tif\"), 0))\n\n    img2 = []\n    for i in tqdm(range(65)):\n        img2.append(cv2.imread(str(DATA_DIR / f\"train/2/surface_volume/{i:02}.tif\"), 0))\n\n    img3 = []\n    for i in tqdm(range(65)):\n        img3.append(cv2.imread(str(DATA_DIR / f\"train/3/surface_volume/{i:02}.tif\"), 0))\n\n    img1 = np.stack(img1)\n    img2 = np.stack(img2)\n    img3 = np.stack(img3)\n\n    img1_label = cv2.imread(str(DATA_DIR / f\"train/1/inklabels.png\"), 0)\n    img2_label = cv2.imread(str(DATA_DIR / f\"train/2/inklabels.png\"), 0)\n    img3_label = cv2.imread(str(DATA_DIR / f\"train/3/inklabels.png\"), 0)\n\n    img1_mask = cv2.imread(str(DATA_DIR / f\"train/1/mask.png\"), 0)\n    img2_mask = cv2.imread(str(DATA_DIR / f\"train/2/mask.png\"), 0)\n    img3_mask = cv2.imread(str(DATA_DIR / f\"train/3/mask.png\"), 0)","metadata":{"execution":{"iopub.status.busy":"2023-03-19T04:52:08.145134Z","iopub.execute_input":"2023-03-19T04:52:08.145597Z","iopub.status.idle":"2023-03-19T04:52:08.156679Z","shell.execute_reply.started":"2023-03-19T04:52:08.145561Z","shell.execute_reply":"2023-03-19T04:52:08.155653Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train","metadata":{}},{"cell_type":"code","source":"def get_augmentation():\n    train_transform = [\n        albu.HorizontalFlip(p=0.5),\n        albu.VerticalFlip(p=0.5),\n        albu.Resize(height=Config.IMG_SIZE, width=Config.IMG_SIZE),\n        albu.Normalize(mean=[0], std=[1]),\n    ]\n    return albu.Compose(train_transform)\n\n\ndef get_test_augmentation():\n    train_transform = [\n        albu.Resize(height=Config.IMG_SIZE, width=Config.IMG_SIZE),\n        albu.Normalize(mean=[0], std=[1]),\n    ]\n    return albu.Compose(train_transform)","metadata":{"papermill":{"duration":0.033222,"end_time":"2021-09-27T02:55:08.979344","exception":false,"start_time":"2021-09-27T02:55:08.946122","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:08.158396Z","iopub.execute_input":"2023-03-19T04:52:08.159095Z","iopub.status.idle":"2023-03-19T04:52:08.166229Z","shell.execute_reply.started":"2023-03-19T04:52:08.159059Z","shell.execute_reply":"2023-03-19T04:52:08.165307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CVDataSet(Dataset):\n    def __init__(self, imgs, transforms, labels=None, data_type=None, crop_size=256):\n        self.crop_size = crop_size\n        self.imgs = imgs\n        self.transforms = transforms\n        self.labels = labels\n        self.data_type = data_type\n\n        self.cell_counts = []\n        for img in self.imgs:\n            cell_count = math.ceil(img.shape[1] / self.crop_size) * math.ceil(\n                img.shape[2] / self.crop_size\n            )\n            self.cell_counts.append(cell_count)\n\n    def __len__(self):\n        data_count = 0\n        if self.data_type == \"train\":\n\n            self.cell_id_maps = {}\n\n            counter = 0\n            for img_num, img in enumerate(self.imgs):\n\n                cell_count = math.ceil(img.shape[1] / self.crop_size) * math.ceil(\n                    img.shape[2] / self.crop_size\n                )\n                for cell_id in range(cell_count):\n                    h_num = cell_id // math.ceil(\n                        self.labels[img_num].shape[1] / self.crop_size\n                    )\n                    w_num = cell_id - (\n                        h_num\n                        * math.ceil(self.labels[img_num].shape[1] / self.crop_size)\n                    )\n\n                    cropped_img = self.labels[img_num][\n                        h_num * self.crop_size : h_num * self.crop_size\n                        + self.crop_size,\n                        w_num * self.crop_size : w_num * self.crop_size\n                        + self.crop_size,\n                    ]\n\n                    if cropped_img.sum() == 0:\n                        continue\n\n                    data_count += 1\n\n                    self.cell_id_maps[counter] = (img_num, cell_id)\n                    counter += 1\n\n        else:\n\n            for img in self.imgs:\n                data_count += math.ceil(img.shape[1] / self.crop_size) * math.ceil(\n                    img.shape[2] / self.crop_size\n                )\n        return data_count\n\n    def calc_img_num(self, idx):\n        cum_cell_count = 0\n        for i, cell_count in enumerate(self.cell_counts):\n            cum_cell_count += cell_count\n            if idx + 1 <= cum_cell_count:\n                return i, idx - (cum_cell_count - cell_count)\n\n    def __getitem__(self, idx):\n        if self.data_type == \"train\":\n            img_num, cell_id = self.cell_id_maps[idx]\n        else:\n            img_num, cell_id = self.calc_img_num(idx)\n\n        target_img = self.imgs[img_num]\n        if self.data_type != \"test\":\n            target_label = self.labels[img_num]\n\n        # print(target_label.shape)\n        target_img = np.moveaxis(target_img, 0, 2)\n        # target_label = np.moveaxis(target_label, 0, 2)\n\n        h_num = cell_id // math.ceil(target_img.shape[1] / self.crop_size)\n        w_num = cell_id - (h_num * math.ceil(target_img.shape[1] / self.crop_size))\n\n        cropped_img = target_img[\n            h_num * self.crop_size : h_num * self.crop_size + self.crop_size,\n            w_num * self.crop_size : w_num * self.crop_size + self.crop_size,\n        ]\n\n        if self.data_type in [\"train\", \"valid\"]:\n            cropped_label = target_label[\n                h_num * self.crop_size : h_num * self.crop_size + self.crop_size,\n                w_num * self.crop_size : w_num * self.crop_size + self.crop_size,\n            ]\n            augmented = self.transforms(image=cropped_img, mask=cropped_label)\n            img = augmented[\"image\"]\n            img = np.moveaxis(img, 2, 0)\n            mask = augmented[\"mask\"]\n        else:\n            augmented = self.transforms(image=cropped_img)\n            img = augmented[\"image\"]\n            img = np.moveaxis(img, 2, 0)\n            mask = -1\n\n        return img, mask / 255","metadata":{"papermill":{"duration":0.035303,"end_time":"2021-09-27T02:55:09.041468","exception":false,"start_time":"2021-09-27T02:55:09.006165","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:08.170454Z","iopub.execute_input":"2023-03-19T04:52:08.170759Z","iopub.status.idle":"2023-03-19T04:52:08.188930Z","shell.execute_reply.started":"2023-03-19T04:52:08.170727Z","shell.execute_reply":"2023-03-19T04:52:08.187771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CVNet(nn.Module):\n    def __init__(self, num_classes):\n        super(CVNet, self).__init__()\n        self.num_classes = num_classes\n        self.contracting_11 = self.conv_block(in_channels=65, out_channels=64)\n        self.contracting_12 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.contracting_21 = self.conv_block(in_channels=64, out_channels=128)\n        self.contracting_22 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.contracting_31 = self.conv_block(in_channels=128, out_channels=256)\n        self.contracting_32 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.contracting_41 = self.conv_block(in_channels=256, out_channels=512)\n        self.contracting_42 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.middle = self.conv_block(in_channels=512, out_channels=1024)\n        self.expansive_11 = nn.ConvTranspose2d(\n            in_channels=1024,\n            out_channels=512,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            output_padding=1,\n        )\n        self.expansive_12 = self.conv_block(in_channels=1024, out_channels=512)\n        self.expansive_21 = nn.ConvTranspose2d(\n            in_channels=512,\n            out_channels=256,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            output_padding=1,\n        )\n        self.expansive_22 = self.conv_block(in_channels=512, out_channels=256)\n        self.expansive_31 = nn.ConvTranspose2d(\n            in_channels=256,\n            out_channels=128,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            output_padding=1,\n        )\n        self.expansive_32 = self.conv_block(in_channels=256, out_channels=128)\n        self.expansive_41 = nn.ConvTranspose2d(\n            in_channels=128,\n            out_channels=64,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            output_padding=1,\n        )\n        self.expansive_42 = self.conv_block(in_channels=128, out_channels=64)\n        self.output = nn.Conv2d(\n            in_channels=64, out_channels=num_classes, kernel_size=3, stride=1, padding=1\n        )\n\n    def conv_block(self, in_channels, out_channels):\n        block = nn.Sequential(\n            nn.Conv2d(\n                in_channels=in_channels,\n                out_channels=out_channels,\n                kernel_size=3,\n                stride=1,\n                padding=1,\n            ),\n            nn.ReLU(),\n            nn.BatchNorm2d(num_features=out_channels),\n            nn.Conv2d(\n                in_channels=out_channels,\n                out_channels=out_channels,\n                kernel_size=3,\n                stride=1,\n                padding=1,\n            ),\n            nn.ReLU(),\n            nn.BatchNorm2d(num_features=out_channels),\n        )\n        return block\n\n    def forward(self, X):\n        contracting_11_out = self.contracting_11(X)  # [-1, 64, 256, 256]\n        contracting_12_out = self.contracting_12(\n            contracting_11_out\n        )  # [-1, 64, 128, 128]\n        contracting_21_out = self.contracting_21(\n            contracting_12_out\n        )  # [-1, 128, 128, 128]\n        contracting_22_out = self.contracting_22(\n            contracting_21_out\n        )  # [-1, 128, 64, 64]\n        contracting_31_out = self.contracting_31(\n            contracting_22_out\n        )  # [-1, 256, 64, 64]\n        contracting_32_out = self.contracting_32(\n            contracting_31_out\n        )  # [-1, 256, 32, 32]\n        contracting_41_out = self.contracting_41(\n            contracting_32_out\n        )  # [-1, 512, 32, 32]\n        contracting_42_out = self.contracting_42(\n            contracting_41_out\n        )  # [-1, 512, 16, 16]\n        middle_out = self.middle(contracting_42_out)  # [-1, 1024, 16, 16]\n        expansive_11_out = self.expansive_11(middle_out)  # [-1, 512, 32, 32]\n        expansive_12_out = self.expansive_12(\n            torch.cat((expansive_11_out, contracting_41_out), dim=1)\n        )  # [-1, 1024, 32, 32] -> [-1, 512, 32, 32]\n        expansive_21_out = self.expansive_21(expansive_12_out)  # [-1, 256, 64, 64]\n        expansive_22_out = self.expansive_22(\n            torch.cat((expansive_21_out, contracting_31_out), dim=1)\n        )  # [-1, 512, 64, 64] -> [-1, 256, 64, 64]\n        expansive_31_out = self.expansive_31(expansive_22_out)  # [-1, 128, 128, 128]\n        expansive_32_out = self.expansive_32(\n            torch.cat((expansive_31_out, contracting_21_out), dim=1)\n        )  # [-1, 256, 128, 128] -> [-1, 128, 128, 128]\n        expansive_41_out = self.expansive_41(expansive_32_out)  # [-1, 64, 256, 256]\n        expansive_42_out = self.expansive_42(\n            torch.cat((expansive_41_out, contracting_11_out), dim=1)\n        )  # [-1, 128, 256, 256] -> [-1, 64, 256, 256]\n        output_out = self.output(expansive_42_out)  # [-1, num_classes, 256, 256]\n        return output_out","metadata":{"papermill":{"duration":0.034874,"end_time":"2021-09-27T02:55:09.102696","exception":false,"start_time":"2021-09-27T02:55:09.067822","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:08.190432Z","iopub.execute_input":"2023-03-19T04:52:08.191122Z","iopub.status.idle":"2023-03-19T04:52:08.209985Z","shell.execute_reply.started":"2023-03-19T04:52:08.191087Z","shell.execute_reply":"2023-03-19T04:52:08.208905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class EarlyStopping:\n    def __init__(self, patience=7, verbose=False, delta=0, fold=\"\"):\n        self.patience = patience\n        self.verbose = verbose\n        self.counter = 0\n        self.best_score = None\n        self.early_stop = False\n        self.val_loss_min = np.Inf\n        self.delta = delta\n\n    def __call__(self, val_loss, model):\n\n        score = -val_loss\n\n        if self.best_score is None:\n            self.best_score = score\n            self.save_checkpoint(val_loss, model)\n        elif score < self.best_score + self.delta:\n            self.counter += 1\n            logger.info(f\"EarlyStopping counter: {self.counter} out of {self.patience}\")\n            if self.counter >= self.patience:\n                self.early_stop = True\n        else:\n            self.best_score = score\n            self.save_checkpoint(val_loss, model)\n            self.counter = 0\n\n    def save_checkpoint(self, val_loss, model):\n        \"\"\"Saves model when validation loss decrease.\"\"\"\n        if self.verbose:\n            logger.info(\n                f\"Validation loss decreased ({self.val_loss_min:.6f} --> {val_loss:.6f}).  Saving model ...\"\n            )\n\n        # if os.path.exists(CP_DIR / f'checkpoint_{NB}_{fold}.pt'):\n        #    shutil.move(CP_DIR / f'checkpoint_{NB}_{fold}.pt', CP_DIR / f'checkpoint_{NB}_{fold}-2.pt')\n        torch.save(model.state_dict(), CP_DIR / f\"{HOST}_{NB}_checkpoint_{fold}.pt\")\n        self.val_loss_min = val_loss","metadata":{"papermill":{"duration":0.03708,"end_time":"2021-09-27T02:55:09.166253","exception":false,"start_time":"2021-09-27T02:55:09.129173","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:08.211686Z","iopub.execute_input":"2023-03-19T04:52:08.212446Z","iopub.status.idle":"2023-03-19T04:52:08.222712Z","shell.execute_reply.started":"2023-03-19T04:52:08.212407Z","shell.execute_reply":"2023-03-19T04:52:08.221961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\ndevice","metadata":{"papermill":{"duration":0.084495,"end_time":"2021-09-27T02:55:09.277010","exception":false,"start_time":"2021-09-27T02:55:09.192515","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:08.224513Z","iopub.execute_input":"2023-03-19T04:52:08.225138Z","iopub.status.idle":"2023-03-19T04:52:08.294868Z","shell.execute_reply.started":"2023-03-19T04:52:08.225103Z","shell.execute_reply":"2023-03-19T04:52:08.293542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if is_train:\n    data_set = []\n    data_set.append(\n        {\n            \"train_img\": [img1, img2],\n            \"train_label\": [img1_label, img2_label],\n            \"valid_img\": [img3],\n            \"valid_label\": [img3_label],\n            \"valid_mask\": [img3_mask],\n        }\n    )\n\n    data_set.append(\n        {\n            \"train_img\": [img1, img3],\n            \"train_label\": [img1_label, img3_label],\n            \"valid_img\": [img2],\n            \"valid_label\": [img2_label],\n            \"valid_mask\": [img2_mask],\n        }\n    )\n\n    data_set.append(\n        {\n            \"train_img\": [img2, img3],\n            \"train_label\": [img2_label, img3_label],\n            \"valid_img\": [img1],\n            \"valid_label\": [img1_label],\n            \"valid_mask\": [img1_mask],\n        }\n    )","metadata":{"execution":{"iopub.status.busy":"2023-03-19T04:52:08.297634Z","iopub.execute_input":"2023-03-19T04:52:08.298657Z","iopub.status.idle":"2023-03-19T04:52:08.309262Z","shell.execute_reply.started":"2023-03-19T04:52:08.298616Z","shell.execute_reply":"2023-03-19T04:52:08.308440Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nif is_train:\n    for fold in range(0, 3):\n        print(f\"====== {fold} ======\")\n\n        net = CVNet(1)\n        net.to(device)\n\n        # criterion = nn.MSELoss()\n        criterion = nn.BCEWithLogitsLoss()\n        optimizer = optim.AdamW(net.parameters(), lr=Config.LR, weight_decay=1.0e-02)\n\n        # train, valid = train_df.iloc[train_index], train_df.iloc[test_index]\n        # y_train, y_valid = train_labels.iloc[train_index], train_labels.iloc[test_index]\n\n        train_dataset = CVDataSet(\n            data_set[fold][\"train_img\"],\n            get_augmentation(),\n            labels=data_set[fold][\"train_label\"],\n            data_type=\"train\",\n            crop_size=Config.IMG_SIZE,\n        )\n        valid_dataset = CVDataSet(\n            data_set[fold][\"valid_img\"],\n            get_augmentation(),\n            labels=data_set[fold][\"valid_label\"],\n            data_type=\"valid\",\n            crop_size=Config.IMG_SIZE,\n        )\n\n        trainloader = DataLoader(\n            train_dataset,\n            batch_size=Config.BATCH_SIZE,\n            pin_memory=True,\n            shuffle=True,\n            drop_last=True,\n            num_workers=Config.NUM_WORKERS // 2,\n        )\n        validloader = DataLoader(\n            valid_dataset,\n            batch_size=Config.BATCH_SIZE,\n            pin_memory=True,\n            num_workers=Config.NUM_WORKERS // 2,\n        )\n\n        early_stopping = EarlyStopping(\n            patience=Config.PATIENCE, verbose=True, fold=fold\n        )\n        scheduler = torch.optim.lr_scheduler.OneCycleLR(\n            optimizer,\n            epochs=Config.EPOCH,\n            steps_per_epoch=len(trainloader),\n            max_lr=Config.MAX_LR,\n            pct_start=0.1,\n            anneal_strategy=\"cos\",\n            div_factor=1.0e3,\n            final_div_factor=1.0e3,\n        )\n\n        val_metrics = []\n        learning_rates = []\n\n        for epoch in range(Config.EPOCH):\n\n            running_loss = 0.0\n            train_rmse_list = []\n            n_iter = len(trainloader)\n            with tqdm(enumerate(trainloader), total=n_iter) as pbar:\n                for i, (img, target) in pbar:\n\n                    net.train()\n                    # zero the parameter gradients\n                    # optimizer.zero_grad()\n\n                    img, target = img.to(device).float(), target.to(device).float()\n\n                    outputs = net(img)\n\n                    loss = criterion(outputs.squeeze(), target)\n\n                    loss.backward()\n                    optimizer.step()\n                    net.zero_grad()\n\n                    # print statistics\n                    running_loss += loss.item()\n\n                    outputs_np = outputs.to(\"cpu\").detach().numpy().copy()\n\n                    pbar.set_postfix(\n                        OrderedDict(\n                            epoch=\"{:>10}\".format(epoch),\n                            loss=\"{:.4f}\".format(loss.item()),\n                        )\n                    )\n                    scheduler.step()\n\n            val_preds = []\n            valid_targets = []\n            n_iter_val = len(validloader)\n            for i, (img, target) in tqdm(\n                enumerate(validloader), total=n_iter_val, smoothing=0\n            ):\n                net.eval()\n\n                with torch.no_grad():\n                    img, pawpularities = (\n                        img.to(device).float(),\n                        target.to(device).float(),\n                    )\n                    outputs = net(img)\n                    outputs = outputs.sigmoid()\n                    outputs_np = outputs.to(\"cpu\").detach().numpy().copy()\n\n                    val_preds.append(outputs_np)\n                    valid_targets.append(\n                        pawpularities.to(\"cpu\").detach().numpy().copy()\n                    )\n\n            ## 端を切る\n            w_count = math.ceil(\n                data_set[fold][\"valid_label\"][0].shape[1] / Config.IMG_SIZE\n            )\n            h_count = math.ceil(\n                data_set[fold][\"valid_label\"][0].shape[0] / Config.IMG_SIZE\n            )\n\n            tile_arry = []\n            stack_pred = np.vstack(val_preds).reshape(\n                -1, Config.IMG_SIZE, Config.IMG_SIZE\n            )\n            for h_i in range(h_count):\n                # print(len(test_preds[h_i * w_count:(h_i + 1) * w_count]), h_i * w_count, (h_i + 1) * w_count)\n                tile_arry.append(stack_pred[h_i * w_count : (h_i + 1) * w_count])\n\n            pred_tile_img = concat_tile(tile_arry)\n            pred_tile_img = np.where(\n                data_set[fold][\"valid_mask\"][0] > 1,\n                pred_tile_img[\n                    : data_set[fold][\"valid_label\"][0].shape[0],\n                    : data_set[fold][\"valid_label\"][0].shape[1],\n                ],\n                0,\n            )\n            auc = roc_auc_score(\n                data_set[fold][\"valid_label\"][0].reshape(-1),\n                pred_tile_img.reshape(-1),\n            )\n            auc\n\n            logger.info(\"auc:{:.4f}\".format(auc))\n\n            lr = optimizer.param_groups[0][\"lr\"]\n\n            val_metrics.append(auc)\n            learning_rates.append(lr)\n\n            early_stopping(-auc, net)\n\n            if early_stopping.early_stop:\n                logger.info(\"Early stopping\")\n                break\n\n        fig = plt.figure()\n        ax1 = fig.add_subplot(111)\n        ax1.plot(learning_rates)\n        ax2 = ax1.twinx()\n        ax2.plot(val_metrics)\n        plt.show()\n\n        del net, validloader, trainloader, train_dataset, valid_dataset, img, target, outputs\n        torch.cuda.empty_cache()\n        gc.collect()","metadata":{"papermill":{"duration":0.049482,"end_time":"2021-09-27T02:55:09.353427","exception":false,"start_time":"2021-09-27T02:55:09.303945","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:08.310834Z","iopub.execute_input":"2023-03-19T04:52:08.311669Z","iopub.status.idle":"2023-03-19T04:52:08.345217Z","shell.execute_reply.started":"2023-03-19T04:52:08.311631Z","shell.execute_reply":"2023-03-19T04:52:08.344122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Validation","metadata":{}},{"cell_type":"code","source":"%%time\nif is_train:\n    all_preds = []\n    all_masks = []\n    for fold in range(0, 3):\n        print(f\"====== {fold} ======\")\n\n        net = CVNet(1)\n        net.load_state_dict(torch.load(CP_DIR / f\"{HOST}_{NB}_checkpoint_{fold}.pt\"))\n        net.to(device)\n\n        valid_dataset = CVDataSet(\n            data_set[fold][\"valid_img\"],\n            get_augmentation(),\n            labels=data_set[fold][\"valid_label\"],\n            data_type=\"valid\",\n            crop_size=Config.IMG_SIZE,\n        )\n\n        validloader = DataLoader(\n            valid_dataset,\n            batch_size=int(Config.BATCH_SIZE / 4),\n            pin_memory=True,\n            num_workers=Config.NUM_WORKERS - 2,\n        )\n\n        val_preds = []\n        valid_targets = []\n        n_iter_val = len(validloader)\n        for i, (img, target) in tqdm(enumerate(validloader), total=n_iter_val):\n            net.eval()\n\n            with torch.no_grad():\n                img, pawpularities = img.to(device).float(), target.to(device).float()\n                outputs = net(img)\n                outputs = outputs.sigmoid()\n                outputs_np = outputs.to(\"cpu\").detach().numpy().copy()\n\n                val_preds.append(outputs_np)\n                valid_targets.append(pawpularities.to(\"cpu\").detach().numpy().copy())\n\n        ## 端を切る\n        w_count = math.ceil(data_set[fold][\"valid_label\"][0].shape[1] / Config.IMG_SIZE)\n        h_count = math.ceil(data_set[fold][\"valid_label\"][0].shape[0] / Config.IMG_SIZE)\n\n        tile_arry = []\n        stack_pred = np.vstack(val_preds).reshape(-1, Config.IMG_SIZE, Config.IMG_SIZE)\n        for h_i in range(h_count):\n            # print(len(test_preds[h_i * w_count:(h_i + 1) * w_count]), h_i * w_count, (h_i + 1) * w_count)\n            tile_arry.append(stack_pred[h_i * w_count : (h_i + 1) * w_count])\n\n        pred_tile_img = concat_tile(tile_arry)\n        pred_tile_img = np.where(\n            data_set[fold][\"valid_mask\"][0] > 1,\n            pred_tile_img[\n                : data_set[fold][\"valid_label\"][0].shape[0],\n                : data_set[fold][\"valid_label\"][0].shape[1],\n            ],\n            0,\n        )\n\n        auc = roc_auc_score(\n            data_set[fold][\"valid_label\"][0].reshape(-1),\n            pred_tile_img.reshape(-1),\n        )\n        auc\n\n        all_masks.append(data_set[fold][\"valid_label\"][0].reshape(-1))\n        all_preds.append(pred_tile_img.reshape(-1))\n\n        print(auc)\n\n        del net, validloader, valid_dataset, img, target, outputs\n        torch.cuda.empty_cache()\n        gc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-03-19T04:52:08.349320Z","iopub.execute_input":"2023-03-19T04:52:08.351513Z","iopub.status.idle":"2023-03-19T04:52:08.372440Z","shell.execute_reply.started":"2023-03-19T04:52:08.351474Z","shell.execute_reply":"2023-03-19T04:52:08.370454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if is_train:\n    flat_preds = np.hstack(all_preds).reshape(-1).astype(np.float)\n    flat_masks = (np.hstack(all_masks).reshape(-1) / 255).astype(int)\n\n    plt.hist(flat_preds, bins=50)\n    plt.show()","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:08.375358Z","iopub.execute_input":"2023-03-19T04:52:08.376282Z","iopub.status.idle":"2023-03-19T04:52:08.382224Z","shell.execute_reply.started":"2023-03-19T04:52:08.376240Z","shell.execute_reply":"2023-03-19T04:52:08.381045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if is_train:\n    thr_list = []\n    for thr in tqdm(np.arange(0.2, 0.6, 0.1)):\n        _val_pred = np.where(flat_preds > thr, 1, 0).astype(np.int)\n        score = f1_score(flat_masks, _val_pred)\n        print(thr, score)\n        thr_list.append({\"thr\": thr, \"score\": score})","metadata":{"execution":{"iopub.status.busy":"2023-03-19T04:52:08.383874Z","iopub.execute_input":"2023-03-19T04:52:08.384373Z","iopub.status.idle":"2023-03-19T04:52:08.391691Z","shell.execute_reply.started":"2023-03-19T04:52:08.384337Z","shell.execute_reply":"2023-03-19T04:52:08.390221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nfrom PIL import Image\n\n\ndef predict(test_data_dir):\n    test_img = []\n    for i in tqdm(range(65)):\n        test_img.append(\n            cv2.imread(str(test_data_dir / f\"surface_volume/{i:02}.tif\"), 0)\n        )\n\n    test_img = np.stack(test_img)\n    print(test_img.shape)\n\n    # mask\n    test_mask = cv2.imread(str(test_data_dir / \"mask.png\"), 0)\n\n    nets = []\n\n    for fold in range(3):\n        net = CVNet(1)\n        net.to(device)\n        net.load_state_dict(torch.load(CP_DIR / f\"{HOST}_{NB}_checkpoint_{fold}.pt\"))\n        nets.append(net)\n\n    test_dataset = CVDataSet(\n        [test_img], get_test_augmentation(), data_type=\"test\", crop_size=Config.IMG_SIZE\n    )\n\n    testloader = DataLoader(\n        test_dataset,\n        batch_size=int(Config.BATCH_SIZE / 8),\n        pin_memory=True,\n        num_workers=Config.NUM_WORKERS,\n    )\n\n    val_metrics = []\n    learning_rates = []\n\n    # for epoch in range(Config.EPOCH):\n    for epoch in range(1):\n\n        test_preds = []\n        n_iter_val = len(testloader)\n        for i, (img, target) in tqdm(enumerate(testloader), total=n_iter_val):\n            net.eval()\n\n            with torch.no_grad():\n                img, pawpularities = img.to(device).float(), target.to(device).float()\n\n                outputs_all = np.zeros((img.shape[0], img.shape[2], img.shape[3]))\n\n                for net in nets:\n                    outputs = net(img)\n                    outputs = outputs.sigmoid()\n                    outputs_np = outputs.squeeze().to(\"cpu\").detach().numpy().copy()\n                    outputs_all += outputs_np / 3\n\n                test_preds.append(outputs_all)\n\n    del net, testloader, test_dataset\n    torch.cuda.empty_cache()\n    gc.collect()\n\n    w_count = math.ceil(test_img[0].shape[1] / Config.IMG_SIZE)\n    h_count = math.ceil(test_img[0].shape[0] / Config.IMG_SIZE)\n\n    plt.imshow(test_img[0])\n    plt.show()\n\n    tile_arry = []\n    stack_pred = np.vstack(test_preds).reshape(-1, Config.IMG_SIZE, Config.IMG_SIZE)\n    for h_i in range(h_count):\n        tile_arry.append(stack_pred[h_i * w_count : (h_i + 1) * w_count])\n\n    plt.imshow(test_mask)\n    plt.show()\n\n    pred_tile_img = concat_tile(tile_arry)\n\n    plt.imshow(pred_tile_img)\n    plt.show()\n\n    pred_tile_img = np.where(\n        test_mask > 1,\n        pred_tile_img[\n            : test_img[0].shape[0],\n            : test_img[0].shape[1],\n        ],\n        0,\n    )\n\n    return pred_tile_img","metadata":{"execution":{"iopub.status.busy":"2023-03-19T04:52:08.393582Z","iopub.execute_input":"2023-03-19T04:52:08.394137Z","iopub.status.idle":"2023-03-19T04:52:08.411590Z","shell.execute_reply.started":"2023-03-19T04:52:08.394100Z","shell.execute_reply":"2023-03-19T04:52:08.410559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# test data inference","metadata":{}},{"cell_type":"code","source":"test_root_dir = DATA_DIR / \"test/*\"\n\npred_list = []\nfor f in glob.glob(str(test_root_dir)):\n    print(f)\n    pred_tile_img = predict(Path(f))\n\n    plt.imshow(pred_tile_img)\n    plt.show()\n\n    if is_train:\n        plt.figure(figsize=(20, 20))\n    plt.imshow(np.where(pred_tile_img > 0.15, 1, 0))\n    plt.show()\n\n    starts_ix, lengths = rle(pred_tile_img, thr=0.4)\n    inklabels_rle = \" \".join(map(str, sum(zip(starts_ix, lengths), ())))\n    inklabels_rle\n\n    pred_list.append({\"Id\": str(f).split(\"/\")[-1], \"Predicted\": inklabels_rle})","metadata":{"tags":[],"execution":{"iopub.status.busy":"2023-03-19T04:52:08.413114Z","iopub.execute_input":"2023-03-19T04:52:08.413649Z","iopub.status.idle":"2023-03-19T04:54:20.423378Z","shell.execute_reply.started":"2023-03-19T04:52:08.413613Z","shell.execute_reply":"2023-03-19T04:54:20.421987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.DataFrame(pred_list).to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-03-19T04:54:20.424645Z","iopub.status.idle":"2023-03-19T04:54:20.425827Z","shell.execute_reply.started":"2023-03-19T04:54:20.425557Z","shell.execute_reply":"2023-03-19T04:54:20.425585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}