{"cells":[{"metadata":{},"cell_type":"markdown","source":"![](https://storage.googleapis.com/kaggle-competitions/kaggle/13836/logos/header.png?t=2020-10-01-17-22-54)"},{"metadata":{},"cell_type":"markdown","source":"Motivation: This is meant to be an easy submission Notebook to be used with the CassavaNet Training/Starter Notebook. Any model is easy to load and run, and they run TTA efficiently (as a batch over the models).\n\nTraining Notebook: https://www.kaggle.com/capiru/cassavanet-starter-easy-gpu-tpu-cv-0-9"},{"metadata":{},"cell_type":"markdown","source":"# Library"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# ====================================================\n# Library\n# ====================================================\nimport sys\nsys.path.append('../input/timm-pytorch-image-models/pytorch-image-models-master')\nimport timm\n\nimport random\nimport os\nimport torch\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport torch\nimport torch.nn as nn\nimport torchvision\nfrom torchvision import models as tvmodels\nfrom torch.cuda.amp import autocast, GradScaler\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms, utils\nfrom tqdm import tqdm\nimport torch.nn.functional as F\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.model_selection import KFold\nimport time\n\nimport math\nfrom matplotlib.pyplot import imread\nimport albumentations as A\nfrom albumentations import Compose\nfrom albumentations.pytorch import ToTensorV2\nimport numpy as np\nimport cv2\nfrom sklearn.model_selection import GroupKFold, StratifiedKFold\n\nimport time\n# Ignore warnings\nimport warnings\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Config"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# Config\n# ====================================================\nDATA_PATH = '../input/cassava-leaf-disease-classification/'\nTRAIN_DIR = DATA_PATH + 'train_images/'\nTEST_DIR = DATA_PATH + 'test_images/'\nMODEL_PATH = '../input/cassavanet-baseline-models/'\n\nN_TTA = 8\n\nHEIGHT = 512\nWIDTH = 512\nCHANNELS = 3\n\nN_CLASSES = 5\n\nMODEL_LIST = [0,1,2,3,4,5,6]\n\nIMG_MEAN = [0.485, 0.456, 0.406] #Mean for normalization Transform cassava = [0.4303, 0.4967, 0.3134] imgnet = [0.485, 0.456, 0.406]\nIMG_STD = [0.229, 0.224, 0.225] #STD for normalization Transform cassava = [0.2142, 0.2191, 0.1954] imgnet = [0.229, 0.224, 0.225]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Seed"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# Seed\n# ====================================================\ndef seed_everything(seed):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True\n\nSEED = 1234\nseed_everything(SEED)  \nDEVICE = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# Model\n# ====================================================\nclass CassavaNet(nn.Module):\n    def __init__(self, model_name=None, pretrained=False):\n        super().__init__()\n        self.model_name = model_name\n        if model_name == 'deit_base_patch16_224' or model_name == 'deit_base_patch16_384':\n            self.model = torch.hub.load('facebookresearch/deit:main', model_name, pretrained=pretrained)\n        else:\n            self.model = timm.create_model(model_name, pretrained=pretrained)\n        if 'efficientnet' in model_name:\n            self.n_features = self.model.classifier.in_features\n            self.model.classifier = nn.Linear(self.n_features, N_CLASSES)\n        elif model_name == 'vit_large_patch16_384' or model_name == 'deit_base_patch16_224' or model_name == 'deit_base_patch16_384':\n            self.n_features = self.model.head.in_features\n            self.model.head = nn.Linear(self.n_features, N_CLASSES)\n        elif 'resnext' in model_name:\n            self.n_features = self.model.fc.in_features\n            self.model.fc = nn.Linear(self.n_features, N_CLASSES)\n        \n    def forward(self, x):\n        return self.model(x)\n    \n    def freeze(self):\n        # To freeze the residual layers\n        for param in self.model.parameters():\n            param.requires_grad = False\n            \n        if 'efficientnet' in self.model_name:\n            for param in self.model.classifier.parameters():\n                param.requires_grad = True\n        elif self.model_name == 'vit_large_patch16_384' or 'deit_base_patch16_224':\n            for param in self.model.head.parameters():\n                param.requires_grad = True\n        elif 'resnext' in self.model_name:\n            for param in self.model.fc.parameters():\n                param.requires_grad = True\n            \n    def unfreeze(self):\n        # Unfreeze all layers\n        for param in self.model.parameters():\n            param.requires_grad = True","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Dataset"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# Dataset\n# ====================================================\nclass GetData(Dataset):\n    def __init__(self, Dir, FNames, labels,Type):\n        self.dir = Dir\n        self.fnames = FNames\n        self.lbs = labels\n        self.type = Type\n        \n    def __len__(self):\n        return len(self.fnames)\n\n    def __getitem__(self, index):\n        x = imread(os.path.join(self.dir, self.fnames[index]))\n        if \"train\" in self.type:\n            aug_data = train_transforms(image = x)\n            return aug_data['image'], self.lbs[index]            \n        elif \"valid\" in self.type:\n            aug_data = valid_transforms(image = x)\n            return aug_data['image'], self.lbs[index]\n        elif \"tr-tst\" in self.type:\n            return x, self.lbs[index]\n        elif \"test\" in self.type:\n            return x, self.fnames[index]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Augmentation"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# Augmentation\n# ====================================================\nAug_Norm = A.Normalize(mean=IMG_MEAN, std=IMG_STD, max_pixel_value=255.0, p=1.0)\ntest_aug = Compose([\n            A.HorizontalFlip(p=0.5),\n            A.VerticalFlip(p=0.5),\n            A.ShiftScaleRotate(p = 1.0),\n            A.ColorJitter(brightness=0.1, contrast=0.2, saturation=0.2, hue=0.00, always_apply=False, p=1.0),\n            A.RandomCrop(height= HEIGHT, width = WIDTH,always_apply=True, p=1.0),\n            Aug_Norm,\n            ToTensorV2(p=1.0)\n        ], p=1.)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"os.listdir(MODEL_PATH)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model Loading"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# Model Loading\n# ====================================================\nmodels = []\ncount = 0\nfor model_fpath in os.listdir(MODEL_PATH):\n    if count in MODEL_LIST:\n        print(\"Model Loaded:\",model_fpath)\n        model_name_split = model_fpath.split('_f')[0]\n        model = CassavaNet(model_name_split,pretrained = False)\n        info = torch.load(MODEL_PATH + model_fpath,map_location = torch.device(DEVICE))\n        model.load_state_dict(info)\n        models.append(model)\n    count+=1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#This sets up the submission dataframe\n\n\nsubmission = pd.DataFrame()\nlist_files = os.listdir(TEST_DIR)\nsubmission['image_id'] = pd.Series(list_files)\nsubmission['label'] = 0\nsubmission.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# TTA"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# TTA\n# ====================================================\nstart_time = time.time()\nBATCH_SIZE = 1\ntest_set = GetData(TEST_DIR,submission['image_id'], submission['label'], Type = 'test')\ntest_loader = DataLoader(test_set, batch_size=BATCH_SIZE, shuffle=False, num_workers=8,pin_memory = True)\nwith torch.no_grad():\n    for i, (images,labels) in enumerate(test_loader):\n        voting = np.zeros((len(models),N_TTA,N_CLASSES))\n        aug_images = np.zeros((N_TTA,CHANNELS,HEIGHT,WIDTH))\n        for aug_no in range(N_TTA):\n            img_np = images.numpy()\n\n            aug_data = test_aug(image = np.reshape(img_np,(600,800,CHANNELS)))\n            aug_images[aug_no,:,:,:] = aug_data['image'].numpy()\n        aug_images = torch.from_numpy(aug_images).to(torch.float32).to(DEVICE)\n        for model_no in range(len(models)):\n            model = models[model_no]\n            model = model.to(DEVICE)\n            model.eval()            \n\n            logits = model(aug_images)\n            voting[model_no,:,:] = F.softmax(logits).cpu().numpy()\n\n        voting = np.sum(voting,axis = 1) / N_TTA\n        voting = np.sum(voting,axis = 0) / len(models)\n        label = np.argmax(voting)\n        submission['label'].loc[submission['image_id'] == labels[0]] = label\nprint(time.time()-start_time)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.to_csv('submission.csv',index=False)\nsubmission.head()","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}