{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Load libraries"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install ../input/efficientnetpytorch/EfficientNet-PyTorch-master","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Import libraries"},{"metadata":{"trusted":true},"cell_type":"code","source":"import math\nimport heapq\nimport torch\nimport torch.nn as nn\nfrom torch.cuda import amp\nfrom efficientnet_pytorch import EfficientNet\nfrom torch.nn import Parameter\nimport torch.nn.functional as F\nfrom collections import OrderedDict\nimport pandas as pd\nimport numpy as np\nfrom tqdm import tqdm\nfrom sklearn.metrics.pairwise import cosine_similarity\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nimport os\nimport cv2\nimport glob\nfrom shutil import copyfile\nimport multiprocessing\nfrom torch.utils.data import Dataset, DataLoader\n\nimport time\nimport copy\nimport gc\nimport operator\nimport pathlib\nimport PIL\nimport pydegensac\nfrom scipy import spatial\nimport tensorflow as tf","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DEBUG = False\n\ntrain_data_dir = '/kaggle/input/landmark-recognition-2020/train/'\ntest_data_dir = '/kaggle/input/landmark-recognition-2020/test/'\ntrain_csv_path = '/kaggle/input/landmark-recognition-2020/train.csv'\n\nimage_size = 640\nembeddings_size = 512\nbatch_size = 30\nnum_workers = multiprocessing.cpu_count()\nn_chunks = 200 if not DEBUG else 20\nn_top_global = 5\nn_top_local = 5\ncalculate_local = True\nreranking = True\ntrain_encodings_from_file = False\nN_rerank_check = 10 if DEBUG else 5000\nN_rerank_select = 5 if DEBUG else 300\nreranking_th = 25\n\ndevice = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Global features model"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"def generate_test_df(data_dir, img_ext='.jpg'):\n    files = [f.split('/')[-1].replace(img_ext,'') for f in glob.glob(data_dir + f'**/*{img_ext}',recursive=True)]\n    return pd.DataFrame(files, columns=['id'])\n\ndef my_collate(batch):\n    all_images = []\n    all_names = []\n    \n    total_n_transforms = len(batch[0][0])\n    \n    for i in range(total_n_transforms):\n        curr_imgs_list = []\n        curr_name_list = []\n        for b in batch:\n            curr_imgs_list.append(b[0][i])\n            curr_name_list.append(b[1][i])\n        curr_imgs_list = torch.stack(curr_imgs_list)\n        all_images.append(curr_imgs_list)\n        all_names.append(curr_name_list)\n    return [all_images, all_names]\n\n\nclass GLRDataset(Dataset):\n    def __init__(self, data_dir, transform, df_path=None, mapper=None, img_ext='.jpg'):\n        super().__init__()\n        self.df = pd.read_csv(df_path) if df_path is not None else generate_test_df(data_dir,img_ext=img_ext)\n        self.data_dir = data_dir\n        self.transform = transform\n        self.img_ext = img_ext\n        self.n_classes = self.df['landmark_id'].nunique() if 'landmark_id' in self.df else None\n        self.n_samples = len(self.df)\n        self.mapper = mapper\n\n    def __len__(self):\n        return len(self.df)\n          \n    def __getitem__(self, index):       \n        img_name = self.df['id'].iloc[index]\n        f1,f2,f3 = img_name[:3]\n        img_path = os.path.join(self.data_dir, f1, f2, f3, img_name+self.img_ext)\n        images = []\n        img_names = []\n        image = cv2.imread(img_path)  # BGR\n        \n        for trans in self.transform:\n            augmented = trans(image=image)\n            images.append(augmented['image'])\n            img_names.append(img_name)\n        return images, img_names\n\n\ndef get_dataloader(data_dir, transform=None, batch_size=8, df_path=None, \n                             mapper=None, num_workers=2, \n                             pin_memory=True, drop_last=True, collate_fn=None):\n    dataset = GLRDataset(data_dir=data_dir, df_path=df_path, mapper=mapper, transform=transform)\n    sampler = None\n    data_loader = DataLoader(dataset=dataset, \n                             batch_size=batch_size, \n                             sampler=sampler, \n                             pin_memory=pin_memory,\n                             drop_last=drop_last,\n                             collate_fn=collate_fn,\n                             num_workers=num_workers)\n    return data_loader, dataset\n\ndef load_ckp(checkpoint_fpath, model, optimizer=None, margin=None, remove_module=False):\n    checkpoint = torch.load(checkpoint_fpath)\n\n    pretrained_dict = checkpoint['model']\n    model_state_dict = model.state_dict()\n    if remove_module:\n        new_state_dict = OrderedDict()\n        for k, v in pretrained_dict.items():\n            name = k[7:] # remove 'module.' of DataParallel/DistributedDataParallel\n            new_state_dict[name] = v\n        pretrained_dict = new_state_dict\n    pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_state_dict}\n    model_state_dict.update(pretrained_dict)\n \n\n    model.load_state_dict(pretrained_dict)\n\n    try:\n        optimizer.load_state_dict(checkpoint['optimizer'])\n    except:\n        print('Cannot load optimizer params')\n        \n    if margin is not None and 'margin' in checkpoint:\n            margin.load_state_dict(checkpoint['margin'])\n\n    epoch = checkpoint['epoch'] if 'epoch' in checkpoint else 0\n    idx_to_class = checkpoint['idx_to_class'] if 'idx_to_class' in checkpoint else {} \n    return model, optimizer, margin, epoch, idx_to_class\n\nclass EmbeddigsNet(nn.Module):\n    def __init__(self, model_name, embeddings_size):\n        super(EmbeddigsNet, self).__init__()\n        self.effnet = EfficientNet.from_name(model_name)\n        # Unfreeze model weights\n        for param in self.effnet.parameters():\n            param.requires_grad = True\n        num_ftrs = self.effnet._fc.in_features\n        self.effnet._fc = nn.Linear(num_ftrs, embeddings_size)\n    def forward(self, x):\n        x = self.effnet(x)\n        return x\n\n\ndef get_model(model_name, embeddings_size):\n    model = EmbeddigsNet(model_name, embeddings_size)\n    return model\n\n\ndef calculate_top_n(sim_matrix,best_top_n_vals,\n                               best_top_n_idxs,\n                               curr_zero_idx=0,\n                               n=10):\n    n_rows, n_cols = sim_matrix.shape\n    total_matrix_vals = sim_matrix\n    total_matrix_idxs = np.tile(np.arange(n_rows).reshape(n_rows,1), (1,n_cols)).astype(int) + curr_zero_idx\n    if curr_zero_idx>0:\n        total_matrix_vals = np.vstack((total_matrix_vals, best_top_n_vals))\n        total_matrix_idxs = np.vstack((total_matrix_idxs, best_top_n_idxs))\n    res = np.argpartition(total_matrix_vals, -n, axis=0)[-n:]\n    res_vals = np.take_along_axis(total_matrix_vals, res, axis=0)\n    res_idxs = np.take_along_axis(total_matrix_idxs, res, axis=0)\n\n    del res, total_matrix_idxs, total_matrix_vals\n    return res_vals, res_idxs\n\n\ndef cosine_similarity_chunks(X, Y, n_chunks=5, top_n=5):\n    ch_sz = X.shape[0]//n_chunks\n    best_top_n_vals = None\n    best_top_n_idxs = None\n    num_chunks = 2 if DEBUG else n_chunks\n    for i in tqdm(range(num_chunks)):\n        chunk = X[i*ch_sz:,:] if i==n_chunks-1 else X[i*ch_sz:(i+1)*ch_sz,:]\n        cosine_sim_matrix_i = cosine_similarity(chunk, Y)\n        best_top_n_vals, best_top_n_idxs = calculate_top_n(cosine_sim_matrix_i,\n                                                           best_top_n_vals,\n                                                            best_top_n_idxs,\n                                                            curr_zero_idx=(i*ch_sz),\n                                                            n=top_n)\n    print(f'Best similar vals shape {best_top_n_vals.shape}')\n    print(f'Best similar idxs shape {best_top_n_idxs.shape}')\n    return best_top_n_vals, best_top_n_idxs\n\n\ndef get_embeddings(model, test_dataloader, device, l2_norm=True):\n    generated_embeddings = {}\n    model.eval()\n\n    tqdm_test = tqdm(test_loader, total=int(len(test_loader)))\n   \n    with torch.no_grad():\n        for batch_index, [data, images_ids] in enumerate(tqdm_test):\n            if DEBUG and batch_index>10:\n                break\n            \n            logits = None\n            for dat in data:\n                dat = dat.to(device)\n                logits_i = model(dat)\n                logits_i = logits_i.cpu().numpy()\n                if logits is None:\n                    logits = logits_i/len(data)\n                else:\n                    logits += logits_i/len(data)\n                    \n            image_ids = images_ids[0]\n            for logits_i, image_id in zip(logits, image_ids):\n               generated_embeddings[image_id] = logits_i / np.linalg.norm(logits_i) if l2_norm else logits_i\n                \n                \n    return generated_embeddings\n\ndef get_max_conf_pred(curr_n_pred, curr_n_conf):\n    dict_conf_list = {}\n    dict_conf_sum = {}\n\n    for p, c in zip(curr_n_pred, curr_n_conf):\n        if p in dict_conf_list:\n            dict_conf_list[p].append(c)\n        else:\n            dict_conf_list[p] = [c]\n\n    dict_conf_sum = { k : sum(v) for k, v in dict_conf_list.items()}\n    pred_i = max(dict_conf_sum, key=dict_conf_sum.get)\n    conf_i = sum(dict_conf_list[pred_i])\n    return pred_i, conf_i\n\ndef generate_submission_df(ids, predictions, confidences, th=0):\n    ids, predictions, confidences = list(ids), list(predictions), list(confidences)\n    pred_conf_strings = [f'{int(p)} {c}' if c>=th else '' for p,c in zip(predictions, confidences)]\n    df = pd.DataFrame(list(zip(ids, pred_conf_strings)), columns =['id', 'landmarks'])\n    return df\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Transformations"},{"metadata":{"trusted":true},"cell_type":"code","source":"transform_no_aug = A.Compose([\n            A.Resize(image_size, image_size),\n            A.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n            ToTensorV2()\n        ])\n\ntransform_resize_d = A.Compose([\n            A.Resize(int(0.75*image_size), int(0.75*image_size)),\n            A.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n            ToTensorV2()\n        ])\n\ntransform_resize_u = A.Compose([\n            A.Resize(int(1.25*image_size), int(1.25*image_size)),\n            A.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n            ToTensorV2()\n        ])\n\ntransform_resize_u2 = A.Compose([\n            A.Resize(int(2*image_size), int(2*image_size)),\n            A.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n            ToTensorV2()\n        ])\n\ntransform_flip_lr = A.Compose([\n            A.Resize(image_size, image_size),\n            A.HorizontalFlip(always_apply=True, p=1),\n            A.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n            ToTensorV2()\n        ])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model_names = ['efficientnet-b3']\n# weights_paths = ['/kaggle/input/efficientnetb3best/best_512.pt']\n\nmodel_names = ['efficientnet-b3']\nweights_paths = ['/kaggle/input/e3-weights/last.pt']\n\n# model_names = ['efficientnet-b3',\n#                'efficientnet-b7']\n# weights_paths = ['/kaggle/input/efficientnetb3best/best_512.pt',\n#                  '/kaggle/input/efficientnetb7best/best_epoch_45_wce.pt']\n\n# model_names = ['efficientnet-b3',\n#                'efficientnet-b7']\n# weights_paths = ['/kaggle/input/efficientnetb3best/best_512.pt',\n#                  '/kaggle/input/efficientnetb7best/best_epoch_45_wce.pt']\n# model_names = ['efficientnet-b3']\n# weights_paths = ['/kaggle/input/efficientnetb3best/best_512.pt']\n\n# model_names = ['efficientnet-b3',\n#                'efficientnet-b5',\n#                'efficientnet-b7']\n# weights_paths = ['/kaggle/input/efficientnetb3best/best_512.pt',\n#                  '/kaggle/input/efficientnetb5best/last.pt',\n#                  '/kaggle/input/efficientnetb7best/best_epoch_45_wce.pt']\n\n# model_names = ['efficientnet-b5',\n#                'efficientnet-b7']\n# weights_paths = ['/kaggle/input/efficientnetb5best/last.pt',\n#                  '/kaggle/input/efficientnetb7best/best_epoch_45_wce.pt']\n# model_names = ['efficientnet-b5']\n# weights_paths = ['/kaggle/input/efficientnetb5best/last.pt']\n# transforms_all = [transform_no_aug]\ntransforms_all = [transform_no_aug, transform_resize_u]\n# transforms_all = [transform_no_aug, transform_resize_u, transform_resize_d]\n\nmax_n_samples = 10000000 if DEBUG else 1000000","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train = pd.read_csv(train_csv_path)\nn_files = len(df_train)\nprint(f'Number of training samples {n_files}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if n_files>max_n_samples:\n    copyfile('/kaggle/input/landmark-recognition-2020/sample_submission.csv', 'submission.csv')\nelse:\n    models = []\n    for model_name, weights_path in zip(model_names, weights_paths):\n        print(model_name)\n        model = get_model(model_name, embeddings_size=embeddings_size)\n        model = model.to(device)\n        model, _, _, _, _ = load_ckp(weights_path, model, remove_module=True)\n        models.append(model)\n        \n    embeddings_all = []\n    \n    train_embeddings_final = {}\n    test_embeddings_final = {}\n    \n    embeddings_transform = []\n    if train_encodings_from_file:\n        data_dirs = [test_data_dir]\n        df = pd.read_csv('/kaggle/input/landmark-recognition-2020/train.csv')\n        encd = np.load('/kaggle/input/encodings/encodings.npy')\n        df_nms = pd.read_csv('/kaggle/input/encodings/names.csv')\n        cl_nms = df_nms['id'].tolist()\n        tr_nms = df['id'].tolist()\n        enc_dict = {}\n        \n        for v_idx , (cl_nm, enc) in tqdm(enumerate(zip(cl_nms, encd)), total=len(cl_nms)):\n            if DEBUG:\n                if v_idx>100:\n                    break\n            if cl_nm in tr_nms:\n                enc_dict[cl_nm] = enc\n        embeddings_transform.append(enc_dict)\n        del tr_nms, cl_nms, df_nms, encd, df, enc_dict\n    else:\n        data_dirs = [train_data_dir, test_data_dir]\n    \n    for data_dir in data_dirs:\n        test_loader, test_data = get_dataloader(data_dir=data_dir,  \n                                                transform=transforms_all , \n                                                batch_size=batch_size,\n                                                num_workers=num_workers,\n                                                collate_fn=my_collate,\n                                                drop_last=False)\n        embeddings = {}\n        for model in models:\n            embeddings_i = get_embeddings(model, test_loader, device)\n            if not embeddings:\n                embeddings = embeddings_i\n            else:\n                for k, v in embeddings_i.items():\n                    embeddings[k] = np.concatenate([embeddings[k], v])\n        embeddings_transform.append(embeddings)\n\n    train_embeddings, test_embeddings = embeddings_transform\n\n    df_train['encodings'] = df_train['id'].map(train_embeddings)\n    df_train = df_train.dropna()\n    df_test = pd.DataFrame(list(test_embeddings.items()), columns=['id', 'encodings'])\n\n    encodings_train = np.array(df_train['encodings'].tolist(), dtype=np.float32)\n    encodings_valid = np.array(df_test['encodings'].tolist(), dtype=np.float32)\n    print(encodings_train.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# DELG"},{"metadata":{"trusted":true},"cell_type":"code","source":"if calculate_local:\n    # Dataset parameters:\n    INPUT_DIR = os.path.join('..', 'input')\n\n    DATASET_DIR = os.path.join(INPUT_DIR, 'landmark-recognition-2020')\n    TEST_IMAGE_DIR = os.path.join(DATASET_DIR, 'test')\n    TRAIN_IMAGE_DIR = os.path.join(DATASET_DIR, 'train')\n    TRAIN_LABELMAP_PATH = os.path.join(DATASET_DIR, 'train.csv')\n\n    # RANSAC parameters:\n    MAX_INLIER_SCORE = 35\n    MAX_REPROJECTION_ERROR = 6.0\n    MAX_RANSAC_ITERATIONS = 5_000_000\n    HOMOGRAPHY_CONFIDENCE = 0.99\n\n    # DELG model:\n    SAVED_MODEL_DIR = '../input/delg-saved-models/local_and_global'\n    DELG_MODEL = tf.saved_model.load(SAVED_MODEL_DIR)\n    DELG_IMAGE_SCALES_TENSOR = tf.convert_to_tensor([0.70710677, 1.0, 1.4142135])\n    DELG_SCORE_THRESHOLD_TENSOR = tf.constant(175.)\n    DELG_INPUT_TENSOR_NAMES = ['input_image:0', 'input_scales:0', 'input_abs_thres:0']\n\n\n    # Local feature extraction:\n    LOCAL_FEATURE_NUM_TENSOR = tf.constant(1000)\n    LOCAL_FEATURE_EXTRACTION_FN = DELG_MODEL.prune(DELG_INPUT_TENSOR_NAMES + ['input_max_feature_num:0'],['boxes:0', 'features:0'])\n\n    def get_image_path(subset, name):\n        return os.path.join(DATASET_DIR, subset, name[0], name[1], name[2],f'{name}.jpg')\n\n\n    def load_image_tensor(image_path):\n        return tf.convert_to_tensor(np.array(PIL.Image.open(image_path).convert('RGB')))\n\n\n    def extract_local_features(image_path):\n      \"\"\"Extracts local features for the given `image_path`.\"\"\"\n\n      image_tensor = load_image_tensor(image_path)\n\n      features = LOCAL_FEATURE_EXTRACTION_FN(image_tensor, DELG_IMAGE_SCALES_TENSOR,\n                                             DELG_SCORE_THRESHOLD_TENSOR,\n                                             LOCAL_FEATURE_NUM_TENSOR)\n\n      # Shape: (N, 2)\n      keypoints = tf.divide(\n          tf.add(\n              tf.gather(features[0], [0, 1], axis=1),\n              tf.gather(features[0], [2, 3], axis=1)), 2.0).numpy()\n\n      # Shape: (N, 128)\n      descriptors = tf.nn.l2_normalize(features[1], axis=1, name='l2_normalization').numpy()\n      return keypoints, descriptors\n    \n    def get_total_score(num_inliers, global_score):\n      local_score = min(num_inliers, MAX_INLIER_SCORE) / MAX_INLIER_SCORE\n      return local_score + global_score\n\n    def get_putative_matching_keypoints(test_keypoints,\n                                        test_descriptors,\n                                        train_keypoints,\n                                        train_descriptors,\n                                        max_distance=0.9):\n      \"\"\"Finds matches from `test_descriptors` to KD-tree of `train_descriptors`.\"\"\"\n\n      train_descriptor_tree = spatial.cKDTree(train_descriptors)\n      _, matches = train_descriptor_tree.query(test_descriptors, distance_upper_bound=max_distance)\n\n      test_kp_count = test_keypoints.shape[0]\n      train_kp_count = train_keypoints.shape[0]\n\n      test_matching_keypoints = np.array([test_keypoints[i,]\n                                          for i in range(test_kp_count)\n                                          if matches[i] != train_kp_count])\n      train_matching_keypoints = np.array([train_keypoints[matches[i],]\n                                           for i in range(test_kp_count)\n                                           if matches[i] != train_kp_count])\n\n      return test_matching_keypoints, train_matching_keypoints\n\n\n    def get_num_inliers(test_keypoints, test_descriptors, train_keypoints, train_descriptors):\n      \"\"\"Returns the number of RANSAC inliers.\"\"\"\n\n      test_match_kp, train_match_kp = get_putative_matching_keypoints(\n          test_keypoints, test_descriptors, train_keypoints, train_descriptors)\n\n      if test_match_kp.shape[0] <= 4:  # Min keypoints supported by `pydegensac.findHomography()`\n        return 0\n\n      try:\n        _, mask = pydegensac.findHomography(test_match_kp, train_match_kp,\n                                            MAX_REPROJECTION_ERROR,\n                                            HOMOGRAPHY_CONFIDENCE,\n                                            MAX_RANSAC_ITERATIONS)\n      except np.linalg.LinAlgError:  # When det(H)=0, can't invert matrix.\n        return 0\n\n      return int(copy.deepcopy(mask).astype(np.float32).sum())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if n_files<=max_n_samples:\n    best_top_n_vals, best_top_n_idxs = cosine_similarity_chunks(encodings_train, encodings_valid, n_chunks=n_chunks, top_n=n_top_global)\n    p = np.argsort(-best_top_n_vals, axis=0)\n    best_top_n_vals = np.take_along_axis(best_top_n_vals, p, axis=0)\n    best_top_n_idxs = np.take_along_axis(best_top_n_idxs, p, axis=0)\n    predictions_n = np.zeros_like(best_top_n_idxs)\n    confidences_n = best_top_n_vals\n    filenames_n = []\n    \n    for row_idx, row in enumerate(best_top_n_idxs):\n        df_prediction = df_train.iloc[row, :]\n        pred = np.array(df_prediction['landmark_id'].tolist())\n        fnames = np.array(df_prediction['id'].tolist(), dtype=str)\n        predictions_n[row_idx, :] = pred\n        filenames_n.append(fnames)\n    filenames_n = np.array(filenames_n)\n    test_images_names = df_test['id'].tolist()\n    \n    predictions_final = np.zeros(confidences_n.shape[1])\n    confidences_final = np.zeros(confidences_n.shape[1])\n    \n    # Extract local features for test images\n    if calculate_local:\n        test_kp_ds = []\n        for test_img_idx, test_img_name in enumerate(tqdm(test_images_names)):\n            test_img_path = get_image_path('test', test_img_name)\n            test_keypoints, test_descriptors = extract_local_features(test_img_path)\n            curr_n_conf = []\n            if DEBUG and test_img_idx>20:\n                break\n            for train_img_idx, train_img_name in enumerate(filenames_n[:n_top_local, test_img_idx]):\n#                 start_time = time.time()\n                train_img_path = get_image_path('train', train_img_name)\n                train_keypoints, train_descriptors = extract_local_features(train_img_path)\n                n_matching = get_num_inliers(test_keypoints, test_descriptors, train_keypoints, train_descriptors)\n                curr_n_conf.append(n_matching)\n             \n            curr_n_conf = np.array(curr_n_conf)\n            curr_n_pred = predictions_n[:, test_img_idx]\n            \n            pred_i, conf_i = get_max_conf_pred(curr_n_pred, curr_n_conf)\n            if reranking:\n                test_kp_ds.append((test_img_name, test_keypoints, test_descriptors, pred_i, conf_i))\n            predictions_final[test_img_idx] = pred_i\n            confidences_final[test_img_idx] = conf_i\n#             print(f'predisctions size without ranking {predictions_final.shape}')\n#                 print(f'One image in { time.time() - start_time} s')\n        if reranking:\n            print('Start reranking')\n            reranking_eps = 0.01\n            N_rerank_check = min(N_rerank_check, len(test_kp_ds))\n            test_kp_ds.sort(key=lambda data: data[4], reverse=True)\n            test_kp_ds_to_rerank = test_kp_ds[:N_rerank_check]\n            reranked_vals = []\n            reranked_vals_names = []\n            \n            for r_i in tqdm(range(N_rerank_select)):\n                im_i, tk_i, td_i, pr_i, c_i = test_kp_ds_to_rerank[r_i]\n                if im_i in reranked_vals_names:\n                    continue\n                curr_rerank = []\n                reranked_vals.append((im_i, pr_i, c_i))\n                reranked_vals_names.append(im_i)\n\n                for r_j in range(r_i+1, N_rerank_check):\n                    im_j, tk_j, td_j, pr_j, c_j = test_kp_ds_to_rerank[r_j]\n                    if pr_i != pr_j:\n#                         pr_j = pr_i\n                        continue\n                    if im_j in reranked_vals_names:\n                        continue\n                    n_matching = get_num_inliers(tk_i, td_i, tk_j, td_j)\n                    if n_matching < reranking_th:\n                        continue\n                    curr_rerank.append((im_j, pr_j, n_matching))\n\n                curr_rerank.sort(key=lambda data: data[2], reverse=True)\n                for j_j, curr_val in enumerate(curr_rerank):\n                    im_j_j, pr_j_j, c_j_j = curr_val\n                    new_score = c_i - (reranking_eps*j_j)\n                    reranked_vals_names.append(im_j_j)\n                    reranked_vals.append((im_j_j, pr_j_j, new_score))\n            for t_kp_ds in test_kp_ds:\n                im_i, tk_i, td_i, pr_i, c_i = t_kp_ds\n                if im_i in reranked_vals_names:\n                    continue\n                reranked_vals.append((im_i, pr_i, c_i))\n            test_images_names, predictions_final, confidences_final = zip(*reranked_vals)\n            print('Reranking completed')\n    else:\n        for j in range(confidences_n.shape[1]):\n            curr_n_pred = predictions_n[:, j]\n            curr_n_conf = confidences_n[:, j]\n            pred_i, conf_i = get_max_conf_pred(curr_n_pred, curr_n_conf)\n            predictions_final[j] = pred_i\n            confidences_final[j] = conf_i\n        \n    sub_csv = generate_submission_df(test_images_names, predictions_final, confidences_final)\n    sub_csv.to_csv('submission.csv', index=False)\n    \n    print(len(sub_csv))\n    sub_csv.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}