{"cells":[{"metadata":{},"cell_type":"markdown","source":"# This is a quick implementation(prototype). \n# No techniques are added here. will fine-tune later.(I used GPU quota almost this week ;) )"},{"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)\n\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\n\nimport os\n'''\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n'''\n\n# Any results you write to the current directory are saved as output.\nimport cv2\nimport torch\nimport torch.nn as nn\nimport torchvision.models as models\nfrom torch.utils.data import Dataset,DataLoader","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Speed up preprocessing"},{"metadata":{"trusted":true},"cell_type":"code","source":"class Resize(object):\n    \n    def __init__(self,_type = 'train'):\n        self.path = '/kaggle/input/aptos2019-blindness-detection/'\n        \n        if 'train' in _type:\n            _type = 'train_images'\n            self.df = pd.read_csv(os.path.join(self.path,'train.csv'))\n            !rm -r resized_train_images\n            !mkdir resized_train_images\n            self.new_path = 'resized_train_images'\n            self.root = os.path.join(self.path,_type)\n        elif 'test' in _type:\n            _type = 'test_images'\n            self.df = os.path.join(self.path,'test.csv')\n            !rm -r resized_test_images\n            !mkdir resized_test_images\n            self.new_path = 'resized_test_images'\n            self.root = pd.read_csv(os.path.join(self.path,_type))\n        else:\n            raise print(f'type should contain either train or test but got {_type}')\n            \n    def __call__(self):\n        fnames = self.df.set_index('id_code').index.values\n        \n        for fname in fnames:\n            #read -> convert BGR to RGB\n            Image = cv2.cvtColor(cv2.imread(os.path.join(self.root,fname+'.png')),cv2.COLOR_BGR2RGB)\n            ## resize 224x224 compatible with resnet-like structures.\n            Image = cv2.resize(Image,(224,224))\n            result = cv2.imwrite(os.path.join(self.new_path,fname+'.png'), Image)\n            print(f'saved successfully at {self.new_path}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"resize = Resize(_type='train')\nresize()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class EyeBallDataset(Dataset):\n    def __init__(self,_type = 'train'):\n        self.path = '/kaggle/input/aptos2019-blindness-detection/'\n        if _type == 'train':\n            print('train dataset')\n            self.df = pd.read_csv(os.path.join(self.path,'train.csv'))\n            self.root = 'resized_train_images'\n        elif _type == 'test':\n            print('test dataset')\n            self.df = pd.read_csv(os.path.join(self.path,'test.csv'))\n            self.root = 'resized_test_images'\n        else:\n            raise print(f'_type should be either train or test but got{_type}')\n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self,idx):\n        fname = self.df.id_code.values[idx]\n        label = self.df.diagnosis.values[idx]\n        Image = cv2.imread(os.path.join(self.root,fname+'.png'))\n        return torch.tensor(Image),label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_images = EyeBallDataset('train')\ntrain_loader = DataLoader(train_images, batch_size=25, shuffle=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"classes = {0:'No DR', 1:'Mild', 2:'Moderate', 3:'Severe', 4:'Proliferative Dr'}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\na = next(iter(train_loader))\n\nfig,ax = plt.subplots(5,5,figsize=(25,25))\n\nfor i in range(25):\n    j = i//5\n    k = i%5\n    ax[j,k].imshow(a[0][i])\n    ax[j,k].set_title(f'{classes[int(a[1][i])]}',fontsize=20)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class ResNet101(nn.Module):\n    def __init__(self,pretrained=True):\n        super().__init__()\n        encoder = models.resnet101(pretrained=pretrained)\n        encoder = nn.Sequential(*list(encoder.children()))\n    \n        self.cnn = nn.Sequential(\n            encoder[0],\n            encoder[1],\n            encoder[2],\n            encoder[3],\n            encoder[4],\n            encoder[5],\n            encoder[6],\n            encoder[7],\n            encoder[8]\n        )\n        self.clf = nn.Linear(2048,5,bias=False)\n    def forward(self,x):\n        x = self.cnn(x)\n        x = x.view(x.size(0),-1)\n        x = self.clf(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_images = EyeBallDataset('train')\ntrain_loader = DataLoader(train_images, batch_size=25, shuffle=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nmodel = ResNet101().to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"accs = []\nlosses = []\nepochs = 10\nlr = 1e-3\noptimizer = torch.optim.Adam(model.parameters(),lr = lr)\ncriterion = nn.CrossEntropyLoss(reduction='mean')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tqdm import tqdm_notebook as tqdm\nmodel.train()\nfor epoch in range(epochs):\n    print(f'epochs {epoch+1}/{epochs}')\n    running_loss = 0.0\n    running_acc = 0.0\n    for idx, (inputs,labels) in tqdm(enumerate(train_loader),total=len(train_loader)):\n        optimizer.zero_grad()\n        inputs = inputs.to(device)\n        labels = labels.to(device)\n        outputs = model(inputs.permute(0,3,2,1).float())\n        loss = criterion(outputs,labels)\n        loss.backward()\n        optimizer.step()\n        running_loss += loss\n        running_acc += (outputs.argmax(1)==labels).float().mean()\n    print('loss : {:.4f} acc: {:.2f}'.format(running_loss/len(train_loader),running_acc/len(train_loader)))\n    losses.append(running_loss/len(train_loader))\n    accs.append(running_acc/len(train_loader))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"figs , ax = plt.subplots(1,2,figsize=(20,5))\nax[0].plot(losses)\nax[0].set_title('train_loss')\nax[1].plot(accs)\nax[1].set_title('train_acc')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!rm -r resized_train_images\n!rm -r resized_test_images","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}