{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import sys\n\nsys.path.append('/kaggle/input/pytorchimagemodels')\nimport random\nimport numpy as np\nimport torch\nimport pandas as pd\nimport warnings\nimport os\nimport timm\nimport cv2\nfrom torch import nn\nfrom torch.utils.data import Dataset\nfrom sklearn.metrics import roc_auc_score\nfrom albumentations.pytorch import ToTensorV2\nfrom albumentations import (\n    Compose, OneOf, Normalize, Resize, RandomResizedCrop, RandomCrop, HorizontalFlip, VerticalFlip,\n    RandomBrightness, RandomContrast, RandomBrightnessContrast, Rotate, ShiftScaleRotate, Cutout,\n    IAAAdditiveGaussianNoise, Transpose\n)\nimport torch.nn.functional as F\n\n# print the whole table\npd.set_option('display.max_rows', 500)\npd.set_option('display.max_columns', 100)\npd.set_option('display.width', 1000)\n\npath = \"/kaggle/input/ranzcr-clip-catheter-line-classification/\"\n\n\n\nclass PARAMETER:\n    split_ratio = 80\n    # 1/100 的验证集\n    stop_train_batch = -1\n    # 在第  100  个  batch停止训练\n    epochs = 1\n    batch_size = 32\n    size = 320\n    target_size = 11\n    num_workers = 4\n    target_cols = ['ETT - Abnormal', 'ETT - Borderline', 'ETT - Normal',\n                   'NGT - Abnormal', 'NGT - Borderline', 'NGT - Incompletely Imaged', 'NGT - Normal',\n                   'CVC - Abnormal', 'CVC - Borderline', 'CVC - Normal',\n                   'Swan Ganz Catheter Present']\n\n\nclass BasicConv2d(nn.Module):\n    def __init__(self, in_channels, out_channels, **kwargs):\n        super(BasicConv2d, self).__init__()\n        self.conv = nn.Conv2d(in_channels, out_channels, **kwargs)\n        self.bn = nn.BatchNorm2d(out_channels)\n\n    def forward(self, x):\n        x = self.conv(x)\n        x = self.bn(x)\n        return F.relu(x)\n\n\nclass InceptionA(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super(InceptionA, self).__init__()\n        # branch1: avgpool --> conv1*1(96)\n        self.b1_1 = nn.AvgPool2d(kernel_size=3, padding=1, stride=1)\n        self.b1_2 = BasicConv2d(in_channels, 96, kernel_size=1)\n\n        # branch2: conv1*1(96)\n        self.b2 = BasicConv2d(in_channels, 96, kernel_size=1)\n\n        # branch3: conv1*1(64) --> conv3*3(96)\n        self.b3_1 = BasicConv2d(in_channels, 64, kernel_size=1)\n        self.b3_2 = BasicConv2d(64, 96, kernel_size=3, padding=1)\n\n        # branch4: conv1*1(64) --> conv3*3(96) --> conv3*3(96)\n        self.b4_1 = BasicConv2d(in_channels, 64, kernel_size=1)\n        self.b4_2 = BasicConv2d(64, 96, kernel_size=3, padding=1)\n        self.b4_3 = BasicConv2d(96, 96, kernel_size=3, padding=1)\n\n    def forward(self, x):\n        y1 = self.b1_2(self.b1_1(x))\n        y2 = self.b2(x)\n        y3 = self.b3_2(self.b3_1(x))\n        y4 = self.b4_3(self.b4_2(self.b4_1(x)))\n\n        outputsA = [y1, y2, y3, y4]\n        return torch.cat(outputsA, 1)\n\n\nclass InceptionB(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super(InceptionB, self).__init__()\n        # branch1: avgpool --> conv1*1(128)\n        self.b1_1 = nn.AvgPool2d(kernel_size=3, padding=1, stride=1)\n        self.b1_2 = BasicConv2d(in_channels, 128, kernel_size=1)\n\n        # branch2: conv1*1(384)\n        self.b2 = BasicConv2d(in_channels, 384, kernel_size=1)\n\n        # branch3: conv1*1(192) --> conv1*7(224) --> conv1*7(256)\n        self.b3_1 = BasicConv2d(in_channels, 192, kernel_size=1)\n        self.b3_2 = BasicConv2d(192, 224, kernel_size=(1, 7), padding=(0, 3))\n        self.b3_3 = BasicConv2d(224, 256, kernel_size=(1, 7), padding=(0, 3))\n\n        # branch4: conv1*1(192) --> conv1*7(192) --> conv7*1(224) --> conv1*7(224) --> conv7*1(256)\n        self.b4_1 = BasicConv2d(in_channels, 192, kernel_size=1, stride=1)\n        self.b4_2 = BasicConv2d(192, 192, kernel_size=(1, 7), padding=(0, 3))\n        self.b4_3 = BasicConv2d(192, 224, kernel_size=(7, 1), padding=(3, 0))\n        self.b4_4 = BasicConv2d(224, 224, kernel_size=(1, 7), padding=(0, 3))\n        self.b4_5 = BasicConv2d(224, 256, kernel_size=(7, 1), padding=(3, 0))\n\n    def forward(self, x):\n        y1 = self.b1_2(self.b1_1(x))\n        y2 = self.b2(x)\n        y3 = self.b3_3(self.b3_2(self.b3_1(x)))\n        y4 = self.b4_5(self.b4_4(self.b4_3(self.b4_2(self.b4_1(x)))))\n\n        outputsB = [y1, y2, y3, y4]\n        return torch.cat(outputsB, 1)\n\n\nclass InceptionC(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super(InceptionC, self).__init__()\n        # branch1: avgpool --> conv1*1(256)\n        self.b1_1 = nn.AvgPool2d(kernel_size=3, padding=1, stride=1)\n        self.b1_2 = BasicConv2d(in_channels, 256, kernel_size=1)\n\n        # branch2: conv1*1(256)\n        self.b2 = BasicConv2d(in_channels, 256, kernel_size=1)\n\n        # branch3: conv1*1(384) --> conv1*3(256) & conv3*1(256)\n        self.b3_1 = BasicConv2d(in_channels, 384, kernel_size=1)\n        self.b3_2_1 = BasicConv2d(384, 256, kernel_size=(1, 3), padding=(0, 1))\n        self.b3_2_2 = BasicConv2d(384, 256, kernel_size=(3, 1), padding=(1, 0))\n\n        # branch4: conv1*1(384) --> conv1*3(448) --> conv3*1(512) --> conv3*1(256) & conv7*1(256)\n        self.b4_1 = BasicConv2d(in_channels, 384, kernel_size=1, stride=1)\n        self.b4_2 = BasicConv2d(384, 448, kernel_size=(1, 3), padding=(0, 1))\n        self.b4_3 = BasicConv2d(448, 512, kernel_size=(3, 1), padding=(1, 0))\n        self.b4_4_1 = BasicConv2d(512, 256, kernel_size=(3, 1), padding=(1, 0))\n        self.b4_4_2 = BasicConv2d(512, 256, kernel_size=(1, 3), padding=(0, 1))\n\n    def forward(self, x):\n        y1 = self.b1_2(self.b1_1(x))\n        y2 = self.b2(x)\n        y3_1 = self.b3_2_1(self.b3_1(x))\n        y3_2 = self.b3_2_2(self.b3_1(x))\n        y4_1 = self.b4_4_1(self.b4_3(self.b4_2(self.b4_1(x))))\n        y4_2 = self.b4_4_2(self.b4_3(self.b4_2(self.b4_1(x))))\n\n        outputsC = [y1, y2, y3_1, y3_2, y4_1, y4_2]\n        return torch.cat(outputsC, 1)\n\n\nclass ReductionA(nn.Module):\n    def __init__(self, in_channels, out_channels, k, l, m, n):\n        super(ReductionA, self).__init__()\n        # branch1: maxpool3*3(stride2 valid)\n        self.b1 = nn.MaxPool2d(kernel_size=3, stride=2)\n\n        # branch2: conv3*3(n stride2 valid)\n        self.b2 = BasicConv2d(in_channels, n, kernel_size=3, stride=2)\n\n        # branch3: conv1*1(k) --> conv3*3(l) --> conv3*3(m stride2 valid)\n        self.b3_1 = BasicConv2d(in_channels, k, kernel_size=1)\n        self.b3_2 = BasicConv2d(k, l, kernel_size=3, padding=1)\n        self.b3_3 = BasicConv2d(l, m, kernel_size=3, stride=2)\n\n    def forward(self, x):\n        y1 = self.b1(x)\n        y2 = self.b2(x)\n        y3 = self.b3_3(self.b3_2(self.b3_1(x)))\n\n        outputsRedA = [y1, y2, y3]\n        return torch.cat(outputsRedA, 1)\n\n\nclass ReductionB(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super(ReductionB, self).__init__()\n        # branch1: maxpool3*3(stride2 valid)\n        self.b1 = nn.MaxPool2d(kernel_size=3, stride=2)\n\n        # branch2: conv1*1(192) --> conv3*3(192 stride2 valid)\n        self.b2_1 = BasicConv2d(in_channels, 192, kernel_size=1)\n        self.b2_2 = BasicConv2d(192, 192, kernel_size=3, stride=2)\n\n        # branch3: conv1*1(256) --> conv1*7(256) --> conv7*1(320) --> conv3*3(320 stride2 valid)\n        self.b3_1 = BasicConv2d(in_channels, 256, kernel_size=1)\n        self.b3_2 = BasicConv2d(256, 256, kernel_size=(1, 7), padding=(0, 3))\n        self.b3_3 = BasicConv2d(256, 320, kernel_size=(7, 1), padding=(3, 0))\n        self.b3_4 = BasicConv2d(320, 320, kernel_size=3, stride=2)\n\n    def forward(self, x):\n        y1 = self.b1(x)\n        y2 = self.b2_2(self.b2_1((x)))\n        y3 = self.b3_4(self.b3_3(self.b3_2(self.b3_1(x))))\n\n        outputsRedB = [y1, y2, y3]\n        return torch.cat(outputsRedB, 1)\n\n\nclass Stem(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super(Stem, self).__init__()\n        # conv3*3(32 stride2 valid)\n        self.conv1 = BasicConv2d(in_channels, 32, kernel_size=3, stride=2)\n        # conv3*3(32 valid)\n        self.conv2 = BasicConv2d(32, 32, kernel_size=3)\n        # conv3*3(64)\n        self.conv3 = BasicConv2d(32, 64, kernel_size=3, padding=1)\n        # maxpool3*3(stride2 valid) & conv3*3(96 stride2 valid)\n        self.maxpool4 = nn.MaxPool2d(kernel_size=3, stride=2)\n        self.conv4 = BasicConv2d(64, 96, kernel_size=3, stride=2)\n\n        # conv1*1(64) --> conv3*3(96 valid)\n        self.conv5_1_1 = BasicConv2d(160, 64, kernel_size=1)\n        self.conv5_1_2 = BasicConv2d(64, 96, kernel_size=3)\n        # conv1*1(64) --> conv7*1(64) --> conv1*7(64) --> conv3*3(96 valid)\n        self.conv5_2_1 = BasicConv2d(160, 64, kernel_size=1)\n        self.conv5_2_2 = BasicConv2d(64, 64, kernel_size=(7, 1), padding=(3, 0))\n        self.conv5_2_3 = BasicConv2d(64, 64, kernel_size=(1, 7), padding=(0, 3))\n        self.conv5_2_4 = BasicConv2d(64, 96, kernel_size=3)\n\n        # conv3*3(192 valid)\n        self.conv6 = BasicConv2d(192, 192, kernel_size=3, stride=2)\n        # maxpool3*3(stride2 valid)\n        self.maxpool6 = nn.MaxPool2d(kernel_size=3, stride=2)\n\n    def forward(self, x):\n        y1_1 = self.maxpool4(self.conv3(self.conv2(self.conv1(x))))\n        y1_2 = self.conv4(self.conv3(self.conv2(self.conv1(x))))\n        y1 = torch.cat([y1_1, y1_2], 1)\n\n        y2_1 = self.conv5_1_2(self.conv5_1_1(y1))\n        y2_2 = self.conv5_2_4(self.conv5_2_3(self.conv5_2_2(self.conv5_2_1(y1))))\n        y2 = torch.cat([y2_1, y2_2], 1)\n\n        y3_1 = self.conv6(y2)\n        y3_2 = self.maxpool6(y2)\n        y3 = torch.cat([y3_1, y3_2], 1)\n\n        return y3\n\n\nclass Googlenetv4(nn.Module):\n    def __init__(self):\n        super(Googlenetv4, self).__init__()\n        self.stem = Stem(3, 384)\n        self.icpA = InceptionA(384, 384)\n        self.redA = ReductionA(384, 1024, 192, 224, 256, 384)\n        self.icpB = InceptionB(1024, 1024)\n        self.redB = ReductionB(1024, 1536)\n        self.icpC = InceptionC(1536, 1536)\n        self.avgpool = nn.AvgPool2d(kernel_size=8)\n        self.dropout = nn.Dropout(p=0.8)\n        self.linear = nn.Linear(1536, 11)\n        self.soft_max = nn.Softmax()\n\n    def forward(self, x):\n        # Stem Module\n        out = self.stem(x)\n        # InceptionA Module * 4\n        out = self.icpA(self.icpA(self.icpA(self.icpA(out))))\n        # ReductionA Module\n        out = self.redA(out)\n        # InceptionB Module * 7\n        out = self.icpB(self.icpB(self.icpB(self.icpB(self.icpB(self.icpB(self.icpB(out)))))))\n        # ReductionB Module\n        out = self.redB(out)\n        # InceptionC Module * 3\n        out = self.icpC(self.icpC(self.icpC(out)))\n        # Average Pooling\n        out = self.avgpool(out)\n        out = out.view(out.size(0), -1)\n        # Dropout\n        out = self.dropout(out)\n        # Linear(Softmax)\n        out = self.linear(out)\n        out = self.soft_max(out)\n\n        return out\n\n\nclass MyModel(torch.nn.Module):\n    def __init__(self, model_name='resnext50_32x4d', pretrained=False):\n        super(MyModel, self).__init__()\n        # define structure of the network here\n        self.model = timm.create_model(model_name, pretrained=pretrained)\n        n_features = self.model.fc.in_features\n        self.model.fc = nn.Linear(n_features, PARAMETER.target_size)\n\n    def forward(self, input):\n        # apply network and return output\n        x = self.model(input)\n        return x\n\n\nclass LoadDataset(Dataset):\n    def __init__(self, df, transform=None):\n        self.df = df\n        self.file_names = df['StudyInstanceUID'].values\n        self.transform = transform\n        self.labels = df[PARAMETER.target_cols].values\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        file_name = self.file_names[idx]\n        file_path = f'{path}/train/{file_name}.jpg'\n        image = cv2.imread(file_path)\n#         image = cv2.resize(image, (512, 512))\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        if self.transform:\n            augmented = self.transform(image=image)\n            image = augmented['image']\n        label = torch.tensor(self.labels[idx]).float()\n        return image, label\n\n\nclass OutputModel(Dataset):\n    def __init__(self, df, transform=None):\n        self.df = df\n        self.file_names = df['StudyInstanceUID'].values\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        file_name = self.file_names[idx]\n        file_path = f'{path}/test/{file_name}.jpg'\n        image = cv2.imread(file_path)\n#         image = cv2.resize(image, (512, 512))\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        if self.transform:\n            augmented = self.transform(image=image)\n            image = augmented['image']\n        return image\n\n\ndef get_transforms(*, data):\n    if data == 'train':\n        return Compose([\n            # Resize(CFG.size, CFG.size),\n            RandomResizedCrop(PARAMETER.size, PARAMETER.size, scale=(0.85, 1.0)),\n            HorizontalFlip(p=0.5),\n            Normalize(\n                mean=[0.485, 0.456, 0.406],\n                std=[0.229, 0.224, 0.225],\n            ),\n            ToTensorV2(),\n        ])\n\n    elif data == 'valid':\n        return Compose([\n            Resize(PARAMETER.size, PARAMETER.size),\n            Normalize(\n                mean=[0.485, 0.456, 0.406],\n                std=[0.229, 0.224, 0.225],\n            ),\n            ToTensorV2(),\n        ])\n\n\ndef get_score(y_true, y_pred):\n    scores = []\n    for i in range(y_true.shape[1]):\n        score = roc_auc_score(y_true[:, i], y_pred[:, i].round())\n        scores.append(score)\n    avg_score = np.mean(scores)\n    return avg_score, scores\n\n\n\nwarnings.filterwarnings('ignore')\ndevice = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')\nprint(\"Using device: {}\"\n      \"\\n\".format(str(device)))\n\n# loading data\n\ndata = pd.read_csv(os.path.join(path, \"train.csv\"))\ndata['split_num'] = [random.randint(0,PARAMETER.split_ratio) for _ in range(len(data))]\n\ntrain = data[data['split_num'] != 1]\ntrain.drop(['split_num'],axis=1,inplace=True)\nvalid = data[data['split_num'] == 1]\nvalid.drop(['split_num'], axis=1, inplace=True)\n\ntrain_dataset = LoadDataset(train, transform=get_transforms(data='train'))\nvalid_dataset = LoadDataset(valid, transform=get_transforms(data='valid'))\n\n\nvalid_labels = valid[PARAMETER.target_cols].values\ntrain_loader = torch.utils.data.DataLoader(train_dataset,\n                                           batch_size=PARAMETER.batch_size,\n                                           shuffle=True,\n                                           num_workers=PARAMETER.num_workers, pin_memory=True, drop_last=True)\n\n\nvalid_loader = torch.utils.data.DataLoader(valid_dataset,\n                                           batch_size=PARAMETER.batch_size,\n                                           shuffle=False,\n                                           num_workers=PARAMETER.num_workers, pin_memory=True, drop_last=False)\n\n# for i in range(5):\n#     image, label = train_dataset[i]\n#     plt.imshow(image[0])\n#     plt.title(f'label: {label}')\n#     plt.show()\n\n#     net = MyModel().to(device)\nnet = Googlenetv4().to(device)\n\ncriterion = nn.BCEWithLogitsLoss()\noptimiser = torch.optim.Adam(net.parameters(), lr=0.003)\n\n# Train.\nfor epoch in range(PARAMETER.epochs):\n    print('\\nEpoch: %2d' % (epoch + 1))\n    runningloss = 0\n    net.train()\n    for i, batch in enumerate(train_loader):\n        length = len(train_loader)\n        inputs, labels = batch\n        inputs = inputs.to(device)\n        labels = labels.to(device)\n        optimiser.zero_grad()\n        outputs = net(inputs)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimiser.step()\n        runningloss += loss.item()\n        if i %32 == 31:\n            print(f'正在训练：{(i + 1) * 100 / len(train_loader):.2f}', '%')\n            print(\"Epoch: %2d, Batch: %4d, Loss: %.3f\"\n                  % (epoch + 1, i + 1, runningloss / 32))\n            runningloss = 0\n        if i == PARAMETER.stop_train_batch:\n            break\n    print('Result processing')\n    correct = 0\n\n    net.eval()\n    for i, batch in enumerate(valid_loader):\n        if i % 8 == 7:\n            print(f'正在评估：{(i + 1) * 100 / len(valid_loader):.2f}', '%')\n        inputs, labels = batch\n        inputs = inputs.to(device)\n        labels = labels.to(device)\n        with torch.no_grad():\n            outputs = net(inputs)\n        prediction = torch.round(torch.sigmoid(outputs))\n        for result in (prediction == labels):\n            if result.tolist().count(True) == 11:\n                correct += 1\n    print(f'total：{len(valid)}  correct: {correct}   acc: {correct*100/len(valid):.2f} %')\n        # preds.append(outputs.sigmoid().to('cpu').numpy())\n\n    # predictions = np.concatenate(preds)\n    # score, scores = get_score(valid_labels, predictions)\n    # print(score)\n    # print(scores)\n\ntest = pd.read_csv(os.path.join(path, \"sample_submission.csv\"))\ntest_dataset = OutputModel(test, transform=get_transforms(data='valid'))\ntest_loader = torch.utils.data.DataLoader(test_dataset,\n                                          batch_size=PARAMETER.batch_size,\n                                          shuffle=False,\n                                          num_workers=PARAMETER.num_workers, pin_memory=True, drop_last=False)\nprint('\\nPredict processing')\nnet.eval()\npreds = []\nfor i, batch in enumerate(test_loader):\n    length = len(train_loader)\n    inputs = batch\n    inputs = inputs.to(device)\n    with torch.no_grad():\n        outputs = net(inputs)\n\n    preds.append(outputs.sigmoid().round().to('cpu').numpy())\npredictions = np.concatenate(preds)\nprint('Save prediction')\ntest[PARAMETER.target_cols] = predictions\ntest[['StudyInstanceUID'] + PARAMETER.target_cols].to_csv('submission.csv', index=False)\nprint('Finish')\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"!pip install timm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install --upgrade pip\n","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}