{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Directory settings"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# ======================================\n# Directory settings \n# ======================================\nimport os\n\nOUTPUT_DIR='./'\nMODEL_DIR= '../input/cassava-inference/'\n\nif not os.path.exists(OUTPUT_DIR):\n    os.makedirs(OUTPUT_DIR)\n    \nTRAIN_PATH='../input/cassava-leaf-disease-classification/train_images'\nTEST_PATH='../input/cassava-leaf-disease-classification/test_images'\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# CFG"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ============================\n# CFG\n# ============================\nclass CFG:\n    debug=False\n    num_worker=4\n    model_name='resnext50_32x4d'\n    size=256\n    batch_size=32\n    seed=42\n    target_size=5\n    target_col='label'\n    n_fold=5\n    trn_fold=[0,1,2,3,4]\n    train=False\n    inference=True","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Library"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ===========================\n# Library\n# ===========================\nimport sys\nsys.path.append('../input/pytorch-image-models/pytorch-image-models-master')\nsys.path.append('../input/adamp-optimizer/AdamP-master')\n\nimport os\nimport math\nimport time\nimport random\nimport shutil\nfrom pathlib import Path\nfrom contextlib import contextmanager\nfrom collections import defaultdict, Counter\n\nimport scipy as sp\nimport numpy as np\nimport pandas as pd\n\nfrom sklearn import preprocessing\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.model_selection import StratifiedKFold\n\n# 파이썬에서 상태바를 나타내기 위해 사용\nfrom tqdm.auto import tqdm\n# 하나 이상의 인수가 이미 채워진 함수의 새 버전을 만들기 위해 사용\n# https://hamait.tistory.com/823\nfrom functools import partial\n\nimport cv2\nfrom PIL import Image\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.optim import SGD\n# Adam 대신 AdamP\nimport adamp\nimport torchvision.models as models\nfrom torch.nn.parameter import Parameter\nfrom torch.utils.data import DataLoader, Dataset\nfrom torch.optim.lr_scheduler import CosineAnnealingWarmRestarts, CosineAnnealingLR, ReduceLROnPlateau\n\nfrom albumentations import (\n    Compose, OneOf, Normalize, Resize, RandomResizedCrop, RandomCrop, HorizontalFlip, VerticalFlip, \n    RandomBrightness, RandomContrast, RandomBrightnessContrast, Rotate, ShiftScaleRotate, Cutout, \n    IAAAdditiveGaussianNoise, Transpose\n    )\n\nfrom albumentations.pytorch import ToTensorV2\nfrom albumentations import ImageOnlyTransform\n\nimport timm\n\nimport warnings\nwarnings.filterwarnings('ignore')\n\ndevice=torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Utils"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# Utils\n# ====================================================\ndef get_score(y_true, y_pred):\n    return accuracy_score(y_true, y_pred)\n\n@contextmanager\ndef timer(name):\n    t0=time.time()\n    LOGGER.info(f'[{name}] start')\n    # Generator, yield 공부할 것\n    yield\n    LOGGER.info(f'[{name}] done in {time.time() - t0:.0f} s.')\n    \ndef init_logger(log_file=OUTPUT_DIR+'inference.log'):\n    from logging import getLogger, INFO, FileHandler, Formatter, StreamHandler\n    logger=getLogger(__name__)\n    logger.setLevel(INFO)\n    handler1=StreamHandler()\n    handler1.setFormatter(Formatter(\"%(message)s\"))\n    handler2.FileHandler(filename=log_file)\n    handler2.setFormatter(Formatter(\"%(message)s\"))\n    logger.addHandler(handler1)\n    logger.addHandler(handler2)\n    return logger\n\ndef seed_torch(seed=42):\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    \nseed_torch(seed=CFG.seed)\n\n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Loading"},{"metadata":{"trusted":true},"cell_type":"code","source":"test=pd.read_csv('../input/cassava-leaf-disease-classification/sample_submission.csv')\ntest.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Dataset"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# Dataset\n# ====================================================\nclass TestDataset(Dataset):\n    def __init__(self, df, transform=None):\n        self.df=df\n        self.file_names=df['image_id'].values\n        self.transform=transform\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx):\n        file_name=self.file_names[idx]\n        file_path=f'{TEST_PATH}/{file_name}'\n        image=cv2.imread(file_path)\n        image=cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        if self.transform:\n            augmented=self.transform(image=image)\n            image=augmented['image']\n        return image\n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Transforms"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# Transforms\n# ====================================================\ndef get_transforms(*,data):\n    \n    if data=='train':\n        return Compose([\n            RandomResizedCrop(CFG.size, CFG.size),\n            Transpose(p=0.5),\n            HorizontalFlip(p=0.5),\n            VerticalFlip(p=0.5),\n            ShiftScaleRotate(p=0.5),\n            Normalize(\n                mean=[0.485, 0.456, 0.406],\n                std=[0.229, 0.224, 0.225],\n            ),\n            ToTensorV2(),\n        ])\n    elif data=='valid':\n        return Compose([\n            Resize(CFG.size, CFG.size),\n            Normalize(\n                mean=[0.485, 0.456, 0.406],\n                std=[0.229, 0.224, 0.225],\n            ),\n            ToTensorV2(),\n        ])\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# MODEL"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# MODEL\n# ====================================================\nclass CustomResNext(nn.Module):\n    def __init__(self, model_name='resnext50_32x4d', pretrained=False):\n        super().__init__()\n        self.model=timm.create_model(model_name, pretrained=pretrained)\n        n_features=self.model.fc.in_features\n        self.model.fc=nn.Linear(n_features, CFG.target_size)\n        \n    def forward(self, x):\n        x=self.model(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Helper functions"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# Helper functions\n# ====================================================\ndef inference(model, states, test_loader, device):\n    model.to(device)\n    tk0=tqdm(enumerate(test_loader), total=len(test_loader))\n    probs=[]\n    for i, (images) in tk0:\n        images=images.to(device)\n        avg_preds=[]\n        for state in states:\n            model.load_state_dict(state['model'])\n            model.eval()\n            with torch.no_grad():\n                y_preds=model(images)\n            avg_preds.append(y_preds.softmax(1).to('cpu').numpy())\n        avg_preds=np.mean(avg_preds, axis=0)\n        probs.append(avg_preds)\n    probs=np.concatenate(probs)\n    return probs","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# inference"},{"metadata":{"trusted":true},"cell_type":"code","source":"# ====================================================\n# inference\n# ====================================================\nmodel=CustomResNext(CFG.model_name, pretrained=False)\nstates=[torch.load(MODEL_DIR+f'{CFG.model_name}_fold{fold}_best.pth') for fold in CFG.trn_fold]\ntest_dataset=TestDataset(test, transform=get_transforms(data='valid'))\ntest_loader=DataLoader(test_dataset, batch_size=CFG.batch_size, shuffle=False,\n                      num_workers=CFG.num_worker, pin_memory=True)\npredictions=inference(model,states, test_loader, device)\n# submission\ntest['label']=predictions.argmax(1)\ntest[['image_id', 'label']].to_csv(OUTPUT_DIR+'submission.csv', index=False)\ntest.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}