{"cells":[{"metadata":{},"cell_type":"markdown","source":"Inference kernel입니다. weight들을 올렸지만, 모든 test image에 대해서 predict를 하기에는 시간의 문제가 존재하였습니다. test image 100개에 대해서만 예측하는 code입니다.\n\nsolution은 discussion에 올려두었습니다."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# saewon님 kernel을 사용했음을 알려드립니다.\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom pathlib import Path\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":false,"_kg_hide-input":false,"trusted":true},"cell_type":"code","source":"!pip install efficientnet_pytorch\n!pip install pretrainedmodels","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"TEST_IMAGE_PATH = Path('../input/testdata/test_crop')\ntest_csv = pd.read_csv('../input/testdata/test.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport time\nimport random\nimport numpy as np\nimport pandas as pd\nfrom pathlib import Path\nimport glob\nfrom PIL import Image, ImageEnhance, ImageOps\n\nfrom tqdm import tqdm, tqdm_notebook\n\nimport torch\nfrom torch import nn, cuda\nfrom torch.autograd import Variable \nimport torch.nn.functional as F\nimport torchvision as vision\nimport torchvision.models as models\nfrom torch.utils.data import Dataset, DataLoader\n\nfrom sklearn.metrics import f1_score","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# seed value fix\n# seed 값을 고정해야 hyper parameter 바꿀 때마다 결과를 비교할 수 있습니다.\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\nSEED = 2019\nseed_everything(SEED)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class TestDataset(Dataset):\n    def __init__(self, df, mode='test', transforms=None):\n        self.df = df\n        self.mode = mode\n        self.transform = transforms[self.mode]\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx):\n        \n        new_idx = idx % len(self.df)\n        image = Image.open(TEST_IMAGE_PATH / self.df[new_idx]).convert(\"RGB\")\n        \n        if self.transform:\n            image = self.transform(image)\n            \n        return image    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"target_size = (299, 299)\n\ndata_transforms = {\n    'test': vision.transforms.Compose([\n        vision.transforms.Resize(target_size),\n        vision.transforms.RandomRotation(5),\n        vision.transforms.RandomHorizontalFlip(),\n        vision.transforms.RandomResizedCrop(target_size, scale=(0.8,1.0)),\n        vision.transforms.ToTensor(),\n        vision.transforms.Normalize(\n            [0.485, 0.456, 0.406], \n            [0.229, 0.224, 0.225])\n    ]),\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_test = test_csv['img_file'][:100]\nnum_classes = 196","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weights_path = Path('../input/careff7')\nweight_list = os.listdir(weights_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from efficientnet_pytorch import EfficientNet\ntta = 5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from collections import OrderedDict\nbatch_size = 256\ntest_dataset = TestDataset(x_test, mode='test', transforms=data_transforms)\ntest_loader = DataLoader(test_dataset, \n                        batch_size=batch_size,\n                        num_workers=2,\n                        shuffle=False,\n                        pin_memory=True,\n                        )\n\n\ntotal_num_models = len(weight_list)*tta \n\nall_prediction1 = np.zeros((len(test_dataset), num_classes))\n\nfor i, weight in enumerate(weight_list):\n    print(\"fold {} prediction starts\".format(i+1))\n    \n    for _ in range(tta):\n        print(\"tta {}\".format(_+1))\n        \n        model = EfficientNet.from_pretrained('efficientnet-b7')\n        # Unfreeze model weights\n        for param in model.parameters():\n            param.requires_grad = True\n        model._fc = nn.Sequential(\n            nn.Dropout(p=0.4),\n            nn.Linear(in_features=2560, out_features=196, bias=True)\n        )\n        \n        # DataParallel 학습된 weight를 문제 없이 단일 gpu로 불러오는 code입니다.\n        # https://discuss.pytorch.org/t/solved-keyerror-unexpected-key-module-encoder-embedding-weight-in-state-dict/1686\n        state_dict = torch.load(weights_path / weight)\n        new_state_dict = OrderedDict()\n        for k, v in state_dict.items():\n            name = k[7:] # remove module.\n            new_state_dict[name] = v\n        model.load_state_dict(new_state_dict)\n        \n        # multi gpu를 사용하는 code입니다. kaggle은 단일 gpu여서 의미가 없는 코드입니다.\n        device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n        if torch.cuda.device_count() > 1:\n            model = nn.DataParallel(model)\n        model.to(device)\n        \n        model.eval()\n        \n        prediction = np.zeros((len(test_dataset), num_classes)) # num_classes=196\n        with torch.no_grad():\n            for i, images in enumerate(tqdm_notebook(test_loader)):\n                images = images.cuda()\n\n                preds = model(images).detach()\n                prediction[i * batch_size: (i+1) * batch_size] = preds.cpu().numpy()\n                all_prediction1 = all_prediction1 + prediction\n    \nall_prediction1 /= total_num_models","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weights_path = Path('../input/carrb6') # careff6에 들어있는 weight인데 오타난 파일명을 바꾸는걸 깜박했네요\nweight_list = os.listdir(weights_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 256\n\ntest_dataset = TestDataset(x_test, mode='test', transforms=data_transforms)\ntest_loader = DataLoader(test_dataset, \n                        batch_size=batch_size,\n                        num_workers=24,\n                        shuffle=False,\n                        pin_memory=True,\n                        )\n\n\ntotal_num_models = len(weight_list)*tta \n\nall_prediction2 = np.zeros((len(test_dataset), num_classes))\n\nfor i, weight in enumerate(weight_list):\n    print(\"fold {} prediction starts\".format(i+1))\n    \n    for _ in range(tta):\n        print(\"tta {}\".format(_+1))\n        \n        model = EfficientNet.from_pretrained('efficientnet-b6')\n        # Unfreeze model weights\n        for param in model.parameters():\n            param.requires_grad = True\n        model._fc = nn.Sequential(\n                    nn.Dropout(p=0.4),\n                    nn.Linear(in_features=2304, out_features=196, bias=True)\n                )\n        state_dict = torch.load(weights_path / weight)\n        new_state_dict = OrderedDict()\n        for k, v in state_dict.items():\n            name = k[7:] # remove module.\n            new_state_dict[name] = v\n        \n        model.load_state_dict(new_state_dict)\n        \n        device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n        if torch.cuda.device_count() > 1: \n            model = nn.DataParallel(model)\n        model.to(device)\n        \n        model.eval()\n        \n        prediction = np.zeros((len(test_dataset), num_classes)) # num_classes=196\n        with torch.no_grad():\n            for i, images in enumerate(tqdm_notebook(test_loader)):\n                images = images.cuda()\n\n                preds = model(images).detach()\n                prediction[i * batch_size: (i+1) * batch_size] = preds.cpu().numpy()\n                all_prediction2 = all_prediction2 + prediction\n    \nall_prediction2 /= total_num_models","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weights_path = Path('../input/careff5')\nweight_list = os.listdir(weights_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 256\n\ntest_dataset = TestDataset(x_test, mode='test', transforms=data_transforms)\ntest_loader = DataLoader(test_dataset, \n                        batch_size=batch_size,\n                        num_workers=24,\n                        shuffle=False,\n                        pin_memory=True,\n                        )\n\n\ntotal_num_models = len(weight_list)*tta \n\nall_prediction3 = np.zeros((len(test_dataset), num_classes))\n\nfor i, weight in enumerate(weight_list):\n    print(\"fold {} prediction starts\".format(i+1))\n    \n    for _ in range(tta):\n        print(\"tta {}\".format(_+1))\n        \n        model = EfficientNet.from_pretrained('efficientnet-b5')\n        # Unfreeze model weights\n        for param in model.parameters():\n            param.requires_grad = True\n        model._fc = nn.Sequential(\n                    nn.Dropout(p=0.4),\n                    nn.Linear(in_features=2048, out_features=196, bias=True)\n                )\n        state_dict = torch.load(weights_path / weight)\n        new_state_dict = OrderedDict()\n        for k, v in state_dict.items():\n            name = k[7:] # remove module.\n            new_state_dict[name] = v\n        \n        model.load_state_dict(new_state_dict)\n        \n        device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n        if torch.cuda.device_count() > 1: \n            model = nn.DataParallel(model)\n        model.to(device)\n        \n        model.eval()\n        \n        prediction = np.zeros((len(test_dataset), num_classes)) # num_classes=196\n        with torch.no_grad():\n            for i, images in enumerate(tqdm_notebook(test_loader)):\n                images = images.cuda()\n\n                preds = model(images).detach()\n                prediction[i * batch_size: (i+1) * batch_size] = preds.cpu().numpy()\n                all_prediction3 = all_prediction3 + prediction\n    \nall_prediction3 /= total_num_models","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.cuda.empty_cache()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"target_size = (331, 331)\n\ndata_transforms = {\n    'test': vision.transforms.Compose([\n        vision.transforms.Resize(target_size),\n        vision.transforms.RandomRotation(5),\n        vision.transforms.RandomHorizontalFlip(),\n        vision.transforms.RandomResizedCrop(target_size, scale=(0.8,1.0)),\n        vision.transforms.ToTensor(),\n        vision.transforms.Normalize(\n            [0.485, 0.456, 0.406], \n            [0.229, 0.224, 0.225])\n    ]),\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weights_path = Path('../input/carnas')\nweight_list = os.listdir(weights_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from pretrainedmodels import nasnetalarge","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 128\n\ntotal_num_models = len(weight_list)*tta \nall_prediction4 = np.zeros((len(test_dataset), num_classes))\n\nfor i, weight in enumerate(weight_list):\n    print(\"fold {} prediction starts\".format(i+1))\n    \n    for _ in range(tta):\n        print(\"tta {}\".format(_+1))\n        test_dataset = TestDataset(x_test, mode='test', transforms=data_transforms)\n        test_loader = DataLoader(test_dataset, \n                                batch_size=batch_size,\n                                num_workers=24,\n                                shuffle=False,\n                                pin_memory=True,\n                                )\n\n        model = nasnetalarge(num_classes=1000, pretrained='imagenet')\n        model.last_linear = nn.Sequential(\n                    nn.Dropout(p=0.4),\n                    nn.Linear(in_features=4032, out_features=196, bias=True)\n                )\n        state_dict = torch.load(weights_path / weight)\n        new_state_dict = OrderedDict()\n        for k, v in state_dict.items():\n            name = k[7:] # remove module.\n            new_state_dict[name] = v\n        \n        model.load_state_dict(new_state_dict)\n        \n        device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n        if torch.cuda.device_count() > 1: \n            model = nn.DataParallel(model)\n        model.to(device)\n        \n        model.eval()\n        \n        prediction = np.zeros((len(test_dataset), num_classes)) # num_classes=196\n        with torch.no_grad():\n            for i, images in enumerate(tqdm_notebook(test_loader)):\n                images = images.cuda()\n\n                preds = model(images).detach()\n                prediction[i * batch_size: (i+1) * batch_size] = preds.cpu().numpy()\n                all_prediction4 = all_prediction4 + prediction\n    \nall_prediction4 /= total_num_models","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weights_path = Path('../input/carpnas')\nweight_list = os.listdir(weights_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from pretrainedmodels import pnasnet5large","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 128\n\ntotal_num_models = len(weight_list)*tta \nall_prediction5 = np.zeros((len(test_dataset), num_classes))\n\nfor i, weight in enumerate(weight_list):\n    print(\"fold {} prediction starts\".format(i+1))\n    \n    for _ in range(tta):\n        print(\"tta {}\".format(_+1))\n        \n        test_dataset = TestDataset(x_test, mode='test', transforms=data_transforms)\n        test_loader = DataLoader(test_dataset, \n                                batch_size=batch_size,\n                                num_workers=24,\n                                shuffle=False,\n                                pin_memory=True,\n                                )\n\n        \n        model = pnasnet5large(num_classes=1000, pretrained='imagenet')\n        model.last_linear = nn.Sequential(\n                    nn.Dropout(p=0.4),\n                    nn.Linear(in_features=4320, out_features=196, bias=True)\n                )\n        state_dict = torch.load(weights_path / weight)\n        new_state_dict = OrderedDict()\n        for k, v in state_dict.items():\n            name = k[7:] # remove module.\n            new_state_dict[name] = v\n        \n        model.load_state_dict(new_state_dict)\n        \n        device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n        if torch.cuda.device_count() > 1: \n            model = nn.DataParallel(model)\n        model.to(device)\n        \n        model.eval()\n        \n        prediction = np.zeros((len(test_dataset), num_classes)) # num_classes=196\n        with torch.no_grad():\n            for i, images in enumerate(tqdm_notebook(test_loader)):\n                images = images.cuda()\n\n                preds = model(images).detach()\n                prediction[i * batch_size: (i+1) * batch_size] = preds.cpu().numpy()\n                all_prediction5 = all_prediction5 + prediction\n    \nall_prediction5 /= total_num_models","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# https://stackoverflow.com/questions/34968722/how-to-implement-the-softmax-function-in-python\n\ndef softmax(z):\n    assert len(z.shape) == 2\n    s = np.max(z, axis=1)\n    s = s[:, np.newaxis] # necessary step to do broadcasting\n    e_x = np.exp(z - s)\n    div = np.sum(e_x, axis=1)\n    div = div[:, np.newaxis] # dito\n    return e_x / div","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"all_prediction1 = softmax(all_prediction1)\nall_prediction2 = softmax(all_prediction2)\nall_prediction3 = softmax(all_prediction3)\nall_prediction4 = softmax(all_prediction4)\nall_prediction5 = softmax(all_prediction5)\n\n# soft-voting\ntotal = (all_prediction1 + all_prediction2 + all_prediction3 + all_prediction4 + all_prediction5)\n\n# argmax를 통하여 가장 높은 확률의 class 추출\nresult = np.argmax(total, axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# predict하는 시간이 너무 길어서 csv 파일로 복원하겠습니다.\n# load result using local gpu\nsubmission = pd.read_csv('../input/final-csv-for-car/soft_voting-5-tta_plus_PNAS.csv')\nsubmission.to_csv(\"submission.csv\", index=False)\nsubmission.head()","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}