{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Intro\nInference notebook for [Hotel-ID starter - similarity - training](https://www.kaggle.com/code/michaln/hotel-id-starter-similarity-training)\n\nUsing model and embeddings from the training notebook to generate embeddings for test data and find similar images.","metadata":{"id":"DAY5rHgTm7e8","papermill":{"duration":0.024896,"end_time":"2022-03-24T14:00:54.588459","exception":false,"start_time":"2022-03-24T14:00:54.563563","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"# Imports","metadata":{"id":"cZoSOL9Qm-Yr","papermill":{"duration":0.023644,"end_time":"2022-03-24T14:00:54.696898","exception":false,"start_time":"2022-03-24T14:00:54.673254","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import os\nfrom sklearn.metrics.pairwise import cosine_similarity,cosine_distances\nfrom torch.nn import DataParallel","metadata":{"execution":{"iopub.status.busy":"2022-06-02T13:40:40.002141Z","iopub.execute_input":"2022-06-02T13:40:40.002425Z","iopub.status.idle":"2022-06-02T13:40:40.006764Z","shell.execute_reply.started":"2022-06-02T13:40:40.002391Z","shell.execute_reply":"2022-06-02T13:40:40.006096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport random\nimport os\nimport math\nimport cv2\nfrom numpy import dot\nfrom numpy.linalg import norm","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","executionInfo":{"elapsed":14459,"status":"ok","timestamp":1619310548121,"user":{"displayName":"Jeom Jin-Ho","photoUrl":"","userId":"00155613517919499503"},"user_tz":-120},"id":"expired-matter","papermill":{"duration":0.030271,"end_time":"2022-03-24T14:00:54.751131","exception":false,"start_time":"2022-03-24T14:00:54.72086","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-06-02T13:40:40.035306Z","iopub.execute_input":"2022-06-02T13:40:40.035654Z","iopub.status.idle":"2022-06-02T13:40:40.039647Z","shell.execute_reply.started":"2022-06-02T13:40:40.035625Z","shell.execute_reply":"2022-06-02T13:40:40.038933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image as pil_image\nfrom tqdm import tqdm","metadata":{"executionInfo":{"elapsed":16003,"status":"ok","timestamp":1619310550014,"user":{"displayName":"Jeom Jin-Ho","photoUrl":"","userId":"00155613517919499503"},"user_tz":-120},"id":"extreme-problem","papermill":{"duration":3.220402,"end_time":"2022-03-24T14:00:57.995239","exception":false,"start_time":"2022-03-24T14:00:54.774837","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-06-02T13:40:40.06886Z","iopub.execute_input":"2022-06-02T13:40:40.06917Z","iopub.status.idle":"2022-06-02T13:40:40.072865Z","shell.execute_reply.started":"2022-06-02T13:40:40.069141Z","shell.execute_reply":"2022-06-02T13:40:40.072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom torch.utils.data import DataLoader\n\n\nfrom sklearn.metrics.pairwise import cosine_similarity","metadata":{"executionInfo":{"elapsed":19672,"status":"ok","timestamp":1619310554099,"user":{"displayName":"Jeom Jin-Ho","photoUrl":"","userId":"00155613517919499503"},"user_tz":-120},"id":"angry-domain","papermill":{"duration":2.727834,"end_time":"2022-03-24T14:01:00.766951","exception":false,"start_time":"2022-03-24T14:00:58.039117","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-06-02T13:40:40.089515Z","iopub.execute_input":"2022-06-02T13:40:40.089796Z","iopub.status.idle":"2022-06-02T13:40:40.095107Z","shell.execute_reply.started":"2022-06-02T13:40:40.089771Z","shell.execute_reply":"2022-06-02T13:40:40.09443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Global","metadata":{"id":"0B00pe7mnBTj","papermill":{"duration":0.023573,"end_time":"2022-03-24T14:01:00.814976","exception":false,"start_time":"2022-03-24T14:01:00.791403","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def load_image(img_path):\n    realImage = cv2.imread(img_path)\n    if realImage is None:\n        return None\n    target_wh = 128\n    height, width, dim = realImage.shape\n\n    scale = 1\n    if height >= width:\n        scale = target_wh / height\n    if width > height:\n        scale = target_wh / width\n    resizedImage = cv2.resize(realImage, (int(width * scale), int(height * scale)))\n    new_height, new_width, new_dim = resizedImage.shape\n\n    paddingTopBottom = int((target_wh - new_height) // 2)\n    extraPaddingTopBottom = target_wh - (2 * paddingTopBottom) - new_height\n    paddingLeftRight = int((target_wh - new_width) // 2)\n    extraPaddingLeftRight = target_wh - (2 * paddingLeftRight) - new_width\n\n    image = cv2.copyMakeBorder(resizedImage, paddingTopBottom + extraPaddingTopBottom, paddingTopBottom, paddingLeftRight + extraPaddingLeftRight, paddingLeftRight, cv2.BORDER_REFLECT)\n    \n    image = np.dstack((image, np.fliplr(image)))\n    image = image.transpose((2, 0, 1))\n    image = image[:, np.newaxis, :, :]\n    image = image.astype(np.float32, copy=False)\n    image -= 127.5\n    image /= 127.5\n    return image","metadata":{"execution":{"iopub.status.busy":"2022-06-02T13:40:40.11693Z","iopub.execute_input":"2022-06-02T13:40:40.11722Z","iopub.status.idle":"2022-06-02T13:40:40.125775Z","shell.execute_reply.started":"2022-06-02T13:40:40.117192Z","shell.execute_reply":"2022-06-02T13:40:40.125086Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_featurs(model, test_list, batch_size=10):\n    images = None\n    features = None\n    cnt = 0\n    for i, img_path in enumerate(test_list):\n        image = load_image(img_path)\n        if image is None:\n            print('read {} error'.format(img_path))\n\n        if images is None:\n            images = image\n        else:\n            images = np.concatenate((images, image), axis=0)\n        \n        if images.shape[0] % batch_size == 0 or i == len(test_list) - 1:\n            cnt += 1\n\n            data = torch.from_numpy(images)\n            data = data.to(torch.device(\"cuda\"))\n            output = model(data)\n            output = output.data.cpu().numpy()\n\n            fe_1 = output[::2]\n            fe_2 = output[1::2]\n            feature = np.hstack((fe_1, fe_2))\n            # print(feature.shape)\n\n            if features is None:\n                features = feature\n            else:\n                features = np.vstack((features, feature))\n\n            images = None\n\n    return features, cnt","metadata":{"execution":{"iopub.status.busy":"2022-06-02T13:40:40.130235Z","iopub.execute_input":"2022-06-02T13:40:40.130484Z","iopub.status.idle":"2022-06-02T13:40:40.140665Z","shell.execute_reply.started":"2022-06-02T13:40:40.130459Z","shell.execute_reply":"2022-06-02T13:40:40.139713Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# -*- coding: utf-8 -*-\n\"\"\"\nCreated on 18-5-21 下午5:26\n\n@author: ronghuaiyang\n\"\"\"\nimport torch\nimport torch.nn as nn\nimport math\nimport torch.utils.model_zoo as model_zoo\nimport torch.nn.utils.weight_norm as weight_norm\nimport torch.nn.functional as F\n\n\n# __all__ = ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101',\n#            'resnet152']\n\n\nmodel_urls = {\n    'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',\n    'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',\n    'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',\n    'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',\n    'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',\n}\n\n\ndef conv3x3(in_planes, out_planes, stride=1):\n    \"\"\"3x3 convolution with padding\"\"\"\n    return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,\n                     padding=1, bias=False)\n\n\nclass BasicBlock(nn.Module):\n    expansion = 1\n\n    def __init__(self, inplanes, planes, stride=1, downsample=None):\n        super(BasicBlock, self).__init__()\n        self.conv1 = conv3x3(inplanes, planes, stride)\n        self.bn1 = nn.BatchNorm2d(planes)\n        self.relu = nn.ReLU(inplace=True)\n        self.conv2 = conv3x3(planes, planes)\n        self.bn2 = nn.BatchNorm2d(planes)\n        self.downsample = downsample\n        self.stride = stride\n\n    def forward(self, x):\n        residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass IRBlock(nn.Module):\n    expansion = 1\n\n    def __init__(self, inplanes, planes, stride=1, downsample=None, use_se=True):\n        super(IRBlock, self).__init__()\n        self.bn0 = nn.BatchNorm2d(inplanes)\n        self.conv1 = conv3x3(inplanes, inplanes)\n        self.bn1 = nn.BatchNorm2d(inplanes)\n        self.prelu = nn.PReLU()\n        self.conv2 = conv3x3(inplanes, planes, stride)\n        self.bn2 = nn.BatchNorm2d(planes)\n        self.downsample = downsample\n        self.stride = stride\n        self.use_se = use_se\n        if self.use_se:\n            self.se = SEBlock(planes)\n\n    def forward(self, x):\n        residual = x\n        out = self.bn0(x)\n        out = self.conv1(out)\n        out = self.bn1(out)\n        out = self.prelu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        if self.use_se:\n            out = self.se(out)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        out += residual\n        out = self.prelu(out)\n\n        return out\n\n\nclass Bottleneck(nn.Module):\n    expansion = 4\n\n    def __init__(self, inplanes, planes, stride=1, downsample=None):\n        super(Bottleneck, self).__init__()\n        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(planes)\n        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,\n                               padding=1, bias=False)\n        self.bn2 = nn.BatchNorm2d(planes)\n        self.conv3 = nn.Conv2d(planes, planes * self.expansion, kernel_size=1, bias=False)\n        self.bn3 = nn.BatchNorm2d(planes * self.expansion)\n        self.relu = nn.ReLU(inplace=True)\n        self.downsample = downsample\n        self.stride = stride\n\n    def forward(self, x):\n        residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass SEBlock(nn.Module):\n    def __init__(self, channel, reduction=16):\n        super(SEBlock, self).__init__()\n        self.avg_pool = nn.AdaptiveAvgPool2d(1)\n        self.fc = nn.Sequential(\n                nn.Linear(channel, channel // reduction),\n                nn.PReLU(),\n                nn.Linear(channel // reduction, channel),\n                nn.Sigmoid()\n        )\n\n    def forward(self, x):\n        b, c, _, _ = x.size()\n        y = self.avg_pool(x).view(b, c)\n        y = self.fc(y).view(b, c, 1, 1)\n        return x * y\n\n\nclass ResNetFace(nn.Module):\n    def __init__(self, block, layers, use_se=True):\n        self.inplanes = 64\n        self.use_se = use_se\n        super(ResNetFace, self).__init__()\n        self.conv1 = nn.Conv2d(1, 64, kernel_size=3, padding=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(64)\n        self.prelu = nn.PReLU()\n        self.maxpool = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.layer1 = self._make_layer(block, 64, layers[0])\n        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)\n        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)\n        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)\n        self.bn4 = nn.BatchNorm2d(512)\n        self.dropout = nn.Dropout()\n        self.fc5 = nn.Linear(512 * 8 * 8, 512)\n        self.bn5 = nn.BatchNorm1d(512)\n\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                nn.init.xavier_normal_(m.weight)\n            elif isinstance(m, nn.BatchNorm2d) or isinstance(m, nn.BatchNorm1d):\n                nn.init.constant_(m.weight, 1)\n                nn.init.constant_(m.bias, 0)\n            elif isinstance(m, nn.Linear):\n                nn.init.xavier_normal_(m.weight)\n                nn.init.constant_(m.bias, 0)\n\n    def _make_layer(self, block, planes, blocks, stride=1):\n        downsample = None\n        if stride != 1 or self.inplanes != planes * block.expansion:\n            downsample = nn.Sequential(\n                nn.Conv2d(self.inplanes, planes * block.expansion,\n                          kernel_size=1, stride=stride, bias=False),\n                nn.BatchNorm2d(planes * block.expansion),\n            )\n        layers = []\n        layers.append(block(self.inplanes, planes, stride, downsample, use_se=self.use_se))\n        self.inplanes = planes\n        for i in range(1, blocks):\n            layers.append(block(self.inplanes, planes, use_se=self.use_se))\n\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.bn1(x)\n        x = self.prelu(x)\n        x = self.maxpool(x)\n\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n        x = self.bn4(x)\n        x = self.dropout(x)\n        x = x.view(x.size(0), -1)\n        x = self.fc5(x)\n        x = self.bn5(x)\n\n        return x\n\n\nclass ResNet(nn.Module):\n\n    def __init__(self, block, layers):\n        self.inplanes = 64\n        super(ResNet, self).__init__()\n        # self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3,\n        #                        bias=False)\n        self.conv1 = nn.Conv2d(1, 64, kernel_size=3, stride=1, padding=1,\n                               bias=False)\n        self.bn1 = nn.BatchNorm2d(64)\n        self.relu = nn.ReLU(inplace=True)\n        # self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        self.layer1 = self._make_layer(block, 64, layers[0], stride=2)\n        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)\n        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)\n        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)\n        # self.avgpool = nn.AvgPool2d(8, stride=1)\n        # self.fc = nn.Linear(512 * block.expansion, num_classes)\n        self.fc5 = nn.Linear(512 * 8 * 8, 512)\n\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')\n            elif isinstance(m, nn.BatchNorm2d):\n                nn.init.constant_(m.weight, 1)\n                nn.init.constant_(m.bias, 0)\n\n    def _make_layer(self, block, planes, blocks, stride=1):\n        downsample = None\n        if stride != 1 or self.inplanes != planes * block.expansion:\n            downsample = nn.Sequential(\n                nn.Conv2d(self.inplanes, planes * block.expansion,\n                          kernel_size=1, stride=stride, bias=False),\n                nn.BatchNorm2d(planes * block.expansion),\n            )\n\n        layers = []\n        layers.append(block(self.inplanes, planes, stride, downsample))\n        self.inplanes = planes * block.expansion\n        for i in range(1, blocks):\n            layers.append(block(self.inplanes, planes))\n\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.bn1(x)\n        x = self.relu(x)\n        # x = self.maxpool(x)\n\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n        # x = nn.AvgPool2d(kernel_size=x.size()[2:])(x)\n        # x = self.avgpool(x)\n        x = x.view(x.size(0), -1)\n        x = self.fc5(x)\n\n        return x\n\n\ndef resnet18(pretrained=False, **kwargs):\n    \"\"\"Constructs a ResNet-18 model.\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n    \"\"\"\n    model = ResNet(BasicBlock, [2, 2, 2, 2], **kwargs)\n    if pretrained:\n        model.load_state_dict(model_zoo.load_url(model_urls['resnet18']))\n    return model\n\n\ndef resnet34(pretrained=False, **kwargs):\n    \"\"\"Constructs a ResNet-34 model.\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n    \"\"\"\n    model = ResNet(BasicBlock, [3, 4, 6, 3], **kwargs)\n    if pretrained:\n        model.load_state_dict(model_zoo.load_url(model_urls['resnet34']))\n    return model\n\n\ndef resnet50(pretrained=False, **kwargs):\n    \"\"\"Constructs a ResNet-50 model.\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n    \"\"\"\n    model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs)\n    if pretrained:\n        model.load_state_dict(model_zoo.load_url(model_urls['resnet50']))\n    return model\n\n\ndef resnet101(pretrained=False, **kwargs):\n    \"\"\"Constructs a ResNet-101 model.\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n    \"\"\"\n    model = ResNet(Bottleneck, [3, 4, 23, 3], **kwargs)\n    if pretrained:\n        model.load_state_dict(model_zoo.load_url(model_urls['resnet101']))\n    return model\n\n\ndef resnet152(pretrained=False, **kwargs):\n    \"\"\"Constructs a ResNet-152 model.\n    Args:\n        pretrained (bool): If True, returns a model pre-trained on ImageNet\n    \"\"\"\n    model = ResNet(Bottleneck, [3, 8, 36, 3], **kwargs)\n    if pretrained:\n        model.load_state_dict(model_zoo.load_url(model_urls['resnet152']))\n    return model\n\n\ndef resnet_face18(use_se=True, **kwargs):\n    model = ResNetFace(IRBlock, [2, 2, 2, 2], use_se=use_se, **kwargs)\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-06-02T13:40:40.231189Z","iopub.execute_input":"2022-06-02T13:40:40.231467Z","iopub.status.idle":"2022-06-02T13:40:40.290748Z","shell.execute_reply.started":"2022-06-02T13:40:40.231434Z","shell.execute_reply":"2022-06-02T13:40:40.289961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SEED = 42\nIMG_SIZE = 256\nN_MATCHES = 5\n\nPROJECT_FOLDER = \"../input/hotel-id-to-combat-human-trafficking-2022-fgvc9/\"\nTRAIN_DATA_FOLDER = \"../input/hotelid-2022-train-images-256x256/images/\"\nTEST_DATA_FOLDER = PROJECT_FOLDER + \"test_images/\"","metadata":{"executionInfo":{"elapsed":589,"status":"ok","timestamp":1619310979015,"user":{"displayName":"Jeom Jin-Ho","photoUrl":"","userId":"00155613517919499503"},"user_tz":-120},"id":"contained-brief","papermill":{"duration":0.03175,"end_time":"2022-03-24T14:01:00.871686","exception":false,"start_time":"2022-03-24T14:01:00.839936","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-06-02T13:40:40.292571Z","iopub.execute_input":"2022-06-02T13:40:40.292828Z","iopub.status.idle":"2022-06-02T13:40:40.303629Z","shell.execute_reply.started":"2022-06-02T13:40:40.292789Z","shell.execute_reply":"2022-06-02T13:40:40.302934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = resnet_face18(False)\n\n# test_model_path = '../input/d/datasets/thomaskolb8/trainmodel/resnet18_9990.pth'\ntest_model_path = '../input/trainmodelwarp/resnet18_3300.pth'\n\nmodel = DataParallel(model)\nmodel.load_state_dict(torch.load(test_model_path))\nmodel.to(torch.device(\"cuda\"))\nmodel.eval()\n\ndef findLabels(test_images, ft_dict):\n    labels = []\n    test_fts, _ = get_featurs(model, test_images, 10)\n    for i, img in enumerate(test_images):\n        test_ft = np.array(test_fts[i])\n        best_label = -1\n        best_avg_sim = 0\n        for label in ft_dict:\n            vectorlist = ft_dict[label]\n            avg_sim = 0\n            for vector in vectorlist:\n                ft = np.array(vector)\n                avg_sim += dot(ft, test_ft)/(norm(ft)*norm(test_ft))\n            avg_sim /= len(vectorlist)\n            if avg_sim > best_avg_sim:\n                best_avg_sim = avg_sim\n                best_label = label\n        labels.append(best_label)\n    return labels\n        \ndef readvectors():\n    location = \"../input/outputvectorswarp/outputvectors_warp.txt\"\n    ft_dict = {}\n    with open(location, \"r\") as f:\n        lines = f.read().split(\"\\n\")[:-1]\n        for line in lines:\n            label_str, vector_str = line.split(':')\n            label = int(label_str)\n            vector = [float(v) for v in vector_str.strip('][ ').split(', ')]\n            if label in ft_dict:\n                ft_dict[label].append(vector)\n            else:\n                ft_dict[label] = [vector]\n    return ft_dict","metadata":{"execution":{"iopub.status.busy":"2022-06-02T13:40:40.304928Z","iopub.execute_input":"2022-06-02T13:40:40.305744Z","iopub.status.idle":"2022-06-02T13:40:42.033766Z","shell.execute_reply.started":"2022-06-02T13:40:40.305707Z","shell.execute_reply":"2022-06-02T13:40:42.033054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submission","metadata":{"papermill":{"duration":0.024227,"end_time":"2022-03-24T14:01:08.278753","exception":false,"start_time":"2022-03-24T14:01:08.254526","status":"completed"},"tags":[]}},{"cell_type":"code","source":"test_images = []\nimage_ids = []\ndirs = os.listdir(TEST_DATA_FOLDER)\nfor image in dirs:\n    filepath = os.path.join(TEST_DATA_FOLDER, image)\n    test_images.append(filepath)\n    image_ids.append(image)\n\nft_dict = readvectors()\nlabels = findLabels(test_images, ft_dict)\n\ntest_df = pd.DataFrame()\ntest_df[\"image_id\"] = image_ids\ntest_df[\"hotel_id\"] = labels\n\ntest_df.to_csv(\"submission.csv\", index=False)\ntest_df.head()","metadata":{"papermill":{"duration":0.047156,"end_time":"2022-03-24T14:01:08.414557","exception":false,"start_time":"2022-03-24T14:01:08.367401","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-06-02T13:40:42.035124Z","iopub.execute_input":"2022-06-02T13:40:42.035388Z","iopub.status.idle":"2022-06-02T13:41:09.83693Z","shell.execute_reply.started":"2022-06-02T13:40:42.035342Z","shell.execute_reply":"2022-06-02T13:41:09.836101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}