{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport torch\nimport torch.nn as nn\nimport torch.utils.data as data_utils\nfrom torchvision import transforms\nfrom torchvision.models import resnet50\nfrom PIL import Image\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport numpy as np\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\nfrom IPython.core.debugger import set_trace\nimport os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_data = pd.read_csv(\"/kaggle/input/aptos2019-blindness-detection/\"  + \"train.csv\")\nall_data.head()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Lets look at the distribution of different training labels in the original data set"},{"metadata":{"trusted":true},"cell_type":"code","source":"all_data[\"diagnosis\"].value_counts().plot(kind=\"pie\")\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data, validation_data = train_test_split(all_data, stratify = all_data.diagnosis.values, test_size=0.01)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"lets looks at the distribution of labels in both train and validation set"},{"metadata":{"trusted":true},"cell_type":"code","source":"\nfig, axes = plt.subplots(nrows=1, ncols=2)\ntrain_data.diagnosis.value_counts().plot(kind=\"pie\", ax=axes[0],title=\"train data\")\nvalidation_data.diagnosis.value_counts().plot(kind=\"pie\", ax=axes[1], title=\"validation data\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"validation_data.shape","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"class dataSet_(data_utils.Dataset):\n    def __init__(self, data_dir, data_frame, image_transform):\n        super().__init__()\n        self.dir = data_dir\n        self.label = data_frame.values[:,0]\n        self.diagnosis = data_frame.values[:,1]\n        self.transfrom = image_transform\n\n    \n    def __len__(self):\n        return len(self.label)\n    \n    def __getitem__(self, idx):\n        file_to_be_loaded = self.label[idx]        \n        array = Image.open(self.dir + file_to_be_loaded + \".png\")\n        array = self.transfrom(array)\n        return array, torch.tensor(self.diagnosis[idx], dtype=torch.float32)\n        \n        \n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dir = '/kaggle/input/aptos2019-blindness-detection/train_images/'\nvalid_dir = '/kaggle/input/aptos2019-blindness-detection/train_images/'\ntest_dir = '/kaggle/input/aptos2019-blindness-detection/test_images/'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_transform={\"train\":transforms.Compose([transforms.RandomRotation(degrees=50),transforms.RandomResizedCrop((224,224)),transforms.RandomHorizontalFlip(p=0.5),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])]),\n                \"test\": transforms.Compose([transforms.Resize((224,224)),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])])}\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TrainData = dataSet_(train_dir, train_data, image_transform[\"train\"])\ntrainloader = data_utils.DataLoader(TrainData,batch_size=64)\n##############################\n## Validation data\n\nValidData = dataSet_(valid_dir, validation_data, image_transform[\"test\"])\nvalidationloader = data_utils.DataLoader(ValidData, batch_size=64)\n\n### test data\ntest_data = pd.read_csv(\"/kaggle/input/aptos2019-blindness-detection/\"  + \"sample_submission.csv\")\nTestData = dataSet_(test_dir, test_data, image_transform[\"test\"])\ntestloader = data_utils.DataLoader(TestData, batch_size=64)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"images,_ = next(iter(testloader))\nplt.imshow(images.data.numpy().squeeze()[0,:,:,:].reshape(224,224,3))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = resnet50(pretrained=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from collections import OrderedDict\nimport torch.functional as F\n\nfor param in model.parameters():\n    param.requires_grad = False\n\nin_feature = model.fc.in_features\n\nfc = nn.Sequential(OrderedDict([(\"fc1\", nn.Linear(in_feature, 512)),\n                                (\"relu1\", nn.ReLU()),\n                                (\"fc2\", nn.Linear(512, 5)),\n                                (\"output\",nn.LogSoftmax(dim=1))]))\nmodel.fc = fc","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = (\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\ncriterion = nn.NLLLoss()\noptimizer = torch.optim.Adam(model.fc.parameters(), lr=0.01)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_loss_min = np.Inf\nmodel.to(device)\nfor epoch in range(10):\n    running_loss = 0.0\n    model.train()\n    for train_data, train_label in trainloader:\n        train_data, train_label = train_data.to(device), train_label.to(device)\n        log_ps = model.forward(train_data)\n        optimizer.zero_grad()        \n        train_loss = criterion(log_ps, train_label.long())\n        running_loss += train_loss.item()\n        train_loss.backward()\n        optimizer.step()\n    else:\n        running_test_loss = 0.0\n        with torch.no_grad():\n            model.eval()\n            for test_data, test_label in validationloader:\n                test_data, test_label = test_data.to(device), test_label.to(device)\n                test_log_ps = model.forward(test_data)\n                test_loss = criterion(test_log_ps, test_label.long())\n                running_test_loss += test_loss.item()\n    if test_loss <= valid_loss_min:\n        print(\"Validation loss decreased from {:.7f} -----> {:.7f}\".format(valid_loss_min,test_loss))\n        # save the model if validation error decreases \n        torch.save(model.state_dict(), 'model_augmented.pt')\n        valid_loss_min = test_loss\n                \n\n    print(f\" Epoch {epoch} , Training loss = {running_loss/len(trainloader)} Test loss = {running_test_loss/len(validationloader)}\")\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Load the model from the disk"},{"metadata":{"trusted":true},"cell_type":"code","source":"checkpoint = torch.load('model_augmented.pt')\nmodel.load_state_dict(checkpoint)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Confusion matrix\nLets print the confusion Matrix"},{"metadata":{"trusted":true},"cell_type":"code","source":"nb_classes = 5\n\nconfusion_matrix = torch.zeros(nb_classes, nb_classes)\nmodel.to(device)\nmodel.eval()\nwith torch.no_grad():\n    for i, (inputs, classes) in enumerate(validationloader):\n        inputs = inputs.to(device)\n        classes = classes.to(device)\n        outputs = model.forward(inputs)\n        _, preds = torch.max(outputs.data.cpu(), 1)\n        #set_trace()\n        for t, p in zip(classes.view(-1), preds.view(-1)):\n                confusion_matrix[t.long(), p.long()] += 1\n\nprint(confusion_matrix)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Classwise accuracy of the results"},{"metadata":{"trusted":true},"cell_type":"code","source":"# initialize lists to monitor test loss and accuracy\ntest_loss = 0.0\nclass_correct = list(0. for i in range(10))\nclass_total = list(0. for i in range(10))\n\n\nmodel.eval() # prep model for evaluation\nwith torch.no_grad():    \n    for data, target in validationloader:\n        # forward pass: compute predicted outputs by passing inputs to the model\n        data, target = data.to(device), target.to(device)\n        output = model(data)\n        # calculate the loss\n        loss = criterion(output, target.long())\n        # update test loss \n        test_loss += loss.item()*data.size(0)\n        # convert output probabilities to predicted class\n        _, pred = torch.max(output, 1)\n        # compare predictions to true label\n        correct = np.squeeze(pred.eq(target.long().data.view_as(pred)))\n        # calculate test accuracy for each object class\n        for i in range(len(target)):\n            #set_trace()\n            label = target[i].long().item()\n            #set_trace()\n            class_correct[label] += correct[i].item()\n            class_total[label] += 1\n\n    # calculate and print avg test loss\n    test_loss = test_loss/len(validationloader)\n    print('Test Loss: {:.6f}\\n'.format(test_loss))\n\n    for i in range(10):\n        if class_total[i] > 0:\n            print('Validation Accuracy of %5s: %2d%% (%2d/%2d)' % (\n                str(i), 100 * class_correct[i] / class_total[i],\n                np.sum(class_correct[i]), np.sum(class_total[i])))\n        else:\n            print('Validation Accuracy of %5s: N/A (no training examples)' % (classes[i]))\n\n    print('\\n Validation Accuracy (Overall): %2d%% (%2d/%2d)' % (\n        100. * np.sum(class_correct) / np.sum(class_total),\n        np.sum(class_correct), np.sum(class_total)))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Visualize the results\nThis cell displays test images and their labels in this format: predicted (ground-truth). The text will be green for accurately classified examples and red for incorrect predictions."},{"metadata":{"trusted":true},"cell_type":"code","source":"# obtain one batch of test images\ndataiter = iter(validationloader)\nimages, labels = dataiter.next()\nimages, labels = images.to(device), labels.to(device)\nwith torch.no_grad():  \n    model.eval()\n    # get sample outputs\n    output = model.forward(images)\n    # convert output probabilities to predicted class\n    _, preds = torch.max(output, 1)\n    # prep images for display\n    images = images.data.cpu().numpy()\n\n    # plot the images in the batch, along with predicted and true labels\n    fig = plt.figure(figsize=(25, 4))\n    for idx in np.arange(20):\n        ax = fig.add_subplot(2, 20/2, idx+1, xticks=[], yticks=[])\n        #set_trace()\n        ax.imshow(images[idx].reshape(224,224,3))\n        ax.set_title(\"{} ({})\".format(str(preds[idx].item()), str(labels[idx].long().item())),\n                     color=(\"green\" if preds[idx]==labels[idx].long() else \"red\"))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Test data"},{"metadata":{"trusted":true},"cell_type":"code","source":"#filename_arrays = []\ntest_output =[]\nwith torch.no_grad():\n    model.eval()\n    for testdata,_ in testloader:\n        testdata = testdata.to(device)\n        #filename_arrays += list(filename)\n        log_ps = model.forward(testdata)\n        test_prob = torch.exp(log_ps)\n        _, test_pred_class = torch.max(test_prob, dim=1)\n        test_output += test_pred_class.cpu().data.tolist()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_output = {\"id\": test_data.id_code.values.tolist(), \"diagnosis\": test_output}\nsample_output_dataframe = pd.DataFrame(sample_output)\nsample_output_dataframe.to_csv(\"submission.csv\",index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nos.chdir(r'../working')\nfrom IPython.display import FileLink\nFileLink(r'submission.csv')","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":1}