{"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 numpy as np \nimport pandas as pd \nimport os\nimport glob as glob\nfrom tqdm import tqdm\n\n# Torch\nimport torch\nimport torchvision\nfrom torchvision.io import read_image\nimport cv2\nimport torchvision.transforms as transforms\nfrom torch.utils.data import Dataset,DataLoader\nfrom torchvision import models as models\nimport torch.optim as optim\nfrom torchvision.models import resnet50\nimport torch.nn as nn\nimport matplotlib\nimport matplotlib.pyplot as plt\nmatplotlib.style.use('ggplot')\n\nimport matplotlib.patches as patches\nfrom IPython.display import display_html\nimport seaborn as sns\nimport re\nimport os\nimport sys\nimport cv2\nimport gc\nimport PIL\nfrom PIL import Image\nfrom glob import glob\nfrom numpy import asarray\nfrom numpy import savetxt\nfrom numpy import save\nfrom numpy import load\nimport cv2\nfrom tqdm import tqdm\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\n\ndevice= torch.device(\"cuda\" if torch.cuda.is_available() else  \"cpu\")\n","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:01:12.314528Z","iopub.execute_input":"2022-09-13T15:01:12.315533Z","iopub.status.idle":"2022-09-13T15:01:15.024942Z","shell.execute_reply.started":"2022-09-13T15:01:12.315426Z","shell.execute_reply":"2022-09-13T15:01:15.023856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# EDA","metadata":{}},{"cell_type":"code","source":"image_list=glob(\"../input/rsna-2022-cervical-spine-fracture-detection/train_images/**/*dcm\")\nplt.subplots(3, 3, figsize=(8, 8))\nfor i in range(9):\n    im = pydicom.dcmread(image_list[i])\n    im = im.pixel_array.astype(float)\n    im = cv2.resize(im, (150,150), interpolation=cv2.INTER_LINEAR)\n    rescaled_img = (np.maximum(im,0)/im.max())*255\n    fin_img_test = np.uint8(rescaled_img)\n    fin_img_test = Image.fromarray(fin_img_test)\n    arr = np.array(fin_img_test)\n    plt.subplot(3, 3, i + 1)\n    plt.imshow(arr, cmap= plt.cm.gist_heat)\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:01:15.02684Z","iopub.execute_input":"2022-09-13T15:01:15.027389Z","iopub.status.idle":"2022-09-13T15:02:15.086205Z","shell.execute_reply.started":"2022-09-13T15:01:15.027359Z","shell.execute_reply":"2022-09-13T15:02:15.085305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta_vir = pd.read_csv(\"../input/rsna-2022-spine-fracture-detection-metadata/meta_train_with_vertebrae.csv\")\n\nmeta_vir.head()","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:15.08725Z","iopub.execute_input":"2022-09-13T15:02:15.087571Z","iopub.status.idle":"2022-09-13T15:02:16.639891Z","shell.execute_reply.started":"2022-09-13T15:02:15.087541Z","shell.execute_reply":"2022-09-13T15:02:16.638838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xy = meta_vir.iloc[:9204,9:]\nxy.shape","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:16.642996Z","iopub.execute_input":"2022-09-13T15:02:16.643649Z","iopub.status.idle":"2022-09-13T15:02:16.653222Z","shell.execute_reply.started":"2022-09-13T15:02:16.643608Z","shell.execute_reply":"2022-09-13T15:02:16.652013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xy.head()","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:16.654917Z","iopub.execute_input":"2022-09-13T15:02:16.655381Z","iopub.status.idle":"2022-09-13T15:02:16.67029Z","shell.execute_reply.started":"2022-09-13T15:02:16.655344Z","shell.execute_reply":"2022-09-13T15:02:16.669237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_path = glob(\"../input/rsna-9204-64-64-jpg/train_64_jpg/*.jpg\")\n\nlen(img_path)","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:16.672369Z","iopub.execute_input":"2022-09-13T15:02:16.673343Z","iopub.status.idle":"2022-09-13T15:02:17.350137Z","shell.execute_reply.started":"2022-09-13T15:02:16.6733Z","shell.execute_reply":"2022-09-13T15:02:17.349018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xy['image']=img_path","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:17.351966Z","iopub.execute_input":"2022-09-13T15:02:17.352355Z","iopub.status.idle":"2022-09-13T15:02:17.361564Z","shell.execute_reply.started":"2022-09-13T15:02:17.352317Z","shell.execute_reply":"2022-09-13T15:02:17.360381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xy[\"overall\"] = xy['C1'] + xy['C2']+ xy['C3']+xy['C4']+xy['C5']+xy ['C6']+xy['C7']\n\nxy['z_total'] = xy[\"overall\"].apply(lambda x:x if x==0 else 1)\n\nxy[\"z_total\"].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:17.363586Z","iopub.execute_input":"2022-09-13T15:02:17.364045Z","iopub.status.idle":"2022-09-13T15:02:17.386288Z","shell.execute_reply.started":"2022-09-13T15:02:17.36401Z","shell.execute_reply":"2022-09-13T15:02:17.385105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del xy[\"overall\"]\nxy.z_total.value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:17.387963Z","iopub.execute_input":"2022-09-13T15:02:17.388419Z","iopub.status.idle":"2022-09-13T15:02:17.401207Z","shell.execute_reply.started":"2022-09-13T15:02:17.388375Z","shell.execute_reply":"2022-09-13T15:02:17.400238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"xy.head()","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:17.405846Z","iopub.execute_input":"2022-09-13T15:02:17.408199Z","iopub.status.idle":"2022-09-13T15:02:17.420521Z","shell.execute_reply.started":"2022-09-13T15:02:17.408161Z","shell.execute_reply":"2022-09-13T15:02:17.419003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class dataset(Dataset):\n    def __init__(self,csv,train, test):\n        self.csv = csv\n        self.train = train\n        self.test = test\n        self.all_patientids_names = self.csv[:]['image']\n        self.all_labels = np.array(self.csv.drop(['image'],axis=1))\n        self.train_ratio= int(0.85*len(self.csv))\n        self.valid_ratio = len(self.csv) - self.train_ratio\n        \n        if self.train==True:\n            print(f\"Number of Training Images : {self.train_ratio}\")\n            self.image_names = list(self.all_patientids_names[:self.train_ratio])\n            self.labels = list(self.all_labels[:self.train_ratio])\n            \n            #train transoforms\n            \n            self.transform = transforms.Compose([\n                  transforms.ToPILImage(),\n                  transforms.Resize((150,150)),\n                  transforms.RandomHorizontalFlip(p=0.50),\n                  transforms.RandomRotation(degrees=45),\n                  transforms.ToTensor(),\n                  transforms.Normalize(torch.Tensor([0.2963,0.2963,0.2963]),torch.Tensor([0.1987,0.1987,0.1987]))\n                                      ])\n            \n        \n        elif self.train==False and self.test==False:\n            \n        \n            print(f\"Number of Validation Images:{self.valid_ratio}\")\n                \n            self.image_names = list(self.all_patientids_names[-self.valid_ratio:-10])\n            self.labels = list(self.all_labels[-self.valid_ratio:])\n\n            self.transform = transforms.Compose([\n                transforms.ToPILImage(),\n                transforms.Resize((150,150)),\n                transforms.ToTensor(),\n                transforms.Normalize(torch.Tensor([0.2963,0.2963,0.2963]),torch.Tensor([0.1987,0.1987,0.1987]))\n                ])\n\n        elif self.test==True and self.train == False:\n            self.image_names =list(self.all_patientids_names[-10:])\n            self.labels = list(self.all_labels[-10:])\n            self.transform = transforms.Compose([\n                   transforms.ToPILImage(),\n                   transforms.ToTensor(),\n                   transforms.Normalize(torch.Tensor([0.2963,0.2963,0.2963]),torch.Tensor([0.1987,0.1987,0.1987]))\n                                        ])\n\n    def __len__(self):\n        return len(self.image_names)\n    \n                    \n    def __getitem__(self,index):\n        image = cv2.imread(self.image_names[index])\n        image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)\n                    \n        image = self.transform(image)\n        targets = self.labels[index]\n                    \n                    \n        return {\n                \"image\": torch.tensor(image,dtype=torch.float32),\n                \"label\" : torch.tensor(targets,dtype= torch.float32)\n                 }","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:17.422438Z","iopub.execute_input":"2022-09-13T15:02:17.423003Z","iopub.status.idle":"2022-09-13T15:02:17.439728Z","shell.execute_reply.started":"2022-09-13T15:02:17.422962Z","shell.execute_reply":"2022-09-13T15:02:17.43878Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TEST_IMAGES_PATH= \"../input/rsna-2022-cervical-spine-fracture-detection/test_images\"","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:17.443287Z","iopub.execute_input":"2022-09-13T15:02:17.443576Z","iopub.status.idle":"2022-09-13T15:02:17.455906Z","shell.execute_reply.started":"2022-09-13T15:02:17.44355Z","shell.execute_reply":"2022-09-13T15:02:17.454818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_slices = glob(f'{TEST_IMAGES_PATH}/*/*')\ntest_slices = [re.findall(f'{TEST_IMAGES_PATH}/(.*)/(.*).dcm', s)[0] for s in test_slices]\ndf_test_slices = pd.DataFrame(data=test_slices, columns=['StudyInstanceUID', 'Slice']).astype({'Slice': int}).sort_values(['StudyInstanceUID', 'Slice']).reset_index(drop=True)\ndf_test_slices.head()","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:17.457334Z","iopub.execute_input":"2022-09-13T15:02:17.458424Z","iopub.status.idle":"2022-09-13T15:02:17.604812Z","shell.execute_reply.started":"2022-09-13T15:02:17.458387Z","shell.execute_reply":"2022-09-13T15:02:17.60368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_jpg_list = glob(\"../input/rsna-9204-64-64-jpg/test_jpg/*\")\nlen(img_jpg_list)","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:17.606418Z","iopub.execute_input":"2022-09-13T15:02:17.607059Z","iopub.status.idle":"2022-09-13T15:02:18.174912Z","shell.execute_reply.started":"2022-09-13T15:02:17.607012Z","shell.execute_reply":"2022-09-13T15:02:18.173868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test_slices[\"image\"]= img_jpg_list\n\ndf_test_slices.head()","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:18.176362Z","iopub.execute_input":"2022-09-13T15:02:18.176677Z","iopub.status.idle":"2022-09-13T15:02:18.188084Z","shell.execute_reply.started":"2022-09-13T15:02:18.176651Z","shell.execute_reply":"2022-09-13T15:02:18.18705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def model(pretrained,requires_grad):\n    model = resnet50(progress=True,pretrained = pretrained)\n    if requires_grad == False:\n        for param in model.parameters():\n            param.requires_grad=False\n    elif requires_grad == True:\n        for param in model.parameters():\n            param.requires_grad = True\n            \n    model.fc = nn.Linear(2048,8)\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:18.189854Z","iopub.execute_input":"2022-09-13T15:02:18.190762Z","iopub.status.idle":"2022-09-13T15:02:18.197917Z","shell.execute_reply.started":"2022-09-13T15:02:18.190724Z","shell.execute_reply":"2022-09-13T15:02:18.196965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nfrom tqdm import tqdm\n# training function\ndef train(model, dataloader, optimizer, criterion, train_data, device):\n    print('Training')\n    model.train()\n    counter = 0\n    train_running_loss = 0.0\n    for i, data in tqdm(enumerate(dataloader), total=int(len(train_data)/dataloader.batch_size)):\n        counter += 1\n        data, target = data['image'].to(device), data['label'].to(device)\n        optimizer.zero_grad()\n        outputs = model(data)\n        # apply sigmoid activation to get all the outputs between 0 and 1\n        outputs = torch.sigmoid(outputs)\n        loss = criterion(outputs, target)\n        train_running_loss += loss.item()\n        # backpropagation\n        loss.backward()\n        # update optimizer parameters\n        optimizer.step()\n        \n    train_loss = train_running_loss / counter\n    return train_loss","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:18.199471Z","iopub.execute_input":"2022-09-13T15:02:18.200132Z","iopub.status.idle":"2022-09-13T15:02:18.209104Z","shell.execute_reply.started":"2022-09-13T15:02:18.200096Z","shell.execute_reply":"2022-09-13T15:02:18.208014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def validate(model,dataloader,criterion,val_data,device):\n    print(\"validating\")\n    model.eval()\n    counter =0\n    val_running_loss = 0.0\n    with torch.no_grad():\n        for i , data in tqdm(enumerate(dataloader),total=int(len(val_data )/dataloader.batch_size)):\n            counter+=1\n            data,target = data['image'].to(device),data['label'].to(device)\n            outputs = model(data)\n            \n            outputs = torch.sigmoid(outputs)\n            loss = criterion(outputs,target)\n            val_running_loss+=loss.item()\n        val_loss = val_running_loss/counter\n        return val_loss","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:18.21147Z","iopub.execute_input":"2022-09-13T15:02:18.212877Z","iopub.status.idle":"2022-09-13T15:02:18.224302Z","shell.execute_reply.started":"2022-09-13T15:02:18.21284Z","shell.execute_reply":"2022-09-13T15:02:18.223202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#intialize the model\nmodel = model(pretrained=True, requires_grad=False).to(device)\n# learning parameters\nlr = 0.0001\nepochs = 15\nbatch_size = 32\noptimizer = optim.Adam(model.parameters(), lr=lr)\ncriterion = nn.BCELoss()","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:18.228032Z","iopub.execute_input":"2022-09-13T15:02:18.228456Z","iopub.status.idle":"2022-09-13T15:02:32.51958Z","shell.execute_reply.started":"2022-09-13T15:02:18.228369Z","shell.execute_reply":"2022-09-13T15:02:32.518577Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# read the training csv file\ntrain_csv =xy\n\n# train dataset\ntrain_data = dataset(\n    train_csv, train=True, test=False\n)\n# validation dataset\nvalid_data = dataset(\n    train_csv, train=False, test=False\n)\n# train data loader\ntrain_loader = DataLoader(\n    train_data, \n    batch_size=batch_size,\n    shuffle=True\n)\n# validation data loader\nvalid_loader = DataLoader(\n    valid_data, \n    batch_size=batch_size,\n    shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:32.521165Z","iopub.execute_input":"2022-09-13T15:02:32.521534Z","iopub.status.idle":"2022-09-13T15:02:32.538252Z","shell.execute_reply.started":"2022-09-13T15:02:32.521495Z","shell.execute_reply":"2022-09-13T15:02:32.537206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# start the training and validation\ntrain_loss = []\nvalid_loss = []\nroot_dir =\"./\"\nfor epoch in range(epochs):\n    print(f\"Epoch {epoch+1} of {epochs}\")\n    train_epoch_loss = train(\n        model, train_loader, optimizer, criterion, train_data, device\n    )\n    valid_epoch_loss = validate(\n        model, valid_loader, criterion, valid_data, device\n    )\n    train_loss.append(train_epoch_loss)\n    valid_loss.append(valid_epoch_loss)\n    print(f\"Train Loss: {train_epoch_loss:.4f}\")\n    print(f'Val Loss: {valid_epoch_loss:.4f}')\n    ","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:02:32.539517Z","iopub.execute_input":"2022-09-13T15:02:32.541081Z","iopub.status.idle":"2022-09-13T15:11:25.904472Z","shell.execute_reply.started":"2022-09-13T15:02:32.541051Z","shell.execute_reply":"2022-09-13T15:11:25.903455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# save the trained model to disk\ntorch.save({\n            'epoch': epochs,\n            'model_state_dict': model.state_dict(),\n            'optimizer_state_dict': optimizer.state_dict(),\n            'loss': criterion,\n            }, './resnet50.pth')\n# plot and save the train and validation line graphs\nplt.figure(figsize=(10, 7))\nplt.plot(train_loss, color='orange', label='train loss')\nplt.plot(valid_loss, color='red', label='validataion loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\nplt.savefig('./resent_loss.jpg')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:11:25.90612Z","iopub.execute_input":"2022-09-13T15:11:25.906784Z","iopub.status.idle":"2022-09-13T15:11:26.37882Z","shell.execute_reply.started":"2022-09-13T15:11:25.906739Z","shell.execute_reply":"2022-09-13T15:11:26.377916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# initialize the computation device\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n#intialize the model\n\n#model = model(pretrained=False, requires_grad=False).to(device)\n# load the model checkpoint\ncheckpoint = torch.load('../input/resnet50/resnet50.pth',map_location='cpu')\n# load model weights state_dict\nmodel.load_state_dict(checkpoint['model_state_dict'])\nmodel.eval()","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:11:26.380073Z","iopub.execute_input":"2022-09-13T15:11:26.380647Z","iopub.status.idle":"2022-09-13T15:11:27.33077Z","shell.execute_reply.started":"2022-09-13T15:11:26.380607Z","shell.execute_reply":"2022-09-13T15:11:27.329775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"geners_col = [col for col in train_csv.columns if train_csv[col].dtype in [\"int64\",\"flot32\"]]\ngeners_col","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:11:27.333097Z","iopub.execute_input":"2022-09-13T15:11:27.333738Z","iopub.status.idle":"2022-09-13T15:11:27.341996Z","shell.execute_reply.started":"2022-09-13T15:11:27.3337Z","shell.execute_reply":"2022-09-13T15:11:27.340912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_csv = xy\ngenres = geners_col\n# prepare the test dataset and dataloader\ntest_data = dataset(\n    train_csv, train=False, test=True\n)\ntest_loader = DataLoader(\n    test_data, \n    batch_size=1,\n    shuffle=False\n)","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:11:27.34363Z","iopub.execute_input":"2022-09-13T15:11:27.344027Z","iopub.status.idle":"2022-09-13T15:11:27.356992Z","shell.execute_reply.started":"2022-09-13T15:11:27.343991Z","shell.execute_reply":"2022-09-13T15:11:27.355992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for counter, data in enumerate(test_loader):\n    image, target = data['image'].to(device), data['label']\n    # get all the index positions where value == 1\n    target_indices = [i for i in range(len(target[0])) if target[0][i] == 1]\n    # get the predictions by passing the image through the model\n    outputs = model(image)\n    outputs = torch.sigmoid(outputs)\n    outputs = outputs.detach().cpu()\n    sorted_indices = np.argsort(outputs[0])\n    best = sorted_indices[-3:]\n    string_predicted = ''\n    string_actual = ''\n    for i in range(len(best)):\n        string_predicted += f\"{genres[best[i]]}    \"\n    for i in range(len(target_indices)):\n        string_actual += f\"{genres[target_indices[i]]}    \"\n    image = image.squeeze(0)\n    image = image.detach().cpu().numpy()\n    image = np.transpose(image, (1, 2, 0))\n    plt.imshow(image)\n    plt.axis('off')\n    plt.title(f\"PREDICTED: {string_predicted}\\nACTUAL: {string_actual}\")\n    #plt.savefig(f\"../input/resnet50.pth{counter}.jpg\")\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-09-13T15:11:27.358549Z","iopub.execute_input":"2022-09-13T15:11:27.358992Z","iopub.status.idle":"2022-09-13T15:11:28.548298Z","shell.execute_reply.started":"2022-09-13T15:11:27.358943Z","shell.execute_reply":"2022-09-13T15:11:28.547437Z"},"trusted":true},"execution_count":null,"outputs":[]}]}