{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport pandas as pd\nimport cv2\nfrom torch.utils.data import Dataset\nfrom albumentations import (\n    Compose, OneOf, Normalize, Resize, RandomResizedCrop, RandomCrop, HorizontalFlip, VerticalFlip,\n    RandomBrightness, RandomContrast, RandomBrightnessContrast, Rotate, ShiftScaleRotate, Cutout,\n    IAAAdditiveGaussianNoise, Transpose\n)\nfrom albumentations.pytorch import ToTensorV2\nimport torch.optim as toptim\nimport timm\n\nclass PARAMETER:\n    epochs = 3\n    batch_size = 16\n    size = 400\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 LoadDataset(Dataset):\n    def __init__(self, df, file='train',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        self.file = file\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n\n        file_name = self.file_names[idx]\n        file_path = f'../input/ranzcr-clip-catheter-line-classification/train/{file_name}.jpg'\n        if self.file == 'test':\n            file_path = f'../input/ranzcr-clip-catheter-line-classification/test/{file_name}.jpg'\n        image = cv2.imread(file_path)\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\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\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\n        return out\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\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 == 'test' or 'validate':\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 binary_accuracy(preds, y):\n    round_preds = torch.round(torch.sigmoid(preds))\n    correct = 0\n    for i in (round_preds == y):\n        if False not in i:\n            correct += 1\n    acc = correct / len(y)\n    return acc\n\n\ntrain = pd.read_csv(\"../input/ranzcr-clip-catheter-line-classification/train.csv\")\ntest = pd.read_csv('../input/ranzcr-clip-catheter-line-classification/sample_submission.csv')\ntrain_dataset = LoadDataset(train, transform=get_transforms(data='train'))\ntest_dataset = LoadDataset(train,file=test, transform=get_transforms(data='test'))\n\ntrain_size = int(0.95 * len(train_dataset))\ntest_size = len(train_dataset) - train_size\n\ntrain_dataset, validate_dataset = torch.utils.data.random_split(train_dataset, [train_size, test_size])\n\ntrain_loader = torch.utils.data.DataLoader(train_dataset,\n                                           batch_size=PARAMETER.batch_size,\n                                           shuffle=True,\n                                           num_workers=0, pin_memory=True, drop_last=True)\n\nvalidate_loader = torch.utils.data.DataLoader(validate_dataset,\n                                           batch_size=PARAMETER.batch_size,\n                                           shuffle=True,\n                                           num_workers=0, pin_memory=True, drop_last=True)\n\ntest_loader = torch.utils.data.DataLoader(test_dataset,\n                                           batch_size=PARAMETER.batch_size,\n                                           shuffle=False,\n                                           num_workers=0, pin_memory=True, drop_last=True)\n\n\n\ndevice = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')\n# device = torch.device('cpu')\n\n\n# model = Googlenetv4().to(device)\nmodel = MyModel().to(device)\nlossFunc = criterion = nn.BCEWithLogitsLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.001, weight_decay=1.0e-8)\n\n\n\n# 训练模型()\ndef train(model, Loader, optimizer, criterion, device):\n    epoch_loss = 0\n    epoch_acc = 0\n    total_len = 0\n    model.train()\n    num = 0\n    for i, batch in enumerate(Loader):\n        print(f'正在训练：{(i+1)*100 / len(Loader):.2f}','%')\n\n        inputs,target = batch\n        inputs = inputs.to(device)\n        target = target.to(device)\n\n        optimizer.zero_grad()\n        # 通过网络向前传递\n        predictions = model(inputs)\n        loss = criterion(predictions, target)\n        acc = binary_accuracy(predictions, target)\n        # 计算梯度\n        loss.backward()\n        optimizer.step()\n\n        epoch_loss += loss.item() * len(target)\n        epoch_acc += acc * len(target)\n        total_len += len(target)\n\n    # 计算平均的loss 和 accuracy\n    return epoch_loss / total_len, epoch_acc / total_len\n\n\n# 评估模型\ndef evaluate(model, Loader, criterion, device):\n    epoch_loss = 0\n    epoch_acc = 0\n    total_len = 0\n    model.eval()\n    num = 0\n    with torch.no_grad():\n        for i, batch in enumerate(Loader):\n            if i == len(Loader) - 1:\n                continue\n            print(f'正在评估：{(i+1)*100 / len(Loader):.2f}','%')\n\n            inputs, target = batch\n            inputs = inputs.to(device)\n            target = target.to(device)\n\n            predictions = model(inputs)\n            loss = criterion(predictions, target)\n            acc = binary_accuracy(predictions, target)\n\n            epoch_loss += loss.item() * len(target)\n            epoch_acc += acc * len(target)\n            total_len += len(target)\n\n    return epoch_loss / total_len, epoch_acc / total_len\n\n\n# 开始训练\nepochs = 4\nbest_valid_loss = float('inf')\nfor epoch in range(epochs):\n\n    train_loss, train_acc = train(model, train_loader, optimizer, lossFunc, device)\n    valida_loss, valid_acc = evaluate(model, validate_loader, lossFunc, device)\n\n    if valida_loss < best_valid_loss:\n        best_valid_loss = valida_loss\n        torch.save(model.state_dict(), 'cnn.pt')\n\n    print(f'Epoch:{epoch + 1:02}')\n    print(f'\\tTrain Loss:{train_loss:.3f}| Train ACC:{train_acc * 100:.2f}%')\n    print(f'\\tVal Loss:{valida_loss:.3f}| Val ACC:{valid_acc * 100:.2f}%')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install timm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pip install --upgrade pip","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install timm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pip install --upgrade pip","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"res= []\nwith torch.no_grad():\n    for batch in test_loader:\n        inputs, target = batch\n        Outputs = torch.round(torch.sigmoid(model(inputs))).int().tolist()\n        res += Outputs\n\ndf1 = pd.DataFrame(res)\ndf1.to_csv('res.csv', index=False)","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}