{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"import sys\npackage_path = '../input/efficientnet/efficientnet-pytorch/EfficientNet-PyTorch/'\nsys.path.append(package_path)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport time\nfrom functools import partial\nimport random\n\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport scipy as sp\nimport torch\nimport torch.nn as nn\nfrom efficientnet_pytorch import EfficientNet\nfrom sklearn.metrics import cohen_kappa_score\nfrom sklearn.model_selection import StratifiedKFold\nfrom torch.utils.data import Dataset\nfrom torchvision import transforms\nfrom tqdm import tqdm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Config:\n    train_img_dir = '../input/aptos2019-blindness-detection/train_images/'\n    test_img_dir = '../input/aptos2019-blindness-detection/test_images/'\n\n    processed_train_img_dir = '../data/aptos2019-blindness-detection/train_images/'\n    process_test_img_dir = '../input/aptos2019-blindness-detection/test_images/'\n\n    train_csv_path = '../input/aptos2019-blindness-detection/train.csv'\n    test_csv_path = '../input/aptos2019-blindness-detection/test.csv'\n\n    img_size = 256\n    seed = 42\n    \nconfig = Config()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def 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    \ndef crop_image_from_gray(img, tol=7):\n    if img.ndim == 2:\n        mask = img > tol\n        return img[np.ix_(mask.any(1), mask.any(0))]\n    elif img.ndim == 3:\n        gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n        mask = gray_img > tol\n\n        check_shape = img[:, :, 0][np.ix_(mask.any(1), mask.any(0))].shape[0]\n        if (check_shape == 0):  # image is too dark so that we crop out everything,\n            return img  # return original image\n        else:\n            img1 = img[:, :, 0][np.ix_(mask.any(1), mask.any(0))]\n            img2 = img[:, :, 1][np.ix_(mask.any(1), mask.any(0))]\n            img3 = img[:, :, 2][np.ix_(mask.any(1), mask.any(0))]\n            #         print(img1.shape,img2.shape,img3.shape)\n            img = np.stack([img1, img2, img3], axis=-1)\n        #         print(img.shape)\n        return img\n\ndef load_ben_color(path, img_size, sigmaX=10):\n    image = cv2.imread(path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    image = crop_image_from_gray(image)\n    image = cv2.resize(image, (img_size, img_size))\n    image = cv2.addWeighted(image, 4, cv2.GaussianBlur(image, (0, 0), sigmaX), -4, 128)\n    return image","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"class MyDataset(Dataset):\n    def __init__(self, dataframe, dirname, transform=None):\n        self.df = dataframe\n        self.dirname = dirname\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        if 'diagnosis' not in self.df:\n            label = 0\n        else:\n            label = self.df.diagnosis.values[idx]\n\n        label = np.expand_dims(label, -1)\n        img_id = self.df.id_code.values[idx]\n        img_path = os.path.join(self.dirname, f'{img_id}.png')\n        image = cv2.imread(img_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        image = crop_image_from_gray(image)\n        image = cv2.resize(image, (256, 256))\n        image = cv2.addWeighted ( image,4, cv2.GaussianBlur( image , (0,0) , 30) ,-4 ,128)\n        \n        image = transforms.ToPILImage()(image)\n\n        if self.transform:\n            image = self.transform(image)\n\n        return image, label\n\nclass OptimizedRounder(object):\n    def __init__(self):\n        self.coef_ = 0\n\n    def _mae_loss(self, coef, X, y):\n        X_p = np.copy(X)\n        for i, pred in enumerate(X_p):\n            if pred < coef[0]:\n                X_p[i] = 0\n            elif pred >= coef[0] and pred < coef[1]:\n                X_p[i] = 1\n            elif pred >= coef[1] and pred < coef[2]:\n                X_p[i] = 2\n            elif pred >= coef[2] and pred < coef[3]:\n                X_p[i] = 3\n            else:\n                X_p[i] = 4\n        score = eval_function(X_p, y)\n        return -score\n\n    def fit(self, X, y):\n        loss_partial = partial(self._mae_loss, X=X, y=y)\n        initial_coef = [0.5, 1.5, 2.5, 3.5]\n        self.coef_ = sp.optimize.minimize(loss_partial, initial_coef, method='nelder-mead')\n\n    def predict(self, X, coef):\n        X_p = np.copy(X)\n        for i, pred in enumerate(X_p):\n            if pred < coef[0]:\n                X_p[i] = 0\n            elif pred >= coef[0] and pred < coef[1]:\n                X_p[i] = 1\n            elif pred >= coef[1] and pred < coef[2]:\n                X_p[i] = 2\n            elif pred >= coef[2] and pred < coef[3]:\n                X_p[i] = 3\n            else:\n                X_p[i] = 4\n        return X_p\n\n    def coefficients(self):\n        return self.coef_['x']\n\ndef test_inference(model_name, ckpt_dir, coef, tta=10):\n    seed_everything(config.seed)\n\n    model = EfficientNet.from_name(model_name)\n    in_features = model._fc.in_features\n    model._fc = nn.Linear(in_features, 1)\n    model.cuda()\n\n    n_folds = sum([1 if name.endswith('.pt') else 0 for name in os.listdir(ckpt_dir)])\n\n    train_transform = transforms.Compose([\n        transforms.RandomHorizontalFlip(),\n        transforms.RandomRotation((-120, 120)),\n        transforms.ToTensor(),\n        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])\n\n    df = pd.read_csv(config.test_csv_path)\n    print(f'test df len: {len(df)}')\n\n    sorted_ckpts = sorted(os.listdir(ckpt_dir), key=lambda name: int(name.split('.')[0][4:]))\n\n    tta_preds = []\n\n    testset = MyDataset(df, config.process_test_img_dir, transform=train_transform)\n    test_loader = torch.utils.data.DataLoader(testset, batch_size=32, shuffle=False, num_workers=4)\n    print(f'testset len: {len(testset)}')\n\n    for _tta in range(tta):\n        for fold in range(n_folds):\n\n            oof_preds = []\n            ckpt_path = os.path.join(ckpt_dir, sorted_ckpts[fold])\n            model.load_state_dict(torch.load(ckpt_path))\n            print(f'Load checkpoint from {ckpt_path}')\n\n            start_time = time.time()\n            model.eval()\n            with torch.no_grad():\n                for idx, (imgs, labels) in enumerate(test_loader):\n                    imgs_vaild, labels_vaild = imgs.cuda(), labels.float().cuda()\n                    output_test = model(imgs_vaild)\n                    oof_preds.append(output_test.squeeze(-1).cpu().numpy())\n            elapsed_time = time.time() - start_time\n            tta_preds.append(np.concatenate(oof_preds))\n            print(f'TTA {_tta} Fold {fold + 1} time={elapsed_time:.2f}s')\n\n    tta_preds = np.mean(tta_preds, axis=0)\n    print(f'len tta_preds: {len(tta_preds)}')\n\n    opt = OptimizedRounder()\n    tta_preds = opt.predict(tta_preds, coef)\n\n    return tta_preds\n\ndef make_submission(tta_preds, output_path):\n    test_df = pd.read_csv(config.test_csv_path)\n    sub = pd.DataFrame()\n    print(len(test_df), len(tta_preds))\n    sub['id_code'] = test_df.id_code\n    sub['diagnosis'] = tta_preds.astype(np.int)\n    sub.to_csv(output_path, index=False)\n    print(f'saved in {output_path}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"! ls ../input/efficientnetb1/efficientnet-b1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tta_preds = test_inference('efficientnet-b1', '../input/efficientnetb1/efficientnet-b1', [0.50202154, 1.51818165, 2.87326943, 2.99355952], tta=1)\nmake_submission(tta_preds, 'submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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":1}