{"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 os\nimport pandas as pd\nimport numpy as np\nfrom sklearn.model_selection import train_test_split\nfrom pydicom import dcmread\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nfrom sklearn.decomposition import PCA\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.preprocessing import StandardScaler\n\nimport torch\nimport torch.nn as nn\nimport torchvision\nimport torchvision.transforms as transforms\nfrom torch.utils import data","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preparing labels","metadata":{}},{"cell_type":"code","source":"label_data = pd.read_csv('../input/rsna-pneumonia-detection-challenge/stage_2_train_labels.csv')\ncolumns = ['patientId', 'Target']\n\nlabel_data = label_data.filter(columns)\nlabel_data.head(5)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Dividing labels for train and validation set","metadata":{}},{"cell_type":"code","source":"train_labels, val_labels = train_test_split(label_data.values, test_size=0.2)\nprint(train_labels.shape)\nprint(val_labels.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'patientId: {train_labels[0][0]}, Target: {train_labels[0][1]}')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preparing train and validation image paths","metadata":{}},{"cell_type":"code","source":"train_f = '../input/rsna-pneumonia-detection-challenge/stage_2_train_images'\ntest_f = '../input/rsna-pneumonia-detection-challenge/stage_2_test_images'\n\ntrain_paths = [os.path.join(train_f, image[0]) for image in train_labels]\nval_paths = [os.path.join(train_f, image[0]) for image in val_labels]\n\nprint(len(train_paths))\nprint(len(val_paths))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Show some samples from data","metadata":{}},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.ToPILImage(),\n    transforms.Resize(128)])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(train_paths)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_np = dcmread(f'{train_paths[0]}.dcm').pixel_array\narr = np.array(transform(img_np)).flatten()\narr","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data_pixels = np.zeros([len(train_paths), 16384])\ntrain_data_labels = np.zeros([len(train_paths), 1])\nfor i in range(0, len(train_paths)):\n    img_np = dcmread(f'{train_paths[i]}.dcm').pixel_array\n    train_data_pixels[i] = np.array(transform(img_np)).flatten()\n    train_data_labels[i] = train_labels[i][1]\n    print(i)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_data = pd.DataFrame(train_data_pixels)\ndf_train_data['label'] = pd.Series(train_data_labels.flatten(), index=df_train_data.index)\ndf_train_data.to_csv('train_data_and_labels.csv')\n\nfrom IPython.display import FileLink\nFileLink(r'train_data_and_labels.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_data = pd.read_csv('train_data_and_labels.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_data_labels.shape, train_data_pixels.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_data_pixels = np.zeros([len(val_paths), 16384])\nval_data_labels = np.zeros([len(val_paths), 1])\nfor i in range(0, len(val_paths)):\n    img_np = dcmread(f'{val_paths[i]}.dcm').pixel_array\n    val_data_pixels[i] = np.array(transform(img_np)).flatten()\n    val_data_labels[i] = val_labels[i][1]\n    print(i)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_val_data = pd.DataFrame(val_data_pixels)\ndf_val_data['label'] = pd.Series(val_data_labels.flatten(), index=df_val_data.index)\ndf_val_data.to_csv('val_data_and_labels.csv')\n\nfrom IPython.display import FileLink\nFileLink(r'val_data_and_labels.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_data = pd.read_csv('train_data_and_labels.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.ensemble import RandomForestClassifier\nclf2 = RandomForestClassifier(n_estimators=50)\nclf2.fit(train_data_pixels, train_data_labels.flatten())\nval_rf2_out = clf2.predict(val_data_pixels)\n(np.square(val_label_vals - val_rf2_out)).mean()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_rf_out2 = clf2.predict(train_data_pixels)\nval_rf_out2 = clf2.predict(val_data_pixels)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"(np.square(train_label_vals - train_rf_out2)).mean()\n(np.square(val_label_vals - val_rf_out2)).mean()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"clf = RandomForestClassifier(n_estimators=100)\nclf.fit(train_data_pixels, train_data_labels.flatten())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_rf_out = clf.predict(train_data_pixels)\nval_rf_out = clf.predict(val_data_pixels)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_label_vals = train_data_labels.flatten()\nval_label_vals = val_data_labels.flatten()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"MSE_train = (np.square(train_label_vals - train_rf_out)).mean() ## 100% accuracy on training sample","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"correct = (val_label_vals == val_rf_out).sum() ## Number of Correct Guesses: 2643\ncorrect / val_rf_out.shape[0]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = StandardScaler().fit_transform(train_data_pixels)\npca = PCA(n_components=2)\nprincipalComponents = pca.fit_transform(x)\nprincipalDf = pd.DataFrame(data = principalComponents\n             , columns = ['principal component 1', 'principal component 2'])\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.scatter(principalDf['principal component 1'],principalDf['principal component 2'], labels=pd.DataFrame(train_data_pixels.flatten()))\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"finalDf","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"(np.square(val_label_vals - val_rf_out)).mean()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_dcm = dcmread(f'{train_paths[0]}.dcm').pixel_array\ntrain_data = np.array(transform(img_dcm)).flatten()\nfor i in range(1, len(train_paths)):\n    img_np = dcmread(f'{train_paths[i]}.dcm').pixel_array\n    arr = np.vstack([arr, np.array(transform(img_np)).flatten()])\n#     img_dcm = dcmread(f'{train_paths[i]}.dcm')\n#     img_np = img_dcm.pixel_array\n#     curr_train_data = np.array(transform(img_np)).flatten()\n#     curr_train_label = train_labels[i][1]\n#     df_train_data.loc[i] = curr_train_data\n#     df_train_labels.loc[i] = curr_train_label\n    print(i)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"arr","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(0, len(val_paths)):\n    img_dcm = dcmread(f'{val_paths[i]}.dcm')\n    img_np = img_dcm.pixel_array\n    curr_val_data = np.array(transform(img_np)).flatten()\n    curr_val_label = val_labels[i][1]\n    df_validation_data.loc[i] = curr_train_data\n    df_validation_labels.loc[i] = curr_train_label","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(0, len(train_paths)):\n    curr_train_data = dcmread(f'{train_paths[i]}.dcm').pixel_array.flatten()\n    curr_train_label = train_labels[i][1]\n    df_train_data.loc[i] = curr_train_data\n    df_train_labels.loc[i] = curr_train_label\ndf_train_data","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(0, len(val_paths)):\n    curr_val_data = dcmread(f'{val_paths[i]}.dcm').pixel_array.flatten()\n    curr_val_label = val_labels[i][1]\n    df_validation_data.loc[i] = curr_val_data\n    df_validation_labels.loc[i] = curr_val_label\ndf_validation_data","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def imshow(num_to_show=9):\n    \n    plt.figure(figsize=(10,10))\n    \n    for i in range(num_to_show):\n        plt.subplot(3, 3, i+1)\n        plt.grid(False)\n        plt.xticks([])\n        plt.yticks([])\n        \n        img_dcm = dcmread(f'{train_paths[i+20]}.dcm')\n        img_np = img_dcm.pixel_array\n        plt.imshow(img_np, cmap=plt.cm.binary)\n        plt.xlabel(train_labels[i+20][1])\n\nimshow()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Composing transformations","metadata":{}},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.RandomHorizontalFlip(),\n    transforms.Resize(224),\n    transforms.ToTensor()])\n# transform = transforms.Compose([\n#     transforms.ToPILImage(),\n#     transforms.RandomHorizontalFlip(),\n#     transforms.Resize(256)])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Write a custom dataset ","metadata":{}},{"cell_type":"code","source":"class Dataset(data.Dataset):\n    \n    def __init__(self, paths, labels, transform=None):\n        self.paths = paths\n        self.labels = labels\n        self.transform = transform\n    \n    def __getitem__(self, index):\n        image = dcmread(f'{self.paths[index]}.dcm')\n        image = image.pixel_array\n        image = image / 255.0\n\n        image = (255*image).clip(0, 255).astype(np.uint8)\n        image = Image.fromarray(image).convert('RGB')\n\n        label = self.labels[index][1]\n        \n        if self.transform is not None:\n            image = self.transform(image)\n            \n        return image, label\n    \n    def __len__(self):\n        \n        return len(self.paths)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Check the custom dataset","metadata":{}},{"cell_type":"code","source":"train_dataset = Dataset(train_paths, train_labels, transform=transform)\nimage = iter(train_dataset)\nimg, label = next(image)\nprint(f'Tensor:{img}, Label:{label}')\nimg = np.transpose(img, (1, 2, 0))\nplt.imshow(img)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train image shape","metadata":{}},{"cell_type":"code","source":"list(train_dataset)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prepare training and validation dataloader","metadata":{}},{"cell_type":"code","source":"train_dataset = Dataset(train_paths, train_labels, transform=transform)\nval_dataset = Dataset(val_paths, val_labels, transform=transform)\ntrain_loader = data.DataLoader(dataset=train_dataset, batch_size=128, shuffle=True)\nval_loader = data.DataLoader(dataset=val_dataset, batch_size=128, shuffle=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Check dataloader","metadata":{}},{"cell_type":"code","source":"batch = iter(train_loader)\nimages, labels = next(batch)\n\nimage_grid = torchvision.utils.make_grid(images[:4])\nimage_np = image_grid.numpy()\nimg = np.transpose(image_np, (1, 2, 0))\nplt.imshow(img)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Specify device object","metadata":{}},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load pre-trained ResNet18 and fine-tune","metadata":{}},{"cell_type":"code","source":"model = torchvision.models.resnet18(pretrained=True)\nnum_ftrs = model.fc.in_features\n# Here the size of each output sample is set to 2.\n# Alternatively, it can be generalized to nn.Linear(num_ftrs, len(class_names)).\nmodel.fc = nn.Linear(num_ftrs, 2)\n\nmodel.to(device)\n\ncriterion = nn.CrossEntropyLoss()\n\n# Observe that all parameters are being optimized\noptimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n\n# Decay LR by a factor of 0.1 every 7 epochs\nexp_lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(model)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Write a train code and RUN","metadata":{}},{"cell_type":"code","source":"num_epochs = 20\n# Train the model\ntotal_step = len(train_loader)\nfor epoch in range(num_epochs):\n    # Training step\n    for i, (images, labels) in tqdm(enumerate(train_loader)):\n        images = images.to(device)\n        labels = labels.to(device)\n        \n        # Forward pass\n        outputs = model(images)\n        loss = criterion(outputs, labels)\n        \n        # Backward and optimize\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        \n        if (i+1) % 2000 == 0:\n            \n            print(\"Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}\"\n                   .format(epoch+1, num_epochs, i+1, total_step, loss.item()))\n\n\n    # Validation step\n    correct = 0\n    total = 0  \n    for images, labels in tqdm(val_loader):\n        images = images.to(device)\n        labels = labels.to(device)\n        predictions = model(images)\n        _, predicted = torch.max(predictions, 1)\n        total += labels.size(0)\n        correct += (labels == predicted).sum()\n    print(f'Epoch: {epoch+1}/{num_epochs}, Val_Acc: {100*correct/total}')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Test model","metadata":{}},{"cell_type":"code","source":"model.eval()\n\ncorrect = 0\ntotal = 0  \nfor images, labels in tqdm(val_loader):\n    images = images.to(device)\n    labels = labels.to(device)\n    predictions = model(images)\n    _, predicted = torch.max(predictions, 1)\n    total += labels.size(0)\n    correct += (labels == predicted).sum()\nprint(f'Val_Acc: {100*correct/total}')","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}