{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install efficientnet_pytorch\n!pip install torchsummary ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import torch\nfrom torchvision import transforms\nfrom torch.utils.data import Dataset,DataLoader\nfrom efficientnet_pytorch import EfficientNet\nfrom torchsummary import summary\nfrom torch import nn\nfrom torch.optim.lr_scheduler import ReduceLROnPlateau\nfrom tqdm import tqdm_notebook as tqdm\n\nimport numpy as np\nimport cv2\nimport matplotlib.pyplot as plt\nimport random\nimport time\nimport pandas as pd\nimport os\n\nfrom albumentations import (\n    HorizontalFlip, VerticalFlip, IAAPerspective, ShiftScaleRotate, CLAHE, RandomRotate90,\n    Transpose, ShiftScaleRotate, Blur, OpticalDistortion, GridDistortion, HueSaturationValue,\n    IAAAdditiveGaussianNoise, GaussNoise, MotionBlur, MedianBlur, IAAPiecewiseAffine, RandomResizedCrop,\n    IAASharpen, IAAEmboss, RandomBrightnessContrast, Flip, OneOf, Compose, Normalize, Cutout, CoarseDropout, ShiftScaleRotate, CenterCrop, Resize\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from albumentations.pytorch import ToTensorV2\n\ndef get_train_transforms():\n    return Compose([\n            RandomResizedCrop(cfg['input_shape'][0], cfg['input_shape'][0]),\n            Transpose(p=0.5),\n            HorizontalFlip(p=0.5),\n            VerticalFlip(p=0.5),\n            ShiftScaleRotate(p=0.5),\n            HueSaturationValue(hue_shift_limit=0.2, sat_shift_limit=0.2, val_shift_limit=0.2, p=0.2),\n            RandomBrightnessContrast(brightness_limit=(-0.1,0.1), contrast_limit=(-0.1, 0.1), p=0.5),\n        ], p=1.)\ndef get_valid_transforms():\n    return Compose([\n            CenterCrop(cfg['input_shape'][0], cfg['input_shape'][0], p=1.),\n            Resize(cfg['input_shape'][0], cfg['input_shape'][0]),\n        ], p=1.)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"#hyperparameters\ntrain_dir = '../input/cassava-leaf-disease-classification/train_images'\ncfg = {\n    'batch_size': 16,\n    'input_shape': (512,512,3),\n    'epochs': 15,\n    'folds': 5,\n    'lr': 0.0001,\n    'gamma': 4.0,\n    'alpha': 2.0,\n    'device':'cuda:0'\n}\n#helper functions:\ndef read_image(path,shape=None):\n    if shape is None:\n        return cv2.imread(path)\n    else:\n        return cv2.resize(cv2.imread(path),shape)\ndef get_input(img,dims=(20,20)):\n    img_cpy = img.copy()\n    size = img.shape[0]\n    X = random.sample([i for i in range(size)], k =20)\n    Y = random.sample([i for i in range(size)], k =20)\n    for x,y in zip(X,Y):\n        img_cpy[x-dims[0]:x+dims[0],y-dims[1]:y+dims[1],:] = 0\n    return img_cpy\ndef normalize_and_to_tensor(img):\n    transform = Compose([Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], max_pixel_value=255.0, p=1.0),\n                       ToTensorV2(p=1.0)],p=1.0)\n    return transform(image=img)['image']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#dataset\nclass CASSAVA(Dataset):\n    def __init__(self,images,input_shape,transforms=None,visualize_mode=False):\n        self.images = images\n        self.input_size=input_shape[0]\n        self.transforms = transforms\n        self.visualize_mode = visualize_mode\n    def __len__(self):\n        return len(self.images)\n    def __getitem__(self,idx):\n        label = self.images[idx]\n        label = read_image(label,(self.input_size,self.input_size))\n        if self.transforms is None:\n            label = self.transforms(image=label)['image']\n        input_image = get_input(label)\n        label = cv2.resize(label,(128,128))\n        if not self.visualize_mode:\n            input_image = normalize_and_to_tensor(input_image)\n            label = normalize_and_to_tensor(label)\n        return input_image,label\n#test\nimages = os.listdir(train_dir)\nimg_dirs = [train_dir+'/'+d for d in images]\ndataset = CASSAVA(img_dirs,\n                  cfg['input_shape'],\n                 transforms = get_train_transforms(),\n                  visualize_mode = True\n                 )\nimage,label = dataset.__getitem__(3)\nplt.imshow(image)\nplt.show()\nplt.imshow(label)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class MY_MODEL(nn.Module):\n    def __init__(self,pretrained = False):\n        super(MY_MODEL, self).__init__()\n        self.pretrained = pretrained\n        self.effn = EfficientNet.from_pretrained('efficientnet-b3')\n        self.upconv1 = nn.Upsample(scale_factor=(2, 2))\n        self.conv1 = nn.Conv2d(1536,256,(3,3),padding=(1,1))\n        self.upconv2 = nn.Upsample(scale_factor=(2, 2))\n        self.conv2 = nn.Conv2d(256,64,(3,3),padding=(1,1))\n        self.upconv3 = nn.Upsample(scale_factor=(2, 2))\n        self.conv3 = nn.Conv2d(64,3,(3,3),padding=(1,1))\n        for p in self.effn.parameters():\n            p.requires_grad = True\n    def forward(self,x):\n        x = self.effn.extract_features(x)\n        x = self.upconv1(x)\n        x = self.conv1(x)\n        x = self.upconv2(x)\n        x = self.conv2(x)\n        x = self.upconv3(x)\n        x = self.conv3(x)\n        return x\n\nmodel = MY_MODEL()\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel.to(device)\nmodel.load_state_dict(torch.load('../input/selfsupervision/trained.pt'))\nsummary(model,(3,512,512))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def loss_fn(y_true,y_pred):\n    y_true = y_true.to(device)\n    y_pred = y_pred.to(device)\n    l = torch.abs(y_true-y_pred)\n    shape = l.shape\n    l = torch.sum(l,axis=[1,2,3])\n    l = l/(shape[-1]*shape[-2]*shape[-3])\n    return l","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"optim = torch.optim.Adam(model.parameters(), lr=0.0001)\nscheduler = ReduceLROnPlateau(optimizer=optim, mode='max', patience=1, verbose=True, factor=0.2)\ndataset = CASSAVA(img_dirs,\n                  cfg['input_shape'],\n                 transforms = get_train_transforms(),\n                  visualize_mode = False\n                 )\n\ntrain_loader = DataLoader(dataset=dataset, batch_size=8, shuffle=True, num_workers=2)\ntotal = dataset.__len__()\nsize = total//30\nfor epoch in range(cfg['epochs']):\n    start = time.time()\n    model.train()\n    epoch_loss = 0\n    for x,y in tqdm(train_loader):\n        x = x.to(device)\n        y = y.to(device)\n        optim.zero_grad()\n        y_pred = model(x)\n        loss = loss_fn(y,y_pred)\n        loss.mean().backward()\n        optim.step()\n        epoch_loss+=loss.mean().item()\n    print('Epoch {:03}: | Loss: {:.3f} | Training time: {}'.format(\n            epoch + 1, \n            epoch_loss, \n            str(time.time() - start)[:7]))\n    scheduler.step(epoch_loss)\n    torch.save(model.state_dict(), 'trained.pt')","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}