{"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":"code","source":"!pip install timm\n\nimport os\nimport gc\nimport cv2\nimport math\nimport copy\nimport time\nimport random\n\n# For data manipulation\nimport numpy as np\nimport pandas as pd\n\n# Pytorch Imports\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.optim import lr_scheduler\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.cuda import amp\n\n# Utils\nimport joblib\nfrom tqdm import tqdm\nfrom collections import defaultdict\n\n# For Image Models\nimport timm\nfrom math import cos, pi\n\n# Albumentations for augmentations\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\n\nimport torch.cuda.amp as amp\n\n# For colored terminal text\nfrom colorama import Fore, Back, Style\nb_ = Fore.BLUE\nsr_ = Style.RESET_ALL\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\n# For descriptive error messages\n#os.environ['CUDA_LAUNCH_BLOCKING'] = \"1\"\nos.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0\"","metadata":{"execution":{"iopub.status.busy":"2022-04-16T15:50:08.592799Z","iopub.execute_input":"2022-04-16T15:50:08.593329Z","iopub.status.idle":"2022-04-16T15:50:22.625463Z","shell.execute_reply.started":"2022-04-16T15:50:08.593211Z","shell.execute_reply":"2022-04-16T15:50:22.624596Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model_name:b7\n#img_size:384\n#weights:\n#in_features\n#test_df\nclass Config(object):\n      version = \"merge\"\n      model_name = \"tf_efficientnet_b7\"\n      #model_name = 'seresnext50_32x4d'\n      seed = 2022\n      img_size = (512,512)\n\n      num_classes = 15587\n    \n      valid_batch_size = 10\n\n\n      #input\n      TEST_DIR = '../input/backfin-test-new/test_images/'\n      TRAIN_DIR = '../input/backfin-train-new/train_images/'\n\n      train_csv = \"../input/train-csv-new/train_box_clear.csv\" \n      label_path = \"../input/happywhalelabel/label.csv\"   \n      sample_submission = \"../input/happy-whale-and-dolphin/sample_submission.csv\"\n      work_dirs = \"./\"\n\n      n_fold = 5\n      num_workers = 2\n\n      # ArcFace Hyperparametes\n      s = 30.0\n      m = 0.50\n      ls_eps = 0.0\n      easy_margin = False\n    \n      KNN = 100\n        \n      device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n\n\n\n\n    \nCONFIG = Config()\nprint (CONFIG.device)\n\ndef set_seed(seed=42):\n    '''Sets the seed of the entire notebook so results are the same every time we run.\n    This is for REPRODUCIBILITY.'''\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    # When running on the CuDNN backend, two further options must be set\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n    # Set a fixed value for the hash seed","metadata":{"execution":{"iopub.status.busy":"2022-04-16T15:50:22.629308Z","iopub.execute_input":"2022-04-16T15:50:22.629528Z","iopub.status.idle":"2022-04-16T15:50:22.692203Z","shell.execute_reply.started":"2022-04-16T15:50:22.629502Z","shell.execute_reply":"2022-04-16T15:50:22.69135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_transforms = {\n    \"train\": A.Compose([\n        A.Resize(CONFIG.img_size[1], CONFIG.img_size[0]),\n        A.HueSaturationValue(p=0.5, hue_shift_limit=20, sat_shift_limit=30, val_shift_limit=50),\n        A.HorizontalFlip(),\n        A.GaussianBlur(),\n        A.RandomBrightnessContrast(p=0.5),\n        A.ShiftScaleRotate(),\n        A.Normalize(\n            mean=[0.485, 0.456, 0.406],\n            std=[0.229, 0.224, 0.225],\n            max_pixel_value=255.0,\n            p=1.0\n        ),\n        ToTensorV2()], p=1.),\n\n    \"test\": A.Compose([\n        A.Resize(CONFIG.img_size[1], CONFIG.img_size[0]),\n        A.Normalize(\n            mean=[0.485, 0.456, 0.406],\n            std=[0.229, 0.224, 0.225],\n            max_pixel_value=255.0,\n            p=1.0\n        ),\n        ToTensorV2()], p=1.),\n    \"test_flip\": A.Compose([\n        A.Resize(CONFIG.img_size[1], CONFIG.img_size[0]),\n        A.HorizontalFlip(p=1.0),\n        A.Normalize(\n            mean=[0.485, 0.456, 0.406],\n            std=[0.229, 0.224, 0.225],\n            max_pixel_value=255.0,\n            p=1.0\n        ),\n        ToTensorV2()], p=1.),\n    \n    \"test_rotate\": A.Compose([\n        A.Resize(CONFIG.img_size[1], CONFIG.img_size[0]),\n        A.ShiftScaleRotate(p=1.0),\n        A.Normalize(\n            mean=[0.485, 0.456, 0.406],\n            std=[0.229, 0.224, 0.225],\n            max_pixel_value=255.0,\n            p=1.0\n        ),\n        ToTensorV2()], p=1.)\n}","metadata":{"execution":{"iopub.status.busy":"2022-04-16T15:50:22.693908Z","iopub.execute_input":"2022-04-16T15:50:22.696361Z","iopub.status.idle":"2022-04-16T15:50:22.708801Z","shell.execute_reply.started":"2022-04-16T15:50:22.696328Z","shell.execute_reply":"2022-04-16T15:50:22.708094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class HappyWhaleDataset(Dataset):\n    def __init__(self, df, model = \"test_valid\", transforms=None, df_boxes = None):\n        self.model = model\n        if model not in [\"test_valid\", \"test\", \"test_tta\"]:\n            assert False, f\"{model} is not in [test_valid, test, test_tta]\"\n\n        self.file_paths = df['file_path'].values\n        #self.check_image_path()\n\n        if self.model in [\"test_valid\"]:\n            self.labels = df['individual_id'].values\n\n        if self.model in [\"test\", \"test_tta\"]:\n            self.labels = [-1] * len(self.file_paths)\n\n\n        self.transforms = transforms\n\n\n    def check_image_path(self):\n        for file in self.file_paths:\n            if not os.path.exists(file):\n                print (file + \" if not exists!\")\n        print (\"check over!\")\n        return\n\n\n\n    def __len__(self):\n        return len(self.labels)\n\n\n\n    def __getitem__(self, index):\n        img_path = self.file_paths[index]\n        label = int(self.labels[index])\n        img_name = img_path.split('/')[-1]\n        img_name = img_name.split(\"_\")[-1]\n\n        img = cv2.imread(img_path)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        \n        '''\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n        img = np.expand_dims(img, axis=2)\n        img = np.concatenate((img, img, img), axis=-1)\n        '''\n        img1 = self.transforms(image=img)[\"image\"]\n        if self.model in [\"test_valid\", \"test\"]:\n            return img1, label, img_name\n        if self.model == \"test_tta\":\n            img2 = data_transforms[\"test_flip\"](image=img)[\"image\"]\n            img3 = data_transforms[\"test_rotate\"](image=img)[\"image\"]\n            return img1, label, img_name, img2, img3","metadata":{"execution":{"iopub.status.busy":"2022-04-16T15:50:22.710951Z","iopub.execute_input":"2022-04-16T15:50:22.712618Z","iopub.status.idle":"2022-04-16T15:50:22.725478Z","shell.execute_reply.started":"2022-04-16T15:50:22.712588Z","shell.execute_reply":"2022-04-16T15:50:22.724695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#GeM Pooling\nclass GeM(nn.Module):\n    def __init__(self, p=3, eps=1e-6):\n        super(GeM, self).__init__()\n        self.p = nn.Parameter(torch.ones(1) * p)\n        self.eps = eps\n\n    def forward(self, x):\n        return self.gem(x, p=self.p, eps=self.eps)\n\n    def gem(self, 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\n    def __repr__(self):\n        return self.__class__.__name__ + \\\n               '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + \\\n               ', ' + 'eps=' + str(self.eps) + ')'\n","metadata":{"execution":{"iopub.status.busy":"2022-04-16T15:50:22.72764Z","iopub.execute_input":"2022-04-16T15:50:22.72786Z","iopub.status.idle":"2022-04-16T15:50:22.737641Z","shell.execute_reply.started":"2022-04-16T15:50:22.727824Z","shell.execute_reply":"2022-04-16T15:50:22.736806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def cosine_sim(x1, x2, dim=1, eps=1e-8):\n    ip = torch.mm(x1, x2.t())\n    w1 = torch.norm(x1, 2, dim)\n    w2 = torch.norm(x2, 2, dim)\n    return ip / torch.ger(w1,w2).clamp(min=eps)\n\nclass CosMarginProduct(nn.Module):\n    r\"\"\"Implement of large margin cosine distance: :\n    Args:\n        in_features: size of each input sample\n        out_features: size of each output sample\n        s: norm of input feature\n        m: margin\n    \"\"\"\n\n    def __init__(self, in_features, out_features, s=30.0, m=0.40):\n        super(CosMarginProduct, self).__init__()\n        self.in_features = in_features\n        self.out_features = out_features\n        self.s = s\n        self.m = m\n        self.weight = nn.Parameter(torch.FloatTensor(out_features, in_features))\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, input, label):\n        cosine = cosine_sim(input, self.weight)\n        # cosine = F.linear(F.normalize(input), F.normalize(self.weight))\n        # --------------------------- convert label to one-hot ---------------------------\n        # https://discuss.pytorch.org/t/convert-int-into-one-hot-format/507\n        one_hot = torch.zeros_like(cosine)\n        one_hot.scatter_(1, label.view(-1, 1), 1.0)\n        # -------------torch.where(out_i = {x_i if condition_i else y_i) -------------\n        output = self.s * (cosine - one_hot * self.m)\n\n        return output\n\n\nclass ArcMarginProduct(nn.Module):\n    r\"\"\"Implement of large margin arc distance: :\n        Args:\n            in_features: size of each input sample\n            out_features: size of each output sample\n            s: norm of input feature\n            m: margin\n            cos(theta + m)\n        \"\"\"\n    def __init__(self, in_features, out_features, s=30.0,\n                 m=0.50, easy_margin=False, ls_eps=0.0):\n        super(ArcMarginProduct, self).__init__()\n        self.in_features = in_features\n        self.out_features = out_features\n        self.s = s\n        self.m = m\n        self.ls_eps = ls_eps  # label smoothing\n        self.weight = nn.Parameter(torch.FloatTensor(out_features, in_features))\n        nn.init.xavier_uniform_(self.weight)\n\n        self.easy_margin = easy_margin\n        self.cos_m = math.cos(m)\n        self.sin_m = math.sin(m)\n        self.th = math.cos(math.pi - m)\n        self.mm = math.sin(math.pi - m) * m\n\n    def forward(self, input, label):\n        # --------------------------- cos(theta) & phi(theta) ---------------------\n        cosine = F.linear(F.normalize(input), F.normalize(self.weight))\n        sine = torch.sqrt(1.0 - torch.pow(cosine, 2))\n        phi = cosine * self.cos_m - sine * self.sin_m\n        if self.easy_margin:\n            phi = torch.where(cosine > 0, phi, cosine)\n        else:\n            phi = torch.where(cosine.to(dtype=phi.dtype) > self.th, phi, cosine.to(dtype=phi.dtype) - self.mm)\n        # --------------------------- convert label to one-hot ---------------------\n        # one_hot = torch.zeros(cosine.size(), requires_grad=True, device='cuda')\n        one_hot = torch.zeros(cosine.size(), device=CONFIG.device)\n        one_hot.scatter_(1, label.view(-1, 1).long(), 1)\n        if self.ls_eps > 0:\n            one_hot = (1 - self.ls_eps) * one_hot + self.ls_eps / self.out_features\n        # -------------torch.where(out_i = {x_i if condition_i else y_i) ------------\n        output = (one_hot * phi) + ((1.0 - one_hot) * cosine)\n        output *= self.s\n\n        return output\n\n\n\ndef l2_norm(input,axis=1):\n    norm = torch.norm(input,2,axis,True)\n    output = torch.div(input, norm)\n    return output\n\n#binary\nclass BinaryHead(nn.Module):\n\n    def __init__(self, emb_size = 2048, num_class=10008,  s = 16.0):\n        super(BinaryHead,self).__init__()\n        self.s = s\n        self.fc = nn.Sequential(nn.Linear(emb_size, num_class))\n\n    def forward(self, fea):\n        fea = l2_norm(fea)\n        logit = self.fc(fea)*self.s\n        return logit\n\n#arc\nclass ArcMarginHead(nn.Module):\n    def __init__(self, embedding_size, num_classes):\n        super(ArcMarginHead, self).__init__()\n        self.arc = ArcMarginProduct(embedding_size, num_classes)\n\n    def forward(self, fea, label):\n        logit = self.arc(fea, label)\n        return logit\n\n#cos\nclass CosMarginHead(nn.Module):\n    def __init__(self, embedding_size, num_classes):\n        super(CosMarginHead, self).__init__()\n        self.cos = CosMarginProduct(embedding_size, num_classes)\n\n    def forward(self, fea, label):\n        logit = self.cos(fea, label)\n        return logit","metadata":{"execution":{"iopub.status.busy":"2022-04-16T15:50:22.73919Z","iopub.execute_input":"2022-04-16T15:50:22.739461Z","iopub.status.idle":"2022-04-16T15:50:22.765479Z","shell.execute_reply.started":"2022-04-16T15:50:22.739429Z","shell.execute_reply":"2022-04-16T15:50:22.764688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndef l2_norm(input,axis=1):\n    norm = torch.norm(input,2,axis,True)\n    output = torch.div(input, norm)\n    return output\n\n#attention\nclass ChannelAttention(nn.Module):\n    def __init__(self, channel, reduction):\n        super().__init__()\n        self.maxpool = nn.AdaptiveMaxPool2d(1)\n        self.avgpool = nn.AdaptiveAvgPool2d(1)\n        self.se = nn.Sequential(\n            nn.Conv2d(channel, channel // reduction, 1, bias=False),\n            nn.ReLU(),\n            nn.Conv2d(channel // reduction, channel, 1, bias=False)\n        )\n        self.sigmoid = nn.Sigmoid()\n\n    def forward(self, x):\n        max_result = self.maxpool(x)\n        avg_result = self.avgpool(x)\n        max_out = self.se(max_result)\n        avg_out = self.se(avg_result)\n        output = self.sigmoid(max_out + avg_out)\n        return output\n    \nclass SpatialAttention(nn.Module):\n    def __init__(self, kernel_size=3):\n        super().__init__()\n        self.conv = nn.Conv2d(2, 1, kernel_size=kernel_size, padding=(kernel_size -1) // 2)\n        self.sigmoid = nn.Sigmoid()\n\n    def forward(self, x):\n        max_result, _ = torch.max(x, dim=1, keepdim=True)\n        avg_result = torch.mean(x, dim=1, keepdim=True)\n        result = torch.cat([max_result, avg_result], 1)\n        output = self.conv(result)\n        output = self.sigmoid(output)\n        return output\n\n    \nclass CBAMBlock(nn.Module):\n\n    def __init__(self, channel, reduction):\n        super().__init__()\n        self.ca = ChannelAttention(channel=channel, reduction=reduction)\n        self.sa = SpatialAttention()\n\n    def init_weights(self):\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                init.kaiming_normal_(m.weight, mode='fan_out')\n                if m.bias is not None:\n                    init.constant_(m.bias, 0)\n            elif isinstance(m, nn.BatchNorm2d):\n                init.constant_(m.weight, 1)\n                init.constant_(m.bias, 0)\n            elif isinstance(m, nn.Linear):\n                init.normal_(m.weight, std=0.001)\n                if m.bias is not None:\n                    init.constant_(m.bias, 0)\n    def forward(self, x):\n        b, c, _, _ = x.size()\n        residual = x\n        out = x * self.ca(x)\n        out = out * self.sa(out)\n        return out + residual ","metadata":{"execution":{"iopub.status.busy":"2022-04-16T15:50:22.766863Z","iopub.execute_input":"2022-04-16T15:50:22.767152Z","iopub.status.idle":"2022-04-16T15:50:22.784968Z","shell.execute_reply.started":"2022-04-16T15:50:22.767117Z","shell.execute_reply":"2022-04-16T15:50:22.784081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class HappyWhaleModel(nn.Module):\n    def __init__(self, model_name, pretrained=False):\n        super(HappyWhaleModel, self).__init__()\n        self.model = timm.create_model(model_name, pretrained=pretrained)\n\n        if model_name in[\"tf_efficientnet_b5\",\"tf_efficientnet_b6\",\"tf_efficientnet_b7\"]:\n            in_features = self.model.classifier.in_features\n            self.model.classifier = nn.Identity()\n            self.model.global_pool = nn.Identity()\n            print (model_name)\n        elif model_name == 'seresnext50_32x4d':\n            in_features = self.model.fc.in_features\n            self.model.global_pool = nn.Identity()\n            self.model.fc = nn.Identity()\n            for param in self.model.layer1.parameters():\n                param.requires_grad = False\n        else:\n            print (\"only support tf_efficientnet_b5, seresnext50_32x4d\")\n            assert 0\n\n        self.pooling = GeM()\n        \n        self.attention = CBAMBlock(channel=in_features, reduction=4)\n\n        embedding_size = 1750\n        #embedding_size = in_features\n        self.neck1 = nn.Sequential(\n            nn.Dropout(p=0.2, inplace=False),\n            nn.Linear(in_features, embedding_size , bias = True),\n            nn.BatchNorm1d(embedding_size),\n            nn.PReLU(),\n        )\n\n        self.neck2 = nn.Sequential(\n            nn.Dropout(p=0.2, inplace=False),\n            nn.Linear(in_features, embedding_size, bias=True),\n            nn.BatchNorm1d(embedding_size),\n            nn.PReLU()\n        )\n\n\n        self.neck3 = nn.Sequential(\n            nn.Dropout(p=0.2, inplace=False),\n            nn.Linear(in_features, embedding_size, bias=True),\n            nn.BatchNorm1d(embedding_size),\n            nn.PReLU()\n        )\n        \n        self.arc= ArcMarginHead(embedding_size, CONFIG.num_classes)\n        self.cos = CosMarginHead(embedding_size, CONFIG.num_classes)\n        self.binary = BinaryHead(embedding_size, CONFIG.num_classes)\n\n\n        self.b4 = BinaryHead(embedding_size, CONFIG.num_classes)\n        self.fc = nn.Sequential(\n            nn.Dropout(p=0.5, inplace=False),\n            nn.Linear(embedding_size * 3, embedding_size, bias=True),\n            nn.BatchNorm1d(embedding_size)\n        )\n\n    def inference(self, images):\n        features = self.model(images)\n        \n        features = self.attention(features)\n        gem_fea = self.pooling(features).flatten(1)\n\n        embedding1 = self.neck1(gem_fea)\n        embedding2 = self.neck2(gem_fea)\n        embedding3 = self.neck3(gem_fea)\n        embedding = torch.cat((embedding1, embedding2, embedding3), dim = 1)\n        \n        embedding4 = self.fc(embedding)\n        embedding = torch.cat((embedding1, embedding2, embedding3, embedding4), dim = 1)\n        return embedding\n\n","metadata":{"execution":{"iopub.status.busy":"2022-04-16T15:50:22.786617Z","iopub.execute_input":"2022-04-16T15:50:22.786869Z","iopub.status.idle":"2022-04-16T15:50:22.803827Z","shell.execute_reply.started":"2022-04-16T15:50:22.786833Z","shell.execute_reply":"2022-04-16T15:50:22.803066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def l2_norm(input,axis=1):\n    norm = torch.norm(input,2,axis,True)\n    output = torch.div(input, norm)\n    return output","metadata":{"execution":{"iopub.status.busy":"2022-04-16T15:50:22.805427Z","iopub.execute_input":"2022-04-16T15:50:22.805941Z","iopub.status.idle":"2022-04-16T15:50:22.81313Z","shell.execute_reply.started":"2022-04-16T15:50:22.805905Z","shell.execute_reply":"2022-04-16T15:50:22.812446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_list = ['938b7e931166', '5bf17305f073', '7593d2aee842', '7362d7a01d00','956562ff2888']\nfrom sklearn.neighbors import NearestNeighbors\n\nclass EmbedFeatureCom():\n    def __init__(self, weights, resuled_csv_path):\n\n        target_df = pd.read_csv(CONFIG.label_path)\n\n        self.resuled_csv_path = resuled_csv_path\n\n        self.inverse_encodings = target_df.set_index([\"id\"])[\"individual_name\"].to_dict()\n        self.encodings = target_df.set_index([\"individual_name\"])[\"id\"].to_dict()\n\n        self.train_df = pd.read_csv(CONFIG.train_csv)\n        self.train_df['file_path'] = \"_\" + self.train_df['image']\n        self.train_df['file_path'] = self.train_df['individual_id'].astype(\"str\") + self.train_df['file_path']\n        self.train_df['file_path'] = CONFIG.TRAIN_DIR + self.train_df['file_path']\n \n\n\n        self.test_df = pd.read_csv(CONFIG.sample_submission)\n        self.test_df['file_path'] = CONFIG.TEST_DIR + self.test_df['image']\n        self.test_df[\"predictions\"] = ''\n        \n        #self.train_df = self.train_df.iloc[:1000]\n        #self.test_df = self.test_df.iloc[:100]\n        \n        \n        self.models = []\n        for weight in weights:\n            model = HappyWhaleModel(CONFIG.model_name)\n            model.load_state_dict(torch.load(weight))\n            model.to(CONFIG.device)\n            model.eval()\n            self.models.append(model)\n\n\n\n    def map_per_image(self, label, predictions):\n\n        try:\n            return 1 / (predictions[:5].index(label) + 1)\n        except ValueError:\n            return 0.0\n\n    def get_loaders(self, df, mode, trans_model = \"test\"):\n\n        dataset = HappyWhaleDataset(df, mode, transforms=data_transforms[trans_model])\n        loader = DataLoader(dataset, batch_size=CONFIG.valid_batch_size,\n                            num_workers=CONFIG.num_workers, shuffle=False, pin_memory=True)\n\n        return loader\n\n\n    def get_embeddings_train(self, data_loader):\n        targets_container  = []\n        embeddings_container  = []\n        names_container = []\n        with torch.no_grad():\n            for i, (images, targets, image_names) in tqdm(enumerate(data_loader), total=len(data_loader)):\n\n                images = images.to(CONFIG.device, dtype=torch.float)\n                embeddings = []\n                for model in self.models:\n                    embedding = model.inference(images)                   \n                    embedding = l2_norm(embedding)                    \n                    embeddings.append(embedding.cpu().numpy())\n                embedding_final = np.max(np.stack(embeddings), axis=0)\n    \n                                        \n                embeddings_container.append(embedding_final)\n                targets_container.append(np.array(targets))\n                names_container.append(np.array(image_names))\n\n            embeddings_container = np.concatenate(embeddings_container)\n            labels_container = np.concatenate(targets_container)\n            names_container = np.concatenate(names_container)\n\n        return embeddings_container, labels_container, names_container\n\n    def get_embeddings_test(self, data_loader):\n        targets_container  = []\n        embeddings_container  = []\n        names_container = []\n        with torch.no_grad():\n            for i, (images, targets, image_names, images_flip, images_rotate) in tqdm(enumerate(data_loader), total=len(data_loader)):\n\n                images = images.to(CONFIG.device, dtype=torch.float)\n                embeddings = []\n                for model in self.models:\n                    embedding = model.inference(images)\n                    embedding = l2_norm(embedding)\n                    \n                    embeddings.append(embedding.cpu().numpy())\n                embedding = np.mean(np.stack(embeddings), axis=0)\n                embeddings_container.append(embedding)\n                targets_container.append(np.array(targets))\n                names_container.append(np.array(image_names))\n\n                images_flip = images_flip.to(CONFIG.device, dtype=torch.float)\n                embeddings = []\n                for model in self.models:\n                    embedding = model.inference(images_flip)\n                    embedding = l2_norm(embedding)\n                    embeddings.append(embedding.cpu().numpy())\n                embedding = np.mean(np.stack(embeddings), axis=0)\n                embeddings_container.append(embedding)\n                targets_container.append(np.array(targets))\n                names_container.append(np.array(image_names))\n                \n                images_rotate = images_rotate.to(CONFIG.device, dtype=torch.float)\n                embeddings = []\n                for model in self.models:\n                    embedding = model.inference(images_rotate)\n                    embedding = l2_norm(embedding)\n                    embeddings.append(embedding.cpu().numpy())\n                embedding = np.mean(np.stack(embeddings), axis=0)\n                embeddings_container.append(embedding)\n                targets_container.append(np.array(targets))\n                names_container.append(np.array(image_names))\n\n\n\n            embeddings_container = np.concatenate(embeddings_container)\n            labels_container = np.concatenate(targets_container)\n            names_container = np.concatenate(names_container)\n\n        return embeddings_container, labels_container, names_container\n\n    def get_Neighbors_dis(self, neigh, embeddings, names, train_targets):\n        test_nn_distances, test_nn_idxs = neigh.kneighbors(embeddings, CONFIG.KNN, return_distance=True)\n\n        test_df = []\n        for i in tqdm(range(len(names))):\n            id_ = names[i]\n            labels = train_targets[test_nn_idxs[i]]\n            distances = test_nn_distances[i]\n\n            subset_preds = pd.DataFrame(np.stack([labels, distances], axis=1), columns=['target', 'distances'])\n\n            subset_preds['target'] = subset_preds['target'].astype('int')\n            subset_preds['distances'] = subset_preds['distances'].astype('float')\n            subset_preds['image'] = id_\n            test_df.append(subset_preds)\n\n        test_df = pd.concat(test_df).reset_index(drop=True)\n        test_df['confidence'] = 1 - test_df['distances']\n\n        return test_df\n\n\n    def get_center(self, embeddings, type):\n        embeddings = np.concatenate(embeddings)\n        if type == \"mean\":\n            embeddings = np.mean(embeddings, axis=0)\n        if type == \"max\":\n            embeddings = np.max(embeddings, axis=0)\n        return embeddings\n\n    def get_center_features(self, train_embeddings, train_targets, type = \"mean\"):\n        labels_to_embeddings = {}\n        for i, label in enumerate(train_targets):\n            if label not in labels_to_embeddings.keys():\n                labels_to_embeddings[label] = []\n            labels_to_embeddings[label].append(train_embeddings[i].reshape(1, -1))\n\n        for label in labels_to_embeddings.keys():\n            embeddings = self.get_center(labels_to_embeddings[label], type)\n            labels_to_embeddings[label] = embeddings\n\n        return np.array(list(labels_to_embeddings.values())), np.array(list(labels_to_embeddings.keys()))\n\n\n    def get_test_Neighbors(self, name):\n\n        train_loader = self.get_loaders(self.train_df, mode=\"test_valid\")\n        train_embeddings1, train_targets1, train_names = self.get_embeddings_train(train_loader)\n\n        train_embeddings2, train_targets2 = self.get_center_features(train_embeddings1, train_targets1, type=\"mean\")\n\n        train_embeddings = np.concatenate([train_embeddings1, train_embeddings2])\n        train_targets = np.concatenate([train_targets1, train_targets2])\n        \n        #pd.DataFrame(train_embeddings).to_csv(\"{}_train_embeddings.csv\".format(name), index = False)\n        #pd.DataFrame(train_targets).to_csv(\"{}_train_targets.csv\".format(name), index = False)\n        neigh = NearestNeighbors(n_neighbors=CONFIG.KNN, metric='cosine')\n        neigh.fit(train_embeddings)\n        \n        \n        '''\n        test_nums = self.test_df.shape[0]\n        print (test_nums)\n        test_nums_half = int(test_nums / 2)\n        \n        df_1 = self.test_df.iloc[:test_nums_half]\n        print(df_1.shape)\n        test_loader1 = self.get_loaders(df_1, mode=\"test_tta\")\n        test_embeddings1, _, test_names1 = self.get_embeddings_test(test_loader1)\n        test_df1 = self.get_Neighbors_dis(neigh, test_embeddings1, test_names1, train_targets)\n        test_df1.to_csv(\"{}_test_df_1_gray.csv\".format(name), index=False)\n        \n        df_2 = self.test_df.iloc[test_nums_half:]\n        print(df_2.shape)\n        test_loader2 = self.get_loaders(df_2, mode=\"test_tta\")\n        test_embeddings2, _, test_names2 = self.get_embeddings_test(test_loader2)\n        test_df2 = self.get_Neighbors_dis(neigh, test_embeddings2, test_names2, train_targets)\n        test_df2.to_csv(\"{}_test_df_2_gray.csv\".format(name), index=False)\n        \n        test_df = pd.concat([test_df1, test_df2])\n       \n        '''\n        test_loader = self.get_loaders(self.test_df, mode=\"test_tta\")\n        test_embeddings, _, test_names = self.get_embeddings_test(test_loader)\n        test_df = self.get_Neighbors_dis(neigh, test_embeddings, test_names, train_targets)\n        test_df.to_csv(\"{}_test_df.csv\".format(name), index=False)\n \n    \n        \n        test_df = test_df.groupby(\n            ['image', 'target']).confidence.max().reset_index()\n\n        test_df = test_df.sort_values('confidence', ascending=False).reset_index(drop=True)\n\n        test_df['target'] = test_df['target'].map(self.inverse_encodings)\n\n        test_df.image.value_counts().value_counts()\n\n        best_threshold_adjusted = 0.7\n\n        predictions = self.get_predictions(test_df, threshold=best_threshold_adjusted)\n\n        for x in predictions:\n            predictions[x] = ' '.join(predictions[x])\n\n        predictions = pd.Series(predictions).reset_index()\n        predictions.columns = ['image', 'predictions']\n        predictions.to_csv(self.resuled_csv_path, index=False)\n        predictions.head()\n\n\n\n\n    def get_predictions(self, dis_df, threshold=0.2):\n        predictions = {}\n\n        for i, row in dis_df.iterrows():\n\n            if row.image in predictions:\n                if len(predictions[row.image]) == 5:\n                    continue\n                predictions[row.image].append(row.target)\n            elif row.confidence > threshold:\n                predictions[row.image] = [row.target, 'new_individual']\n            else:\n                predictions[row.image] = ['new_individual', row.target]\n\n        for x in predictions:\n            if len(predictions[x]) < 5:\n                remaining = [y for y in sample_list if y not in predictions]\n                predictions[x] = predictions[x] + remaining\n                predictions[x] = predictions[x][:5]\n\n        return predictions\n\n\n    def get_Neighbors_score(self, name, fold):\n\n        '''\n\n        df_train = self.train_df[self.train_df.kfold != fold].reset_index(drop=True)\n        df_valid = self.train_df[self.train_df.kfold == fold].reset_index(drop=True)\n        '''\n\n\n        valid_proportion = 0.1\n\n        df_valid = self.train_df.sample(frac=valid_proportion, replace=False, random_state=1).copy()\n        df_train = self.train_df[~self.train_df['image'].isin(df_valid['image'])].copy()\n\n\n        train_targets = np.array(df_train.individual_id)\n        valid_names = np.array(df_valid.image)\n        valid_targets = np.array(df_valid.individual_id)\n\n\n        train_loader = self.get_loaders(df_train, mode=\"test_valid\")\n        valid_loader = self.get_loaders(df_valid, mode=\"test_valid\")\n        train_embeddings1, train_targets1, train_names = self.get_embeddings_train(train_loader)\n        valid_embeddings, valid_targets, valid_names = self.get_embeddings_train(valid_loader)\n\n        \n        train_embeddings2, train_targets2 = self.get_center_features(train_embeddings1, train_targets1, type=\"mean\")\n\n        train_embeddings = np.concatenate([train_embeddings1, train_embeddings2])\n        train_targets = np.concatenate([train_targets1, train_targets2])\n\n\n        neigh = NearestNeighbors(n_neighbors=CONFIG.KNN, metric='cosine')\n        neigh.fit(train_embeddings)\n\n\n        test_df = self.get_Neighbors_dis(neigh, valid_embeddings, valid_names, train_targets)\n\n        test_df.to_csv(name + \"_train0.1_test_df.csv\", index=False)\n\n\n        test_df = test_df.groupby(['image', 'target']).confidence.max().reset_index()\n\n        test_df = test_df.sort_values('confidence', ascending=False).reset_index(drop=True)\n        test_df['target'] = test_df['target'].map(self.inverse_encodings)\n\n        allowed_targets = set([self.inverse_encodings[x] for x in np.unique(train_targets)])\n        val_targets_df = pd.DataFrame(np.stack([valid_names, valid_targets], axis=1), columns=['image', 'target'])\n        val_targets_df['target'] = val_targets_df['target'].astype(int).map(self.inverse_encodings)\n\n\n        val_targets_df.loc[~val_targets_df.target.isin(allowed_targets), 'target'] = 'new_individual'\n        val_targets_df.target.value_counts()\n\n        ## Compute CV\n        best_cv = 0\n        for th in [0.01 * x for x in range(60, 90)]:\n            all_preds = self.get_predictions(test_df, threshold=th)\n            for i, row in val_targets_df.iterrows():\n                target = row.target\n                preds = all_preds[row.image]\n                val_targets_df.loc[i, th] = self.map_per_image(target, preds)\n            cv = val_targets_df[th].mean()\n            print(f\"CV at threshold {round(th, 2)}: {cv}\")\n            if cv > best_cv:\n                best_th = th\n                best_cv = cv \n\n\n                \nweight1 = \"../input/v38-b7-512-29/best_v38_b7_512_fold0_epoch_29_Loss0.9888.bin\"\n\nweights = [weight1]\nname = (weight1.split('/')[-1])[:-4]\nresuled_csv_path = \"./{}_0.7.csv\".format( name)\n\ncomper = EmbedFeatureCom(weights, resuled_csv_path)\ncomper.get_Neighbors_score(name, fold=0)\n#comper.get_test_Neighbors(name)","metadata":{"execution":{"iopub.status.busy":"2022-04-16T15:50:22.815394Z","iopub.execute_input":"2022-04-16T15:50:22.815673Z","iopub.status.idle":"2022-04-16T15:50:49.057248Z","shell.execute_reply.started":"2022-04-16T15:50:22.815622Z","shell.execute_reply":"2022-04-16T15:50:49.056079Z"},"trusted":true},"execution_count":null,"outputs":[]}]}