{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import sys\nsys.path.append('../input/timm-pytorch-image-models/pytorch-image-models-master')\nimport os\nimport cv2\nimport timm\nimport torch\nfrom torch import nn\nimport pandas as pd\nimport numpy as np\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\nfrom torch.utils.data import Dataset,DataLoader\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,\n    CenterCrop, Resize, ColorJitter, RandomCrop\n)\n\nfrom albumentations.pytorch import ToTensorV2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"CFG = {\n    'model_arch1': 'resnest101e',\n    'model_arch2': 'tf_efficientnet_b4_ns',\n    'model_arch7': 'vit_base_patch16_384',\n    'img_size': 512,\n    'valid_bs': 32,\n    'num_workers': 4,\n    'device': 'cuda:0',\n    'tta': 5,\n    'used_epochs_model1': [9,9,6,6,8],\n    'used_epochs_model2': [11,13,13,11,12],\n    'used_epochs_model7': [9,8,9,8,8],\n    'used_epochs_model8': [\"../input/testmodel/tf_efficientnet_b4_ns_f0_b0.893.pth\",\n                           \"../input/testmodel/tf_efficientnet_b4_ns_f0_b0.893.pth\",\n                           \"../input/testmodel/tf_efficientnet_b4_ns_f2_b0.9018.pth\",\n                          ],\n    'weights': [1,1,1,1,1]\n}\nsubmission = pd.read_csv('../input/cassava-leaf-disease-classification/sample_submission.csv')\nsubmission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_img(path):\n    '''使用 opencv 加载图片.\n    由于历史原因，opencv 读取的图片格式是 bgr\n    Args:\n        path : str  图片文件路径 e.g '../data/train_img/1.jpg'\n    '''\n    img_bgr = cv2.imread(path)\n    img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)\n    return img_rgb","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CassavaDataset(Dataset):\n    '''木薯叶比赛数据加载类\n    Attributes:\n        __len__ : 数据的样本个数.\n        __getitem__ : 索引函数.\n    '''\n    def __init__(\n            self,\n            df,\n            data_root,\n            transforms=None,\n            output_label=True,\n            one_hot_label=False,\n            do_fmix=False,\n            fmix_params={\n                'alpha': 1.,\n                'decay_power': 3.,\n                'shape': (512, 512),\n                'max_soft': 0.3,\n                'reformulate': False\n            },\n            do_cutmix=False,\n            cutmix_params={\n                'alpha': 1,\n            }):\n\n        super().__init__()\n        self.df = df.reset_index(drop=True).copy()  # 重新生成索引\n        self.transforms = transforms\n        self.data_root = data_root\n        self.do_fmix = do_fmix\n        self.fmix_params = fmix_params\n        self.do_cutmix = do_cutmix\n        self.cutmix_params = cutmix_params\n        self.output_label = output_label\n        self.one_hot_label = one_hot_label\n        if output_label:\n            self.labels = self.df['label'].values\n            if one_hot_label:\n                self.labels = np.eye(self.df['label'].max() +\n                                     1)[self.labels]  # 使用单位矩阵生成 onehot 编码\n\n    def __len__(self):\n        return self.df.shape[0]\n\n    def __getitem__(self, index):\n        '''\n        Args:\n            index : int , 索引\n        Returns:\n            img, target(optional)\n        '''\n        if self.output_label:\n            target = self.labels[index]\n\n        img = get_img(\n            os.path.join(self.data_root,\n                         self.df.loc[index]['image_id']))  # 拼接地址，加载图片\n\n        if self.transforms:  # 使用图片增强\n            img = self.transforms(image=img)['image']\n\n        if self.do_fmix and np.random.uniform(\n                0., 1., size=1)[0] > 0.5:  # 50% 概率触发 fmix 数据增强\n\n            with torch.no_grad():\n                lam, mask = sample_mask(\n                    **self.fmix_params)  # 可以考虑魔改，使用 clip 规定上下限制\n\n                fmix_ix = np.random.choice(self.df.index,\n                                           size=1)[0]  # 随机选择待 mix 的图片\n                fmix_img = get_img(\n                    os.path.join(self.data_root,\n                                 self.df.loc[fmix_ix]['image_id']))\n\n                if self.transforms:\n                    fmix_img = self.transforms(image=fmix_img)['image']\n\n                mask_torch = torch.from_numpy(mask)\n\n                img = mask_torch * img + (1. - mask_torch) * fmix_img  # mix 图片\n\n                rate = mask.sum() / float(img.size)  # 获取 mix 的 rate\n                target = rate * target + (\n                    1. - rate) * self.labels[fmix_ix]  # target 进行 mix\n\n        if self.do_cutmix and np.random.uniform(\n                0., 1., size=1)[0] > 0.5:  # 50% 概率触发 cutmix 数据增强\n            with torch.no_grad():\n                cmix_ix = np.random.choice(self.df.index, size=1)[0]\n                cmix_img = get_img(\n                    os.path.join(self.data_root,\n                                 self.df.loc[cmix_ix]['image_id']))\n                if self.transforms:\n                    cmix_img = self.transforms(image=cmix_img)['image']\n\n                lam = np.clip(\n                    np.random.beta(self.cutmix_params['alpha'],\n                                   self.cutmix_params['alpha']), 0.3, 0.4)\n                bbx1, bby1, bbx2, bby2 = rand_bbox(cmix_img.shape[:2], lam)\n\n                img[:, bbx1:bbx2, bby1:bby2] = cmix_img[:, bbx1:bbx2,\n                                                        bby1:bby2]\n\n                rate = 1 - ((bbx2 - bbx1) *\n                            (bby2 - bby1) / float(img.size))  # 获取 mix 的 rate\n                target = rate * target + (\n                    1. - rate) * self.labels[cmix_ix]  # target 进行 mix\n\n        if self.output_label:\n            return img, target\n        else:\n            return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CassvaImgClassifier(nn.Module):\n    def __init__(self, model_arch, n_class, pretrained=False):\n        super().__init__()\n        self.model = timm.create_model(model_arch, pretrained=pretrained, num_classes=5)\n        \n    def forward(self, x):\n        x = self.model(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def inference_one_epoch(model, data_loader, device):\n    model.eval()\n    image_preds_all = []\n    pbar = tqdm(enumerate(data_loader), total=len(data_loader))\n    # print(pbar)\n    for step, (imgs) in pbar:\n        imgs = imgs.to(device).float()\n        image_preds = model(imgs) \n        image_preds_all += [torch.softmax(image_preds, 1).detach().cpu().numpy()]\n    image_preds_all = np.concatenate(image_preds_all, axis=0)\n    return image_preds_all","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test = pd.DataFrame()\ntest['image_id'] = list(os.listdir('../input/cassava-leaf-disease-classification/test_images/'))\ndevice = torch.device(CFG['device'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"val_preds = []\ntst_preds = []\n\n# model1\ndef get_inference_transforms():\n    return Compose([\n            RandomResizedCrop(CFG['img_size'], CFG['img_size']),\n            Transpose(p=0.5),\n            HorizontalFlip(p=0.5),\n            VerticalFlip(p=0.5),\n            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),\n        ], p=1.)\n\ntest_ds = CassavaDataset(test, '../input/cassava-leaf-disease-classification/test_images/', transforms=get_inference_transforms(), output_label=False)\ntst_loader = torch.utils.data.DataLoader(\n            test_ds, \n            batch_size=CFG['valid_bs'],\n            num_workers=CFG['num_workers'],\n            shuffle=False,\n            pin_memory=False,\n        )\n\nmodel = CassvaImgClassifier(CFG['model_arch1'], 5).to(device)\n\nfor fold, epoch in enumerate(CFG['used_epochs_model1']):    \n    model.load_state_dict(torch.load('../input/baseline210110/resnest101e_bs8x2_1e-4_0111/{}_fold_{}_{}'.format('_'.join(CFG['model_arch1'].split('_')), fold, epoch,CFG['model_arch1'], fold, epoch),\n                                    map_location=CFG['device']))\n\n    with torch.no_grad():\n        for _ in range(CFG['tta']):\n            tst_preds += [CFG['weights'][fold]/sum(CFG['weights'])/CFG['tta']*inference_one_epoch(model, tst_loader, device)]\n\ndel model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# # model2\n# def get_inference_transforms_eff():\n#     return Compose([\n#             RandomCrop(512, 512),\n#             Transpose(p=0.5),\n#             HorizontalFlip(p=0.5),\n#             VerticalFlip(p=0.5),\n#             HueSaturationValue(hue_shift_limit=10, sat_shift_limit=10, val_shift_limit=10, p=0.5),\n#             RandomBrightnessContrast(brightness_limit=(-0.1,0.1), contrast_limit=(-0.1, 0.1), p=0.5),\n#             Normalize(mean=[0.42984136, 0.49624753, 0.3129598], std=[0.21417203, 0.21910103, 0.19542212], max_pixel_value=255.0, p=1.0),\n#             ToTensorV2(p=1.0),\n#         ], p=1.)\n\n# test_ds1 = CassavaDataset(test, '../input/cassava-leaf-disease-classification/test_images/', transforms=get_inference_transforms_eff(), output_label=False)\n# tst_loader1 = torch.utils.data.DataLoader(\n#     test_ds1, \n#     batch_size=CFG['valid_bs'],\n#     num_workers=CFG['num_workers'],\n#     shuffle=False,\n#     pin_memory=False,\n# )     \n\n\n# model = CassvaImgClassifier(CFG['model_arch2'], 5).to(device)\n            \n# for fold, epoch in enumerate(CFG['used_epochs_model2']):    \n#     model.load_state_dict(torch.load('../input/train1212fold5/tf_efficientnet_b4_ns_1212_fold_{}_{}'.format(fold, epoch),\n#                                     map_location=CFG['device']))\n\n#     with torch.no_grad():\n#         for _ in range(6):\n#             tst_preds += [CFG['weights'][fold]/sum(CFG['weights'])/6*inference_one_epoch(model, tst_loader1, device)]\n\n# del model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model3\ndef get_inference_transforms_384():\n    return Compose([\n            RandomResizedCrop(384, 384),\n            Transpose(p=0.5),\n            HorizontalFlip(p=0.5),\n            VerticalFlip(p=0.5),\n            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),\n        ], p=1.)\ntest_ds2 = CassavaDataset(test, '../input/cassava-leaf-disease-classification/test_images/', transforms=get_inference_transforms_384(), output_label=False)\ntst_loader2 = torch.utils.data.DataLoader(\n    test_ds2, \n    batch_size=CFG['valid_bs'],\n    num_workers=CFG['num_workers'],\n    shuffle=False,\n    pin_memory=False,\n)     \n\nmodel = CassvaImgClassifier(CFG['model_arch7'], 5).to(device)\nfor fold, epoch in enumerate(CFG['used_epochs_model7']):    \n    model.load_state_dict(torch.load('../input/vit210211/vit_base_patch16_384_bs8x2/{}_fold_{}_{}'.format('_'.join(CFG['model_arch7'].split('_')), fold, epoch,CFG['model_arch7'], fold, epoch),\n                                    map_location=CFG['device']))\n\n    with torch.no_grad():\n        for _ in range(CFG['tta']):\n            tst_preds += [CFG['weights'][fold]/sum(CFG['weights'])/CFG['tta']*inference_one_epoch(model, tst_loader2, device)]\n\ndel model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"N_CLASSES = 6\nclass CassavaNet(nn.Module):\n    def __init__(self, model_name=None, pretrained=False):\n        super().__init__()\n        self.model_name = model_name\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        \n    def forward(self, x):\n        return self.model(x)\n\n\n# model4\ndef get_inference_transforms_chentuoeffb4():\n    return Compose([\n            HorizontalFlip(p=0.5),\n            VerticalFlip(p=0.5),\n            ShiftScaleRotate(p = 1.0),\n            ColorJitter(brightness=0.1, contrast=0.2, saturation=0.2, hue=0.00, always_apply=False, p=1.0),\n            RandomCrop(height= 512, width = 512,always_apply=True, p=1.0),\n            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)\n        ], p=1.)\n\ntest_ds3 = CassavaDataset(test, '../input/cassava-leaf-disease-classification/test_images/', transforms=get_inference_transforms_chentuoeffb4(), output_label=False)\n\ntst_loader3 = torch.utils.data.DataLoader(\n    test_ds3, \n    batch_size=CFG['valid_bs'],\n    num_workers=CFG['num_workers'],\n    shuffle=False,\n    pin_memory=False,\n)\n\nmodel = CassavaNet(CFG['model_arch2'], pretrained = False).to(device) # N_CLASSES = 6\nfor v_model in CFG['used_epochs_model8']:    \n    model.load_state_dict(torch.load(v_model, map_location=CFG['device']))\n\n    with torch.no_grad():\n        for _ in range(8):\n            output_pro = inference_one_epoch(model, tst_loader3, device)\n            output_pro[:,1] = max(output_pro[:,1], output_pro[:,5])\n            output_pro = output_pro[:,:5]\n            # print(output_pro)\n            tst_preds += 1/3/8*output_pro\n\ndel model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.cuda.empty_cache()\ntst_preds = np.sum(tst_preds, axis=0) \ntest['label'] = np.argmax(tst_preds, axis=1)\ntest.to_csv('submission.csv', index=False)","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}