{"cells":[{"metadata":{},"cell_type":"markdown","source":"## iMet ResNet50 Inference","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"This is inference code for [Yandex Praktikum PyTorch train baseline - LB 0.699](https://www.kaggle.com/alimbekovkz/yandex-praktikum-pytorch-train-baseline-lb-0-699)\n\nI was inspired thos [code](https://www.kaggle.com/nxrprime/imet-2020-resnet18-inference)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport json\nimport sys\nimport gc\nimport random\nimport time\nfrom typing import Dict\nfrom contextlib import contextmanager\nfrom pathlib import Path\nfrom collections import defaultdict, Counter\n\nimport cv2\nfrom PIL import Image\nimport numpy as np\nimport pandas as pd\nimport scipy as sp\n\nimport sklearn.metrics\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.model_selection import StratifiedKFold\n\nfrom functools import partial\nfrom tqdm import tqdm\n\nimport torch\nimport torch.nn as nn\nfrom torch.nn import functional as F\nimport torchvision.models as M\nfrom torch.optim import Adam, SGD\nfrom torch.optim.lr_scheduler import CosineAnnealingLR, ReduceLROnPlateau\nfrom torch.utils.data import DataLoader, Dataset\nimport torchvision.models as models\n\nfrom albumentations import Compose, Normalize, Resize, RandomResizedCrop, RandomCrop, HorizontalFlip\nfrom albumentations.pytorch import ToTensorV2\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\ndevice","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.read_csv('../input/imet-2020-fgvc7/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Utils\n@contextmanager\ndef timer(name):\n    t0 = time.time()\n    LOGGER.info(f'[{name}] start')\n    yield\n    LOGGER.info(f'[{name}] done in {time.time() - t0:.0f} s.')\n\n    \ndef init_logger(log_file='train.log'):\n    from logging import getLogger, DEBUG, FileHandler,  Formatter,  StreamHandler\n    \n    log_format = '%(asctime)s %(levelname)s %(message)s'\n    \n    stream_handler = StreamHandler()\n    stream_handler.setLevel(DEBUG)\n    stream_handler.setFormatter(Formatter(log_format))\n    \n    file_handler = FileHandler(log_file)\n    file_handler.setFormatter(Formatter(log_format))\n    \n    logger = getLogger('Herbarium')\n    logger.setLevel(DEBUG)\n    logger.addHandler(stream_handler)\n    logger.addHandler(file_handler)\n    \n    return logger\n\nLOG_FILE = 'train.log'\nLOGGER = init_logger(LOG_FILE)\n\n\ndef seed_torch(seed=777):\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 = 777\nseed_torch(SEED)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"N_CLASSES = 3474\n\n\nclass TrainDataset(Dataset):\n    def __init__(self, df, labels, transform=None):\n        self.df = df\n        self.labels = labels\n        self.transform = transform\n        \n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        file_name = self.df['id'].values[idx]\n        file_path = f'../input/imet-2020-fgvc7/train/{file_name}.png'\n        image = cv2.imread(file_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        \n        if self.transform:\n            augmented = self.transform(image=image)\n            image = augmented['image']\n            \n        label = self.labels.values[idx]\n        target = torch.zeros(N_CLASSES)\n        for cls in label.split():\n            target[int(cls)] = 1\n        \n        return image, target\n    \n\nclass TestDataset(Dataset):\n    def __init__(self, df, transform=None):\n        self.df = df\n        self.transform = transform\n        \n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        file_name = self.df['id'].values[idx]\n        file_path = f'../input/imet-2020-fgvc7/test/{file_name}.png'\n        image = cv2.imread(file_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        \n        if self.transform:\n            augmented = self.transform(image=image)\n            image = augmented['image']\n        \n        return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"HEIGHT = 128\nWIDTH = 128\n\n\ndef get_transforms(*, data):\n    \n    assert data in ('train', 'valid')\n    \n    if data == 'train':\n        return Compose([\n            #Resize(HEIGHT, WIDTH),\n            RandomResizedCrop(HEIGHT, WIDTH),\n            Normalize(\n                mean=[0.485, 0.456, 0.406],\n                std=[0.229, 0.224, 0.225],\n            ),\n            ToTensorV2(),\n        ])\n    \n    elif data == 'valid':\n        return Compose([\n            #Resize(HEIGHT, WIDTH),\n            RandomCrop(256, 256),\n            HorizontalFlip(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        ])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 128\n\ntest_dataset = TestDataset(submission, transform=get_transforms(data='valid'))\ntest_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class AvgPool(nn.Module):\n    def forward(self, x):\n        return F.avg_pool2d(x, x.shape[2:])\n\nclass ResNet(nn.Module):\n    def __init__(self, num_classes, pretrained=False, net_cls=M.resnet50, dropout=False):\n        super().__init__()\n        self.net = net_cls(pretrained=pretrained)\n        self.net.avgpool = AvgPool()\n        if dropout:\n            self.net.fc = nn.Sequential(\n                nn.Dropout(),\n                nn.Linear(self.net.fc.in_features, num_classes),\n            )\n        else:\n            self.net.fc = nn.Linear(self.net.fc.in_features, num_classes)\n\n    def fresh_params(self):\n        return self.net.fc.parameters()\n\n    def forward(self, x):\n        return self.net(x)\n\n\nclass DenseNet(nn.Module):\n    def __init__(self, num_classes, pretrained=False, net_cls=M.densenet121):\n        super().__init__()\n        self.net = net_cls(pretrained=pretrained)\n        self.avg_pool = AvgPool()\n        self.net.classifier = nn.Linear(\n            self.net.classifier.in_features, num_classes)\n\n    def fresh_params(self):\n        return self.net.classifier.parameters()\n\n    def forward(self, x):\n        out = self.net.features(x)\n        out = F.relu(out, inplace=True)\n        out = self.avg_pool(out).view(out.size(0), -1)\n        out = self.net.classifier(out)\n        return out\n\nclass ShuffleNet(nn.Module):\n    def __init__(self, num_classes, pretrained=False, net_cls=M.shufflenet_v2_x1_0, dropout=False):\n        super().__init__()\n        self.net = net_cls(pretrained=pretrained)\n        if dropout:\n            self.net.fc = nn.Sequential(\n                nn.Dropout(),\n                nn.Linear(self.net.fc.in_features, num_classes),\n            )\n        else:\n            self.net.fc = nn.Linear(self.net.fc.in_features, num_classes)\n\n    def fresh_params(self):\n        return self.net.classifier.parameters()\n\n    def forward(self, x):\n        return self.net(x)\n    \nclass SqueezeNet(nn.Module):\n    def __init__(self, num_classes, pretrained=False, net_cls=M.squeezenet1_0, dropout=False):\n        super().__init__()\n        self.net = net_cls(pretrained=pretrained)\n    \n        fin_conv = nn.Conv2d(512, num_classes, kernel_size=1)\n        self.net.classifier = nn.Sequential(\n            nn.Dropout(p=0.5),\n            fin_conv,\n            nn.ReLU(inplace=True),\n            nn.AdaptiveAvgPool2d((1, 1))\n        )\n    def fresh_params(self):\n        return self.net.classifier.parameters()\n\n    def forward(self, x):\n        out = self.net.features(x)\n        out = self.net.classifier(out)\n        out = out.view(-1, 3474)\n        return out\n    \n    \nclass MobileNet(nn.Module):\n    def __init__(self, num_classes, pretrained=False, net_cls=M.shufflenet_v2_x1_0, dropout=False):\n        super().__init__()\n        self.net = net_cls(pretrained=pretrained)\n        \n        self.net.classifier = nn.Sequential(\n            nn.Dropout(0.2),\n            nn.Linear(self.net.last_channel, num_classes),\n        )\n\n    def fresh_params(self):\n        return self.net.classifier.parameters()\n\n    def forward(self, x):\n        return self.net(x)\n        \n\nresnet50 = partial(ResNet, net_cls=M.resnet50)\ndensenet121 = partial(DenseNet, net_cls=M.densenet121)\nshufflenet = partial(ShuffleNet, net_cls=M.shufflenet_v2_x1_0)\nsqueezenet = partial(SqueezeNet, net_cls=M.squeezenet1_0)\nmobilenet = partial(MobileNet, net_cls=M.mobilenet_v2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from efficientnet_pytorch import * \n\ndef load_pretrained_weights2(model, model_name, weights_path=None, load_fc=True, advprop=False):\n    \"\"\"Loads pretrained weights from weights path or download using url.\n    Args:\n        model (Module): The whole model of efficientnet.\n        model_name (str): Model name of efficientnet.\n        weights_path (None or str): \n            str: path to pretrained weights file on the local disk.\n            None: use pretrained weights downloaded from the Internet.\n        load_fc (bool): Whether to load pretrained weights for fc layer at the end of the model.\n        advprop (bool): Whether to load pretrained weights\n                        trained with advprop (valid when weights_path is None).\n    \"\"\"\n    if isinstance(weights_path,str):\n        if torch.cuda.is_available():\n            state_dict = torch.load(weights_path)\n        else:\n            state_dict = torch.load(weights_path,map_location=torch.device('cpu'))\n    else:\n        # AutoAugment or Advprop (different preprocessing)\n        url_map_ = url_map_advprop if advprop else url_map\n        state_dict = model_zoo.load_url(url_map_[model_name])\n    \n    if load_fc:\n        ret = model.load_state_dict(state_dict, strict=False)\n        assert not ret.missing_keys, f'Missing keys when loading pretrained weights: {ret.missing_keys}'\n    else:\n        state_dict.pop('_fc.weight')\n        state_dict.pop('_fc.bias')\n        ret = model.load_state_dict(state_dict, strict=False)\n        assert set(ret.missing_keys) == set(\n            ['_fc.weight', '_fc.bias']), f'Missing keys when loading pretrained weights: {ret.missing_keys}'\n    assert not ret.unexpected_keys, f'Missing keys when loading pretrained weights: {ret.unexpected_keys}'\n\n    print('Loaded pretrained weights for {}'.format(model_name))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DIR_WEIGHTS = '/kaggle/input/imet2020'\nWEIGHTS_FILE = f'{DIR_WEIGHTS}/EfficientNet_b0_epoch5.pth'\n\n# model = resnet50(num_classes=N_CLASSES, pretrained=False)\n\n# model = squeezenet(num_classes=N_CLASSES, pretrained=False)\n\n# model = densenet121(num_classes=N_CLASSES)\n\n# model = mobilenet(num_classes=N_CLASSES, pretrained=False)\n\n# model = shufflenet(num_classes=N_CLASSES)\n\nmodel = EfficientNet.from_name('efficientnet-b0', override_params={'num_classes': 3474})\nload_pretrained_weights2(model, 'efficientnet-b0', weights_path=WEIGHTS_FILE, advprop=False)\n\n# if torch.cuda.is_available():\n#     model.load_state_dict(torch.load(WEIGHTS_FILE))\n# else:\n#     model.load_state_dict(torch.load(WEIGHTS_FILE, map_location=torch.device('cpu')))\n    \nmodel.to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"criterion = nn.BCEWithLogitsLoss(reduction='none')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with timer('inference'):\n    \n    model.eval()\n    \n    preds = []\n    tk0 = tqdm(enumerate(test_loader), total=len(test_loader))\n\n    for i, images in tk0:\n            \n        images = images.to(device)\n            \n        with torch.no_grad():\n            y_preds = model(images)\n            \n        preds.append(torch.sigmoid(y_preds).to('cpu').numpy())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"threshold = 0.10\npredictions = np.concatenate(preds) > threshold\n\nfor i, row in enumerate(predictions):\n    ids = np.nonzero(row)[0]\n    submission.iloc[i].attribute_ids = ' '.join([str(x) for x in ids])\n    \nsubmission.to_csv('submission.csv', index=False)\nsubmission.head()","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":4}