{"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":"# Since the evaluation method for this competition is \"instance segmentation\", this notebook **cannot** be used directly for submission.\n \nPlease use this notebook as a reference for semantic segmentation.","metadata":{}},{"cell_type":"markdown","source":"The codes in this notebook refer to https://github.com/YutaroOgawa/pytorch_advanced/tree/master/3_semantic_segmentation.\n\n\nCopyright (c) 2019 Yutaro Ogawa\n\nReleased under the MIT license\nhttps://github.com/YutaroOgawa/pytorch_advanced/blob/master/LICENSE","metadata":{}},{"cell_type":"code","source":"import os\nimport sys\n\nimport random\nimport math\nimport time\nimport pandas as pd\nimport numpy as np\n\nimport torch\nimport torch.utils.data as data\nimport torch.nn as nn\nimport torch.nn.init as init\nimport torch.nn.functional as F\nimport torch.optim as optim","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:02.727599Z","iopub.execute_input":"2021-11-08T10:14:02.728365Z","iopub.status.idle":"2021-11-08T10:14:04.375372Z","shell.execute_reply.started":"2021-11-08T10:14:02.728231Z","shell.execute_reply":"2021-11-08T10:14:04.374316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.manual_seed(1234)\nnp.random.seed(1234)\nrandom.seed(1234)","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:04.37763Z","iopub.execute_input":"2021-11-08T10:14:04.378027Z","iopub.status.idle":"2021-11-08T10:14:04.387704Z","shell.execute_reply.started":"2021-11-08T10:14:04.37797Z","shell.execute_reply":"2021-11-08T10:14:04.386508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.mkdir('./utils')\nos.mkdir('./weights')\nsys.path.append('./utils')","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:04.388717Z","iopub.execute_input":"2021-11-08T10:14:04.388986Z","iopub.status.idle":"2021-11-08T10:14:04.398261Z","shell.execute_reply.started":"2021-11-08T10:14:04.388941Z","shell.execute_reply":"2021-11-08T10:14:04.397224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from shutil import copyfile\ncopyfile(src = \"../input/utils-train/data_augumentation.py\", dst = \"./utils/data_augumentation.py\")\ncopyfile(src = \"../input/utils-train/dataloader.py\", dst = \"./utils/dataloader.py\")\ncopyfile(src = \"../input/utils-train/pspnet.py\", dst = \"./utils/pspnet.py\")","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:04.402114Z","iopub.execute_input":"2021-11-08T10:14:04.402619Z","iopub.status.idle":"2021-11-08T10:14:04.435274Z","shell.execute_reply.started":"2021-11-08T10:14:04.402439Z","shell.execute_reply":"2021-11-08T10:14:04.434182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from dataloader import make_datapath_list, DataTransform, VOCDataset\n\nrootpath = \"../input/sartorius-cell-instance-segmentation/\"\ntrain_img_list, train_anno_list, val_img_list, val_anno_list = make_datapath_list(\n    rootpath=rootpath)\n\ncolor_mean = (1.0, 1.0, 1.0)\ncolor_std = (1.0, 1.0, 1.0)\n\ntrain_dataset = VOCDataset(train_img_list, train_anno_list, phase=\"train\", transform=DataTransform(\n    input_size=520, color_mean=color_mean, color_std=color_std))\n\nval_dataset = VOCDataset(val_img_list, val_anno_list, phase=\"val\", transform=DataTransform(\n    input_size=520, color_mean=color_mean, color_std=color_std))\n\nbatch_size = 8\n\ntrain_dataloader = data.DataLoader(\n    train_dataset, batch_size=batch_size, shuffle=True)\n\nval_dataloader = data.DataLoader(\n    val_dataset, batch_size=batch_size, shuffle=False)\n\ndataloaders_dict = {\"train\": train_dataloader, \"val\": val_dataloader}","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:04.436813Z","iopub.execute_input":"2021-11-08T10:14:04.437203Z","iopub.status.idle":"2021-11-08T10:14:04.857944Z","shell.execute_reply.started":"2021-11-08T10:14:04.437129Z","shell.execute_reply":"2021-11-08T10:14:04.856802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(val_dataset.__getitem__(0)[0].shape)\nprint(val_dataset.__getitem__(0)[1].shape)\nprint(val_dataset.__getitem__(0))","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:04.862351Z","iopub.execute_input":"2021-11-08T10:14:04.862676Z","iopub.status.idle":"2021-11-08T10:14:05.238212Z","shell.execute_reply.started":"2021-11-08T10:14:04.862645Z","shell.execute_reply":"2021-11-08T10:14:05.236548Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from utils.pspnet import PSPNet\n\nnet = PSPNet(n_classes=150)\n\nn_classes = 1\nnet.decode_feature.classification = nn.Conv2d(\n    in_channels=512, out_channels=n_classes, kernel_size=1, stride=1, padding=0)\n\nnet.aux.classification = nn.Conv2d(\n    in_channels=256, out_channels=n_classes, kernel_size=1, stride=1, padding=0)\n\ndef weights_init(m):\n    if isinstance(m, nn.Conv2d):\n        nn.init.xavier_normal_(m.weight.data)\n        if m.bias is not None:\n            nn.init.constant_(m.bias, 0.0)\n\nnet.decode_feature.classification.apply(weights_init)\nnet.aux.classification.apply(weights_init)","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:05.240882Z","iopub.execute_input":"2021-11-08T10:14:05.241217Z","iopub.status.idle":"2021-11-08T10:14:05.995101Z","shell.execute_reply.started":"2021-11-08T10:14:05.24117Z","shell.execute_reply":"2021-11-08T10:14:05.994012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"net","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:05.99695Z","iopub.execute_input":"2021-11-08T10:14:05.997298Z","iopub.status.idle":"2021-11-08T10:14:06.010054Z","shell.execute_reply.started":"2021-11-08T10:14:05.997255Z","shell.execute_reply":"2021-11-08T10:14:06.008713Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import log_loss","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:06.012336Z","iopub.execute_input":"2021-11-08T10:14:06.013175Z","iopub.status.idle":"2021-11-08T10:14:06.956291Z","shell.execute_reply.started":"2021-11-08T10:14:06.013108Z","shell.execute_reply":"2021-11-08T10:14:06.955205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class PSPLoss(nn.Module):\n\n    def __init__(self, aux_weight=0.4):\n        super(PSPLoss, self).__init__()\n        self.aux_weight = aux_weight\n\n    def forward(self, outputs, targets):\n        \n        loss = F.binary_cross_entropy_with_logits(torch.reshape(outputs[0], ([-1, 520, 520])), targets.to(torch.float32))      \n        loss_aux = F.binary_cross_entropy_with_logits(torch.reshape(outputs[1], ([-1, 520, 520])), targets.to(torch.float32)) \n\n        return loss+self.aux_weight*loss_aux\n\ncriterion = PSPLoss(aux_weight=0.4)","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:06.961463Z","iopub.execute_input":"2021-11-08T10:14:06.96176Z","iopub.status.idle":"2021-11-08T10:14:06.972272Z","shell.execute_reply.started":"2021-11-08T10:14:06.96171Z","shell.execute_reply":"2021-11-08T10:14:06.970822Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer = optim.SGD([\n    {'params': net.feature_conv.parameters(), 'lr': 1e-3},\n    {'params': net.feature_res_1.parameters(), 'lr': 1e-3},\n    {'params': net.feature_res_2.parameters(), 'lr': 1e-3},\n    {'params': net.feature_dilated_res_1.parameters(), 'lr': 1e-3},\n    {'params': net.feature_dilated_res_2.parameters(), 'lr': 1e-3},\n    {'params': net.pyramid_pooling.parameters(), 'lr': 1e-3},\n    {'params': net.decode_feature.parameters(), 'lr': 1e-2},\n    {'params': net.aux.parameters(), 'lr': 1e-2},\n], momentum=0.9, weight_decay=0.0001)\n\ndef lambda_epoch(epoch):\n    max_epoch = 100\n    return math.pow((1-epoch/max_epoch), 0.9)\n\nscheduler = optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda_epoch)","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:06.974071Z","iopub.execute_input":"2021-11-08T10:14:06.974906Z","iopub.status.idle":"2021-11-08T10:14:06.991224Z","shell.execute_reply.started":"2021-11-08T10:14:06.974846Z","shell.execute_reply":"2021-11-08T10:14:06.990066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_model(net, dataloaders_dict, criterion, scheduler, optimizer, num_epochs):\n\n    device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n\n    net.to(device)\n\n    torch.backends.cudnn.benchmark = True\n\n    num_train_imgs = len(dataloaders_dict[\"train\"].dataset)\n    num_val_imgs = len(dataloaders_dict[\"val\"].dataset)\n    batch_size = dataloaders_dict[\"train\"].batch_size\n\n    iteration = 1\n    logs = []\n\n    batch_multiplier = 3\n\n    for epoch in range(num_epochs):\n\n        t_epoch_start = time.time()\n        t_iter_start = time.time()\n        epoch_train_loss = 0.0 \n        epoch_val_loss = 0.0 \n\n        print('-------------')\n        print('Epoch {}/{}'.format(epoch+1, num_epochs))\n        print('-------------')\n\n        for phase in ['train', 'val']:\n            if phase == 'train':\n                net.train()  \n                scheduler.step()\n                optimizer.zero_grad()\n                print('（train）')\n\n            else:\n                if((epoch+1) % 5 == 0):\n                    net.eval() \n                    print('-------------')\n                    print('（val）')\n                else:\n                    continue\n\n            count = 0 \n            for imges, anno_class_imges in dataloaders_dict[phase]:\n                if imges.size()[0] == 1:\n                    continue\n\n                imges = imges.to(device)\n                anno_class_imges = anno_class_imges.to(device)\n\n                if (phase == 'train') and (count == 0):\n                    optimizer.step()\n                    optimizer.zero_grad()\n                    count = batch_multiplier\n\n                with torch.set_grad_enabled(phase == 'train'):\n                    outputs = net(imges)\n                    loss = criterion(\n                        outputs, anno_class_imges.long()) / batch_multiplier\n\n                    if phase == 'train':\n                        loss.backward()\n                        count -= 1 \n\n                        if (iteration % 10 == 0):\n                            t_iter_finish = time.time()\n                            duration = t_iter_finish - t_iter_start\n                            print('iterations {} || Loss: {:.4f} || 10iter: {:.4f} sec.'.format(\n                                iteration, loss.item()/batch_size*batch_multiplier, duration))\n                            t_iter_start = time.time()\n\n                        epoch_train_loss += loss.item() * batch_multiplier\n                        iteration += 1\n\n                    else:\n                        epoch_val_loss += loss.item() * batch_multiplier\n\n        t_epoch_finish = time.time()\n        print('-------------')\n        print('epoch {} || Epoch_TRAIN_Loss:{:.4f} ||Epoch_VAL_Loss:{:.4f}'.format(\n            epoch+1, epoch_train_loss/num_train_imgs, epoch_val_loss/num_val_imgs))\n        print('timer:  {:.4f} sec.'.format(t_epoch_finish - t_epoch_start))\n        t_epoch_start = time.time()\n\n        log_epoch = {'epoch': epoch+1, 'train_loss': epoch_train_loss /\n                     num_train_imgs, 'val_loss': epoch_val_loss/num_val_imgs}\n        logs.append(log_epoch)\n        df = pd.DataFrame(logs)\n        df.to_csv(\"log_output.csv\")\n\n    torch.save(net.state_dict(), 'weights/pspnet50_' +\n               str(epoch+1) + '.pth')","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:06.992818Z","iopub.execute_input":"2021-11-08T10:14:06.993414Z","iopub.status.idle":"2021-11-08T10:14:07.018333Z","shell.execute_reply.started":"2021-11-08T10:14:06.993356Z","shell.execute_reply":"2021-11-08T10:14:07.016637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_epochs = 40\ntrain_model(net, dataloaders_dict, criterion, scheduler, optimizer, num_epochs=num_epochs)","metadata":{"execution":{"iopub.status.busy":"2021-11-08T10:14:07.025947Z","iopub.execute_input":"2021-11-08T10:14:07.027645Z","iopub.status.idle":"2021-11-08T10:16:50.927338Z","shell.execute_reply.started":"2021-11-08T10:14:07.027574Z","shell.execute_reply":"2021-11-08T10:16:50.92631Z"},"trusted":true},"execution_count":null,"outputs":[]}]}