{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport copy\nimport time\nimport os\nimport cv2\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport matplotlib.pyplot as plt\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom sklearn.model_selection import train_test_split\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import models\nfrom torch.optim import lr_scheduler\n\nos.listdir('/kaggle/input/ranzcr-clip-catheter-line-classification')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"path = '/kaggle/input/ranzcr-clip-catheter-line-classification/'\ntrain_image = path + 'train/'\ntest_image = path + 'test/'\n\ndf = pd.read_csv(path + 'train.csv')\n\ntrain_df, val_df = train_test_split(df, test_size=0.2, random_state=42)\n\ntrain_df = train_df.reset_index(drop=True)\nval_df = val_df.reset_index(drop=True)\n\nprint(train_df.shape)\nprint(val_df.shape)\n\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"label_cols = ['ETT - Abnormal', 'ETT - Borderline', 'ETT - Normal', 'NGT - Abnormal', 'NGT - Borderline', 'NGT - Incompletely Imaged', 'NGT - Normal', 'CVC - Abnormal', 'CVC - Borderline', 'CVC - Normal', 'Swan Ganz Catheter Present']\nout_features = len(label_cols)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class XrayData(Dataset):\n    def __init__(self, df, img_paths, transform=None, verbose=False):\n        self.df = df\n        self.imgs = (self.df['StudyInstanceUID'] + '.jpg').values\n        self.labels = self.df[label_cols].values\n        self.img_paths = img_paths\n        self.transform = transform\n        self.verbose = verbose\n    \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx):\n        if torch.is_tensor(idx):\n            idx = torch.tolist(idx)\n            \n        image_path = self.img_paths + self.imgs[idx]\n        image = cv2.imread(image_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        label = self.labels[idx]\n        label = torch.tensor(label).float()\n        \n        if self.transform:\n            aug = self.transform(image=image)\n            image = aug['image']\n        \n        if self.verbose:\n            print(image_path)\n            print(label)\n            \n            plt.imshow(image.numpy().transpose(1, 2, 0))\n            plt.axis('off')\n            plt.show()\n        \n        return (image, label)\n    \n    \ntrain_data = XrayData(train_df, train_image,\n                      transform=A.Compose([\n                          A.RandomResizedCrop(224, 224),\n                          A.HorizontalFlip(),\n                          A.Normalize(),\n                          ToTensorV2(),\n                      ]))\nval_data = XrayData(val_df, train_image,\n                    transform=A.Compose([\n                        A.Resize(256, 256),\n                        A.CenterCrop(224, 224),\n                        A.Normalize(),\n                        ToTensorV2(),\n                    ]))\n\ndataloaders = {\n    'train': DataLoader(train_data, batch_size=32, shuffle=True, num_workers=4),\n    'val': DataLoader(val_data, batch_size=32, shuffle=False, num_workers=4)\n}\n\ndataset_sizes = {\n    'train': len(train_data),\n    'val': len(val_data)\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true},"cell_type":"code","source":"# # For Testing Only (Best Practice) \n\n# model = models.resnet50(pretrained=True)\n# in_features = model.fc.in_features\n# model.fc = nn.Linear(in_features, out_features)\n\n# device = torch.device('cuda:0' if torch.cuda.is_available() else \"cpu\")\n# model = model.to(device)\n\n# criterion = nn.BCEWithLogitsLoss()\n\n# optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n\n# scheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)\n\n# sample_image, sample_label = next(iter(dataloaders['train']))\n# model.eval()\n# outputs = model(sample_image)\n# sample_label = sample_label\n# # print(outputs)\n# # print(sample_label)\n# # print(criterion(outputs, sample_label))\n# temp = []\n# temp.append(outputs.detach().numpy())\n# temp.append(outputs.detach().numpy())\n# temp = np.array(temp)\n# temp = temp.reshape(-1, 11)\n# pd.DataFrame(temp)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train_model(model, criterion, optimizer, scheduler, epochs=25):\n    since = time.time()\n    \n    best_model_wts = copy.deepcopy(model.state_dict())\n    best_loss = 0.0\n    \n    for epoch in range(epochs):\n        print(f\"Epoch {epoch}/{epochs-1}\")\n        print(\"-\"*10)\n        \n        running_loss = 0.0\n        \n        for phase in ['train', 'val']:\n            if phase == 'train':\n                model.train()\n            else:\n                model.eval()\n              \n            for images, labels in dataloaders[phase]:\n                images = images.to(device)\n                labels = labels.to(device)\n                \n                optimizer.zero_grad()\n                \n                with torch.set_grad_enabled(phase == 'train'):\n                    outputs = model(images)\n                    loss = criterion(outputs, labels.data)\n                    \n                if phase == 'train':\n                    loss.backward()\n                    optimizer.step()\n                \n                running_loss += loss.item() * images.size(0)\n            \n            if phase == 'train':\n                scheduler.step()\n            \n            epoch_loss = running_loss / dataset_sizes[phase]\n            \n            print(f'{phase} loss: {epoch_loss:.4f}')\n            \n            if phase == 'val':\n                if epoch == 0:\n                    best_loss = epoch_loss\n                    best_model_wts = copy.deepcopy(model.state_dict())\n                else:\n                    if epoch_loss < best_loss:\n                        best_loss = epoch_loss\n                        best_model_wts = copy.deepcopy(model.state_dict())\n            \n        print()\n    \n    time_elapsed = time.time() - since\n    print(f'Training complete in {time_elapsed // 60}m {time_elapsed % 60}s')\n    print(f'Best val loss: {best_loss:.4f}')\n    \n    model.load_state_dict(best_model_wts)\n    \n    return model\n\n\n# Define Model\nmodel = models.resnet50(pretrained=True)\nin_features = model.fc.in_features\nmodel.fc = nn.Linear(in_features, out_features)\n\n# Set to GPU\ndevice = torch.device('cuda:0' if torch.cuda.is_available() else \"cpu\")\nmodel = model.to(device)\n\n# Set Loss\ncriterion = nn.BCEWithLogitsLoss()\n\n# Set Optimizer\noptimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n\n# Set Scheduler for optimizer\nscheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)\n\n# Retrieve the best model and its predictions\nmodel = train_model(model, criterion, optimizer, scheduler, epochs=25)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.save(model, 'model_ranzcr.pth')","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}