{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":18647,"databundleVersionId":1126921,"sourceType":"competition"},{"sourceId":6939087,"sourceType":"datasetVersion","datasetId":3886268},{"sourceId":7083941,"sourceType":"datasetVersion","datasetId":4081278}],"dockerImageVersionId":30559,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"DEBUG = False","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-11-29T15:50:36.273694Z","iopub.execute_input":"2023-11-29T15:50:36.274093Z","iopub.status.idle":"2023-11-29T15:50:36.2785Z","shell.execute_reply.started":"2023-11-29T15:50:36.274061Z","shell.execute_reply":"2023-11-29T15:50:36.277566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"get_ipython().system('pip install git+https://github.com/ildoonet/pytorch-gradual-warmup-lr.git')","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:50:37.795086Z","iopub.execute_input":"2023-11-29T15:50:37.795413Z","iopub.status.idle":"2023-11-29T15:50:53.314943Z","shell.execute_reply.started":"2023-11-29T15:50:37.795387Z","shell.execute_reply":"2023-11-29T15:50:53.313923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!git clone https://github.com/lukemelas/EfficientNet-PyTorch.git","metadata":{"execution":{"iopub.status.busy":"2023-10-27T16:54:10.015687Z","iopub.execute_input":"2023-10-27T16:54:10.016433Z","iopub.status.idle":"2023-10-27T16:54:10.985214Z","shell.execute_reply.started":"2023-10-27T16:54:10.016397Z","shell.execute_reply":"2023-10-27T16:54:10.98409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport sys\nsys.path = [\n    '/kaggle/working/EfficientNet-PyTorch',\n] + sys.path","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:50:55.829817Z","iopub.execute_input":"2023-11-29T15:50:55.830578Z","iopub.status.idle":"2023-11-29T15:50:55.835245Z","shell.execute_reply.started":"2023-11-29T15:50:55.830546Z","shell.execute_reply":"2023-11-29T15:50:55.834162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install efficientnet_pytorch","metadata":{"execution":{"iopub.status.busy":"2023-11-18T19:08:45.898654Z","iopub.execute_input":"2023-11-18T19:08:45.899004Z","iopub.status.idle":"2023-11-18T19:08:59.409041Z","shell.execute_reply.started":"2023-11-18T19:08:45.898974Z","shell.execute_reply":"2023-11-18T19:08:59.407942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!apt-get install -y openslide-tools\n!pip install openslide-python","metadata":{"execution":{"iopub.status.busy":"2023-11-18T19:09:11.175914Z","iopub.execute_input":"2023-11-18T19:09:11.176268Z","iopub.status.idle":"2023-11-18T19:09:25.080324Z","shell.execute_reply.started":"2023-11-18T19:09:11.176231Z","shell.execute_reply":"2023-11-18T19:09:25.079379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import time\nimport skimage.io\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport PIL.Image\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nfrom torch.optim import lr_scheduler\nfrom torch.utils.data import DataLoader, Dataset\nfrom torch.utils.data.sampler import SubsetRandomSampler, RandomSampler, SequentialSampler\nfrom warmup_scheduler import GradualWarmupScheduler\nfrom efficientnet_pytorch import model as enet\nimport albumentations\nfrom sklearn.model_selection import StratifiedKFold\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import cohen_kappa_score\nfrom tqdm import tqdm_notebook as tqdm\nfrom openslide import OpenSlide\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2 \nfrom tqdm.notebook import tqdm\nimport skimage.io\nimport tensorflow as tf\nimport math\nimport glob","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:50:58.894075Z","iopub.execute_input":"2023-11-29T15:50:58.89472Z","iopub.status.idle":"2023-11-29T15:51:11.011301Z","shell.execute_reply.started":"2023-11-29T15:50:58.894691Z","shell.execute_reply":"2023-11-29T15:51:11.010312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_dir = '../input/prostate-cancer-grade-assessment'\ndf_train = pd.read_csv(os.path.join(data_dir, 'train.csv'))\nimage_folder = os.path.join(data_dir, 'train_images')\n\nkernel_type = 'how_to_train_effnet_b0_to_get_LB_0.86'\n\nenet_type = 'efficientnet-b0'\nfold = 0\ntile_size = 256 #256\nimage_size = 256 #256\nn_tiles = 36 #36\nbatch_size = 2\nnum_workers = 2 #4\nout_dim = 5\ninit_lr = 3e-4\nwarmup_factor = 10\n\nwarmup_epo = 1\nn_epochs = 1 if DEBUG else 10\ndf_train = df_train.sample(100).reset_index(drop=True) if DEBUG else df_train\n\ndevice = torch.device('cuda')\n\nprint(image_folder)","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:51:24.63001Z","iopub.execute_input":"2023-11-29T15:51:24.63039Z","iopub.status.idle":"2023-11-29T15:51:24.671254Z","shell.execute_reply.started":"2023-11-29T15:51:24.630362Z","shell.execute_reply":"2023-11-29T15:51:24.670315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"skf = StratifiedKFold(5, shuffle=True, random_state=42)\ndf_train['fold'] = -1\nfor i, (train_idx, valid_idx) in enumerate(skf.split(df_train, df_train['isup_grade'])):\n    df_train.loc[valid_idx, 'fold'] = i\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:51:26.726598Z","iopub.execute_input":"2023-11-29T15:51:26.726948Z","iopub.status.idle":"2023-11-29T15:51:26.762126Z","shell.execute_reply.started":"2023-11-29T15:51:26.72692Z","shell.execute_reply":"2023-11-29T15:51:26.761204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nfrom efficientnet_pytorch import EfficientNet\n\nmodel_name = 'efficientnet-b0'  # Replace with the desired model name (e.g., b0, b1, etc.)\n\npretrained_model = EfficientNet.from_pretrained(model_name)","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:51:28.565252Z","iopub.execute_input":"2023-11-29T15:51:28.565672Z","iopub.status.idle":"2023-11-29T15:51:29.195919Z","shell.execute_reply.started":"2023-11-29T15:51:28.565638Z","shell.execute_reply":"2023-11-29T15:51:29.195226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class enetv2(nn.Module):\n    def __init__(self, backbone, out_dim):\n        super(enetv2, self).__init__()\n        self.enet = enet.EfficientNet.from_pretrained(backbone)\n#         self.enet.load_state_dict(torch.load(pretrained_model[backbone\n\n        self.myfc = nn.Linear(self.enet._fc.in_features, out_dim)\n        self.enet._fc = nn.Identity()\n\n    def extract(self, x):\n        return self.enet(x)\n\n    def forward(self, x):\n        x = self.extract(x)\n        x = self.myfc(x)\n        return x\nprint(\"hecho\")","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:51:31.732547Z","iopub.execute_input":"2023-11-29T15:51:31.73317Z","iopub.status.idle":"2023-11-29T15:51:31.74Z","shell.execute_reply.started":"2023-11-29T15:51:31.733139Z","shell.execute_reply":"2023-11-29T15:51:31.739067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prueba sin tiles en blanco","metadata":{}},{"cell_type":"code","source":"def get_tiles(img, mode=0):\n        result = []\n        h, w, c = img.shape\n        pad_h = (tile_size - h % tile_size) % tile_size + ((tile_size * mode) // 2)\n        pad_w = (tile_size - w % tile_size) % tile_size + ((tile_size * mode) // 2)\n\n        img2 = np.pad(img,[[pad_h // 2, pad_h - pad_h // 2], [pad_w // 2,pad_w - pad_w//2], [0,0]], constant_values=255)\n        img3 = img2.reshape(\n            img2.shape[0] // tile_size,\n            tile_size,\n            img2.shape[1] // tile_size,\n            tile_size,\n            3\n        )\n\n        img3 = img3.transpose(0,2,1,3,4).reshape(-1, tile_size, tile_size,3)\n        n_tiles_with_info = (img3.reshape(img3.shape[0],-1).sum(1) < tile_size ** 2 * 3 * 255).sum()\n        if len(img3) < n_tiles:\n            img3 = np.pad(img3,[[0,n_tiles-len(img3)],[0,0],[0,0],[0,0]], constant_values=255)\n        idxs = np.argsort(img3.reshape(img3.shape[0],-1).sum(-1))[:n_tiles]\n        img3 = img3[idxs]\n        for i in range(len(img3)):\n            result.append({'img':img3[i], 'idx':i})\n        return result, n_tiles_with_info >= n_tiles\n\nclass PANDADataset(Dataset):\n    def __init__(self,\n                 df,\n                 image_size,\n                 n_tiles=n_tiles,\n                 tile_mode=0,\n                 rand=False,\n                 transform=None,\n                ):\n\n        self.df = df.reset_index(drop=True)\n        self.image_size = image_size\n        self.n_tiles = n_tiles\n        self.tile_mode = tile_mode\n        self.rand = rand\n        self.transform = transform\n\n    def __len__(self):\n        return self.df.shape[0]\n\n    def __getitem__(self, index):\n        row = self.df.iloc[index]\n        img_id = row.image_id\n        \n        tiff_file = os.path.join(image_folder, f'{img_id}.tiff')\n        image = OpenSlide(tiff_file)\n        image_layer_2 = image.read_region((0, 0), 1, image.level_dimensions[1])\n        image_layer_2 = np.array(image_layer_2)[:, :, :3]\n        tiles, OK = get_tiles(image_layer_2, self.tile_mode)\n\n        if self.rand:\n            idxes = np.random.choice(list(range(self.n_tiles)), self.n_tiles, replace=False)\n        else:\n            idxes = list(range(self.n_tiles))\n\n        n_row_tiles = int(np.sqrt(self.n_tiles))\n        images = np.zeros((image_size * n_row_tiles, image_size * n_row_tiles, 3))\n        for h in range(n_row_tiles):\n            for w in range(n_row_tiles):\n                i = h * n_row_tiles + w\n    \n                if len(tiles) > idxes[i]:\n                    this_img = tiles[idxes[i]]['img']\n                else:\n                    this_img = np.ones((self.image_size, self.image_size, 3)).astype(np.uint8) * 255\n                this_img = 255 - this_img\n                if self.transform is not None:\n                    this_img = self.transform(image=this_img)['image']\n                h1 = h * image_size\n                w1 = w * image_size\n                images[h1:h1+image_size, w1:w1+image_size] = this_img\n\n        if self.transform is not None:\n            images = self.transform(image=images)['image']\n        images = images.astype(np.float32)\n        images /= 255\n        images = images.transpose(2, 0, 1)\n\n        label = np.zeros(5).astype(np.float32)\n        label[:row.isup_grade] = 1.\n        return torch.tensor(images), torch.tensor(label)\n\n\n# # Augmentations\n\n# In[10]:\n\n\ntransforms_train = albumentations.Compose([\n    albumentations.Transpose(p=0.5),\n    albumentations.VerticalFlip(p=0.5),\n    albumentations.HorizontalFlip(p=0.5),\n])\ntransforms_val = albumentations.Compose([])\nprint(\"hecho\")","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:53:20.709006Z","iopub.execute_input":"2023-11-29T15:53:20.70972Z","iopub.status.idle":"2023-11-29T15:53:20.73176Z","shell.execute_reply.started":"2023-11-29T15:53:20.709688Z","shell.execute_reply":"2023-11-29T15:53:20.730775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_show = PANDADataset(df_train, image_size, n_tiles, 0, transform=transforms_train)\nfrom pylab import rcParams\nrcParams['figure.figsize'] = 20,10\nfor i in range(2):\n    f, axarr = plt.subplots(1,5)\n    for p in range(5):\n        idx = np.random.randint(0, len(dataset_show))\n        img, label = dataset_show[idx]\n        axarr[p].imshow(1. - img.transpose(0, 1).transpose(1,2).squeeze())\n        axarr[p].set_title(str(sum(label)))","metadata":{"execution":{"iopub.status.busy":"2023-11-19T16:50:53.316328Z","iopub.execute_input":"2023-11-19T16:50:53.317034Z","iopub.status.idle":"2023-11-19T16:51:28.903944Z","shell.execute_reply.started":"2023-11-19T16:50:53.317004Z","shell.execute_reply":"2023-11-19T16:51:28.903048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Normal\n","metadata":{}},{"cell_type":"code","source":"def get_tiles(img, mode=0):\n        result = []\n        h, w, c = img.shape\n        pad_h = (tile_size - h % tile_size) % tile_size + ((tile_size * mode) // 2)\n        pad_w = (tile_size - w % tile_size) % tile_size + ((tile_size * mode) // 2)\n\n        img2 = np.pad(img, [[pad_h // 2, pad_h - pad_h // 2], [pad_w // 2, pad_w - pad_w // 2], [0, 0]], constant_values=255)\n        img3 = img2.reshape(\n            img2.shape[0] // tile_size,\n            tile_size,\n            img2.shape[1] // tile_size,\n            tile_size,\n            3\n        )\n\n        img3 = img3.transpose(0, 2, 1, 3, 4).reshape(-1, tile_size, tile_size, 3)\n        n_tiles_with_info = (img3.reshape(img3.shape[0], -1).sum(1) < tile_size ** 2 * 3 * 255).sum()\n\n        # Identify tiles with over 30% white area\n        white_area_threshold = 0.3 * tile_size**2 * 3 * 255\n        tiles_to_replace = np.where(img3.reshape(img3.shape[0], -1).sum(-1) > white_area_threshold)[0]\n\n        # Replace identified tiles with ones having at least 70% region of interest\n        for tile_index in tiles_to_replace:\n            candidate_indices = np.where(img3.reshape(img3.shape[0], -1).sum(-1) < 0.7 * tile_size**2 * 3 * 255)[0]\n            if len(candidate_indices) > 0:\n                replacement_index = np.random.choice(candidate_indices)\n                img3[tile_index] = img3[replacement_index]\n\n        # Repeat random tiles that contain information\n        while len(img3) < n_tiles:\n            random_indices = np.random.choice(np.arange(len(img3)), size=(n_tiles - len(img3)), replace=True)\n            img3 = np.concatenate([img3, img3[random_indices]])\n\n        img3 = img3[:n_tiles]  # Trim to the desired number of tiles\n\n        for i in range(len(img3)):\n            result.append({'img': img3[i], 'idx': i})\n\n        return result, n_tiles_with_info >= n_tiles\n\nclass PANDADataset(Dataset):\n    def __init__(self,\n                 df,\n                 image_size,\n                 n_tiles=n_tiles,\n                 tile_mode=0,\n                 rand=False,\n                 transform=None,\n                ):\n\n        self.df = df.reset_index(drop=True)\n        self.image_size = image_size\n        self.n_tiles = n_tiles\n        self.tile_mode = tile_mode\n        self.rand = rand\n        self.transform = transform\n\n    def __len__(self):\n        return self.df.shape[0]\n\n    def __getitem__(self, index):\n        row = self.df.iloc[index]\n        img_id = row.image_id\n        \n        tiff_file = os.path.join(image_folder, f'{img_id}.tiff')\n        image = OpenSlide(tiff_file)\n        image_layer_2 = image.read_region((0, 0), 1, image.level_dimensions[1])\n        image_layer_2 = np.array(image_layer_2)[:, :, :3]\n        tiles, OK = get_tiles(image_layer_2, self.tile_mode)\n\n        if self.rand:\n            idxes = np.random.choice(list(range(self.n_tiles)), self.n_tiles, replace=False)\n        else:\n            idxes = list(range(self.n_tiles))\n\n        n_row_tiles = int(np.sqrt(self.n_tiles))\n        images = np.zeros((image_size * n_row_tiles, image_size * n_row_tiles, 3))\n        for h in range(n_row_tiles):\n            for w in range(n_row_tiles):\n                i = h * n_row_tiles + w\n    \n                if len(tiles) > idxes[i]:\n                    this_img = tiles[idxes[i]]['img']\n                else:\n                    this_img = np.ones((self.image_size, self.image_size, 3)).astype(np.uint8) * 255\n                this_img = 255 - this_img\n                if self.transform is not None:\n                    this_img = self.transform(image=this_img)['image']\n                h1 = h * image_size\n                w1 = w * image_size\n                images[h1:h1+image_size, w1:w1+image_size] = this_img\n\n        if self.transform is not None:\n            images = self.transform(image=images)['image']\n        images = images.astype(np.float32)\n        images /= 255\n        images = images.transpose(2, 0, 1)\n\n        label = np.zeros(5).astype(np.float32)\n        label[:row.isup_grade] = 1.\n        return torch.tensor(images), torch.tensor(label)\n\n\n# # Augmentations\n\n# In[10]:\n\n\ntransforms_train = albumentations.Compose([\n    albumentations.Transpose(p=0.5),\n    albumentations.VerticalFlip(p=0.5),\n    albumentations.HorizontalFlip(p=0.5),\n])\ntransforms_val = albumentations.Compose([])\nprint(\"hecho\")","metadata":{"execution":{"iopub.status.busy":"2023-11-19T16:27:58.284796Z","iopub.execute_input":"2023-11-19T16:27:58.285534Z","iopub.status.idle":"2023-11-19T16:27:58.308542Z","shell.execute_reply.started":"2023-11-19T16:27:58.285499Z","shell.execute_reply":"2023-11-19T16:27:58.307674Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_show = PANDADataset(df_train, image_size, n_tiles, 0, transform=transforms_train)\nfrom pylab import rcParams\nrcParams['figure.figsize'] = 20,10\nfor i in range(2):\n    f, axarr = plt.subplots(1,5)\n    for p in range(5):\n        idx = p\n        img, label = dataset_show[idx]\n        axarr[p].imshow(1. - img.transpose(0, 1).transpose(1,2).squeeze())\n        axarr[p].set_title(str(sum(label)))","metadata":{"execution":{"iopub.status.busy":"2023-11-19T16:28:01.917218Z","iopub.execute_input":"2023-11-19T16:28:01.917943Z","iopub.status.idle":"2023-11-19T16:28:27.141935Z","shell.execute_reply.started":"2023-11-19T16:28:01.917912Z","shell.execute_reply":"2023-11-19T16:28:27.141027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"criterion = nn.BCEWithLogitsLoss()","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:53:27.341423Z","iopub.execute_input":"2023-11-29T15:53:27.341783Z","iopub.status.idle":"2023-11-29T15:53:27.346406Z","shell.execute_reply.started":"2023-11-29T15:53:27.341754Z","shell.execute_reply":"2023-11-29T15:53:27.34545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_epoch(loader, optimizer):\n\n    model.train()\n    train_loss = []\n    bar = tqdm(loader)\n    for (data, target) in bar:\n        \n        data, target = data.to(device), target.to(device)\n        loss_func = criterion\n        optimizer.zero_grad()\n        logits = model(data)\n        loss = loss_func(logits, target)\n        loss.backward()\n        optimizer.step()\n\n        loss_np = loss.detach().cpu().numpy()\n        train_loss.append(loss_np)\n        smooth_loss = sum(train_loss[-100:]) / min(len(train_loss), 100)\n        bar.set_description('loss: %.5f, smth: %.5f' % (loss_np, smooth_loss))\n    return train_loss\n\n\ndef val_epoch(loader, get_output=False):\n\n    model.eval()\n    val_loss = []\n    LOGITS = []\n    PREDS = []\n    TARGETS = []\n\n    with torch.no_grad():\n        for (data, target) in tqdm(loader):\n            data, target = data.to(device), target.to(device)\n            logits = model(data)\n\n            loss = criterion(logits, target)\n\n            pred = logits.sigmoid().sum(1).detach().round()\n            LOGITS.append(logits)\n            PREDS.append(pred)\n            TARGETS.append(target.sum(1))\n\n            val_loss.append(loss.detach().cpu().numpy())\n        val_loss = np.mean(val_loss)\n\n    LOGITS = torch.cat(LOGITS).cpu().numpy()\n    PREDS = torch.cat(PREDS).cpu().numpy()\n    TARGETS = torch.cat(TARGETS).cpu().numpy()\n    acc = (PREDS == TARGETS).mean() * 100.\n    \n    qwk = cohen_kappa_score(PREDS, TARGETS, weights='quadratic')\n    qwk_k = cohen_kappa_score(PREDS[df_valid['data_provider'] == 'karolinska'], df_valid[df_valid['data_provider'] == 'karolinska'].isup_grade.values, weights='quadratic')\n    qwk_r = cohen_kappa_score(PREDS[df_valid['data_provider'] == 'radboud'], df_valid[df_valid['data_provider'] == 'radboud'].isup_grade.values, weights='quadratic')\n    print('qwk', qwk, 'qwk_k', qwk_k, 'qwk_r', qwk_r)\n\n    if get_output:\n        return LOGITS\n    else:\n        return val_loss, acc, qwk","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:53:28.754053Z","iopub.execute_input":"2023-11-29T15:53:28.754697Z","iopub.status.idle":"2023-11-29T15:53:28.768426Z","shell.execute_reply.started":"2023-11-29T15:53:28.754666Z","shell.execute_reply":"2023-11-29T15:53:28.76754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_idx = np.where((df_train['fold'] != fold))[0]\nvalid_idx = np.where((df_train['fold'] == fold))[0]\n\ndf_this  = df_train.loc[train_idx]\ndf_valid = df_train.loc[valid_idx]\n\ndataset_train = PANDADataset(df_this , image_size, n_tiles, transform=transforms_train)\ndataset_valid = PANDADataset(df_valid, image_size, n_tiles, transform=transforms_val)\n\ntrain_loader = torch.utils.data.DataLoader(dataset_train, batch_size=batch_size, sampler=RandomSampler(dataset_train), num_workers=num_workers)\nvalid_loader = torch.utils.data.DataLoader(dataset_valid, batch_size=batch_size, sampler=SequentialSampler(dataset_valid), num_workers=num_workers)\n\nmodel = enetv2(enet_type, out_dim=out_dim)\nmodel = model.to(device)\n\noptimizer = optim.Adam(model.parameters(), lr=init_lr/warmup_factor)\nscheduler_cosine = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, n_epochs-warmup_epo)\nscheduler = GradualWarmupScheduler(optimizer, multiplier=warmup_factor, total_epoch=warmup_epo, after_scheduler=scheduler_cosine)\n\nprint(len(dataset_train), len(dataset_valid))\n","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:53:31.185966Z","iopub.execute_input":"2023-11-29T15:53:31.186834Z","iopub.status.idle":"2023-11-29T15:53:31.324907Z","shell.execute_reply.started":"2023-11-29T15:53:31.186802Z","shell.execute_reply":"2023-11-29T15:53:31.323891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"save_dir = \"/kaggle/working/checks/\"","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:47:11.497948Z","iopub.execute_input":"2023-11-24T19:47:11.498629Z","iopub.status.idle":"2023-11-24T19:47:11.502977Z","shell.execute_reply.started":"2023-11-24T19:47:11.498598Z","shell.execute_reply":"2023-11-24T19:47:11.501892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.makedirs(save_dir, exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2023-11-19T16:54:46.124673Z","iopub.execute_input":"2023-11-19T16:54:46.125042Z","iopub.status.idle":"2023-11-19T16:54:46.130222Z","shell.execute_reply.started":"2023-11-19T16:54:46.125011Z","shell.execute_reply":"2023-11-19T16:54:46.128956Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"start_epoch = 5","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:47:26.152402Z","iopub.execute_input":"2023-11-24T19:47:26.153218Z","iopub.status.idle":"2023-11-24T19:47:26.157194Z","shell.execute_reply.started":"2023-11-24T19:47:26.153186Z","shell.execute_reply":"2023-11-24T19:47:26.156154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import time\nimport numpy as np\nimport matplotlib\nmatplotlib.use('Agg')  # Use a non-interactive backend (Agg) for headless operation\nimport matplotlib.pyplot as plt\n\n# Initialize empty lists to collect loss values\ntrain_losses = []\nval_losses = []\n\nqwk_max = 0.72390\n\n\nfor epoch in range(start_epoch, n_epochs + 1):\n    best_file = f'{kernel_type}_best_fold{epoch}.pth'\n    checkpoint_name = f'{kernel_type}_checkpoint{epoch}.pth'\n    print(time.ctime(), 'Epoch:', epoch)\n    scheduler.step(epoch - 1)\n\n    train_loss = train_epoch(train_loader, optimizer)\n    val_loss, acc, qwk = val_epoch(valid_loader)\n\n    # Append the loss values to the lists\n    train_losses.append(np.mean(train_loss))\n    val_losses.append(np.mean(val_loss))\n\n    content = time.ctime() + ' ' + f'Epoch {epoch}, lr: {optimizer.param_groups[0][\"lr\"]:.7f}, train loss: {np.mean(train_loss):.5f}, val loss: {np.mean(val_loss):.5f}, acc: {(acc):.5f}, qwk: {(qwk):.5f}'\n    print(content)\n    with open(f'log_{kernel_type}.txt', 'a') as appender:\n        appender.write(content + '\\n')\n\n    if qwk > qwk_max:\n        print('score2 ({:.6f} --> {:.6f}).  Saving model ...'.format(qwk_max, qwk))\n        torch.save(model.state_dict(), best_file)\n        qwk_max = qwk\n        checkpoint = {\n            'epoch': epoch,\n            'valid_loss_min': val_loss,\n            'state_dict': model.state_dict(),\n            'optimizer': optimizer.state_dict(),\n        }\n        torch.save(checkpoint, os.path.join(save_dir, checkpoint_name))\n\n    # Create a plot for the current epoch and save it as a PNG file\n    plt.figure()\n    plt.plot(train_losses, label='Training Loss')\n    plt.plot(val_losses, label='Validation Loss')\n    plt.xlabel('Epoch')\n    plt.ylabel('Loss')\n    plt.legend() \n    plt.title(f'Training and Validation Loss - Epoch {epoch}')\n    plt.close()  # Close the plot to release resources\n    plt.savefig(f'loss_plot_epoch_{epoch}.png')\n\n# Save the final model\ntorch.save(model.state_dict(), os.path.join(f'{kernel_type}_final_fold{fold}.pth'))","metadata":{"execution":{"iopub.status.busy":"2023-11-24T19:47:27.714547Z","iopub.execute_input":"2023-11-24T19:47:27.71522Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2023-11-19T21:46:54.247744Z","iopub.execute_input":"2023-11-19T21:46:54.248417Z","iopub.status.idle":"2023-11-19T21:46:54.452713Z","shell.execute_reply.started":"2023-11-19T21:46:54.248381Z","shell.execute_reply":"2023-11-19T21:46:54.451716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"qwk","metadata":{"execution":{"iopub.status.busy":"2023-11-19T21:51:38.330152Z","iopub.execute_input":"2023-11-19T21:51:38.330984Z","iopub.status.idle":"2023-11-19T21:51:38.336543Z","shell.execute_reply.started":"2023-11-19T21:51:38.33095Z","shell.execute_reply":"2023-11-19T21:51:38.335569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load Checkpoint","metadata":{}},{"cell_type":"markdown","source":"https://www.kaggle.com/code/vortanasay/saving-loading-and-cont-training-model-in-pytorch","metadata":{}},{"cell_type":"code","source":"def load_ckp(checkpoint_fpath, model, optimizer):\n    checkpoint = torch.load(checkpoint_fpath)\n    model.load_state_dict(checkpoint['state_dict'])\n    optimizer.load_state_dict(checkpoint['optimizer'])\n    valid_loss_min = checkpoint['valid_loss_min']\n    return model, optimizer, checkpoint['epoch'], valid_loss_min.item()","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:50:29.63677Z","iopub.execute_input":"2023-11-29T15:50:29.637234Z","iopub.status.idle":"2023-11-29T15:50:29.64441Z","shell.execute_reply.started":"2023-11-29T15:50:29.637194Z","shell.execute_reply":"2023-11-29T15:50:29.643466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_ckp(checkpoint_fpath, model, optimizer):\n    checkpoint = torch.load(checkpoint_fpath)\n    \n    # Load model state_dict directly\n    model.load_state_dict(checkpoint)\n\n    # Note: Depending on the structure of your optimizer, you might need to handle it separately.\n\n    # Return any relevant information from the checkpoint\n    return model, optimizer, None, None\n","metadata":{"execution":{"iopub.status.busy":"2023-11-29T16:00:59.350663Z","iopub.execute_input":"2023-11-29T16:00:59.351035Z","iopub.status.idle":"2023-11-29T16:00:59.35585Z","shell.execute_reply.started":"2023-11-29T16:00:59.350995Z","shell.execute_reply":"2023-11-29T16:00:59.354755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"use_cuda = torch.cuda.is_available()\nmodel = enetv2(enet_type, out_dim=out_dim)\n# move model to GPU if CUDA is available\nif use_cuda:\n    model = model.cuda()","metadata":{"execution":{"iopub.status.busy":"2023-11-29T15:51:42.900037Z","iopub.execute_input":"2023-11-29T15:51:42.900359Z","iopub.status.idle":"2023-11-29T15:51:48.042401Z","shell.execute_reply.started":"2023-11-29T15:51:42.900335Z","shell.execute_reply":"2023-11-29T15:51:48.04164Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ckp_path = \"/kaggle/input/final-pth/Final.pth\"\nmodel, optimizer, start_epoch, valid_loss_min = load_ckp(ckp_path, model, optimizer)","metadata":{"execution":{"iopub.status.busy":"2023-11-29T16:01:01.381678Z","iopub.execute_input":"2023-11-29T16:01:01.382068Z","iopub.status.idle":"2023-11-29T16:01:01.43724Z","shell.execute_reply.started":"2023-11-29T16:01:01.382011Z","shell.execute_reply":"2023-11-29T16:01:01.436453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"optimizer = \", optimizer)\nprint(\"start_epoch = \", start_epoch)\nprint(\"valid_loss_min = \", valid_loss_min)\nprint(\"valid_loss_min = {:.6f}\".format(valid_loss_min))","metadata":{"execution":{"iopub.status.busy":"2023-11-29T16:01:04.901963Z","iopub.execute_input":"2023-11-29T16:01:04.902836Z","iopub.status.idle":"2023-11-29T16:01:04.947762Z","shell.execute_reply.started":"2023-11-29T16:01:04.902804Z","shell.execute_reply":"2023-11-29T16:01:04.946653Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Pruebas normalización","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Instalamos la librería stainlib","metadata":{}},{"cell_type":"code","source":"get_ipython().system('pip install git+https://github.com/sebastianffx/stainlib.git')","metadata":{"execution":{"iopub.status.busy":"2023-11-06T21:53:25.900911Z","iopub.execute_input":"2023-11-06T21:53:25.90158Z","iopub.status.idle":"2023-11-06T21:53:43.562513Z","shell.execute_reply.started":"2023-11-06T21:53:25.90155Z","shell.execute_reply":"2023-11-06T21:53:43.561339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Normalizar imagen tiff","metadata":{}},{"cell_type":"code","source":"import stainlib\nfrom PIL import Image\nfrom stainlib.normalization.normalizer import ExtractiveStainNormalizer, ReinhardStainNormalizer","metadata":{"execution":{"iopub.status.busy":"2023-11-06T21:55:18.998444Z","iopub.execute_input":"2023-11-06T21:55:18.999047Z","iopub.status.idle":"2023-11-06T21:55:19.003255Z","shell.execute_reply.started":"2023-11-06T21:55:18.999015Z","shell.execute_reply":"2023-11-06T21:55:19.002368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from stainlib.normalization.normalizer import ExtractiveStainNormalizer, ReinhardStainNormalizer\nfrom PIL import Image\n\n\n# Load the target image to normalize\nimage = OpenSlide('/kaggle/input/prostate-cancer-grade-assessment/train_images/0005f7aaab2800f6170c399693a96917.tiff')\nimage_layer_2 = image.read_region((0, 0), 1, image.level_dimensions[1])\nimage_layer_2 = np.array(image_layer_2)[:, :, :3]\n\n# Create a normalizer with the 'vahadane' method\nnormalizer = ReinhardStainNormalizer()\n\n# Standardize brightness (optional)\ntarget_image = stainlib.utils.stain_utils.LuminosityStandardizer.standardize(image_layer_2)\n\n# Fit the normalizer to the target image\nnormalizer.fit(image_layer_2)\n\n# Normalize the target image\nnormalized_target_image = normalizer.transform(image_layer_2)\nnormalized_target_image_pil = Image.fromarray(normalized_target_image)\n\n# Save the normalized target image\noutput_path = '/kaggle/working/normalizada-reinhard.png'  # Specify the output path\nnormalized_target_image_pil.save(output_path)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-06T20:19:27.500327Z","iopub.execute_input":"2023-11-06T20:19:27.50074Z","iopub.status.idle":"2023-11-06T20:19:47.338562Z","shell.execute_reply.started":"2023-11-06T20:19:27.500709Z","shell.execute_reply":"2023-11-06T20:19:47.33777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Normalizar imagen png","metadata":{}},{"cell_type":"code","source":"import cv2\n# Load the target image to normalize\ntarget_path = '/kaggle/working/normalizada-reinhard3-valid.png'\ntarget_image = cv2.imread(target_path)\n# Create a normalizer with the 'vahadane' method\nnormalizer = ReinhardStainNormalizer()\n\n# Standardize brightness (optional)\ntarget_image = stainlib.utils.stain_utils.LuminosityStandardizer.standardize(target_image)\n\n# Fit the normalizer to the target image\nnormalizer.fit(target_image)\n\n# Normalize the target image\nnormalized_target_image = normalizer.transform(target_image)\nnormalized_target_image_pil = Image.fromarray(normalized_target_image)\n\n# Save the normalized target image\noutput_path = '/kaggle/working/normalizada-reinhard4-valid.png'  # Specify the output path\nnormalized_target_image_pil.save(output_path)","metadata":{"execution":{"iopub.status.busy":"2023-11-06T22:00:10.517991Z","iopub.execute_input":"2023-11-06T22:00:10.518859Z","iopub.status.idle":"2023-11-06T22:00:59.526578Z","shell.execute_reply.started":"2023-11-06T22:00:10.518827Z","shell.execute_reply":"2023-11-06T22:00:59.52579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Mostrar imagen tiff","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimg_path = '/kaggle/input/prostate-cancer-grade-assessment/train_images/0005f7aaab2800f6170c399693a96917.tiff'\nslide = OpenSlide(img_path)\n\n# Get the dimensions of the whole image at level 0\nlevel = 1\nimage_width, image_height = slide.level_dimensions[level]\n\n# Define the region as the entire image\nregion = (0, 0)\nsize = (image_width, image_height)\n\n# Read and display the whole image\nregion = slide.read_region(region, level, size)\nplt.figure(figsize=(20, 20))\nplt.imshow(region)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-06T20:12:17.015582Z","iopub.execute_input":"2023-11-06T20:12:17.015964Z","iopub.status.idle":"2023-11-06T20:12:24.624488Z","shell.execute_reply.started":"2023-11-06T20:12:17.015935Z","shell.execute_reply":"2023-11-06T20:12:24.623632Z"},"trusted":true},"execution_count":null,"outputs":[]}]}