{"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":"!nvidia-smi","metadata":{"id":"ikMF-nQSdTbF","outputId":"041c6767-86ab-46e4-9b22-a4840121ecca","papermill":{"duration":1.301859,"end_time":"2021-02-16T15:59:41.363841","exception":false,"start_time":"2021-02-16T15:59:40.061982","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-06-01T17:45:13.489899Z","iopub.execute_input":"2021-06-01T17:45:13.490227Z","iopub.status.idle":"2021-06-01T17:45:14.154297Z","shell.execute_reply.started":"2021-06-01T17:45:13.490195Z","shell.execute_reply":"2021-06-01T17:45:14.153458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n    import resnest\nexcept ModuleNotFoundError:\n    !pip install -q \"../input/resnest50-fast-package/resnest-0.0.6b20200701/resnest\"","metadata":{"execution":{"iopub.status.busy":"2021-06-01T17:45:14.156270Z","iopub.execute_input":"2021-06-01T17:45:14.156636Z","iopub.status.idle":"2021-06-01T17:45:14.166266Z","shell.execute_reply.started":"2021-06-01T17:45:14.156598Z","shell.execute_reply":"2021-06-01T17:45:14.165360Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"effnet_path = '../input/efficientnet-pytorch/'\nimport sys\nsys.path.append(effnet_path)","metadata":{"execution":{"iopub.status.busy":"2021-06-01T17:45:14.549992Z","iopub.execute_input":"2021-06-01T17:45:14.550306Z","iopub.status.idle":"2021-06-01T17:45:14.554261Z","shell.execute_reply.started":"2021-06-01T17:45:14.550277Z","shell.execute_reply":"2021-06-01T17:45:14.553452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from efficientnet_pytorch import EfficientNet\nimport resnest.torch as resnest_torch\nimport torchvision.models as models\nimport numpy as np\nimport collections\nimport librosa as lb\nimport soundfile as sf\nimport pandas as pd\nimport cv2\nfrom pathlib import Path\nimport re\n\nimport torch\nfrom torch import nn\nfrom  torch.utils.data import Dataset, DataLoader\n\nfrom tqdm.notebook import tqdm\n\nimport time\nfrom resnest.torch import resnest50\nfrom efficientnet_pytorch import EfficientNet\n\n\npd.set_option('display.max_rows', 750)","metadata":{"execution":{"iopub.status.busy":"2021-06-01T17:45:14.989874Z","iopub.execute_input":"2021-06-01T17:45:14.990200Z","iopub.status.idle":"2021-06-01T17:45:16.153947Z","shell.execute_reply.started":"2021-06-01T17:45:14.990171Z","shell.execute_reply":"2021-06-01T17:45:16.153054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_config_list = [\n    \n    {'model_name': 'resnest50', 'thresh': 0.11, 'checkpoint': Path(\"../input/kkiller-birdclef-models-public/birdclef_resnest50_fold0_epoch_10_f1_val_06471_20210417161101.pth\")},\n    {'model_name': 'resnext50_32x4d', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnext50_32x4d_fold4_epoch_13.pth\")},\n    {'model_name': 'resnext50_32x4d', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnext50_32x4d_fold0_epoch_11.pth\")},\n    {'model_name': 'resnest50', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/resnest50_fold0_epoch_10_686.pth\")},\n    {'model_name': 'resnest50', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnest50_fold0_epoch_13.pth\")},\n\n    # \n    {'model_name': 'resnest50', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnest50_fold2_epoch_13.pth\")},\n    {'model_name': 'resnest50', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/resnest50_fold1_epoch_10_681.pth\")},\n#     {'model_name': 'resnest50', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnest50_fold1_epoch_10.pth\")},\n    {'model_name': 'resnext50_32x4d', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnext50_32x4d_fold2_epoch_12.pth\")},\n    {'model_name': 'resnest50', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/resnest50_fold3_epoch_11_677.pth\")},\n    {'model_name': 'resnest50', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/resnest50_fold2_epoch_11_676.pth\")},\n\n    {'model_name': 'resnet34', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnet34_fold0_epoch_10.pth\")},\n    {'model_name': 'resnet50', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnet50_fold3_epoch_13.pth\")},\n    {'model_name': 'resnet50', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnet50_fold2_epoch_14.pth\")},\n    {'model_name': 'resnet34', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnet34_fold4_epoch_10.pth\")},\n    {'model_name': 'resnet50', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnet50_fold1_epoch_10.pth\")},\n\n    {'model_name': 'resnest50', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnest50_fold2_epoch_23.pth\")},\n    {'model_name': 'resnet50', 'thresh': 0.11, 'checkpoint': Path(\"../input/bird-models/birdclef_resnet50_fold4_epoch_13.pth\")},\n   \n] ","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","id":"kSCcqxf0c_O7","papermill":{"duration":4.153186,"end_time":"2021-02-16T15:59:57.894303","exception":false,"start_time":"2021-02-16T15:59:53.741117","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-06-01T18:10:18.361945Z","iopub.execute_input":"2021-06-01T18:10:18.362273Z","iopub.status.idle":"2021-06-01T18:10:18.372657Z","shell.execute_reply.started":"2021-06-01T18:10:18.362244Z","shell.execute_reply":"2021-06-01T18:10:18.371450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"[x['checkpoint'].exists() for x in model_config_list]","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:10:31.156010Z","iopub.execute_input":"2021-06-01T18:10:31.156331Z","iopub.status.idle":"2021-06-01T18:10:31.222696Z","shell.execute_reply.started":"2021-06-01T18:10:31.156299Z","shell.execute_reply":"2021-06-01T18:10:31.222007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"[str(x['checkpoint']) for x in model_config_list]","metadata":{"papermill":{"duration":0.046502,"end_time":"2021-02-16T15:59:59.284533","exception":false,"start_time":"2021-02-16T15:59:59.238031","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-06-01T18:10:33.849195Z","iopub.execute_input":"2021-06-01T18:10:33.849531Z","iopub.status.idle":"2021-06-01T18:10:33.856181Z","shell.execute_reply.started":"2021-06-01T18:10:33.849486Z","shell.execute_reply":"2021-06-01T18:10:33.855288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Configs","metadata":{"papermill":{"duration":0.046996,"end_time":"2021-02-16T15:59:59.377834","exception":false,"start_time":"2021-02-16T15:59:59.330838","status":"completed"},"tags":[]}},{"cell_type":"code","source":"NUM_CLASSES = 397\nSR = 32_000\nDURATION = 5\nTHRESH = 0.29\nAP = 24\nSS = 12","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:26:11.874254Z","iopub.execute_input":"2021-06-01T18:26:11.874616Z","iopub.status.idle":"2021-06-01T18:26:11.879864Z","shell.execute_reply.started":"2021-06-01T18:26:11.874575Z","shell.execute_reply":"2021-06-01T18:26:11.878765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 0\t24\t12\t0.3\t0.728181\n# 4430\t29\t17\t0.3\t0.727944\n\n\n\nDEVICE = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(\"DEVICE:\", DEVICE)\n\nTEST_AUDIO_ROOT = Path(\"../input/birdclef-2021/test_soundscapes\")\nSAMPLE_SUB_PATH = \"../input/birdclef-2021/sample_submission.csv\"\nTARGET_PATH = None\n    \nif not len(list(TEST_AUDIO_ROOT.glob(\"*.ogg\"))):\n    TEST_AUDIO_ROOT = Path(\"../input/birdclef-2021/train_soundscapes\")\n    SAMPLE_SUB_PATH = None\n    # SAMPLE_SUB_PATH = \"../input/birdclef-2021/sample_submission.csv\"\n    TARGET_PATH = Path(\"../input/birdclef-2021/train_soundscape_labels.csv\")","metadata":{"id":"rJhYZVIDc_O9","papermill":{"duration":0.440614,"end_time":"2021-02-16T15:59:59.86408","exception":false,"start_time":"2021-02-16T15:59:59.423466","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-06-01T18:16:24.672026Z","iopub.execute_input":"2021-06-01T18:16:24.672347Z","iopub.status.idle":"2021-06-01T18:16:24.685293Z","shell.execute_reply.started":"2021-06-01T18:16:24.672315Z","shell.execute_reply":"2021-06-01T18:16:24.684186Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_config_list = model_config_list[:SS]","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:21:57.816291Z","iopub.execute_input":"2021-06-01T18:21:57.816633Z","iopub.status.idle":"2021-06-01T18:21:57.820793Z","shell.execute_reply.started":"2021-06-01T18:21:57.816600Z","shell.execute_reply":"2021-06-01T18:21:57.819761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(model_config_list))","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:21:58.080803Z","iopub.execute_input":"2021-06-01T18:21:58.081128Z","iopub.status.idle":"2021-06-01T18:21:58.085563Z","shell.execute_reply.started":"2021-06-01T18:21:58.081098Z","shell.execute_reply":"2021-06-01T18:21:58.084703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data","metadata":{"papermill":{"duration":0.046026,"end_time":"2021-02-16T16:00:00.054107","exception":false,"start_time":"2021-02-16T16:00:00.008081","status":"completed"},"tags":[]}},{"cell_type":"code","source":"class MelSpecComputer:\n    def __init__(self, sr, n_mels, fmin, fmax, **kwargs):\n        self.sr = sr\n        self.n_mels = n_mels\n        self.fmin = fmin\n        self.fmax = fmax\n        kwargs[\"n_fft\"] = kwargs.get(\"n_fft\", self.sr//10)\n        kwargs[\"hop_length\"] = kwargs.get(\"hop_length\", self.sr//(10*4))\n        self.kwargs = kwargs\n\n    def __call__(self, y):\n\n        melspec = lb.feature.melspectrogram(\n            y, sr=self.sr, n_mels=self.n_mels, fmin=self.fmin, fmax=self.fmax, **self.kwargs,\n        )\n\n        melspec = lb.power_to_db(melspec).astype(np.float32)\n        return melspec","metadata":{"id":"4fwNhdbJc_O-","papermill":{"duration":0.056975,"end_time":"2021-02-16T16:00:00.157168","exception":false,"start_time":"2021-02-16T16:00:00.100193","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-06-01T17:46:57.150462Z","iopub.execute_input":"2021-06-01T17:46:57.150828Z","iopub.status.idle":"2021-06-01T17:46:57.157893Z","shell.execute_reply.started":"2021-06-01T17:46:57.150796Z","shell.execute_reply":"2021-06-01T17:46:57.156970Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def mono_to_color(X, eps=1e-6, mean=None, std=None):\n    mean = mean or X.mean()\n    std = std or X.std()\n    X = (X - mean) / (std + eps)\n    \n    _min, _max = X.min(), X.max()\n\n    if (_max - _min) > eps:\n        V = np.clip(X, _min, _max)\n        V = 255 * (V - _min) / (_max - _min)\n        V = V.astype(np.uint8)\n    else:\n        V = np.zeros_like(X, dtype=np.uint8)\n\n    return V\n\ndef crop_or_pad(y, length):\n    if len(y) < length:\n        y = np.concatenate([y, length - np.zeros(len(y))])\n    elif len(y) > length:\n        y = y[:length]\n    return y","metadata":{"id":"Nk0haSTIc_O_","papermill":{"duration":0.065406,"end_time":"2021-02-16T16:00:00.271104","exception":false,"start_time":"2021-02-16T16:00:00.205698","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-06-01T17:46:57.839702Z","iopub.execute_input":"2021-06-01T17:46:57.840007Z","iopub.status.idle":"2021-06-01T17:46:57.848824Z","shell.execute_reply.started":"2021-06-01T17:46:57.839979Z","shell.execute_reply":"2021-06-01T17:46:57.847935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class BirdCLEFDataset(Dataset):\n    def __init__(self, data, sr=SR, n_mels=128, fmin=0, fmax=None, duration=DURATION, step=None, res_type=\"kaiser_fast\", resample=True):\n        \n        self.data = data\n        \n        self.sr = sr\n        self.n_mels = n_mels\n        self.fmin = fmin\n        self.fmax = fmax or self.sr//2\n\n        self.duration = duration\n        self.audio_length = self.duration*self.sr\n        self.step = step or self.audio_length\n        \n        self.res_type = res_type\n        self.resample = resample\n\n        self.mel_spec_computer = MelSpecComputer(sr=self.sr, n_mels=self.n_mels, fmin=self.fmin,\n                                                 fmax=self.fmax)\n    def __len__(self):\n        return len(self.data)\n    \n    @staticmethod\n    def normalize(image):\n        image = image.astype(\"float32\", copy=False) / 255.0\n        image = np.stack([image, image, image])\n        return image\n    \n    def audio_to_image(self, audio):\n        melspec = self.mel_spec_computer(audio) \n        image = mono_to_color(melspec)\n        image = self.normalize(image)\n        return image\n\n    def read_file(self, filepath):\n        audio, orig_sr = sf.read(filepath, dtype=\"float32\")\n\n        if self.resample and orig_sr != self.sr:\n            audio = lb.resample(audio, orig_sr, self.sr, res_type=self.res_type)\n          \n        audios = []\n        for i in range(self.audio_length, len(audio) + self.step, self.step):\n            start = max(0, i - self.audio_length)\n            end = start + self.audio_length\n            audios.append(audio[start:end])\n            \n        if len(audios[-1]) < self.audio_length:\n            audios = audios[:-1]\n            \n        images = [self.audio_to_image(audio) for audio in audios]\n        images = np.stack(images)\n        \n        return images\n    \n        \n    def __getitem__(self, idx):\n        return self.read_file(self.data.loc[idx, \"filepath\"])","metadata":{"execution":{"iopub.status.busy":"2021-06-01T17:46:58.379001Z","iopub.execute_input":"2021-06-01T17:46:58.379321Z","iopub.status.idle":"2021-06-01T17:46:58.391493Z","shell.execute_reply.started":"2021-06-01T17:46:58.379289Z","shell.execute_reply":"2021-06-01T17:46:58.390629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = pd.DataFrame(\n     [(path.stem, *path.stem.split(\"_\"), path) for path in Path(TEST_AUDIO_ROOT).glob(\"*.ogg\")],\n    columns = [\"filename\", \"id\", \"site\", \"date\", \"filepath\"]\n)\nprint(data.shape)\ndata.head()","metadata":{"id":"rVwlOrbxc_PD","outputId":"9b53ec99-634a-4b30-f9b5-75036184482b","papermill":{"duration":0.162256,"end_time":"2021-02-16T16:00:01.102152","exception":false,"start_time":"2021-02-16T16:00:00.939896","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-06-01T17:46:58.819914Z","iopub.execute_input":"2021-06-01T17:46:58.820230Z","iopub.status.idle":"2021-06-01T17:46:58.875393Z","shell.execute_reply.started":"2021-06-01T17:46:58.820198Z","shell.execute_reply":"2021-06-01T17:46:58.874628Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv(\"../input/birdclef-2021/train_metadata.csv\")\n\nLABEL_IDS = {label: label_id for label_id,label in enumerate(sorted(df_train[\"primary_label\"].unique()))}\nINV_LABEL_IDS = {val: key for key,val in LABEL_IDS.items()}","metadata":{"execution":{"iopub.status.busy":"2021-06-01T17:46:59.327087Z","iopub.execute_input":"2021-06-01T17:46:59.327413Z","iopub.status.idle":"2021-06-01T17:46:59.686972Z","shell.execute_reply.started":"2021-06-01T17:46:59.327384Z","shell.execute_reply":"2021-06-01T17:46:59.686030Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inference","metadata":{"id":"BNsivZZZc_PG","papermill":{"duration":0.048675,"end_time":"2021-02-16T16:00:08.424781","exception":false,"start_time":"2021-02-16T16:00:08.376106","status":"completed"},"tags":[]}},{"cell_type":"code","source":"test_data = BirdCLEFDataset(data=data)\nlen(test_data), test_data[0].shape","metadata":{"id":"AzlOErOmc_PH","papermill":{"duration":0.058312,"end_time":"2021-02-16T16:00:08.531199","exception":false,"start_time":"2021-02-16T16:00:08.472887","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-06-01T17:47:00.371215Z","iopub.execute_input":"2021-06-01T17:47:00.371562Z","iopub.status.idle":"2021-06-01T17:47:03.813065Z","shell.execute_reply.started":"2021-06-01T17:47:00.371529Z","shell.execute_reply":"2021-06-01T17:47:03.802910Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model = getattr(models, 'resnext50_32x4d')(pretrained=False)","metadata":{"execution":{"iopub.status.busy":"2021-06-01T17:47:03.816167Z","iopub.execute_input":"2021-06-01T17:47:03.816621Z","iopub.status.idle":"2021-06-01T17:47:03.828152Z","shell.execute_reply.started":"2021-06-01T17:47:03.816580Z","shell.execute_reply":"2021-06-01T17:47:03.827194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_model(name, checkpoint_path, num_classes=NUM_CLASSES):\n    \"\"\"\n    Loads a pretrained model. \n    Supports ResNest, ResNext-wsl, EfficientNet, ResNext and ResNet.\n\n    Arguments:\n        name {str} -- Name of the model to load\n\n    Keyword Arguments:\n        num_classes {int} -- Number of classes to use (default: {1})\n\n    Returns:\n        torch model -- Pretrained model\n    \"\"\"\n    if \"resnest\" in name:\n        model = getattr(resnest_torch, name)(pretrained=False)\n    elif \"wsl\" in name:\n        model = torch.hub.load(\"facebookresearch/WSL-Images\", name)\n    elif name.startswith(\"resnext\") or  name.startswith(\"resnet\"):\n        #model = torch.hub.load(\"pytorch/vision:v0.6.0\", name, pretrained=False)\n        model = getattr(models, name)(pretrained=False)\n    elif name.startswith(\"tf_efficientnet_b\"):\n        model = getattr(timm.models.efficientnet, name)(pretrained=True)\n    elif \"efficientnet-b\" in name:\n        model = EfficientNet.from_name(name)\n    else:\n        model = pretrainedmodels.__dict__[name](pretrained='imagenet')\n\n    if hasattr(model, \"fc\"):\n        nb_ft = model.fc.in_features\n        model.fc = nn.Linear(nb_ft, num_classes)\n    elif hasattr(model, \"_fc\"):\n        nb_ft = model._fc.in_features\n        model._fc = nn.Linear(nb_ft, num_classes)\n    elif hasattr(model, \"classifier\"):\n        nb_ft = model.classifier.in_features\n        model.classifier = nn.Linear(nb_ft, num_classes)\n    elif hasattr(model, \"last_linear\"):\n        nb_ft = model.last_linear.in_features\n        model.last_linear = nn.Linear(nb_ft, num_classes)\n\n    dummy_device = torch.device(\"cpu\")\n    d = torch.load(checkpoint_path, map_location=dummy_device)\n    for key in list(d.keys()):\n        d[key.replace(\"model.\", \"\")] = d.pop(key)\n    model.load_state_dict(d)\n    model = model.to(DEVICE)\n    model = model.eval()\n    return model","metadata":{"papermill":{"duration":0.048931,"end_time":"2021-02-16T16:00:14.351476","exception":false,"start_time":"2021-02-16T16:00:14.302545","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-06-01T17:47:03.829377Z","iopub.execute_input":"2021-06-01T17:47:03.829799Z","iopub.status.idle":"2021-06-01T17:47:03.853873Z","shell.execute_reply.started":"2021-06-01T17:47:03.829759Z","shell.execute_reply":"2021-06-01T17:47:03.852728Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model = get_model('resnest50',Path(\"../input/kkiller-birdclef-models-public/birdclef_resnest50_fold0_epoch_10_f1_val_06471_20210417161101.pth\"))","metadata":{"execution":{"iopub.status.busy":"2021-06-01T17:47:03.856106Z","iopub.execute_input":"2021-06-01T17:47:03.857081Z","iopub.status.idle":"2021-06-01T17:47:03.868373Z","shell.execute_reply.started":"2021-06-01T17:47:03.857044Z","shell.execute_reply":"2021-06-01T17:47:03.867590Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ******************************\n# 0 0.6654861111111114 0.7000000000000001\n# ******************************\n# 1 0.6654166666666669 0.6000000000000001\n# ******************************\n# 2 0.6643055555555558 0.7000000000000001\n# ******************************\n# 3 0.6539583333333335 0.5\n# ******************************\n# 4 0.654375 0.6000000000000001\n# ******************************\n# 5 0.6614166666666669 0.7000000000000001\n# ******************************\n# 6 0.6537083333333334 0.7000000000000001\n# ******************************\n# 7 0.7012083333333341 0.1\n# ******************************\n# 8 0.663291666666667 0.6000000000000001","metadata":{"execution":{"iopub.status.busy":"2021-06-01T17:47:03.870347Z","iopub.execute_input":"2021-06-01T17:47:03.870880Z","iopub.status.idle":"2021-06-01T17:47:03.880462Z","shell.execute_reply.started":"2021-06-01T17:47:03.870836Z","shell.execute_reply":"2021-06-01T17:47:03.879617Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# v1\n# model_config_list = [\n#     {'model_name': 'resnest50', 'thresh': 0.11, 'checkpoint': Path(\"../input/kkiller-birdclef-models-public/birdclef_resnest50_fold0_epoch_10_f1_val_06471_20210417161101.pth\")},\n#     {'model_name': 'resnest50', 'thresh': 0.7, 'checkpoint': Path(\"../input/bird-models/birdclef_resnest50_fold0_epoch_19_f1_val_07711_20210523161407.pth\")},\n#     {'model_name': 'resnest50', 'thresh': 0.7, 'checkpoint': Path(\"../input/bird-models/birdclef_resnest50_fold1_epoch_19_f1_val_07678_20210523031425.pth\")},\n#     {'model_name': 'resnest50', 'thresh': 0.7, 'checkpoint': Path(\"../input/bird-models/birdclef_resnest50_fold2_epoch_19_f1_val_07680_20210523050005.pth\")},\n#     {'model_name': 'resnest50', 'thresh': 0.7, 'checkpoint': Path(\"../input/bird-models/birdclef_resnest50_fold3_epoch_19_f1_val_07685_20210523064705.pth\")},\n#     {'model_name': 'resnest50', 'thresh': 0.7, 'checkpoint': Path(\"../input/bird-models/birdclef_resnest50_fold4_epoch_19_f1_val_07678_20210523175922.pth\")},\n#     {'model_name': 'resnext50_32x4d', 'thresh': 0.7, 'checkpoint': Path(\"../input/bird-models/birdclef_resnext50_32x4d_fold0_epoch_11_f1_val_07318_20210523012734.pth\")},\n\n# ]\n\n","metadata":{"id":"ayVLRTzLc_PI","papermill":{"duration":14.506299,"end_time":"2021-02-16T16:00:30.268614","exception":false,"start_time":"2021-02-16T16:00:15.762315","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-06-01T17:47:03.882061Z","iopub.execute_input":"2021-06-01T17:47:03.883136Z","iopub.status.idle":"2021-06-01T17:47:03.892447Z","shell.execute_reply.started":"2021-06-01T17:47:03.883096Z","shell.execute_reply":"2021-06-01T17:47:03.891618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# @torch.no_grad()\ndef get_thresh_preds(out, thresh=None):\n    thresh = thresh or THRESH\n    o = (-out).argsort(1)\n    npreds = (out > thresh).sum(1)\n    preds = []\n    for oo, npred in zip(o, npreds):\n        preds.append(oo[:npred].tolist())\n    return preds\n\n\ndef get_metrics(s_true, s_pred):\n    s_true = set(s_true.split())\n    s_pred = set(s_pred.split())\n    n, n_true, n_pred = len(s_true.intersection(s_pred)), len(s_true), len(s_pred)\n    \n    prec = n/n_pred\n    rec = n/n_true\n    f1 = 2*prec*rec/(prec + rec) if prec + rec else 0\n    \n    return {\"f1\": f1, \"prec\": prec, \"rec\": rec, \"n_true\": n_true, \"n_pred\": n_pred, \"n\": n}\n\ndef get_bird_names(preds):\n    bird_names = []\n    for pred in preds:\n        if not pred:\n            bird_names.append(\"nocall\")\n        else:\n            bird_names.append(\" \".join([INV_LABEL_IDS[bird_id] for bird_id in pred]))\n    return bird_names\n\ndef predict(net, test_data, names=False):\n    preds = []\n    with torch.no_grad():\n        for idx in  tqdm(list(range(len(test_data)))):\n            xb = torch.from_numpy(test_data[idx]).to(DEVICE)\n            o = net(xb)\n            pred = torch.sigmoid(o)\n            if names:\n                pred = get_bird_names(get_thresh_preds(pred))\n\n            preds.append(pred)\n    return preds\n\n\ndef predict_nets(nets, test_data, names=False):\n    preds = []\n    with torch.no_grad():\n        for idx in  tqdm(list(range(len(test_data)))):\n            xb = torch.from_numpy(test_data[idx]).to(DEVICE)\n            pred = 0.\n            for j, net in enumerate(nets):\n                o = net(xb)\n                o = torch.sigmoid(o)\n                if j==0:\n                    pred += AP * o\n                else:\n                    pred += o\n\n            pred /= SS\n            \n            if names:\n                pred = get_bird_names(get_thresh_preds(pred))\n\n            preds.append(pred)\n    return preds\n\n\ndef preds_as_df(data, preds):\n    sub = {\n        \"row_id\": [],\n        \"birds\": [],\n    }\n    \n    for row, pred in zip(data.itertuples(False), preds):\n        row_id = [f\"{row.id}_{row.site}_{5*i}\" for i in range(1, len(pred)+1)]\n        sub[\"birds\"] += pred\n        sub[\"row_id\"] += row_id\n        \n    sub = pd.DataFrame(sub)\n    \n    if SAMPLE_SUB_PATH:\n        sample_sub = pd.read_csv(SAMPLE_SUB_PATH, usecols=[\"row_id\"])\n        sub = sample_sub.merge(sub, on=\"row_id\", how=\"left\")\n        sub[\"birds\"] = sub[\"birds\"].fillna(\"nocall\")\n    return sub\n\n\ndef check_sub(sub):\n    sub_target = pd.read_csv(TARGET_PATH)\n    sub_target = sub_target.merge(sub, how=\"left\", on=\"row_id\")\n    \n    assert sub_target[\"birds_x\"].notnull().all()\n    assert sub_target[\"birds_y\"].notnull().all()\n    \n    df_metrics = pd.DataFrame([get_metrics(s_true, s_pred) for s_true, s_pred in zip(sub_target.birds_x, sub_target.birds_y)])\n    \n    print(df_metrics.mean())\n    \ndef filter_site(sub, s_dict, site_id):\n    ret = []\n    for row in sub.itertuples(False):\n        i = row.row_id\n        bird = row.birds\n        s = i.split('_')[1]\n        sid = site_id[s]\n        site_birds = s_dict[sid]\n        c = []\n        for b in bird.split(' '):\n            if b=='nocall' or b in site_birds:\n                c.append(b)\n        if len(c)==0:\n            ret.append('nocall')\n        else:\n            ret.append(' '.join(c))\n    return ret\n\ndef get_season(mon, lat):\n    if lat>0:\n        if mon <= 3:\n            s = 0\n        elif mon <= 6:\n            s = 1\n        elif mon <=9:\n            s = 2\n        else:\n            s = 3\n        return s\n    else:\n        if mon <= 3:\n            s = 3\n        elif mon <= 6:\n            s = 2\n        elif mon <=9:\n            s = 1\n        else:\n            s = 0\n        return s\n","metadata":{"papermill":{"duration":0.059925,"end_time":"2021-02-16T16:00:30.912547","exception":false,"start_time":"2021-02-16T16:00:30.852622","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2021-06-01T18:26:19.904599Z","iopub.execute_input":"2021-06-01T18:26:19.904961Z","iopub.status.idle":"2021-06-01T18:26:19.929203Z","shell.execute_reply.started":"2021-06-01T18:26:19.904929Z","shell.execute_reply":"2021-06-01T18:26:19.928051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"nets = [\n        get_model(row['model_name'], row['checkpoint'].as_posix()) for row in model_config_list\n]\n\n\n\npred_probas = predict_nets(nets, test_data, names=False)\nprint('nets', len(nets))\nprint(len(pred_probas))\n\npred_probas = [x.cpu().numpy() for x in pred_probas]\n\n","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:26:20.258249Z","iopub.execute_input":"2021-06-01T18:26:20.258618Z","iopub.status.idle":"2021-06-01T18:26:25.462812Z","shell.execute_reply.started":"2021-06-01T18:26:20.258578Z","shell.execute_reply":"2021-06-01T18:26:25.460230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(pred_probas[0])\n\npreds = [get_bird_names(get_thresh_preds(pred, thresh=THRESH)) for pred in pred_probas]\n\nsub = preds_as_df(data, preds)\nprint(sub.shape)\nprint(sub['birds'].value_counts().shape)\ncheck_sub(sub)\n# f1        0.726792\n# f1        0.725556\n# f1        0.726111\n","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:26:25.463857Z","iopub.status.idle":"2021-06-01T18:26:25.464259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:26:25.465239Z","iopub.status.idle":"2021-06-01T18:26:25.465812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_meta = pd.read_csv('../input/birdclef-2021/train_metadata.csv')","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:24:23.428310Z","iopub.execute_input":"2021-06-01T18:24:23.428662Z","iopub.status.idle":"2021-06-01T18:24:23.628465Z","shell.execute_reply.started":"2021-06-01T18:24:23.428628Z","shell.execute_reply":"2021-06-01T18:24:23.627439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nimport collections\n\nrules = collections.defaultdict(list)\nfor row in df_meta.itertuples(False):\n    bird, lat, mon = row.primary_label, float(row.latitude), int(row.date.split('-')[1])\n#     if lat>0:\n#         a = 'n'\n#     else:\n#         a = 's'\n    \n    s = get_season(mon, lat)    \n    rules[str(s)].append(bird)\n    \nfor key in rules:\n    c = collections.Counter(rules[key])\n    c = [x[0] for x in c.items() if x[1]>3]\n#     c = [x[0] for x in c.items()]\n    rules[key] = c\n    print(key, len(c))","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:25:56.091859Z","iopub.execute_input":"2021-06-01T18:25:56.092194Z","iopub.status.idle":"2021-06-01T18:25:56.404690Z","shell.execute_reply.started":"2021-06-01T18:25:56.092162Z","shell.execute_reply":"2021-06-01T18:25:56.403661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lat_dict = {\n    'COL':5.57,\n    'COR':10.12,\n    'SNE': 38.49,\n    'SSW': 42.47\n}","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:25:56.439147Z","iopub.execute_input":"2021-06-01T18:25:56.439456Z","iopub.status.idle":"2021-06-01T18:25:56.443741Z","shell.execute_reply.started":"2021-06-01T18:25:56.439424Z","shell.execute_reply":"2021-06-01T18:25:56.442755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"p_preds = []\nfor filename, pred in zip(data['filename'], preds):\n    p_pred = []\n    _, site, dt = filename.split('_')\n    month = dt[4:6]\n    s = get_season(int(month), 1)    \n    birds = rules[str(s)]\n    for i in pred:\n        tmp = []\n        for j in i.split(' '):\n            if j in birds or j=='nocall':\n                tmp.append(j)\n        if len(tmp)==0:\n            tmp.append('nocall')\n        tmp = ' '.join(tmp)\n        p_pred.append(tmp)\n    p_preds.append(p_pred)","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:25:56.630566Z","iopub.execute_input":"2021-06-01T18:25:56.630848Z","iopub.status.idle":"2021-06-01T18:25:56.653345Z","shell.execute_reply.started":"2021-06-01T18:25:56.630821Z","shell.execute_reply":"2021-06-01T18:25:56.652220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = preds_as_df(data, p_preds)\nprint(sub.shape)\nprint(sub['birds'].value_counts().shape)\nsub.head()\n\ncheck_sub(sub)\n\n# 0.724931\n# 0.7242222222222232\n# f1        0.723806\n# 0.726417","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:25:56.830624Z","iopub.execute_input":"2021-06-01T18:25:56.830919Z","iopub.status.idle":"2021-06-01T18:25:56.868957Z","shell.execute_reply.started":"2021-06-01T18:25:56.830892Z","shell.execute_reply":"2021-06-01T18:25:56.868257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_meta = pd.read_pickle('../input/bird-models/df_meta.pkl')","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:25:56.990533Z","iopub.execute_input":"2021-06-01T18:25:56.990805Z","iopub.status.idle":"2021-06-01T18:25:57.085926Z","shell.execute_reply.started":"2021-06-01T18:25:56.990780Z","shell.execute_reply":"2021-06-01T18:25:57.084978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"site_id_0 = {'COL': '8067fffffffffff',\n 'COR': '8067fffffffffff',\n 'SNE': '8029fffffffffff',\n 'SSW': '802bfffffffffff'}\n\nsite_id_1 = {'COL': '81663ffffffffff',\n 'COR': '816d7ffffffffff',\n 'SNE': '8129bffffffffff',\n 'SSW': '812bbffffffffff'}\n\nsite_id_2 = {'COL': '82661ffffffffff',\n 'COR': '826d6ffffffffff',\n 'SNE': '82298ffffffffff',\n 'SSW': '822aa7fffffffff'}\n\nsite_id_3 = {'COL': '83661bfffffffff',\n 'COR': '836d69fffffffff',\n 'SNE': '83298dfffffffff',\n 'SSW': '832aa4fffffffff'}","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:25:57.180972Z","iopub.execute_input":"2021-06-01T18:25:57.181244Z","iopub.status.idle":"2021-06-01T18:25:57.186717Z","shell.execute_reply.started":"2021-06-01T18:25:57.181218Z","shell.execute_reply":"2021-06-01T18:25:57.185818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"s1 = df_meta.groupby('r1')['primary_label'].agg(lambda x:set(x))\ns1 = s1.to_dict()","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:25:57.528915Z","iopub.execute_input":"2021-06-01T18:25:57.529231Z","iopub.status.idle":"2021-06-01T18:25:57.553443Z","shell.execute_reply.started":"2021-06-01T18:25:57.529201Z","shell.execute_reply":"2021-06-01T18:25:57.552466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub1 = sub.copy()\nret = filter_site(sub, s1, site_id_1)\nsub1['birds'] = ret\nprint(sub1['birds'].value_counts().shape)\n","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:25:57.776206Z","iopub.execute_input":"2021-06-01T18:25:57.776620Z","iopub.status.idle":"2021-06-01T18:25:57.789415Z","shell.execute_reply.started":"2021-06-01T18:25:57.776577Z","shell.execute_reply":"2021-06-01T18:25:57.788583Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"check_sub(sub1)\n# f1        0.729764\n# 0.729806\n# 0.731389\n# 0.733194\n# f1        0.734083\n# 0.185 f1        0.734500\n\n# f1        0.733292\n","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:25:58.352762Z","iopub.execute_input":"2021-06-01T18:25:58.353453Z","iopub.status.idle":"2021-06-01T18:25:58.396272Z","shell.execute_reply.started":"2021-06-01T18:25:58.353405Z","shell.execute_reply":"2021-06-01T18:25:58.395323Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub1.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-06-01T18:25:58.816324Z","iopub.execute_input":"2021-06-01T18:25:58.816655Z","iopub.status.idle":"2021-06-01T18:25:58.828142Z","shell.execute_reply.started":"2021-06-01T18:25:58.816623Z","shell.execute_reply":"2021-06-01T18:25:58.827227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}