{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"import sys\nsys.path.append('../input/pytorch-image-models/pytorch-image-models-master')","execution_count":null,"outputs":[]},{"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 os\nimport time \nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom collections import defaultdict\nfrom tqdm import tqdm\nfrom sklearn import model_selection, preprocessing \nfrom sklearn.model_selection import KFold, GroupKFold\nimport cv2\nfrom matplotlib import pyplot as plt\nfrom PIL import Image\nimport copy\n\nimport torch \nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.optim.lr_scheduler import CosineAnnealingWarmRestarts, CosineAnnealingLR, ReduceLROnPlateau\n\nfrom torch.utils.data import Dataset, DataLoader \nimport torchvision\nfrom torchvision import models, transforms \nfrom torch.cuda.amp import autocast, GradScaler\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"params = {\n    \"model\": \"efficientnet_b3\",\n    \"device\": torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\"),\n    \"lr\": 0.0001,\n    \"batch_size\": 2,\n    \"num_workers\": 16,\n    \"num_epochs\": 5,\n    \"T_0\":6, # CosineAnnealingWarmRestarts\n    \"min_lr\":1e-6\n}","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"ROOT_DIR = \"../input/ranzcr-clip-catheter-line-classification\"\ntrain_dir = \"../input/ranzcr-clip-catheter-line-classification/train/\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv(os.path.join(ROOT_DIR, \"train.csv\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(df['StudyInstanceUID'].unique())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Plot some Data**"},{"metadata":{"trusted":true},"cell_type":"code","source":"import random \nimg_list = os.listdir(os.path.join(ROOT_DIR, \"train/\"))\nfig, ax = plt.subplots(3, 3, figsize = (12, 12))\n\nfor row in range(3):\n    for col in range(3):\n        rand_idx = np.random.randint(len(img_list))\n        img = cv2.imread(os.path.join(ROOT_DIR, \"train/\"+img_list[rand_idx]),cv2.COLOR_BGR2RGB)\n        ax[row, col].imshow(img)\n        #print(img.shape)\n        \n                    \nfig.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_df = pd.read_csv(os.path.join(ROOT_DIR, \"sample_submission.csv\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"classes = sample_df.columns[1:]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(classes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = df[classes]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#img_list = os.list_dir(os.path.join(ROOT_DIR, df[\"StudyInstanceUID\"]+\".jpg\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"classes = df.columns[1:].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_df.columns[1:]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"classes = ['ETT - Abnormal', 'ETT - Borderline', 'ETT - Normal', 'NGT - Abnormal',\n       'NGT - Borderline', 'NGT - Incompletely Imaged', 'NGT - Normal',\n       'CVC - Abnormal', 'CVC - Borderline', 'CVC - Normal',\n       'Swan Ganz Catheter Present']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df[classes].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df[classes[:5]].value_counts().plot.bar(figsize=(12, 8))\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Defining Datasets and visualization**"},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.iloc[: ,0][1]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class RANZRDataset(Dataset):\n    def __init__(self, data_dir, df, transform=None):\n        self.data_dir = data_dir\n        self.df = df\n        self.files = df[\"StudyInstanceUID\"].values\n        self.labels = df[classes].values\n        self.transform = transform\n        \n    def __getitem__(self, idx):\n        img_name = self.files[idx]\n        file_path = f\"{self.data_dir}{img_name}\"+\".jpg\"\n#         image = Image.open(file_path).convert('RGB')\n#         image = np.array(image)\n        image = cv2.imread(file_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n        #print(file_path)\n        if self.transform:\n            augmented = self.transform(image = image)\n            image = augmented[\"image\"]\n        \n        label = torch.tensor(self.labels[idx]).float()\n        \n        return image, label\n    def __len__(self):\n        return len(self.df)\n        \n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset = RANZRDataset(train_dir, df)\nimg, label = dataset[0]\nplt.imshow(img)\nplt.show()\nprint(label)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_train_transform():\n    return A.Compose([\n        A.RandomResizedCrop(300, 300, p=1),\n        A.Flip(p=0.5),\n        A.RandomRotate90(),\n        A.OneOf([\n            A.OpticalDistortion(p=0.3),\n            A.GridDistortion(p=.1),\n            A.IAAPiecewiseAffine(p=0.3),\n        ], p=0.2),\n        A.OneOf([\n            A.CLAHE(clip_limit=2),\n            A.IAASharpen(),\n            A.IAAEmboss(),\n            A.RandomBrightnessContrast(),            \n        ], p=0.3),\n        A.HueSaturationValue(p=0.3),\n        #A.ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.50, rotate_limit=45, p=.25),\n        #A.Normalize(mean = [0.485, 0.456, 0.406], std = [0.229, 0.224, 0.225]),\n        ToTensorV2(),\n\n    ])\n        \ndef get_valid_transform():\n    return A.Compose([\n        A.RandomResizedCrop(300, 300, p=1),\n        #A.Flip(0.5),\n        #A.Normalize(mean = [0.485, 0.456, 0.406], std = [0.229, 0.224, 0.225]),\n        ToTensorV2(),\n\n    ])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset = RANZRDataset(train_dir, df, get_train_transform())\n#img , label = dataset[0]\nprint(np.array(img).shape)\nfig, ax = plt.subplots(1, 4, figsize = (12, 10))\nfor i in range(0, 4):\n    img , label = dataset[i]\n    ax[i].imshow(img.permute(2,1,0))\n    ax[i].set_title(np.array(label))\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dataset = RANZRDataset(train_dir, df, get_train_transform())\nvalid_dataset = RANZRDataset(train_dir, df, get_valid_transform())\n\n#indices = torch.randperm(len(train_dataset)).tolist()\n\n# train_dataset = torch.utils.data.Subset(train_dataset, indices=indices[:-100] )\n# valid_dataset = torch.utils.data.Subset(valid_dataset, indices=indices[-100:] )\ntrain_loader = DataLoader(train_dataset, \n                         batch_size = params[\"batch_size\"], \n                         num_workers = params[\"num_workers\"], \n                         pin_memory=True, \n                         shuffle = True)\nvalid_loader = DataLoader(valid_dataset, \n                         batch_size = params[\"batch_size\"], \n                         num_workers = params[\"num_workers\"],\n                         pin_memory= True, \n                         shuffle = False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(train_dataset), len(valid_dataset))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Defining models**"},{"metadata":{"trusted":true},"cell_type":"code","source":"len(classes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import timm\n#EFFICIENTNET-B7\nclass RANZRModel(nn.Module):\n    def __init__(self, model_name=params[\"model\"], pretrained=False):\n        super().__init__()\n        self.model = timm.create_model(model_name, pretrained=pretrained)\n        n_features = self.model.classifier.in_features\n        self.model.classifier = nn.Linear(n_features, len(classes))\n\n    def forward(self, x):\n        x = self.model(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train_one_epoch(epoch, model, criterion, optimizer, scheduler):\n    since = time.time()\n\n    \n    data_cnt = 0\n    model.train()# Set model to training mode \n    print('Epoch {}/{}'.format(epoch, params[\"num_epochs\"] - 1))\n    print('-' * 10)\n    running_loss = 0.0\n    for (inputs, labels) in train_loader:\n        \n        inputs = inputs.to(params[\"device\"]).float()\n        labels = labels.to(params[\"device\"]).float()\n        \n        \n        optimizer.zero_grad()\n        outputs = model(inputs)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n        # statistics\n        running_loss += loss.item() \n        scheduler.step()\n        \n    print(\"Epoch {} - Training loss: {:.4f}\".format(epoch, running_loss/len(train_loader)))\n        \n        \ndef valid_one_epoch(epoch, model, criterion, optimizer, scheduler):\n    since = time.time()\n\n\n    # Each epoch has a training and validation phase\n\n    preds =[]\n    model.eval()  \n    valid_loss = 0.0\n\n    # Iterate over data.\n    for inputs, labels in valid_loader:\n        inputs = inputs.to(params[\"device\"]).float()\n        labels = labels.to(params[\"device\"]).float()\n        \n        outputs = model(inputs)\n        loss = criterion(outputs, labels)\n        \n        preds.append(outputs.sigmoid().detach().cpu().numpy()) \n        #print(np.mean(preds))\n        valid_loss += loss.item() \n   \n    valid_loss = valid_loss/len(valid_loader)\n    y_pred = np.concatenate(preds)\n    print(\"val_loss: {:0.4f} \".format(valid_loss))\n    return valid_loss, y_pred","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = RANZRModel(model_name=params[\"model\"], pretrained=True)\nmodel.to(params[\"device\"])\ncriterion = nn.BCEWithLogitsLoss().to(params[\"device\"])\noptimizer = torch.optim.Adam(model.parameters(), lr=params[\"lr\"])\nscheduler = CosineAnnealingWarmRestarts(optimizer, T_0=params[\"T_0\"], T_mult=1, eta_min=params[\"min_lr\"], last_epoch=-1)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"kf = GroupKFold(n_splits=3)\ngroups = df[\"PatientID\"].values\nX = df[\"StudyInstanceUID\"]\ny = df[classes]\nfold_var = 1\n#kf = kf.get_n_splits(X,y,groups)\nfor train_index, test_index in kf.split(X,y, groups):\n    #print(train_index, test_index)\n    train_dataset = RANZRDataset(train_dir, df.iloc[train_index], get_train_transform())\n    valid_dataset = RANZRDataset(train_dir, df.iloc[test_index], get_valid_transform())\n    \n    #print(len(train_dataset), len(valid_dataset))\n    train_loader = DataLoader(train_dataset, \n                         batch_size = params[\"batch_size\"], \n                         num_workers = params[\"num_workers\"], \n                         pin_memory=True, \n                         shuffle = True)\n    valid_loader = DataLoader(valid_dataset, \n                             batch_size = params[\"batch_size\"], \n                             num_workers = params[\"num_workers\"],\n                             pin_memory= True, \n                             shuffle = False)\n    \n    print(f\"{'-'*10} fold {fold_var} result {'-'*10}\")\n    best_loss = 1e10\n    for epochs in range (params[\"num_epochs\"]):\n        train_one_epoch(epochs,model, criterion, optimizer, scheduler)\n        with torch.no_grad():\n            val_loss , preds = valid_one_epoch(epochs,model, criterion, optimizer, scheduler)\n            scheduler.step()\n            if best_loss > val_loss:\n                best_loss = val_loss\n                torch.save(model.state_dict(), f'./fold_{fold_var}_{params[\"model\"]}_best.pth')\n    fold_var += 1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Inference Notebook is here [kaggle kernels pull razatabish/ranzr-clip-inference](http://)"}],"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}