{"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","execution":{"iopub.status.busy":"2022-08-02T09:51:09.131079Z","iopub.execute_input":"2022-08-02T09:51:09.131964Z","iopub.status.idle":"2022-08-02T09:51:09.164786Z","shell.execute_reply.started":"2022-08-02T09:51:09.131867Z","shell.execute_reply":"2022-08-02T09:51:09.163760Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import zipfile\nif not os.path.exists('/kaggle/working/data'):\n    os.mkdir('/kaggle/working/data')\n    \nzip_path = '/kaggle/input/data-science-bowl-2018/stage1_train.zip'\nwith zipfile.ZipFile(zip_path, 'r') as zip_ref:\n    zip_ref.extractall('/kaggle/working/data')\n    print('Done!')","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:51:14.768657Z","iopub.execute_input":"2022-08-02T09:51:14.769496Z","iopub.status.idle":"2022-08-02T09:51:20.019022Z","shell.execute_reply.started":"2022-08-02T09:51:14.769462Z","shell.execute_reply":"2022-08-02T09:51:20.017978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\nfrom torch.utils.data import Dataset, DataLoader, random_split\nfrom skimage import io, transform","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:51:22.021405Z","iopub.execute_input":"2022-08-02T09:51:22.022098Z","iopub.status.idle":"2022-08-02T09:51:24.913624Z","shell.execute_reply.started":"2022-08-02T09:51:22.022059Z","shell.execute_reply":"2022-08-02T09:51:24.912629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Albumentation\ndef get_transforms(is_transform):\n    if is_transform:\n        return A.Compose(\n            [\n                A.Resize(256, 256),\n                A.Normalize(mean=(0.5,0.5,0.5), std=(0.5,0.5,0.5)),\n                A.HorizontalFlip(p=0.25),\n                A.VerticalFlip(p=0.25),\n                ToTensorV2()\n            ])\n    else:\n        return A.Compose(\n            [\n                A.Resize(256, 256),\n                A.Normalize(mean=(0.5,0.5,0.5), std=(0.5,0.5,0.5)),\n                ToTensorV2()\n            ])","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:51:38.366089Z","iopub.execute_input":"2022-08-02T09:51:38.366691Z","iopub.status.idle":"2022-08-02T09:51:38.375110Z","shell.execute_reply.started":"2022-08-02T09:51:38.366651Z","shell.execute_reply":"2022-08-02T09:51:38.373940Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Nuclie_data(Dataset):\n        def __init__(self,path,is_transform=True):\n            self.path = path\n            self.folders = os.listdir(path)\n            self.transforms = get_transforms(is_transform)\n        \n        def __len__(self):\n            return len(self.folders)\n              \n        \n        def __getitem__(self,idx):\n            image_folder = os.path.join(self.path,self.folders[idx],'images/')\n            mask_folder = os.path.join(self.path,self.folders[idx],'masks/')\n            image_path = os.path.join(image_folder,os.listdir(image_folder)[0])\n            \n            img = io.imread(image_path)[:,:,:3].astype('float32')\n            img = transform.resize(img,(128,128))\n            \n            mask = self.get_mask(mask_folder, 128, 128 ).astype('float32')\n            augmented = self.transforms(image=img,mask=mask)\n            img = augmented['image']\n            mask = augmented['mask']\n            mask = mask.permute(2, 0, 1)\n            return (img,mask) \n\n\n        def get_mask(self,mask_folder,IMG_HEIGHT, IMG_WIDTH):\n            mask = np.zeros((IMG_HEIGHT, IMG_WIDTH, 1), dtype=bool)\n            for mask_ in os.listdir(mask_folder):\n                    mask_ = io.imread(os.path.join(mask_folder,mask_))\n                    mask_ = transform.resize(mask_, (IMG_HEIGHT, IMG_WIDTH))\n                    mask_ = np.expand_dims(mask_,axis=-1)\n                    mask = np.maximum(mask, mask_)\n              \n            return mask","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:51:49.207095Z","iopub.execute_input":"2022-08-02T09:51:49.207454Z","iopub.status.idle":"2022-08-02T09:51:49.218733Z","shell.execute_reply.started":"2022-08-02T09:51:49.207423Z","shell.execute_reply":"2022-08-02T09:51:49.217269Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_dir = '/kaggle/working/data/'\ndata = Nuclie_data(base_dir)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:51:52.124545Z","iopub.execute_input":"2022-08-02T09:51:52.125030Z","iopub.status.idle":"2022-08-02T09:51:52.135689Z","shell.execute_reply.started":"2022-08-02T09:51:52.124990Z","shell.execute_reply":"2022-08-02T09:51:52.134663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(data.__len__())\ndata.__getitem__(0)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:51:53.721495Z","iopub.execute_input":"2022-08-02T09:51:53.721984Z","iopub.status.idle":"2022-08-02T09:51:53.863222Z","shell.execute_reply.started":"2022-08-02T09:51:53.721941Z","shell.execute_reply":"2022-08-02T09:51:53.862231Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for img,msk in data:\n    print(img.shape)\n    print(msk.shape)\n    break","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:08:12.026132Z","iopub.execute_input":"2022-08-02T05:08:12.027308Z","iopub.status.idle":"2022-08-02T05:08:12.143741Z","shell.execute_reply.started":"2022-08-02T05:08:12.027244Z","shell.execute_reply":"2022-08-02T05:08:12.142387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:08:13.596522Z","iopub.execute_input":"2022-08-02T05:08:13.596934Z","iopub.status.idle":"2022-08-02T05:08:13.602305Z","shell.execute_reply.started":"2022-08-02T05:08:13.596902Z","shell.execute_reply":"2022-08-02T05:08:13.601245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')\ndevice","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:08:15.599266Z","iopub.execute_input":"2022-08-02T05:08:15.599801Z","iopub.status.idle":"2022-08-02T05:08:15.655808Z","shell.execute_reply.started":"2022-08-02T05:08:15.599732Z","shell.execute_reply":"2022-08-02T05:08:15.654476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:08:17.296605Z","iopub.execute_input":"2022-08-02T05:08:17.297041Z","iopub.status.idle":"2022-08-02T05:08:17.302356Z","shell.execute_reply.started":"2022-08-02T05:08:17.297006Z","shell.execute_reply":"2022-08-02T05:08:17.300860Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 将对image，mask所做的数据增强还原，方便绘图\ndef mask_convert(mask):\n    mask = mask.clone().cpu().detach().numpy()\n    mask = mask.transpose((1,2,0))\n    std = np.array((0.5))\n    mean = np.array((0.5))\n    mask  = std * mask + mean\n    mask = mask.clip(0,1)\n    mask = np.squeeze(mask)\n    return mask\n\ndef image_convert(image):\n    image = image.clone().cpu().numpy()\n    image = image.transpose((1,2,0))\n    std = np.array((0.5,0.5,0.5))\n    mean = np.array((0.5,0.5,0.5))\n    image  = std * image + mean\n    image = image.clip(0,1)\n    image = (image * 255).astype(np.uint8)\n    return image","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:08:25.856549Z","iopub.execute_input":"2022-08-02T05:08:25.856944Z","iopub.status.idle":"2022-08-02T05:08:25.867261Z","shell.execute_reply.started":"2022-08-02T05:08:25.856912Z","shell.execute_reply":"2022-08-02T05:08:25.864486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_img(no_):\n    iter_ = iter(train_loader)\n    images,masks = next(iter_)\n    images = images.to(device)\n    masks = masks.to(device)\n    plt.figure(figsize=(10,6))\n    for idx in range(0,no_):\n         image = image_convert(images[idx])\n         plt.subplot(2,no_,idx+1)\n         plt.title('image')\n         plt.imshow(image)\n    for idx in range(0,no_):\n         mask = mask_convert(masks[idx])\n         plt.subplot(2,no_,idx+no_+1)\n         plt.title('mask')\n         plt.imshow(mask,cmap='gray')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-08-02T08:31:41.709785Z","iopub.execute_input":"2022-08-02T08:31:41.710234Z","iopub.status.idle":"2022-08-02T08:31:41.718813Z","shell.execute_reply.started":"2022-08-02T08:31:41.710194Z","shell.execute_reply":"2022-08-02T08:31:41.717418Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# splitting to trainset and validation set and loading the data with batch size of 10\n# 划分数据集\n\ntrainset, valset = random_split(data, [580, 90])\n\ntrain_loader = torch.utils.data.DataLoader(dataset=trainset, batch_size=10, shuffle=True)\n\nval_loader = torch.utils.data.DataLoader(dataset=valset, batch_size=10)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:08:30.018444Z","iopub.execute_input":"2022-08-02T05:08:30.019494Z","iopub.status.idle":"2022-08-02T05:08:30.026959Z","shell.execute_reply.started":"2022-08-02T05:08:30.019453Z","shell.execute_reply":"2022-08-02T05:08:30.025764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_img(5)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:08:31.673922Z","iopub.execute_input":"2022-08-02T05:08:31.674356Z","iopub.status.idle":"2022-08-02T05:08:36.770013Z","shell.execute_reply.started":"2022-08-02T05:08:31.674319Z","shell.execute_reply":"2022-08-02T05:08:36.768858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch import nn\nfrom torch.nn import Linear, ReLU, CrossEntropyLoss, Sequential, Conv2d, MaxPool2d, Module, Softmax, BatchNorm2d, Dropout\nfrom torch.optim import Adam, SGD\nimport torch.nn.functional as F","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:09:27.681462Z","iopub.execute_input":"2022-08-02T05:09:27.681900Z","iopub.status.idle":"2022-08-02T05:09:27.689108Z","shell.execute_reply.started":"2022-08-02T05:09:27.681864Z","shell.execute_reply":"2022-08-02T05:09:27.687448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class  UNetConvBlock(nn.Module):\n    '''\n    Double Convolution layer with both 2 BN and Activation Layer in between\n    Conv2d==>BN==>Activation==>Conv2d==>BN==>Activation\n    '''\n    def __init__(self, in_channel, out_channel):\n        super(UNetConvBlock, self).__init__()\n        self.conv = nn.Sequential(\n            nn.Conv2d(in_channel, out_channel, 3, padding=1),\n            nn.ReLU(inplace=True),\n            nn.BatchNorm2d(out_channel),\n            nn.Conv2d(out_channel, out_channel, 3, padding=1),\n            nn.ReLU(inplace=True),\n            nn.BatchNorm2d(out_channel)\n        )\n    def forward(self, x):\n        x = self.conv(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:09:29.410209Z","iopub.execute_input":"2022-08-02T05:09:29.411410Z","iopub.status.idle":"2022-08-02T05:09:29.419837Z","shell.execute_reply.started":"2022-08-02T05:09:29.411363Z","shell.execute_reply":"2022-08-02T05:09:29.418673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class down_conv(nn.Module):\n    '''\n    A maxpool layer followed by a Double Convolution.\n    '''\n    def __init__(self, in_channel, out_channel):\n        super(down_conv, self).__init__()\n        self.down = nn.Sequential(\n            nn.MaxPool2d(2),\n            UNetConvBlock(in_channel, out_channel)\n        )\n    def forward(self, x):\n        x = self.down(x)\n        return x\n\nclass up_sample(nn.Module):\n    def __init__(self, in_channel, out_channel):\n        super(up_sample, self).__init__()\n        self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)\n        self.unet_conv = UNetConvBlock(in_channel, out_channel)\n\n    def forward(self, x1, x2):\n        x1 = self.up(x1)\n        x = torch.cat([x1, x2], dim=1)\n        x = self.unet_conv(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:09:31.283266Z","iopub.execute_input":"2022-08-02T05:09:31.284012Z","iopub.status.idle":"2022-08-02T05:09:31.293618Z","shell.execute_reply.started":"2022-08-02T05:09:31.283975Z","shell.execute_reply":"2022-08-02T05:09:31.291796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class UNet(nn.Module):\n    def __init__(self,in_channel,out_channel):\n        super(UNet, self).__init__()\n        self.down_block1 = UNetConvBlock(in_channel,64)\n        self.down_block2 = down_conv(64, 128)\n        self.down_block3 = down_conv(128, 256)\n        self.down_block4 = down_conv(256, 512)\n        self.down_block5 = down_conv(512, 1024)\n        ## UpSampling Block\n        self.up_block1 = up_sample(1024+512, 512)\n        self.up_block2 = up_sample(512+256, 256)\n        self.up_block3 = up_sample(256+128, 128)\n        self.up_block4 = up_sample(128+64, 64)\n        self.up_block5 = nn.Conv2d(64, out_channel, 1)\n\n\n    def forward(self, x):\n        #Down\n        x1 = self.down_block1(x)\n        x2 = self.down_block2(x1)\n        x3 = self.down_block3(x2)\n        x4 = self.down_block4(x3)\n        x5 = self.down_block5(x4)\n        #Up\n        x6 = self.up_block1(x5, x4)\n        x7 = self.up_block2(x6, x3)\n        x8 = self.up_block3(x7, x2)\n        x9 = self.up_block4(x8, x1)\n        x10 = self.up_block5(x9)\n        out = torch.sigmoid(x10)\n        return out","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:09:34.365587Z","iopub.execute_input":"2022-08-02T05:09:34.366307Z","iopub.status.idle":"2022-08-02T05:09:34.377349Z","shell.execute_reply.started":"2022-08-02T05:09:34.366271Z","shell.execute_reply":"2022-08-02T05:09:34.376239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 损失函数\nclass DiceBCELoss(nn.Module):\n    def __init__(self, weight=None, size_average=True):\n        super(DiceBCELoss, self).__init__()\n\n    def forward(self, inputs, targets, smooth=1):\n        \n        #comment out if your model contains a sigmoid or equivalent activation layer\n        # inputs = F.sigmoid(inputs)       \n        bce_weight = 0.5\n        #flatten label and prediction tensors\n        inputs = inputs.view(-1)\n        targets = targets.view(-1)\n        \n        intersection = (inputs * targets).sum()                            \n        dice_loss = 1 - (2.*intersection + smooth)/(inputs.sum() + targets.sum() + smooth)  \n        BCE = F.binary_cross_entropy(inputs, targets, reduction='mean')\n        loss_final = BCE * bce_weight + dice_loss * (1 - bce_weight)\n        return loss_final\n    \n## IOU computation\ndef iou_(y_pred,y):\n    inputs = y_pred.reshape(-1)\n    targets = y.reshape(-1)\n    intersection = (inputs * targets).sum()\n    total = (inputs + targets).sum()\n    union = total - intersection \n    smooth = 1    \n    iou = (intersection + smooth)/(union + smooth)\n    return iou\n\n\n\ndef iou_batch(y_pred,y):\n    '''computes mean iou for a batch of ground truth masks and predicted masks'''\n    ious = []\n    y_pred = torch.sigmoid(y_pred)\n    y_pred = y_pred.clone().cpu().detach().numpy()\n    y = y.clone().cpu().detach().numpy() \n    \n    for pred, label in zip(y_pred, y):\n        ious.append(iou_(pred, label))\n    iou = np.nanmean(ious)\n    return iou    ","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:09:37.453890Z","iopub.execute_input":"2022-08-02T05:09:37.454317Z","iopub.status.idle":"2022-08-02T05:09:37.480064Z","shell.execute_reply.started":"2022-08-02T05:09:37.454281Z","shell.execute_reply":"2022-08-02T05:09:37.476689Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:09:53.921834Z","iopub.execute_input":"2022-08-02T05:09:53.922859Z","iopub.status.idle":"2022-08-02T05:09:53.928827Z","shell.execute_reply.started":"2022-08-02T05:09:53.922811Z","shell.execute_reply":"2022-08-02T05:09:53.927398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#ref https://towardsdatascience.com/how-to-save-and-load-a-model-in-pytorch-with-a-complete-example-c2920e617dee\n\ndef save_ckp(state, is_best, checkpoint_path, best_model_path):\n    \"\"\"\n    state: checkpoint we want to save\n    is_best: is this the best checkpoint; min validation loss\n    checkpoint_path: path to save checkpoint\n    best_model_path: path to save best model\n    \"\"\"\n    # save checkpoint data to the path given, checkpoint_path\n    torch.save(state, checkpoint_path)\n    # if it is a best model, min validation loss\n    if is_best:\n        # copy that checkpoint file to best path given, best_model_path\n        shutil.copyfile(checkpoint_path, best_model_path)\n        \ndef load_ckp(checkpoint_fpath, model, optimizer):\n    \"\"\"\n    checkpoint_path: path to save checkpoint\n    model: model that we want to load checkpoint parameters into       \n    optimizer: optimizer we defined in previous training\n    \"\"\"\n    # load check point\n    checkpoint = torch.load(checkpoint_fpath)\n    # initialize state_dict from checkpoint to model\n    model.load_state_dict(checkpoint['state_dict'])\n    # initialize optimizer from checkpoint to optimizer\n    optimizer.load_state_dict(checkpoint['optimizer'])\n    # initialize valid_loss_min from checkpoint to valid_loss_min\n    valid_loss_min = checkpoint['valid_loss_min']\n    # return model, optimizer, epoch value, min validation loss \n    return model, optimizer, checkpoint['epoch'], valid_loss_min.item()","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:09:55.632368Z","iopub.execute_input":"2022-08-02T05:09:55.632798Z","iopub.status.idle":"2022-08-02T05:09:55.640657Z","shell.execute_reply.started":"2022-08-02T05:09:55.632761Z","shell.execute_reply":"2022-08-02T05:09:55.639513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not os.path.exists(\"model\"):\n    os.makedirs(\"model\")","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:10:01.266847Z","iopub.execute_input":"2022-08-02T05:10:01.267253Z","iopub.status.idle":"2022-08-02T05:10:01.273146Z","shell.execute_reply.started":"2022-08-02T05:10:01.267216Z","shell.execute_reply":"2022-08-02T05:10:01.271782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{}},{"cell_type":"code","source":"from tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:10:04.789121Z","iopub.execute_input":"2022-08-02T05:10:04.789556Z","iopub.status.idle":"2022-08-02T05:10:04.795625Z","shell.execute_reply.started":"2022-08-02T05:10:04.789523Z","shell.execute_reply":"2022-08-02T05:10:04.794345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint_path = '/kaggle/working/chkpoint_'\nbest_model_path = '/kaggle/working/bestmodel.pt'\nepochs = 25\nmodel = UNet(3,1).to(device)\ncriterion = DiceBCELoss()\nlearning_rate = 1e-3\noptimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\nvalid_loss_min = 3.95275","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:10:05.811111Z","iopub.execute_input":"2022-08-02T05:10:05.811727Z","iopub.status.idle":"2022-08-02T05:10:06.206911Z","shell.execute_reply.started":"2022-08-02T05:10:05.811692Z","shell.execute_reply":"2022-08-02T05:10:06.205686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"total_train_loss = []\ntotal_train_score = []\ntotal_valid_loss = []\ntotal_valid_score = []","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:10:07.602428Z","iopub.execute_input":"2022-08-02T05:10:07.605659Z","iopub.status.idle":"2022-08-02T05:10:07.613558Z","shell.execute_reply.started":"2022-08-02T05:10:07.605608Z","shell.execute_reply":"2022-08-02T05:10:07.611672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(epochs):\n    print(f'Epoch {epoch + 1}/{epochs}')\n    train_loss = []\n    train_score = []\n    valid_loss = []\n    valid_score = []\n    #<-----------Training Loop---------------------------->\n    pbar = tqdm(train_loader, desc = 'description')\n    model.train()\n    for image, mask in pbar:\n        image = image.to(device,dtype=torch.float)\n        mask = mask.to(device,dtype=torch.float)\n        optimizer.zero_grad()\n        output = model(image)\n        #Loss\n        loss = criterion(output, mask)\n        losses_value = loss.item()\n        #Score\n        score = iou_batch(output,mask)\n        loss.backward()\n        optimizer.step()\n        train_loss.append(losses_value)\n        train_score.append(score.item())\n        #train_score.append(score)\n        pbar.set_description(f\"Epoch: {epoch+1}, loss: {losses_value}, IoU: {score}\")\n    #<---------------Validation Loop---------------------->\n    model.eval()\n    with torch.no_grad():\n        for image,mask in val_loader:\n            image = image.to(device,dtype=torch.float)\n            mask = mask.to(device,dtype=torch.float)\n            output = model(image)\n            ## Compute Loss Value.\n            loss = criterion(output, mask)\n            losses_value = loss.item()\n            ## Compute Accuracy Score\n            score = iou_batch(output,mask)\n            valid_loss.append(losses_value)\n            valid_score.append(score.item())\n    total_train_loss.append(np.mean(train_loss))\n    total_train_score.append(np.mean(train_score))\n    total_valid_loss.append(np.mean(valid_loss))\n    total_valid_score.append(np.mean(valid_score))\n    print(f\"\\n###############Train Loss: {total_train_loss[-1]}, Train IOU: {total_train_score[-1]}###############\")\n    print(f\"###############Valid Loss: {total_valid_loss[-1]}, Valid IOU: {total_valid_score[-1]}###############\")\n    # Save best model Checkpoint\n    # create checkpoint variable and add important data\n    checkpoint = {\n        'epoch': epoch + 1,\n        'valid_loss_min': total_valid_loss[-1],\n        'state_dict': model.state_dict(),\n        'optimizer': optimizer.state_dict(),\n    }\n    \n    # save checkpoint\n    save_ckp(checkpoint, False, checkpoint_path, best_model_path)\n    \n    ## TODO: save the model if validation loss has decreased\n    if total_valid_loss[-1] <= valid_loss_min:\n        print('Validation loss decreased ({:.6f} --> {:.6f}).  Saving model ...'.format(valid_loss_min,total_valid_loss[-1]))\n        # save checkpoint as best model\n        save_ckp(checkpoint, True, checkpoint_path, best_model_path)\n        valid_loss_min = total_valid_loss[-1]","metadata":{"execution":{"iopub.status.busy":"2022-08-02T05:10:08.970599Z","iopub.execute_input":"2022-08-02T05:10:08.970990Z","iopub.status.idle":"2022-08-02T07:12:43.494930Z","shell.execute_reply.started":"2022-08-02T05:10:08.970957Z","shell.execute_reply":"2022-08-02T07:12:43.493256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 加载保存模型\nmodel, optimizer, start_epoch, valid_loss_min = load_ckp(checkpoint_path, model, optimizer)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T07:29:05.502157Z","iopub.execute_input":"2022-08-02T07:29:05.502996Z","iopub.status.idle":"2022-08-02T07:29:05.879664Z","shell.execute_reply.started":"2022-08-02T07:29:05.502955Z","shell.execute_reply":"2022-08-02T07:29:05.878246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def visualize_predict(model, n_images):\n    # model = model.eval()\n    figure, ax = plt.subplots(nrows=n_images, ncols=3, figsize=(15, 18))\n    with torch.no_grad():\n        for image,mask in val_loader:\n            image = image.to(device,dtype=torch.float)\n            mask =  mask.to(device,dtype=torch.float)\n            o = model(image)\n            break\n    for img_no in range(0, n_images):\n        tm=o[img_no][0].data.cpu().numpy()\n        img = image[img_no].data.cpu()\n        msk = mask[img_no].data.cpu()\n        img = image_convert(img)\n        msk = mask_convert(msk)\n        ax[img_no, 0].imshow(img)\n        ax[img_no, 1].imshow(msk, interpolation=\"nearest\", cmap=\"gray\")\n        ax[img_no, 2].imshow(tm, interpolation=\"nearest\", cmap=\"gray\")\n        ax[img_no, 0].set_title(\"Ground Truth Image\")\n        ax[img_no, 1].set_title(\"Ground Truth Mask\")\n        ax[img_no, 2].set_title(\"Predicted Mask\")\n        ax[img_no, 0].set_axis_off()\n        ax[img_no, 1].set_axis_off()\n        ax[img_no, 2].set_axis_off()\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-08-02T07:31:31.126687Z","iopub.execute_input":"2022-08-02T07:31:31.127344Z","iopub.status.idle":"2022-08-02T07:31:31.144044Z","shell.execute_reply.started":"2022-08-02T07:31:31.127288Z","shell.execute_reply":"2022-08-02T07:31:31.143060Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize_predict(model, 6)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T07:31:33.928700Z","iopub.execute_input":"2022-08-02T07:31:33.929742Z","iopub.status.idle":"2022-08-02T07:31:37.118821Z","shell.execute_reply.started":"2022-08-02T07:31:33.929692Z","shell.execute_reply":"2022-08-02T07:31:37.117851Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import zipfile\nif not os.path.exists('/kaggle/working/sample'):\n    os.mkdir('/kaggle/working/sample')\n    \nzip_path = '/kaggle/input/data-science-bowl-2018/stage1_sample_submission.csv.zip'\nwith zipfile.ZipFile(zip_path, 'r') as zip_ref:\n    zip_ref.extractall('/kaggle/working/sample')\n    print('Done!')","metadata":{"execution":{"iopub.status.busy":"2022-08-02T07:31:41.821953Z","iopub.execute_input":"2022-08-02T07:31:41.822353Z","iopub.status.idle":"2022-08-02T07:31:41.848107Z","shell.execute_reply.started":"2022-08-02T07:31:41.822316Z","shell.execute_reply":"2022-08-02T07:31:41.847036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\ndf=pd.read_csv('/kaggle/working/sample/stage1_sample_submission.csv')\ndf","metadata":{"execution":{"iopub.status.busy":"2022-08-02T07:31:43.572075Z","iopub.execute_input":"2022-08-02T07:31:43.573619Z","iopub.status.idle":"2022-08-02T07:31:43.606863Z","shell.execute_reply.started":"2022-08-02T07:31:43.573554Z","shell.execute_reply":"2022-08-02T07:31:43.605136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import zipfile\nif not os.path.exists('/kaggle/working/test'):\n    os.mkdir('/kaggle/working/test')\n    \nzip_path = '/kaggle/input/data-science-bowl-2018/stage1_test.zip'\nwith zipfile.ZipFile(zip_path, 'r') as zip_ref:\n    zip_ref.extractall('/kaggle/working/test')\n    print('Done!')","metadata":{"execution":{"iopub.status.busy":"2022-08-02T07:37:50.741322Z","iopub.execute_input":"2022-08-02T07:37:50.742424Z","iopub.status.idle":"2022-08-02T07:37:50.957115Z","shell.execute_reply.started":"2022-08-02T07:37:50.742383Z","shell.execute_reply":"2022-08-02T07:37:50.955868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Test_data(Dataset):\n        def __init__(self,path,is_transform=False):\n            self.path = path\n            self.folders = os.listdir(path)\n            self.transforms = get_transforms(is_transform)\n        \n        def __len__(self):\n            return len(self.folders)\n              \n        \n        def __getitem__(self,idx):\n            image_folder = os.path.join(self.path,self.folders[idx],'images/')\n            image_path = os.path.join(image_folder,os.listdir(image_folder)[0])\n            img = io.imread(image_path)[:,:,:3].astype('float32')\n            img = transform.resize(img,(128,128))\n            augmented = self.transforms(image=img)\n            img = augmented['image']\n            return img\n","metadata":{"execution":{"iopub.status.busy":"2022-08-02T08:39:00.878838Z","iopub.execute_input":"2022-08-02T08:39:00.879832Z","iopub.status.idle":"2022-08-02T08:39:00.888635Z","shell.execute_reply.started":"2022-08-02T08:39:00.879783Z","shell.execute_reply":"2022-08-02T08:39:00.887432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dir = '/kaggle/working/test/'\ntest_data = Test_data(test_dir,is_transform=False)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T08:39:04.679504Z","iopub.execute_input":"2022-08-02T08:39:04.680283Z","iopub.status.idle":"2022-08-02T08:39:04.685840Z","shell.execute_reply.started":"2022-08-02T08:39:04.680241Z","shell.execute_reply":"2022-08-02T08:39:04.684410Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_loader = torch.utils.data.DataLoader(dataset=test_data,shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:12:07.621231Z","iopub.execute_input":"2022-08-02T09:12:07.621885Z","iopub.status.idle":"2022-08-02T09:12:07.628157Z","shell.execute_reply.started":"2022-08-02T09:12:07.621845Z","shell.execute_reply":"2022-08-02T09:12:07.626757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict(loader=test_loader):\n    predictions=[]\n    # pbar = tqdm(loader, desc = 'description')\n    with torch.no_grad():\n        # for image in pbar:\n        for image in loader:\n            image = image.to(device,dtype=torch.float)\n            output = model(image)\n            prediction=torch.squeeze(output,0)\n            predictions.append(mask_convert(prediction))\n    return predictions","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:14:41.636441Z","iopub.execute_input":"2022-08-02T09:14:41.636898Z","iopub.status.idle":"2022-08-02T09:14:41.644246Z","shell.execute_reply.started":"2022-08-02T09:14:41.636861Z","shell.execute_reply":"2022-08-02T09:14:41.642615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions=predict()","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:14:43.998585Z","iopub.execute_input":"2022-08-02T09:14:43.999682Z","iopub.status.idle":"2022-08-02T09:14:46.584865Z","shell.execute_reply.started":"2022-08-02T09:14:43.999641Z","shell.execute_reply":"2022-08-02T09:14:46.583746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:14:52.706300Z","iopub.execute_input":"2022-08-02T09:14:52.707425Z","iopub.status.idle":"2022-08-02T09:14:52.757855Z","shell.execute_reply.started":"2022-08-02T09:14:52.707371Z","shell.execute_reply":"2022-08-02T09:14:52.756457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from skimage.morphology import label","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:21:54.132694Z","iopub.execute_input":"2022-08-02T09:21:54.133086Z","iopub.status.idle":"2022-08-02T09:21:54.138700Z","shell.execute_reply.started":"2022-08-02T09:21:54.133052Z","shell.execute_reply":"2022-08-02T09:21:54.137498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Run-length encoding stolen from https://www.kaggle.com/rakhlin/fast-run-length-encoding-python\ndef rle_encoding(x):\n    dots = np.where(x.T.flatten() == 1)[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    return run_lengths\n\ndef prob_to_rles(x, cutoff=0.5):\n    lab_img = label(x > cutoff)\n    for i in range(1, lab_img.max() + 1):\n        yield rle_encoding(lab_img == i)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:21:56.974249Z","iopub.execute_input":"2022-08-02T09:21:56.974909Z","iopub.status.idle":"2022-08-02T09:21:56.982580Z","shell.execute_reply.started":"2022-08-02T09:21:56.974869Z","shell.execute_reply":"2022-08-02T09:21:56.981440Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_ids=os.listdir(test_dir)\n","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:22:05.675839Z","iopub.execute_input":"2022-08-02T09:22:05.676816Z","iopub.status.idle":"2022-08-02T09:22:05.682523Z","shell.execute_reply.started":"2022-08-02T09:22:05.676772Z","shell.execute_reply":"2022-08-02T09:22:05.681366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_test_ids = []\nrles = []\nfor n, id_ in enumerate(test_ids):\n    rle = list(prob_to_rles(predictions[n]))\n    rles.extend(rle)\n    new_test_ids.extend([id_] * len(rle))","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:22:07.100914Z","iopub.execute_input":"2022-08-02T09:22:07.101322Z","iopub.status.idle":"2022-08-02T09:22:08.511022Z","shell.execute_reply.started":"2022-08-02T09:22:07.101285Z","shell.execute_reply":"2022-08-02T09:22:08.509945Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.DataFrame()\nsub['ImageId'] = new_test_ids\nsub['EncodedPixels'] = pd.Series(rles).apply(lambda x: ' '.join(str(y) for y in x))\nsub.to_csv('sub.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:23:38.242312Z","iopub.execute_input":"2022-08-02T09:23:38.242729Z","iopub.status.idle":"2022-08-02T09:23:38.255311Z","shell.execute_reply.started":"2022-08-02T09:23:38.242691Z","shell.execute_reply":"2022-08-02T09:23:38.253868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub","metadata":{"execution":{"iopub.status.busy":"2022-08-02T09:23:39.929370Z","iopub.execute_input":"2022-08-02T09:23:39.929766Z","iopub.status.idle":"2022-08-02T09:23:39.946731Z","shell.execute_reply.started":"2022-08-02T09:23:39.929732Z","shell.execute_reply":"2022-08-02T09:23:39.945551Z"},"trusted":true},"execution_count":null,"outputs":[]}]}