{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install pretrainedmodels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pretrainedmodels","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"os.listdir(\"../input/train/train\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"os.listdir(\"../input/train/train/cgm\")[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"os.listdir(\"../input/test/test/0\")[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%matplotlib inline\nimport time\nimport numpy as np\nimport pandas as pd\nimport os\nimport cv2\nimport datetime as dt\nimport matplotlib.pyplot as plt\nfrom mpl_toolkits.axes_grid1 import ImageGrid\nfrom os import listdir, makedirs, getcwd, remove\nfrom os.path import isfile, join, abspath, exists, isdir, expanduser\nfrom PIL import Image\nimport torch\nfrom torch.optim import lr_scheduler\nfrom torch.autograd import Variable\nfrom torch.utils.data import Dataset, DataLoader\nimport torchvision\nfrom torchvision import transforms, datasets, models\n\nfrom sklearn.model_selection import train_test_split","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_path = \"../input/train/train\"\ntest_path = \"../input/test/test/0\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_labels(file_path): \n    dir_name = os.path.dirname(file_path)\n    split_dir_name = dir_name.split(\"/\")\n    dir_levels = len(split_dir_name)\n    label  = split_dir_name[dir_levels - 1]\n    return(label)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"get_labels(\"../input/train/train/cgm/train-cgm-528.jpg\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from glob import glob\nimagePatches = glob(\"../input/train/train/*/*.*\", recursive=True)\nimagePatches[0:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"images_df = pd.DataFrame()\nimages_df[\"images\"] = imagePatches\n\ny = []\nfor img in imagePatches:\n    y.append(get_labels(img))   \n\nimages_df[\"labels\"] = y","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\nlabelencoder = LabelEncoder()\nimages_df[\"labels\"] = labelencoder.fit_transform(images_df[\"labels\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"images_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class MyDataset(Dataset):\n    def __init__(self, df_data,transform=None):\n        super().__init__()\n        self.df = df_data.values\n        \n        self.transform = transform\n\n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, index):\n        img_path,label = self.df[index]\n        \n        image = cv2.imread(img_path)\n        #image = cv2.resize(image, (500,500))\n        if self.transform is not None:\n            image = self.transform(image)\n        return image, label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 16\n# Device configuration\ndevice = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Splitting data into train and val\ntrain, val = train_test_split(images_df, stratify=images_df.labels, test_size=0.2)\nlen(train), len(val)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mean=[0.485, 0.456, 0.406]\nstd=[0.229, 0.224, 0.225]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"imagePatches_test = glob(\"../input/test/test/0/*.*\", recursive=True)\nimagePatches_test[0:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"images_df_test = pd.DataFrame()\nimages_df_test[\"images\"] = imagePatches_test\nimages_df_test[\"label\"] = -1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import random\nimport math\nclass RandomErasing(object):\n    '''\n    Class that performs Random Erasing in Random Erasing Data Augmentation by Zhong et al. \n    -------------------------------------------------------------------------------------\n    probability: The probability that the operation will be performed.\n    sl: min erasing area\n    sh: max erasing area\n    r1: min aspect ratio\n    mean: erasing value\n    -------------------------------------------------------------------------------------\n    '''\n    def __init__(self, probability = 0.5, sl = 0.02, sh = 0.4, r1 = 0.3, mean=[0.4914, 0.4822, 0.4465]):\n        self.probability = probability\n        self.mean = mean\n        self.sl = sl\n        self.sh = sh\n        self.r1 = r1\n       \n    def __call__(self, img):\n\n        if random.uniform(0, 1) > self.probability:\n            return img\n\n        for attempt in range(100):\n            area = img.size()[1] * img.size()[2]\n       \n            target_area = random.uniform(self.sl, self.sh) * area\n            aspect_ratio = random.uniform(self.r1, 1/self.r1)\n\n            h = int(round(math.sqrt(target_area * aspect_ratio)))\n            w = int(round(math.sqrt(target_area / aspect_ratio)))\n\n            if w < img.size()[2] and h < img.size()[1]:\n                x1 = random.randint(0, img.size()[1] - h)\n                y1 = random.randint(0, img.size()[2] - w)\n                if img.size()[0] == 3:\n                    img[0, x1:x1+h, y1:y1+w] = self.mean[0]\n                    img[1, x1:x1+h, y1:y1+w] = self.mean[1]\n                    img[2, x1:x1+h, y1:y1+w] = self.mean[2]\n                else:\n                    img[0, x1:x1+h, y1:y1+w] = self.mean[0]\n                return img\n\n        return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from torchvision import transforms as T\nsize = 500\ntrans = transforms.Compose([transforms.ToPILImage(),\n                                  T.RandomApply([T.RandomAffine(45, shear=15)], 0.8),\n                                T.RandomResizedCrop(size, scale=(0.6, 1.0), ratio=(3/5, 5/3)),\n                                T.RandomHorizontalFlip(),\n                                T.RandomVerticalFlip(),\n                                T.ToTensor(),\n                                T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n                                RandomErasing(probability=0.3, sh=0.3)])\n\ndataset_train = MyDataset(df_data=train, transform=trans)\ndataset_valid = MyDataset(df_data=val,transform=trans)\n\nloader_train = DataLoader(dataset = dataset_train, batch_size=batch_size, shuffle=True, num_workers=0)\nloader_valid = DataLoader(dataset = dataset_valid, batch_size=batch_size//2, shuffle=False, num_workers=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset_test = MyDataset(df_data=images_df_test,transform=trans)\nloader_test = DataLoader(dataset = dataset_test, batch_size=batch_size//2, shuffle=False, num_workers=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def imshow(axis, inp):\n    \"\"\"Denormalize and show\"\"\"\n    inp = inp.numpy().transpose((1, 2, 0))\n    inp = std * inp + mean\n    axis.imshow(inp)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img, label = next(iter(loader_train))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(1, figsize=(8,8))\ngrid = ImageGrid(fig, 111, nrows_ncols=(1, 4), axes_pad=0.05)    \nfor i in range(4):\n    ax = grid[i]\n    imshow(ax, img[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"use_gpu = torch.cuda.is_available()\ninputs, labels = next(iter(loader_train))\nif use_gpu:\n    inputs, labels = Variable(inputs.cuda()), Variable(labels.cuda())   \nelse:\n    inputs, labels = Variable(inputs), Variable(labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def se_resnext50_32x4d(pretrained=False):\n    pretrained = 'imagenet' if pretrained else None\n    model = pretrainedmodels.se_resnext50_32x4d(pretrained=pretrained)\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = se_resnext50_32x4d(pretrained=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"use_gpu = torch.cuda.is_available()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for param in model.parameters():\n    param.requires_grad = False\n\n# new final layer with 5 classes\nmodel.avg_pool = torch.nn.AdaptiveAvgPool2d(1)\nnum_ftrs = model.last_linear.in_features\nmodel.last_linear = torch.nn.Linear(num_ftrs, 5)\nif use_gpu:\n    model = model.cuda()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"criterion = torch.nn.CrossEntropyLoss()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"num_epochs = 15","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"total_step = len(loader_train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for epoch in range(num_epochs):\n    if (epoch < 2):\n        optimizer = torch.optim.Adam(model.parameters(), lr=0.00008)\n    else:\n        optimizer = torch.optim.Adam(model.parameters(), lr=0.0001)\n        \n    for i, (images, labels) in enumerate(loader_train):\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) % 100 == 0:\n            print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' \n                   .format(epoch+1, num_epochs, i+1, total_step, loss.item()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Test the model\nmodel.eval()  # eval mode (batchnorm uses moving mean/variance instead of mini-batch mean/variance)\nwith torch.no_grad():\n    correct = 0\n    total = 0\n    for images, labels in loader_valid:\n        images = images.to(device)\n        labels = labels.to(device)\n        outputs = model(images)\n        _, predicted = torch.max(outputs.data, 1)\n        total += labels.size(0)\n        correct += (predicted == labels).sum().item()\n          \n    print('Test Accuracy of the model on the test images: {} %'.format(100 * correct / total))\n\n# Save the model checkpoint\ntorch.save(model.state_dict(), 'model.ckpt')","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}