{"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":"#导入相关路径与包","metadata":{}},{"cell_type":"code","source":"pip install timm","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:28.317906Z","iopub.execute_input":"2021-12-28T08:09:28.318365Z","iopub.status.idle":"2021-12-28T08:09:38.901366Z","shell.execute_reply.started":"2021-12-28T08:09:28.318244Z","shell.execute_reply":"2021-12-28T08:09:38.900570Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# pip install pytorch-lightning==1.5.6","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:38.903655Z","iopub.execute_input":"2021-12-28T08:09:38.903952Z","iopub.status.idle":"2021-12-28T08:09:38.907625Z","shell.execute_reply.started":"2021-12-28T08:09:38.903910Z","shell.execute_reply":"2021-12-28T08:09:38.906552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pathlib\nimport torch\nimport torch.utils.data\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport numpy as np\nimport pandas as pd\nfrom random import sample\nimport PIL.Image\nimport albumentations.pytorch\nimport cv2\nimport matplotlib.pyplot as plt\n\nfrom typing import List, Tuple\n\n\n\nBATCH_SIZE = 200\nMAX_IMAGE_PER_CLASS = 4\ndef gpu_unravel(batch):\n        input_dict, target_dict = batch\n        input_dict = {k: input_dict[k].cuda() for k in input_dict}\n        target_dict = {k: target_dict[k].cuda() for k in target_dict}\n        return input_dict, target_dict\ndict_unravel = gpu_unravel\n\nimport sys\nimport importlib\nfrom types import SimpleNamespace\nimport matplotlib.pyplot as plt\nfrom tqdm.notebook import tqdm\nfrom scipy.special import softmax\nfrom joblib import Parallel, delayed\nimport seaborn as sns\nfrom random import sample\n\nname = \"config1\"\n# MODEL_PATH = \"E:/download/.kaggle/results/\"+f\"{name}_ckpt_4.pth\"\n# configPath = '../configs'\nMODEL_PATH = \"/kaggle/input/config1/\"+f\"{name}_ckpt_4.pth\"\nconfigPath = '/kaggle/input/config1'\nsys.path.append(configPath)\n# args = importlib.import_module('config1_test').args #导入对应config中的变量\nargs = importlib.import_module('config1-test').args #导入对应config中的变量\n\nargs =  SimpleNamespace(**args)\n\nargs.img_path_train = args.data_path + 'train/'\nargs.img_path_val = args.data_path_valid + 'valid/'\nargs.img_path_test = args.data_path + 'test/'\n\n","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:38.908907Z","iopub.execute_input":"2021-12-28T08:09:38.909146Z","iopub.status.idle":"2021-12-28T08:09:38.921278Z","shell.execute_reply.started":"2021-12-28T08:09:38.909114Z","shell.execute_reply":"2021-12-28T08:09:38.920529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 削减训练集数量","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv(args.data_path + args.train_csv_fn)\nif len(train_df) == 1580470:# submission use all the training images\n    records = {}\n\n    for image_id, landmark_id in train_df.values:\n        if landmark_id in records:\n            records[landmark_id].append(image_id)\n        else:\n            records[landmark_id] = [image_id]\n        \n    image_ids = []\n    landmark_ids = []\n\n    for landmark_id, img_ids in records.items():\n        num = min(len(img_ids), MAX_IMAGE_PER_CLASS)# maxium two images\n        # image_ids.extend(records[landmark_id][:num])\n        # landmark_ids.extend([landmark_id] * num)\n        image_ids.extend(sample(records[landmark_id],num))\n        landmark_ids.extend([landmark_id] * num)\n\n    train_df = pd.DataFrame({'id': image_ids, 'landmark_id': landmark_ids})\n\ntrain_df[\"img_folder\"] = args.img_path_train\ntrain_df[\"target\"] = 0\n# train_df.to_csv(TRAIN_LABEL_FILE, index=False)\ntrain_df","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:38.922862Z","iopub.execute_input":"2021-12-28T08:09:38.923480Z","iopub.status.idle":"2021-12-28T08:09:43.724371Z","shell.execute_reply.started":"2021-12-28T08:09:38.923442Z","shell.execute_reply":"2021-12-28T08:09:43.723535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 非地标图像","metadata":{}},{"cell_type":"code","source":"valid_df = pd.read_csv(args.data_path_valid+ args.valid_csv_fn)\nvalid_df = valid_df[valid_df['landmark_id'] == -1].reset_index(drop=True)\nvalid_df[\"img_folder\"] = args.img_path_val\nvalid_df[\"target\"] = -1\nvalid_df","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.727238Z","iopub.execute_input":"2021-12-28T08:09:43.727524Z","iopub.status.idle":"2021-12-28T08:09:43.836050Z","shell.execute_reply.started":"2021-12-28T08:09:43.727482Z","shell.execute_reply":"2021-12-28T08:09:43.833635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.read_csv(args.data_path+ 'sample_submission.csv')\ntest_df[\"img_folder\"] = args.img_path_test\ntest_df[\"target\"] = -1\ntest_df=test_df.rename(columns={'landmarks':'landmark_id'})\ntest_df['landmark_id']=-1\ntest_df","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.836831Z","iopub.status.idle":"2021-12-28T08:09:43.837131Z","shell.execute_reply.started":"2021-12-28T08:09:43.836976Z","shell.execute_reply":"2021-12-28T08:09:43.836996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.to_csv('train.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.838503Z","iopub.status.idle":"2021-12-28T08:09:43.839314Z","shell.execute_reply.started":"2021-12-28T08:09:43.839074Z","shell.execute_reply":"2021-12-28T08:09:43.839100Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_df = train_df.iloc[:128,]\n# valid_df = valid_df.iloc[:96,]\n# test_df = test_df.iloc[:96,]","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.840601Z","iopub.status.idle":"2021-12-28T08:09:43.841021Z","shell.execute_reply.started":"2021-12-28T08:09:43.840784Z","shell.execute_reply":"2021-12-28T08:09:43.840807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 数据集类","metadata":{}},{"cell_type":"code","source":"\nfrom torch.utils.data import Dataset, DataLoader, RandomSampler, SequentialSampler\nimport torch \nimport albumentations as A\nimport multiprocessing as mp \nfrom tqdm import tqdm\nimport numpy as np\nimport cv2\n\ndef collate_fn(batch):\n    \n    input_dict = {}\n    target_dict = {}\n    \n    for key in ['input']:\n        input_dict[key] = torch.stack([b[key] for b in batch])\n    for key in ['idx']:\n        input_dict[key] = torch.stack([b[key] for b in batch]).long()   \n    \n    for key in ['target']:\n        target_dict[key] = torch.stack([b[key] for b in batch]).long()\n        \n    return input_dict, target_dict\n\nclass GLRDataset(Dataset):\n\n    def __init__(self, df, suffix='.jpg', preload=False, aug = None, normalization='simple'):\n\n        self.df = df\n        self.aug = aug\n        self.normalization = normalization\n        self.labels = self.df.target.values\n        self.img_folder = self.df.img_folder.values\n        self.suffix = suffix\n        self.image_names = self.df.id.values\n        self.images_cache = {}\n        self.images_in_cache = False\n\n        if preload:\n            self.preload()\n            self.images_in_cache = True\n        self.eps = 1e-6\n\n    def __getitem__(self, idx):\n        id_ = self.image_names[idx]\n        img_folder_ = self.img_folder[idx]\n        \n        if self.images_in_cache:\n            img = self.images_cache[id_]\n        else:\n            img = self.load_one(id_, img_folder_)\n            \n        if self.aug:\n            img = img.astype(np.uint8)\n            img = self.augment(img)\n                \n        img = img.astype(np.float32)       \n        if self.normalization:\n            img = self.normalize_img(img)\n    \n        tensor = self.to_torch_tensor(img)\n        \n        target = torch.tensor(self.labels[idx])\n        feature_dict = {'idx':torch.tensor(idx).long(),\n                        'input':tensor,\n                       'target':target.float()}\n        return feature_dict\n\n    def __len__(self):\n        return len(self.image_names)\n\n\n    def preload(self):\n        if self.n_threads > 1:\n            with mp.Pool(self.n_threads) as p:\n                imgs = p.map(self.load_one,self.id)\n            self.images_cache = dict(zip(self.id, imgs))\n        else:\n            for i in tqdm(self.id):\n                self.images_cache[i] = self.load_one(i)\n\n    def load_one(self, id_, img_folder_):\n        try:\n            img = cv2.imread(img_folder_ + f'{id_[0]}/{id_[1]}/{id_[2]}/{id_}{self.suffix}')\n            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB )\n        except:\n            print(\"FAIL READING IMG\", img_folder_ + f'{id_[0]}/{id_[1]}/{id_[2]}/{id_}{self.suffix}')\n            img = np.zeros((512,512,3), dtype=np.int8)\n        return img\n\n    def augment(self,img):\n        img_aug = self.aug(image=img)['image']\n        return img_aug.astype(np.float32)\n\n    def normalize_img(self,img):\n        \n        if self.normalization == 'channel':\n            pixel_mean = img.mean((0,1))\n            pixel_std = img.std((0,1)) + self.eps\n            img = (img - pixel_mean[None,None,:]) / pixel_std[None,None,:]\n            img = img.clip(-20,20)\n\n        elif self.normalization == 'channel_mean':\n            pixel_mean = img.mean((0,1))\n            img = (img - pixel_mean[None,None,:])\n            img = img.clip(-20,20)\n            \n        elif self.normalization == 'image':\n            img = (img - img.mean()) / img.std() + self.eps\n            img = img.clip(-20,20)\n            \n        elif self.normalization == 'simple':\n            img = img/255\n            \n        elif self.normalization == 'inception':\n            \n            mean = np.array([0.5, 0.5 , 0.5], dtype=np.float32)\n            std = np.array([0.5, 0.5 , 0.5], dtype=np.float32)\n            img = img.astype(np.float32)\n            img = img/255.\n            img -= mean\n            img *= np.reciprocal(std, dtype=np.float32)\n            \n        elif self.normalization == 'imagenet':\n            \n            mean = np.array([123.675, 116.28 , 103.53 ], dtype=np.float32)\n            std = np.array([58.395   , 57.120, 57.375   ], dtype=np.float32)\n            img = img.astype(np.float32)\n            img -= mean\n            img *= np.reciprocal(std, dtype=np.float32)\n            \n        else:\n            pass\n        \n        return img\n    \n    \n    def to_torch_tensor(self,img):\n        return torch.from_numpy(img.transpose((2, 0, 1)))\n    \n","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.843805Z","iopub.status.idle":"2021-12-28T08:09:43.844687Z","shell.execute_reply.started":"2021-12-28T08:09:43.844403Z","shell.execute_reply":"2021-12-28T08:09:43.844431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport random\nimport numpy as np\nimport os\n\nfrom typing import Dict, Tuple, Any\n\nfrom sklearn.metrics import roc_auc_score\nfrom scipy.special import expit, softmax\nfrom sklearn.metrics import precision_score\n\n\n\ndef set_seed(seed=1234):\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 = False\n    torch.backends.cudnn.benchmark = True\n\ndef count_parameters(model):\n    return sum(p.numel() for p in model.parameters() if p.requires_grad)\n\ndef global_average_precision_score(y_true, y_pred, ignore_non_landmarks=False):\n    indexes = np.argsort(y_pred[1])[::-1]\n    queries_with_target = (y_true < args.n_classes).sum()\n    correct_predictions = 0\n    total_score = 0.\n    i = 1\n    # print(\"y_true:\",y_true,\"y_pred\",y_pred)\n    for k in indexes:\n        if ignore_non_landmarks and y_true[k] == args.n_classes:\n            continue\n        if y_pred[0][k] == args.n_classes:\n            continue\n        relevance_of_prediction_i = 0\n        if y_true[k] == y_pred[0][k]:\n            correct_predictions += 1\n            relevance_of_prediction_i = 1\n        precision_at_rank_i = correct_predictions / i\n        total_score += precision_at_rank_i * relevance_of_prediction_i\n        i += 1\n    return 1 / queries_with_target * total_score\n\ndef comp_metric(y_true, logits, ignore_non_landmarks=False):\n    \n    score = global_average_precision_score(y_true, logits, ignore_non_landmarks=ignore_non_landmarks)\n    return score\n\ndef cos_similarity_matrix(a, b, eps=1e-8):\n    a_n, b_n = a.norm(dim=1)[:, None], b.norm(dim=1)[:, None]\n    a_norm = a / torch.max(a_n, eps * torch.ones_like(a_n))\n    b_norm = b / torch.max(b_n, eps * torch.ones_like(b_n))\n    sim_mt = torch.mm(a_norm, b_norm.transpose(0, 1))\n    return sim_mt\n\ndef get_topk_cossim(test_emb, tr_emb, batchsize = 64, k=10, device='cuda:0',verbose=True):\n    tr_emb = torch.tensor(tr_emb, dtype = torch.float32, device=torch.device(device))\n    test_emb = torch.tensor(test_emb, dtype = torch.float32, device=torch.device(device))\n    vals = []\n    inds = []\n\n    for test_batch in test_emb.split(batchsize):\n        sim_mat = cos_similarity_matrix(test_batch, tr_emb)\n        vals_batch, inds_batch = torch.topk(sim_mat, k=k, dim=1)\n        vals += [vals_batch.detach().cpu()]\n        inds += [inds_batch.detach().cpu()]\n    vals = torch.cat(vals)\n    inds = torch.cat(inds)\n    return vals, inds\ndef get_topk_cossim_sub(test_emb, tr_emb, vals_x, batchsize = 64, k=10, device='cuda:0',verbose=True):\n    tr_emb = torch.tensor(tr_emb, dtype = torch.float32, device=torch.device(device))\n    test_emb = torch.tensor(test_emb, dtype = torch.float32, device=torch.device(device))\n    vals_x = torch.tensor(vals_x, dtype = torch.float32, device=torch.device(device))\n    vals = []\n    inds = []\n    for test_batch in tqdm(test_emb.split(batchsize),disable=1-verbose):\n        sim_mat = cos_similarity_matrix(test_batch, tr_emb)\n        sim_mat = torch.clamp(sim_mat,0,1) - vals_x.repeat(sim_mat.shape[0], 1)\n        \n        vals_batch, inds_batch = torch.topk(sim_mat, k=k, dim=1)\n        vals += [vals_batch.detach().cpu()]\n        inds += [inds_batch.detach().cpu()]\n    vals = torch.cat(vals)\n    inds = torch.cat(inds)\n    return vals, inds","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.845975Z","iopub.status.idle":"2021-12-28T08:09:43.846548Z","shell.execute_reply.started":"2021-12-28T08:09:43.846308Z","shell.execute_reply":"2021-12-28T08:09:43.846333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#from pytorchcv.model_provider import get_model as ptcv_get_model\nimport timm\nfrom torch import nn\n\nimport math\nimport torch\nfrom torch.nn import functional as F\nfrom torch.nn.parameter import Parameter\n\nclass ArcMarginProduct(nn.Module):\n    def __init__(self, in_features, out_features):\n        super().__init__()\n        self.weight = nn.Parameter(torch.Tensor(out_features, in_features))\n        self.reset_parameters()\n\n    def reset_parameters(self):\n        nn.init.xavier_uniform_(self.weight)\n        # stdv = 1. / math.sqrt(self.weight.size(1))\n        # self.weight.data.uniform_(-stdv, stdv)\n\n    def forward(self, features):\n        cosine = F.linear(F.normalize(features), F.normalize(self.weight))\n        return cosine\n\ndef gem(x, p=3, eps=1e-6):\n    return F.avg_pool2d(x.clamp(min=eps).pow(p), (x.size(-2), x.size(-1))).pow(1./p)\n\nclass GeM(nn.Module):\n    def __init__(self, p=3, eps=1e-6, p_trainable=True):\n        super(GeM,self).__init__()\n        if p_trainable:\n            self.p = Parameter(torch.ones(1)*p)\n        else:\n            self.p = p\n        self.eps = eps\n\n    def forward(self, x):\n        return gem(x, p=self.p, eps=self.eps)       \n    def __repr__(self):\n        return self.__class__.__name__ + '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + ', ' + 'eps=' + str(self.eps) + ')'\n\n    \nclass Backbone(nn.Module):\n\n    \n    def __init__(self, name='resnet18', pretrained=True,checkpoint_path=''):\n        super(Backbone, self).__init__()\n\n        self.net = timm.create_model(name, pretrained=pretrained,checkpoint_path=checkpoint_path)\n        \n        if 'regnet' in name:\n            self.out_features = self.net.head.fc.in_features\n        elif 'csp' in name:\n            self.out_features = self.net.head.fc.in_features\n        elif 'res' in name: #works also for resnest\n            self.out_features = self.net.fc.in_features\n        elif 'efficientnet' in name:\n            self.out_features = self.net.classifier.in_features\n        elif 'densenet' in name:\n            self.out_features = self.net.classifier.in_features\n        elif 'senet' in name:\n            self.out_features = self.net.fc.in_features\n        elif 'inception' in name:\n            self.out_features = self.net.last_linear.in_features\n\n        else:\n            self.out_features = self.net.classifier.in_features\n\n    def forward(self, x):\n        x = self.net.forward_features(x)\n\n        return x\n\n    \nclass Net(nn.Module):\n    def __init__(self, args, pretrained=False):\n        super(Net, self).__init__()\n        \n        self.args = args\n        self.backbone = Backbone(args.backbone, pretrained=pretrained,checkpoint_path=args.checkpoint_path)\n        \n        if args.pool == \"gem\":\n            self.global_pool = GeM(p_trainable=args.p_trainable)\n        elif args.pool == \"identity\":\n            self.global_pool = torch.nn.Identity()\n        else:\n            self.global_pool = nn.AdaptiveAvgPool2d(1)\n\n        self.embedding_size = args.embedding_size        \n        \n        # https://www.groundai.com/project/arcface-additive-angular-margin-loss-for-deep-face-recognition\n        if args.neck == \"option-D\":\n            self.neck = nn.Sequential(\n                nn.Linear(self.backbone.out_features, self.embedding_size, bias=True),\n                nn.BatchNorm1d(self.embedding_size),\n                torch.nn.PReLU()\n            )\n        elif args.neck == \"option-F\":\n            self.neck = nn.Sequential(\n                nn.Dropout(0.3),\n                nn.Linear(self.backbone.out_features, self.embedding_size, bias=True),\n                nn.BatchNorm1d(self.embedding_size),\n                torch.nn.PReLU()\n            )\n        else:\n            self.neck = nn.Sequential(\n                nn.Linear(self.backbone.out_features, self.embedding_size, bias=False),\n                nn.BatchNorm1d(self.embedding_size),\n            )\n            \n        self.head = ArcMarginProduct(self.embedding_size, args.n_classes)\n        \n        if args.pretrained_weights is not None:\n            self.load_state_dict(torch.load(args.pretrained_weights, map_location='cpu'), strict=False)\n            print('weights loaded from',args.pretrained_weights)\n\n    def forward(self, input_dict, get_embeddings=False, get_attentions=False):\n\n        x = input_dict['input']\n        # print(\"input\",x)\n        x = self.backbone(x)\n        # print(\"after backbone\",x)\n        x = self.global_pool(x)\n        x = x[:,:,0,0]\n        # print(\"after pool\",x)\n        x = self.neck(x)\n        # print(\"embedding\",x)\n        logits = self.head(x)\n        \n        if get_embeddings:\n            return {'logits': logits, 'embeddings': x}\n        else:\n            return {'logits': logits}","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.848003Z","iopub.status.idle":"2021-12-28T08:09:43.848594Z","shell.execute_reply.started":"2021-12-28T08:09:43.848356Z","shell.execute_reply":"2021-12-28T08:09:43.848380Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 获得embedding","metadata":{}},{"cell_type":"code","source":"def get_embeddings(dl, model):\n    with torch.no_grad():\n        # embeddings = np.zeros((len(dl.dataset) , 512))\n\n        out_list=[]\n        total = len(dl)\n        # for idx, batch in tqdm(enumerate(dl), total=len(dl)):\n        for idx, batch in tqdm(enumerate(dl),total=len(dl)):\n            \n            # print(\"idx:\",idx)\n            input_dict, target_dict = dict_unravel(batch)\n            outs = model.forward(input_dict, get_embeddings=True)[\"embeddings\"]\n            # embeddings[idx*BATCH_SIZE:idx*BATCH_SIZE+outs.size(0),:] = outs.detach().cpu().numpy()\n\n            out_dict={}\n            out_dict['idx']=input_dict['idx']\n            out_dict['embeddings']=outs\n            out_list.append(out_dict)\n\n    return out_list","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.849905Z","iopub.status.idle":"2021-12-28T08:09:43.850779Z","shell.execute_reply.started":"2021-12-28T08:09:43.850524Z","shell.execute_reply":"2021-12-28T08:09:43.850549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"aug = args.test_aug","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.851862Z","iopub.status.idle":"2021-12-28T08:09:43.852771Z","shell.execute_reply.started":"2021-12-28T08:09:43.852526Z","shell.execute_reply":"2021-12-28T08:09:43.852550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr_ds = GLRDataset(train_df, normalization=args.normalization, aug=aug)\ntr_dl = DataLoader(dataset=tr_ds,\n                    batch_size=BATCH_SIZE,\n                    sampler=SequentialSampler(tr_ds), collate_fn=collate_fn, num_workers=2, pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.853829Z","iopub.status.idle":"2021-12-28T08:09:43.854700Z","shell.execute_reply.started":"2021-12-28T08:09:43.854457Z","shell.execute_reply":"2021-12-28T08:09:43.854481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_ds = GLRDataset(valid_df, normalization=args.normalization, aug=aug)\nval_dl = DataLoader(dataset=val_ds,\n                    batch_size=BATCH_SIZE,\n                    sampler=SequentialSampler(val_ds), collate_fn=collate_fn, num_workers=2, pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.855768Z","iopub.status.idle":"2021-12-28T08:09:43.856637Z","shell.execute_reply.started":"2021-12-28T08:09:43.856394Z","shell.execute_reply":"2021-12-28T08:09:43.856419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_ds = GLRDataset(test_df, normalization=args.normalization, aug=aug)\ntest_dl = DataLoader(dataset=test_ds,\n                    batch_size=BATCH_SIZE,\n                    sampler=SequentialSampler(test_ds), collate_fn=collate_fn, num_workers=2, pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.857702Z","iopub.status.idle":"2021-12-28T08:09:43.858513Z","shell.execute_reply.started":"2021-12-28T08:09:43.858285Z","shell.execute_reply":"2021-12-28T08:09:43.858309Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inference and submission","metadata":{}},{"cell_type":"code","source":"t_m = torch.load(MODEL_PATH)\nargs.n_classes = t_m['head.weight'].shape[0]\nmodel = Net(args)\nmodel.eval()\nmodel.cuda()\nmodel.load_state_dict(t_m)","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.859562Z","iopub.status.idle":"2021-12-28T08:09:43.860432Z","shell.execute_reply.started":"2021-12-28T08:09:43.860199Z","shell.execute_reply":"2021-12-28T08:09:43.860223Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr_eb = get_embeddings(tr_dl, model)\nval_eb = get_embeddings(val_dl, model)\ntest_eb = get_embeddings(test_dl, model)","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.861471Z","iopub.status.idle":"2021-12-28T08:09:43.862266Z","shell.execute_reply.started":"2021-12-28T08:09:43.862022Z","shell.execute_reply":"2021-12-28T08:09:43.862048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def con_eb(d):\n    out_val={}\n    for key in d[0].keys():\n        out_val[key] = torch.cat([o[key]  for o in d])\n    return out_val","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.863486Z","iopub.status.idle":"2021-12-28T08:09:43.864296Z","shell.execute_reply.started":"2021-12-28T08:09:43.863997Z","shell.execute_reply":"2021-12-28T08:09:43.864024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"out_tr = con_eb(tr_eb)\nout_val = con_eb(val_eb)\nout_test =con_eb(test_eb)\nfor key in out_tr:\n    out_tr[key]=out_tr[key].detach().cpu().numpy().astype(np.float32)\nfor key in out_val:\n   out_val[key]=out_val[key].detach().cpu().numpy().astype(np.float32)\nfor key in out_val:\n   out_test[key]=out_test[key].detach().cpu().numpy().astype(np.float32)\n","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.865769Z","iopub.status.idle":"2021-12-28T08:09:43.866196Z","shell.execute_reply.started":"2021-12-28T08:09:43.865964Z","shell.execute_reply":"2021-12-28T08:09:43.865988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr_idx = out_tr['idx']\nval_idx =out_val['idx']","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.867510Z","iopub.status.idle":"2021-12-28T08:09:43.867964Z","shell.execute_reply.started":"2021-12-28T08:09:43.867709Z","shell.execute_reply":"2021-12-28T08:09:43.867734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr_names = train_df['landmark_id'][tr_idx].values\nval_names = valid_df['landmark_id'][val_idx].values\ntest_names = test_df['id'].values","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.870465Z","iopub.status.idle":"2021-12-28T08:09:43.871114Z","shell.execute_reply.started":"2021-12-28T08:09:43.870880Z","shell.execute_reply":"2021-12-28T08:09:43.870905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr_embeddings = out_tr['embeddings']\nnonlandmark_embeddings = out_val['embeddings']\ntest_embeddings = out_test['embeddings']","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.872167Z","iopub.status.idle":"2021-12-28T08:09:43.872701Z","shell.execute_reply.started":"2021-12-28T08:09:43.872460Z","shell.execute_reply":"2021-12-28T08:09:43.872485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.decomposition import PCA\nfrom sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler, QuantileTransformer\nfrom sklearn.random_projection import GaussianRandomProjection\n\nf = QuantileTransformer(output_distribution=\"normal\")\n\nf.fit(np.concatenate([test_embeddings],axis=0))\n\n\ntr_embeddings = f.transform(tr_embeddings)\nnonlandmark_embeddings = f.transform(nonlandmark_embeddings)\ntest_embeddings = f.transform(test_embeddings)","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.874123Z","iopub.status.idle":"2021-12-28T08:09:43.875005Z","shell.execute_reply.started":"2021-12-28T08:09:43.874752Z","shell.execute_reply":"2021-12-28T08:09:43.874776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\nEMB_SIZE = 512\nvals_blend = []\nlabels_blend = []\ninds_blend = []\nvals_nl, inds_nl = get_topk_cossim(tr_embeddings, nonlandmark_embeddings, k=5)\nvals_nl = vals_nl[:,:].mean(axis=1).detach().cpu().numpy()\n\nvals, inds = get_topk_cossim_sub(test_embeddings, tr_embeddings, vals_nl, k=3)\nvals = vals.data.cpu().numpy()\ninds = inds.data.cpu().numpy()\n# labels = np.concatenate([targets_train[inds[:,i]].reshape(-1,1) for i in range(inds.shape[1])], axis=1)\nlabels = tr_names[inds]\nvals_blend.append(vals)\nlabels_blend.append(labels)\ninds_blend.append(inds)","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.876085Z","iopub.status.idle":"2021-12-28T08:09:43.876814Z","shell.execute_reply.started":"2021-12-28T08:09:43.876578Z","shell.execute_reply":"2021-12-28T08:09:43.876602Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from collections import defaultdict\n\nvals_new = []\nlabels_new = []\n\nfor i in tqdm(range(len(vals))):\n    cnts = defaultdict(list)\n\n    x = 0\n    for j,l in enumerate(labels[i,:]):\n\n        curr = vals[i][j]\n\n        cnts[l].append(curr)\n\n    for k,v in cnts.items():\n        cnts[k] = np.sum(v)\n        \n    labels_new.append(max(cnts, key=cnts.get))\n    vals_new.append(cnts[labels_new[-1]])\n        \nl = np.array(labels_new).reshape(-1)\nv = np.array(vals_new).reshape(-1)","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.878042Z","iopub.status.idle":"2021-12-28T08:09:43.878789Z","shell.execute_reply.started":"2021-12-28T08:09:43.878548Z","shell.execute_reply":"2021-12-28T08:09:43.878573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vals_2, inds_2 = get_topk_cossim(test_embeddings, nonlandmark_embeddings, k=11)\n# starting from index 1 on val as index 0 is the same image\nvals_2 = vals_2[:,1:].mean(axis=1).detach().cpu().numpy()","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.879991Z","iopub.status.idle":"2021-12-28T08:09:43.880871Z","shell.execute_reply.started":"2021-12-28T08:09:43.880607Z","shell.execute_reply":"2021-12-28T08:09:43.880641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import scipy as sp\n\nl3 = pd.Series(l.copy()).reset_index(drop=True)\nv3 = v.copy()\n\nv3 -= 1*vals_2","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.881950Z","iopub.status.idle":"2021-12-28T08:09:43.882900Z","shell.execute_reply.started":"2021-12-28T08:09:43.882583Z","shell.execute_reply":"2021-12-28T08:09:43.882607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"max_conf = max(v3)\nmin_conf = min(v3)\nsubmit_confidences = [\n    (v - min_conf) / (max_conf - min_conf) for v in v3]","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.884149Z","iopub.status.idle":"2021-12-28T08:09:43.885155Z","shell.execute_reply.started":"2021-12-28T08:09:43.884884Z","shell.execute_reply":"2021-12-28T08:09:43.884913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit_ids=[]\nsubmit_landmark_ids = []\nfor i in l3.values:\n    submit_landmark_ids.append(i)\nfor i in test_names:\n    submit_ids.append(i)","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.886282Z","iopub.status.idle":"2021-12-28T08:09:43.887156Z","shell.execute_reply.started":"2021-12-28T08:09:43.886920Z","shell.execute_reply":"2021-12-28T08:09:43.886945Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nsubmit_landmarks = [\n        f'{i} {c:.8f}' for i, c in zip(submit_landmark_ids, submit_confidences)]\n        ","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.888223Z","iopub.status.idle":"2021-12-28T08:09:43.888967Z","shell.execute_reply.started":"2021-12-28T08:09:43.888731Z","shell.execute_reply":"2021-12-28T08:09:43.888756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit_df = pd.DataFrame({'id': submit_ids, 'landmarks': submit_landmarks})\nsubmit_df","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.890214Z","iopub.status.idle":"2021-12-28T08:09:43.891086Z","shell.execute_reply.started":"2021-12-28T08:09:43.890854Z","shell.execute_reply":"2021-12-28T08:09:43.890879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.892146Z","iopub.status.idle":"2021-12-28T08:09:43.892890Z","shell.execute_reply.started":"2021-12-28T08:09:43.892640Z","shell.execute_reply":"2021-12-28T08:09:43.892664Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vals_2_s=vals_2.reshape(len(vals_2),1)\nvals_2_s=vals_2_s.repeat(vals.shape[1],1)\no_vals = vals -vals_2_s\n\nout_summary={}\nout_summary['labels']=labels\nout_summary['vals']=o_vals\nout_summary['tr_eb']=tr_eb\nout_summary['val_eb']=val_eb\nout_summary['test_eb']=test_eb","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.894168Z","iopub.status.idle":"2021-12-28T08:09:43.894924Z","shell.execute_reply.started":"2021-12-28T08:09:43.894666Z","shell.execute_reply":"2021-12-28T08:09:43.894691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pickle\nwith open('out_summary.p', 'wb') as handle:\n    pickle.dump(out_summary, handle)","metadata":{"execution":{"iopub.status.busy":"2021-12-28T08:09:43.896151Z","iopub.status.idle":"2021-12-28T08:09:43.896903Z","shell.execute_reply.started":"2021-12-28T08:09:43.896648Z","shell.execute_reply":"2021-12-28T08:09:43.896673Z"},"trusted":true},"execution_count":null,"outputs":[]}]}