{"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":"import os\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nimport cv2\nimport matplotlib.pyplot as plt\n\nfrom sklearn.model_selection import train_test_split\n\nimport torch \nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchvision\nimport torchvision.transforms as transforms\nfrom torch.utils.data import TensorDataset, DataLoader, Dataset","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-03-27T07:26:28.730302Z","iopub.execute_input":"2022-03-27T07:26:28.730777Z","iopub.status.idle":"2022-03-27T07:26:31.449123Z","shell.execute_reply.started":"2022-03-27T07:26:28.730696Z","shell.execute_reply":"2022-03-27T07:26:31.448399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataの読み込み","metadata":{}},{"cell_type":"code","source":"path='../input/histopathologic-cancer-detection/train/'\nannotation_file='../input/histopathologic-cancer-detection/train_labels.csv'\ntest_path='../input/histopathologic-cancer-detection/test/'","metadata":{"execution":{"iopub.status.busy":"2022-03-27T07:26:33.606903Z","iopub.execute_input":"2022-03-27T07:26:33.607568Z","iopub.status.idle":"2022-03-27T07:26:33.612144Z","shell.execute_reply.started":"2022-03-27T07:26:33.607532Z","shell.execute_reply":"2022-03-27T07:26:33.61132Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data =pd.read_csv('../input/histopathologic-cancer-detection/train_labels.csv')\nsub_df = pd.read_csv('../input/histopathologic-cancer-detection/sample_submission.csv')\ntrain_data.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-27T09:45:45.170909Z","iopub.execute_input":"2022-03-27T09:45:45.17116Z","iopub.status.idle":"2022-03-27T09:45:45.584923Z","shell.execute_reply.started":"2022-03-27T09:45:45.171133Z","shell.execute_reply":"2022-03-27T09:45:45.584216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_data.shape)","metadata":{"execution":{"iopub.status.busy":"2022-03-27T07:26:38.072275Z","iopub.execute_input":"2022-03-27T07:26:38.072808Z","iopub.status.idle":"2022-03-27T07:26:38.077865Z","shell.execute_reply.started":"2022-03-27T07:26:38.072769Z","shell.execute_reply":"2022-03-27T07:26:38.076744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataの内訳","metadata":{}},{"cell_type":"code","source":"#　円グラフにてデータの内訳を視覚化\nplt.pie(train_data.label.value_counts(), labels=['No Cancer', 'Cancer'], \n        colors=['#1f18ed', '#ed1818'], autopct='%1.1f', startangle=90)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-27T07:26:39.539184Z","iopub.execute_input":"2022-03-27T07:26:39.539737Z","iopub.status.idle":"2022-03-27T07:26:39.671166Z","shell.execute_reply.started":"2022-03-27T07:26:39.539701Z","shell.execute_reply":"2022-03-27T07:26:39.670228Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data['label'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-03-27T07:26:41.917851Z","iopub.execute_input":"2022-03-27T07:26:41.918094Z","iopub.status.idle":"2022-03-27T07:26:41.925973Z","shell.execute_reply.started":"2022-03-27T07:26:41.918066Z","shell.execute_reply":"2022-03-27T07:26:41.925227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 画像の視覚化\nランダムで画像を２０枚抽出しラベル１とラベル０を貼り付ける","metadata":{}},{"cell_type":"code","source":"# サイズの指定\nfig = plt.figure(figsize=(25, 25))\n# 20枚画像を表示\ntrain_imgs = os.listdir(path)\nfor idx, img in enumerate(np.random.choice(train_imgs, 20)):\n    ax = fig.add_subplot(4, 20//4, idx+1, xticks=[], yticks=[])\n    im = Image.open(path + img)\n    plt.imshow(im)\n    lab = train_data.loc[train_data['id'] == img.split('.')[0], 'label'].values[0]\n    ax.set_title(f'Label: {lab}')","metadata":{"execution":{"iopub.status.busy":"2022-03-27T07:26:44.001916Z","iopub.execute_input":"2022-03-27T07:26:44.002522Z","iopub.status.idle":"2022-03-27T07:26:49.812555Z","shell.execute_reply.started":"2022-03-27T07:26:44.002483Z","shell.execute_reply":"2022-03-27T07:26:49.809459Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataを学習用とテスト用に分ける","metadata":{}},{"cell_type":"code","source":"train, val = train_test_split(train_data, stratify=train_data.label, test_size=0.1)\nlen(train), len(val)","metadata":{"execution":{"iopub.status.busy":"2022-03-27T07:26:54.936508Z","iopub.execute_input":"2022-03-27T07:26:54.936757Z","iopub.status.idle":"2022-03-27T07:26:55.040226Z","shell.execute_reply.started":"2022-03-27T07:26:54.93673Z","shell.execute_reply":"2022-03-27T07:26:55.039392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DadaSetの作成","metadata":{}},{"cell_type":"code","source":"class Dataset(Dataset):\n    def __init__(self, data_df, data_dir = './', transform=None):\n        super().__init__()\n        self.df = data_df.values\n        self.data_dir = data_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, index):\n        img_name,label = self.df[index]\n        img_path = os.path.join(self.data_dir, img_name + '.tif')\n        image = cv2.imread(img_path)\n        if self.transform is not None:\n            image = self.transform(image)\n        return image, label","metadata":{"execution":{"iopub.status.busy":"2022-03-27T07:26:56.664089Z","iopub.execute_input":"2022-03-27T07:26:56.664816Z","iopub.status.idle":"2022-03-27T07:26:56.67175Z","shell.execute_reply.started":"2022-03-27T07:26:56.664765Z","shell.execute_reply":"2022-03-27T07:26:56.671091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 128\n\nvalid_size = 0.1","metadata":{"execution":{"iopub.status.busy":"2022-03-27T07:26:58.807797Z","iopub.execute_input":"2022-03-27T07:26:58.808348Z","iopub.status.idle":"2022-03-27T07:26:58.812029Z","shell.execute_reply.started":"2022-03-27T07:26:58.808307Z","shell.execute_reply":"2022-03-27T07:26:58.810953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 画像の処理","metadata":{}},{"cell_type":"code","source":"trans_train = transforms.Compose([transforms.ToPILImage(),                      #compose=複数のTransformを連続して行う\n                                  transforms.Pad(64, padding_mode='reflect'),   #テンソルまたは ndarray を PIL Image オブジェクトに変換する\n                                  transforms.RandomHorizontalFlip(),            #ランダムに左右反転を行う\n                                  transforms.RandomVerticalFlip(),              #ランダムに上下反転を行う\n                                  transforms.RandomRotation(20),                #ランダムに回転を行う\n                                  transforms.ToTensor(),                        #PIL Image をテンソルに変換する\n                                  transforms.Normalize(mean=[0.5, 0.5, 0.5],std=[0.5, 0.5, 0.5])])      #正規化を行う()\n\ntrans_valid = transforms.Compose([transforms.ToPILImage(),\n                                  transforms.Pad(64, padding_mode='reflect'),\n                                  transforms.ToTensor(),\n                                  transforms.Normalize(mean=[0.5, 0.5, 0.5],std=[0.5, 0.5, 0.5])])\n\ndataset_train = Dataset(data_df=train, data_dir=path, transform=trans_train)\ndataset_valid = Dataset(data_df=val, data_dir=path, transform=trans_valid)\n\ntrain_loader = DataLoader(dataset = dataset_train, batch_size=batch_size, shuffle=True, num_workers=0)\nvalid_loader = DataLoader(dataset = dataset_valid, batch_size=batch_size//2, shuffle=False, num_workers=0)","metadata":{"execution":{"iopub.status.busy":"2022-03-27T07:27:01.051521Z","iopub.execute_input":"2022-03-27T07:27:01.051859Z","iopub.status.idle":"2022-03-27T07:27:01.080843Z","shell.execute_reply.started":"2022-03-27T07:27:01.051825Z","shell.execute_reply":"2022-03-27T07:27:01.080147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# モデルの定義","metadata":{}},{"cell_type":"code","source":"class CNN(nn.Module):\n    def __init__(self):\n        super(CNN, self).__init__()\n        self.layer1 = nn.Sequential(\n            nn.Conv2d(3, 32, kernel_size=3, padding=2),\n            nn.BatchNorm2d(32),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size=2, stride=2))\n        self.layer2 = nn.Sequential(\n            nn.Conv2d(32, 64, kernel_size=3, padding=2),\n            nn.BatchNorm2d(64),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size=2, stride=2))\n        self.layer3 = nn.Sequential(\n            nn.Conv2d(64, 128, kernel_size=3, padding=2),\n            nn.BatchNorm2d(128),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size=2, stride=2))\n        self.layer4 = nn.Sequential(\n            nn.Conv2d(128, 256, kernel_size=3, padding=2),\n            nn.BatchNorm2d(256),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size=2, stride=2))\n        self.layer5 = nn.Sequential(\n            nn.Conv2d(256, 512, kernel_size=3, padding=2),\n            nn.BatchNorm2d(512),\n            nn.ReLU(),\n            nn.MaxPool2d(kernel_size=2, stride=2))\n        self.avg = nn.AvgPool2d(8)\n        self.fc = nn.Linear(512 * 1 * 1, 2)\n        \n    def forward(self,x):\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n        x = self.layer5(x)\n        x = self.avg(x)\n        x = x.view(-1, 512 * 1 * 1)\n        x = self.fc(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-03-27T07:27:05.448149Z","iopub.execute_input":"2022-03-27T07:27:05.448694Z","iopub.status.idle":"2022-03-27T07:27:05.46108Z","shell.execute_reply.started":"2022-03-27T07:27:05.448655Z","shell.execute_reply":"2022-03-27T07:27:05.460254Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# モデルの入出力の確認","metadata":{}},{"cell_type":"code","source":"device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')\nmodel = CNN().to(device)\nprint(model)","metadata":{"execution":{"iopub.status.busy":"2022-03-27T07:27:10.546421Z","iopub.execute_input":"2022-03-27T07:27:10.546729Z","iopub.status.idle":"2022-03-27T07:27:13.629185Z","shell.execute_reply.started":"2022-03-27T07:27:10.546699Z","shell.execute_reply":"2022-03-27T07:27:13.627666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 最適化と損失関数\n","metadata":{}},{"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\n\nlearning_rate = 0.002\noptimizer = torch.optim.Adam(model.parameters(),lr=learning_rate)","metadata":{"execution":{"iopub.status.busy":"2022-03-27T07:27:17.149078Z","iopub.execute_input":"2022-03-27T07:27:17.149769Z","iopub.status.idle":"2022-03-27T07:27:17.156148Z","shell.execute_reply.started":"2022-03-27T07:27:17.149731Z","shell.execute_reply":"2022-03-27T07:27:17.155397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 学習モデル","metadata":{}},{"cell_type":"code","source":"num_epochs = 10\ntotal_step = len(train_loader)\nfor epoch in range(num_epochs):\n    \n    train_loss = 0.0\n    valid_loss = 0.0\n    \n    for i, (images, labels) in enumerate(train_loader):\n        images = images.to(device)\n        labels = labels.to(device)\n        \n        output = model(images)\n        loss = criterion(output, labels)\n        \n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        \n        train_loss += loss.item()*images.size(0)\n        \n        train_loss = train_loss/len(train_loader.sampler)\n        \n        if (i+1) % 100 == 0:\n            print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' \n                   .format(epoch+1, num_epochs, i+1, total_step, loss.item()))","metadata":{"execution":{"iopub.status.busy":"2022-03-27T08:33:31.368204Z","iopub.execute_input":"2022-03-27T08:33:31.368925Z","iopub.status.idle":"2022-03-27T09:26:09.734223Z","shell.execute_reply.started":"2022-03-27T08:33:31.368886Z","shell.execute_reply":"2022-03-27T09:26:09.733519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# テストモデル","metadata":{}},{"cell_type":"code","source":"model.eval()  \nwith torch.no_grad():\n    correct = 0\n    total = 0\n    for images, labels in valid_loader:\n        images = images.to(device)\n        labels = labels.to(device)\n        outputs = model(images)\n        _, predicted = torch.max(outputs.data, 1)\n        total += labels.size(0)\n        correct += (predicted == labels).sum().item()\n          \n    print('Test Accuracy of the model on the 22003 test images: {} %'.format(100 * correct / total))\n\n# Save the model checkpoint\ntorch.save(model.state_dict(), 'model.ckpt')","metadata":{"execution":{"iopub.status.busy":"2022-03-27T09:28:31.390507Z","iopub.execute_input":"2022-03-27T09:28:31.390757Z","iopub.status.idle":"2022-03-27T09:29:54.641683Z","shell.execute_reply.started":"2022-03-27T09:28:31.390731Z","shell.execute_reply":"2022-03-27T09:29:54.640902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_valid = Dataset(data_df=sub_df, data_dir=test_path, transform=trans_valid)\nloader_test = DataLoader(dataset = dataset_valid, batch_size=32, shuffle=False, num_workers=0)","metadata":{"execution":{"iopub.status.busy":"2022-03-27T09:30:35.059313Z","iopub.execute_input":"2022-03-27T09:30:35.059621Z","iopub.status.idle":"2022-03-27T09:30:35.070651Z","shell.execute_reply.started":"2022-03-27T09:30:35.059589Z","shell.execute_reply":"2022-03-27T09:30:35.069553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.eval()\n\npreds = []\nfor batch_i, (data, target) in enumerate(loader_test):\n    data, target = data.cuda(), target.cuda()\n    output = model(data)\n\n    pr = output[:,1].detach().cpu().numpy()\n    for i in pr:\n        preds.append(i)","metadata":{"execution":{"iopub.status.busy":"2022-03-27T09:30:37.911687Z","iopub.execute_input":"2022-03-27T09:30:37.911934Z","iopub.status.idle":"2022-03-27T09:41:42.398009Z","shell.execute_reply.started":"2022-03-27T09:30:37.911907Z","shell.execute_reply":"2022-03-27T09:41:42.397148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 提出","metadata":{}},{"cell_type":"code","source":"sub_df.shape, len(preds)\nsub_df['label'] = preds\nsub_df.to_csv(\"./submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2022-03-27T09:46:10.698325Z","iopub.execute_input":"2022-03-27T09:46:10.699151Z","iopub.status.idle":"2022-03-27T09:46:10.918701Z","shell.execute_reply.started":"2022-03-27T09:46:10.699113Z","shell.execute_reply":"2022-03-27T09:46:10.917981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}