{"cells":[{"metadata":{},"cell_type":"markdown","source":"## Install Tez and efficientnet-pytorch impelmentation\n"},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"!pip install tez\n!pip install efficientnet-pytorch","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## What is Diabetic Retinopathy?\nThere are at least 5 things to spot on in order to know that a patient have diabetic retinopahy. Image credit \n\n![](https://sa1s3optim.patientpop.com/assets/images/provider/photos/1947516.jpeg)\n\n\n- [Image source](https://www.eyeops.com/contents/our-services/eye-diseases/diabetic-retinopathy)\n\nFrom quick investigations of the data (see various pictures below), Hemorrphages, Hard Exudates and Cotton Wool spots are quite easily observed. However, examples of Aneurysm or Abnormal Growth of Blood Vessels are hard to find in the data. Perhaps the latter two cases are important if we want to catch up human benchmnark using our model."},{"metadata":{},"cell_type":"markdown","source":"## Why [Tez](https://github.com/abhishekkrthakur/tez)?\nI always found the learning curve of pytorch a bit complicated, **Tez (तेज़ / تیز)** aims to make  pytorch training easy and allow fast prototyping by keeping things as simple and as customizable as possible."},{"metadata":{},"cell_type":"markdown","source":"## Import What You Need\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport albumentations\nimport pandas as pd\nimport numpy as np\nimport tez\nfrom tez.datasets import ImageDataset\nfrom tez.callbacks import EarlyStopping\n\nimport torch\nimport torch.nn as nn\nfrom torch.nn import functional as F\n\nfrom efficientnet_pytorch import EfficientNet\nfrom sklearn import metrics, model_selection, preprocessing\nimport matplotlib.pyplot as plt\nimport cv2\n\nSEED = 42\nIMAGE_SIZE = 256\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Split Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"dfx = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')\ndf_train, df_valid = model_selection.train_test_split(\n        dfx, test_size=0.1, random_state=SEED, stratify=dfx.diagnosis.values\n)\n\ndf_train = df_train.reset_index(drop=True)\ndf_valid = df_valid.reset_index(drop=True)\n\nimage_path = \"../input/aptos2019-blindness-detection/train_images/\"\ntrain_image_paths = [os.path.join(image_path, x+\".png\") for x in df_train.id_code.values]\nvalid_image_paths = [os.path.join(image_path, x+\".png\") for x in df_valid.id_code.values]\ntrain_targets = df_train.diagnosis.values\nvalid_targets = df_valid.diagnosis.values","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Visualize Data"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize=(25, 16))\n# display 10 images from each class\nfor class_id in sorted(np.unique(train_targets)):\n    for i, (idx, row) in enumerate(df_train.loc[df_train['diagnosis'] == class_id].sample(5, random_state=SEED).iterrows()):\n        ax = fig.add_subplot(5, 5, class_id * 5 + i + 1, xticks=[], yticks=[])\n        path=f\"../input/aptos2019-blindness-detection/train_images/{row['id_code']}.png\"\n        image = cv2.imread(path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        image = cv2.resize(image, (IMAGE_SIZE, IMAGE_SIZE))\n\n        plt.imshow(image)\n        ax.set_title('Label: %d-%d-%s' % (class_id, idx, row['id_code']) )","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize=(25, 16))\n# display 10 images from each class\nfor class_id in sorted(np.unique(train_targets)):\n    for i, (idx, row) in enumerate(df_train.loc[df_train['diagnosis'] == class_id].sample(5, random_state=SEED).iterrows()):\n        ax = fig.add_subplot(5, 5, class_id * 5 + i + 1, xticks=[], yticks=[])\n        path=f\"../input/aptos2019-blindness-detection/train_images/{row['id_code']}.png\"\n        image = cv2.imread(path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n        image = cv2.resize(image, (IMAGE_SIZE, IMAGE_SIZE))\n\n        plt.imshow(image, cmap='gray')\n        ax.set_title('Label: %d-%d-%s' % (class_id, idx, row['id_code']) )","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Model via Tez.Model\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"class EyeModel(tez.Model):\n    def __init__(self, num_classes):\n        super().__init__()\n\n        self.effnet = EfficientNet.from_pretrained(\"efficientnet-b4\")\n        self.dropout = nn.Dropout(0.1)\n        self.out = nn.Linear(1792, num_classes)\n        self.step_scheduler_after = \"epoch\"\n        \n    def monitor_metrics(self, outputs, targets):\n        if targets is None:\n            return {}\n        outputs = torch.argmax(outputs, dim=1).cpu().detach().numpy()\n        targets = targets.cpu().detach().numpy()\n        accuracy = metrics.accuracy_score(targets, outputs)\n        return {\"accuracy\": accuracy}\n    \n    def fetch_optimizer(self):\n        opt = torch.optim.Adam(self.parameters(), lr=3e-4)\n        return opt\n    \n    def fetch_scheduler(self):\n        sch = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(\n            self.optimizer, T_0=10, T_mult=1, eta_min=1e-6, last_epoch=-1\n        )\n        return sch\n\n    def forward(self, image, targets=None):\n        batch_size, _, _, _ = image.shape\n\n        x = self.effnet.extract_features(image)\n        x = F.adaptive_avg_pool2d(x, 1).reshape(batch_size, -1)\n        outputs = self.out(self.dropout(x))\n        \n        if targets is not None:\n            loss = nn.CrossEntropyLoss()(outputs, targets)\n            metrics = self.monitor_metrics(outputs, targets)\n            return outputs, loss, metrics\n        return outputs, None, None\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Augmentations\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"\ntrain_aug = albumentations.Compose([\n            albumentations.Resize(IMAGE_SIZE, IMAGE_SIZE, p=1.0),\n            albumentations.Normalize(\n                mean=[0.485], \n                std=[0.229], \n                max_pixel_value=255.0, \n                p=1.0\n            )])\n        \nvalid_aug = albumentations.Compose([\n            albumentations.Resize(IMAGE_SIZE, IMAGE_SIZE, p=1.0),\n            albumentations.Normalize(\n                mean=[0.485], \n                std=[0.229], \n                max_pixel_value=255.0, \n                p=1.0\n            )])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Generate Training and Validation dataset\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dataset = ImageDataset(\n    image_paths=train_image_paths,\n    targets=train_targets,\n    augmentations=train_aug,\n)\n\ntest_dataset = ImageDataset(\n    image_paths=valid_image_paths,\n    targets=valid_targets,\n    augmentations=valid_aug,\n)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Load, Train & Save Model\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"model = EyeModel(num_classes=5)\nes = EarlyStopping(\n    monitor=\"valid_loss\", model_path=\"model.bin\", patience=5, mode=\"min\"\n)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.fit(\n    train_dataset,\n    valid_dataset=test_dataset,\n    train_bs=32,\n    valid_bs=64,\n    device=\"cuda\",\n    epochs=10,\n    callbacks=[es],\n    fp16=True,\n)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save(\"model.bin\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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":4}