{"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":"# 🐦 BirdCLEF '21 -2nd place model - Submit [0.66]\n## [BirdCLEF 2022](https://www.kaggle.com/c/birdclef-2022)\n### Identify bird calls in soundscapes\n![](https://storage.googleapis.com/kaggle-competitions/kaggle/33246/logos/header.png)\n\n# BirdCLEF 2021 - 2nd place model - Submit [LB:0.66]\n\nThis is one of the models of the 2nd place solution ensemble of 2021' BirdCLEF competition, adapted to BirdCLEF 2022, using only the 21 relevant classes.\n\n# Training notebook: [🐦 BirdCLEF '21 - 2nd place model - Train [0.66]](https://www.kaggle.com/code/julian3833/birdclef-2021-2nd-place-model-train-lb-0-66)\n\nIt uses MEL spectrograms, 5 secs chunking, GeM and a Resnet.\n\n* Check the writedown by the original authors for more details: https://www.kaggle.com/c/birdclef-2021/discussion/243463\n* Also their paper: http://ceur-ws.org/Vol-2936/paper-134.pdf \n* and their github, from where I've got the original code I have adapted: https://github.com/ChristofHenkel/kaggle-birdclef2021-2nd-place\n\n# Please, _DO_ upvote if you found this notebook useful or interesing!","metadata":{}},{"cell_type":"code","source":"!pip install ../input/birds-inference-pip-wheels/audiomentations-0.16.0-py3-none-any.whl --no-index --no-deps\n!pip install ../input/birds-inference-pip-wheels/torchlibrosa-0.0.9-py3-none-any.whl --no-index --no-deps","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-05-24T13:25:21.752438Z","iopub.execute_input":"2022-05-24T13:25:21.752990Z","iopub.status.idle":"2022-05-24T13:25:25.642937Z","shell.execute_reply.started":"2022-05-24T13:25:21.752919Z","shell.execute_reply":"2022-05-24T13:25:25.641931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.append(\"../input/timmpytorch\")\nimport os\nimport importlib\nimport multiprocessing as mp\n\nfrom tqdm import tqdm\nimport numpy as np\nimport pandas as pd\nimport glob\nimport torch\nfrom copy import copy\n\nfrom torch.utils.data import DataLoader\n\nimport pandas as pd\nimport timm\nfrom torch import nn\nimport torch\nimport torchaudio as ta\nfrom torch.cuda.amp import autocast\nimport random\n\nfrom torch.nn import functional as F\nfrom torch.distributions import Beta\nfrom torch.nn.parameter import Parameter\nfrom torch.utils.data import Dataset\n\nimport numpy as np\nimport librosa\nimport ast\n\nimport os\nfrom types import SimpleNamespace\nimport numpy as np\n\nimport numpy as np\nimport pandas as pd\nimport importlib\nimport sys\nimport random\nfrom tqdm import tqdm\nimport gc\nimport argparse\nimport torch\nfrom torch import optim\nfrom torch.cuda.amp import GradScaler, autocast\nfrom collections import defaultdict\nimport cv2\nfrom copy import copy\nimport os\nfrom transformers import get_cosine_schedule_with_warmup\nfrom torch.utils.data import SequentialSampler, DataLoader\nimport timm\ntimm.__version__","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:25:25.645905Z","iopub.execute_input":"2022-05-24T13:25:25.646526Z","iopub.status.idle":"2022-05-24T13:25:36.173951Z","shell.execute_reply.started":"2022-05-24T13:25:25.646475Z","shell.execute_reply":"2022-05-24T13:25:36.173149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def 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","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:25:36.175568Z","iopub.execute_input":"2022-05-24T13:25:36.176153Z","iopub.status.idle":"2022-05-24T13:25:36.181431Z","shell.execute_reply.started":"2022-05-24T13:25:36.176112Z","shell.execute_reply":"2022-05-24T13:25:36.180670Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Config","metadata":{}},{"cell_type":"code","source":"cfg = SimpleNamespace()\n\n# paths\ncfg.data_folder = ''\ncfg.name = \"julian\"\ncfg.data_dir = \"../input/birdclef-2022/\"\ncfg.train_data_folder = cfg.data_dir + \"train_audio/\"\ncfg.val_data_folder = cfg.data_dir + \"train_audio/\"\ncfg.output_dir = \"first_model\"\n\n# dataset\ncfg.dataset = \"base_ds\"\ncfg.min_rating = 0\ncfg.val_df = None\ncfg.batch_size_val = 1\ncfg.train_aug = None\ncfg.val_aug = None\ncfg.test_augs = None\ncfg.wav_len_val = 5  # seconds\n\n# audio\ncfg.window_size = 1048\ncfg.hop_size = 480\ncfg.sample_rate = 32000\ncfg.fmin = 16\ncfg.fmax = 14000\ncfg.power = 2\ncfg.mel_bins = 224\ncfg.top_db = 80.0\n\ncfg.window_size = 1024\ncfg.hop_size = 320\ncfg.fmin = 50\ncfg.fmax = 14000\ncfg.mel_bins = 64\n\n# img model\ncfg.backbone = \"tf_efficientnetv2_s_in21k\"\ncfg.pretrained = False\ncfg.pretrained_weights = None\ncfg.train = True\ncfg.val = False\ncfg.in_chans = 1\n\ncfg.alpha = 1\ncfg.eval_epochs = 1\ncfg.eval_train_epochs = 1\ncfg.warmup = 0\n\ncfg.mel_norm = True\n\ncfg.label_smoothing = 0\n\ncfg.remove_pretrained = []\n\n# training\ncfg.seed = 123\ncfg.save_val_data = True\n\n# ressources\ncfg.mixed_precision = True\ncfg.gpu = 0\ncfg.num_workers = 4 # 18\ncfg.drop_last = True \n\ncfg.mixup2 = 0\n\ncfg.label_smoothing = 0\n\ncfg.mixup_2x = False\n\n\ncfg.birds = np.array(['afrsil1', 'akekee', 'akepa1', 'akiapo', 'akikik', 'amewig',\n       'aniani', 'apapan', 'arcter', 'barpet', 'bcnher', 'belkin1',\n       'bkbplo', 'bknsti', 'bkwpet', 'blkfra', 'blknod', 'bongul',\n       'brant', 'brnboo', 'brnnod', 'brnowl', 'brtcur', 'bubsan',\n       'buffle', 'bulpet', 'burpar', 'buwtea', 'cacgoo1', 'calqua',\n       'cangoo', 'canvas', 'caster1', 'categr', 'chbsan', 'chemun',\n       'chukar', 'cintea', 'comgal1', 'commyn', 'compea', 'comsan',\n       'comwax', 'coopet', 'crehon', 'dunlin', 'elepai', 'ercfra',\n       'eurwig', 'fragul', 'gadwal', 'gamqua', 'glwgul', 'gnwtea',\n       'golphe', 'grbher3', 'grefri', 'gresca', 'gryfra', 'gwfgoo',\n       'hawama', 'hawcoo', 'hawcre', 'hawgoo', 'hawhaw', 'hawpet1',\n       'hoomer', 'houfin', 'houspa', 'hudgod', 'iiwi', 'incter1',\n       'jabwar', 'japqua', 'kalphe', 'kauama', 'laugul', 'layalb',\n       'lcspet', 'leasan', 'leater1', 'lessca', 'lesyel', 'lobdow',\n       'lotjae', 'madpet', 'magpet1', 'mallar3', 'masboo', 'mauala',\n       'maupar', 'merlin', 'mitpar', 'moudov', 'norcar', 'norhar2',\n       'normoc', 'norpin', 'norsho', 'nutman', 'oahama', 'omao', 'osprey',\n       'pagplo', 'palila', 'parjae', 'pecsan', 'peflov', 'perfal',\n       'pibgre', 'pomjae', 'puaioh', 'reccar', 'redava', 'redjun',\n       'redpha1', 'refboo', 'rempar', 'rettro', 'ribgul', 'rinduc',\n       'rinphe', 'rocpig', 'rorpar', 'rudtur', 'ruff', 'saffin', 'sander',\n       'semplo', 'sheowl', 'shtsan', 'skylar', 'snogoo', 'sooshe',\n       'sooter1', 'sopsku1', 'sora', 'spodov', 'sposan', 'towsol',\n       'wantat1', 'warwhe1', 'wesmea', 'wessan', 'wetshe', 'whfibi',\n       'whiter', 'whttro', 'wiltur', 'yebcar', 'yefcan', 'zebdov'])\n\n\ncfg.n_classes = len(cfg.birds)\n# dataset\ncfg.min_rating = 2.0\n\ncfg.wav_crop_len = 30  # seconds\n\ncfg.lr = 0.0001\ncfg.epochs = 5\ncfg.batch_size = 32\ncfg.batch_size_val = 32\n\n\ncfg.save_val_data = True\ncfg.mixed_precision = True\n\ncfg.mixup = True\ncfg.mix_beta = 1\n\n\ncfg.train_df1 = \"../input/birdclef-2022/train_metadata.csv\"\ncfg.train_df2 = \"../input/birdclef-2022-df-train-with-durations/df-with-durations.csv\"\n\n\ncfg.device = 'cuda' if torch.cuda.is_available() else 'cpu'\n\ncfg.tr_collate_fn = None\ncfg.val_collate_fn = None\ncfg.val = False\n\ncfg.dev = False\n\ncfg.model = \"RN34\"\n\ncfg","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:24.347455Z","iopub.execute_input":"2022-05-24T13:29:24.347869Z","iopub.status.idle":"2022-05-24T13:29:24.381924Z","shell.execute_reply.started":"2022-05-24T13:29:24.347831Z","shell.execute_reply":"2022-05-24T13:29:24.381215Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# cfg = importlib.import_module('default_config')\n# importlib.reload(cfg)\n# cfg = importlib.import_module('cfg_ps_6_v2')\n# importlib.reload(cfg)\n# cfg = copy(cfg.cfg)\n\nTEST_AUDIO_ROOT = \"../input/birdclef-2022/test_soundscapes/\"\ncfg.val_data_folder = TEST_AUDIO_ROOT\ncfg.pretrained = False\n\n\nprint(cfg.model, cfg.dataset, cfg.backbone, cfg.pretrained_weights, cfg.mel_norm)\n","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:24.427800Z","iopub.execute_input":"2022-05-24T13:29:24.428095Z","iopub.status.idle":"2022-05-24T13:29:24.435730Z","shell.execute_reply.started":"2022-05-24T13:29:24.428054Z","shell.execute_reply":"2022-05-24T13:29:24.434846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Compose:\n    def __init__(self, transforms: list):\n        self.transforms = transforms\n\n    def __call__(self, y: np.ndarray, sr):\n        for trns in self.transforms:\n            y = trns(y, sr)\n        return y\n\n\nclass AudioTransform:\n    def __init__(self, always_apply=False, p=0.5):\n        self.always_apply = always_apply\n        self.p = p\n\n    def __call__(self, y: np.ndarray, sr):\n        if self.always_apply:\n            return self.apply(y, sr=sr)\n        else:\n            if np.random.rand() < self.p:\n                return self.apply(y, sr=sr)\n            else:\n                return y\n\n    def apply(self, y: np.ndarray, **params):\n        raise NotImplementedError\n\n\nclass OneOf(Compose):\n    # https://github.com/albumentations-team/albumentations/blob/master/albumentations/core/composition.py\n    def __init__(self, transforms, p=0.5):\n        super().__init__(transforms)\n        self.p = p\n        transforms_ps = [t.p for t in transforms]\n        s = sum(transforms_ps)\n        self.transforms_ps = [t / s for t in transforms_ps]\n\n    def __call__(self, y: np.ndarray, sr):\n        data = y\n        if self.transforms_ps and (random.random() < self.p):\n            random_state = np.random.RandomState(random.randint(0, 2**32 - 1))\n            t = random_state.choice(self.transforms, p=self.transforms_ps)\n            data = t(y, sr)\n        return data\n\n\nclass Normalize(AudioTransform):\n    def __init__(self, always_apply=False, p=1):\n        super().__init__(always_apply, p)\n\n    def apply(self, y: np.ndarray, **params):\n        max_vol = np.abs(y).max()\n        y_vol = y * 1 / max_vol\n        return np.asfortranarray(y_vol)\n\n\nclass NewNormalize(AudioTransform):\n    def __init__(self, always_apply=False, p=1):\n        super().__init__(always_apply, p)\n\n    def apply(self, y: np.ndarray, **params):\n        y_mm = y - y.mean()\n        return y_mm / y_mm.abs().max()\n\n\nclass NoiseInjection(AudioTransform):\n    def __init__(self, always_apply=False, p=0.5, max_noise_level=0.5):\n        super().__init__(always_apply, p)\n\n        self.noise_level = (0.0, max_noise_level)\n\n    def apply(self, y: np.ndarray, **params):\n        noise_level = np.random.uniform(*self.noise_level)\n        noise = np.random.randn(len(y))\n        augmented = (y + noise * noise_level).astype(y.dtype)\n        return augmented\n\n\nclass GaussianNoise(AudioTransform):\n    def __init__(self, always_apply=False, p=0.5, min_snr=5, max_snr=20):\n        super().__init__(always_apply, p)\n\n        self.min_snr = min_snr\n        self.max_snr = max_snr\n\n    def apply(self, y: np.ndarray, **params):\n        snr = np.random.uniform(self.min_snr, self.max_snr)\n        a_signal = np.sqrt(y**2).max()\n        a_noise = a_signal / (10 ** (snr / 20))\n\n        white_noise = np.random.randn(len(y))\n        a_white = np.sqrt(white_noise**2).max()\n        augmented = (y + white_noise * 1 / a_white * a_noise).astype(y.dtype)\n        return augmented\n\n\nclass PinkNoise(AudioTransform):\n    def __init__(self, always_apply=False, p=0.5, min_snr=5, max_snr=20):\n        super().__init__(always_apply, p)\n\n        self.min_snr = min_snr\n        self.max_snr = max_snr\n\n    def apply(self, y: np.ndarray, **params):\n        snr = np.random.uniform(self.min_snr, self.max_snr)\n        a_signal = np.sqrt(y**2).max()\n        a_noise = a_signal / (10 ** (snr / 20))\n\n        pink_noise = cn.powerlaw_psd_gaussian(1, len(y))\n        a_pink = np.sqrt(pink_noise**2).max()\n        augmented = (y + pink_noise * 1 / a_pink * a_noise).astype(y.dtype)\n        return augmented\n\n\nclass PitchShift(AudioTransform):\n    def __init__(self, always_apply=False, p=0.5, max_range=5):\n        super().__init__(always_apply, p)\n        self.max_range = max_range\n\n    def apply(self, y: np.ndarray, sr, **params):\n        n_steps = np.random.randint(-self.max_range, self.max_range)\n        augmented = librosa.effects.pitch_shift(y, sr, n_steps)\n        return augmented\n\n\nclass TimeStretch(AudioTransform):\n    def __init__(self, always_apply=False, p=0.5, max_rate=1):\n        super().__init__(always_apply, p)\n        self.max_rate = max_rate\n\n    def apply(self, y: np.ndarray, **params):\n        rate = np.random.uniform(0, self.max_rate)\n        augmented = librosa.effects.time_stretch(y, rate)\n        return augmented\n\n\ndef _db2float(db: float, amplitude=True):\n    if amplitude:\n        return 10 ** (db / 20)\n    else:\n        return 10 ** (db / 10)\n\n\ndef volume_down(y: np.ndarray, db: float):\n    \"\"\"\n    Low level API for decreasing the volume\n    Parameters\n    ----------\n    y: numpy.ndarray\n        stereo / monaural input audio\n    db: float\n        how much decibel to decrease\n    Returns\n    -------\n    applied: numpy.ndarray\n        audio with decreased volume\n    \"\"\"\n    applied = y * _db2float(-db)\n    return applied\n\n\ndef volume_up(y: np.ndarray, db: float):\n    \"\"\"\n    Low level API for increasing the volume\n    Parameters\n    ----------\n    y: numpy.ndarray\n        stereo / monaural input audio\n    db: float\n        how much decibel to increase\n    Returns\n    -------\n    applied: numpy.ndarray\n        audio with increased volume\n    \"\"\"\n    applied = y * _db2float(db)\n    return applied\n\n\nclass RandomVolume(AudioTransform):\n    def __init__(self, always_apply=False, p=0.5, limit=10):\n        super().__init__(always_apply, p)\n        self.limit = limit\n\n    def apply(self, y: np.ndarray, **params):\n        db = np.random.uniform(-self.limit, self.limit)\n        if db >= 0:\n            return volume_up(y, db)\n        else:\n            return volume_down(y, db)\n\n\nclass CosineVolume(AudioTransform):\n    def __init__(self, always_apply=False, p=0.5, limit=10):\n        super().__init__(always_apply, p)\n        self.limit = limit\n\n    def apply(self, y: np.ndarray, **params):\n        db = np.random.uniform(-self.limit, self.limit)\n        cosine = np.cos(np.arange(len(y)) / len(y) * np.pi * 2)\n        dbs = _db2float(cosine * db)\n        return y * dbs","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:24.573375Z","iopub.execute_input":"2022-05-24T13:29:24.573579Z","iopub.status.idle":"2022-05-24T13:29:24.610878Z","shell.execute_reply.started":"2022-05-24T13:29:24.573549Z","shell.execute_reply":"2022-05-24T13:29:24.610189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def batch_to_device(batch, device):\n    batch_dict = {key: batch[key].to(device) for key in batch}\n    return batch_dict\n\n\n\nclass CustomDataset(Dataset):\n    def __init__(self, df, cfg, aug, mode=\"train\"):\n\n        self.cfg = cfg\n        self.mode = mode\n        self.df = df.copy()\n\n        self.bird2id = {bird: idx for idx, bird in enumerate(cfg.birds)}\n        if self.mode == \"train\":\n            self.data_folder = cfg.train_data_folder\n            self.df = self.df[self.df[\"rating\"] >= self.cfg.min_rating]\n        elif self.mode == \"val\":\n            self.data_folder = cfg.val_data_folder\n        elif self.mode == \"test\":\n            self.data_folder = cfg.test_data_folder\n\n        self.fns = self.df[\"filename\"].unique()\n\n        self.df = self.setup_df()\n\n\n\n    def setup_df(self):\n        df = self.df.copy()\n\n        if self.mode == \"train\":\n\n            df[\"weight\"] = np.clip(df[\"rating\"] / df[\"rating\"].max(), 0.1, 1.0)\n            df['target'] = df['primary_label'].apply(self.bird2id.get)\n            labels = np.eye(self.cfg.n_classes)[df[\"target\"].astype(int).values]\n            label2 = df[\"secondary_labels\"].apply(lambda x: self.secondary2target(x)).values\n            for i, t in enumerate(label2):\n                labels[i, t] = 1\n        else:\n            targets = df[\"birds\"].apply(lambda x: self.birds2target(x)).values\n#             labels = np.zeros((df.shape[0], self.cfg.n_classes))\n#             # import pdb; pdb.set_trace()\n#             for i, t in enumerate(targets):\n#                 labels[i, t] = 1\n\n#         df[[f\"t{i}\" for i in range(self.cfg.n_classes)]] = labels\n\n        if self.mode != \"train\":\n            df = df.groupby(\"filename\")\n\n        return df\n\n    def __getitem__(self, idx):\n\n        if self.mode == \"train\":\n            row = self.df.iloc[idx]\n            fn = row[\"filename\"]\n            label = row[[f\"t{i}\" for i in range(self.cfg.n_classes)]].values\n            weight = row[\"weight\"]\n            #fold = row[\"fold\"]\n            fold = -1\n\n            #wav_len = row[\"length\"]\n            parts = 1\n        else:\n            fn = self.fns[idx]\n            row = self.df.get_group(fn)\n            wav_len = None\n            # Este es mi \"entrada\" a que un audio dure mucho\n            parts = len(row)\n            fold = -1\n            weight = 1\n\n        if self.mode == \"train\":\n            #wav_len_sec = wav_len / self.cfg.sample_rate\n            wav_len_sec = row['duration']\n            duration = self.cfg.wav_crop_len\n            max_offset = wav_len_sec - duration\n            max_offset = max(max_offset, 1)\n            offset = np.random.randint(max_offset)\n        else:\n            offset = 0.0\n            duration = None\n\n        wav = self.load_one(fn, offset, duration)\n\n        if wav.shape[0] < (self.cfg.wav_crop_len * self.cfg.sample_rate):\n            pad = self.cfg.wav_crop_len * self.cfg.sample_rate - wav.shape[0]\n            wav = np.pad(wav, (0, pad))\n\n#         wav = self.aug_audio(wav, sr=self.cfg.sample_rate)\n\n        wav_tensor = torch.tensor(wav)  # (n_samples)\n        if parts > 1:\n            n_samples = wav_tensor.shape[0]\n            wav_tensor = wav_tensor[: n_samples // parts * parts].reshape(\n                parts, n_samples // parts\n            )\n\n        feature_dict = {\n            \"input\": wav_tensor,\n            \"weight\": torch.tensor(weight),\n            \"fold\": torch.tensor(fold),\n        }\n        return feature_dict\n\n    def __len__(self):\n        if cfg.dev:\n            return 256\n        return len(self.fns)\n\n    def load_one(self, id_, offset, duration):\n        fp = self.data_folder + id_\n        try:\n            wav, sr = librosa.load(fp, sr=None, offset=offset, duration=duration)\n        except:\n            print(\"FAIL READING rec\", fp)\n\n        return wav\n\n    def birds2target(self, birds):\n        #birds = birds.split()\n        target = [self.bird2id.get(item) for item in birds if not item == \"nocall\"]\n        return target\n\n    def secondary2target(self, secondary_label):\n        birds = ast.literal_eval(secondary_label)\n        target = [self.bird2id.get(item) for item in birds if not item == \"nocall\"]\n        return target\n","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:24.667635Z","iopub.execute_input":"2022-05-24T13:29:24.667822Z","iopub.status.idle":"2022-05-24T13:29:24.690165Z","shell.execute_reply.started":"2022-05-24T13:29:24.667800Z","shell.execute_reply":"2022-05-24T13:29:24.689295Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def 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.0 / p)\n\n\nclass GeM(nn.Module):\n    # Generalized mean: https://arxiv.org/abs/1711.02512\n    def __init__(self, p=3, eps=1e-6):\n        super(GeM, self).__init__()\n        self.p = Parameter(torch.ones(1) * p)\n        self.eps = eps\n\n    def forward(self, x):\n        ret = gem(x, p=self.p, eps=self.eps)\n        return ret\n\n    def __repr__(self):\n        return (self.__class__.__name__+ \"(p=\"+ \"{:.4f}\".format(self.p.data.tolist()[0])+ \", eps=\"+ str(self.eps)+ \")\")\n\n\nclass Mixup(nn.Module):\n    def __init__(self, mix_beta):\n\n        super(Mixup, self).__init__()\n        self.beta_distribution = Beta(mix_beta, mix_beta)\n\n    def forward(self, X, Y, weight=None):\n\n        bs = X.shape[0]\n        n_dims = len(X.shape)\n        perm = torch.randperm(bs)\n        coeffs = self.beta_distribution.rsample(torch.Size((bs,))).to(X.device)\n\n        if n_dims == 2:\n            X = coeffs.view(-1, 1) * X + (1 - coeffs.view(-1, 1)) * X[perm]\n        elif n_dims == 3:\n            X = coeffs.view(-1, 1, 1) * X + (1 - coeffs.view(-1, 1, 1)) * X[perm]\n        else:\n            X = coeffs.view(-1, 1, 1, 1) * X + (1 - coeffs.view(-1, 1, 1, 1)) * X[perm]\n\n        Y = coeffs.view(-1, 1) * Y + (1 - coeffs.view(-1, 1)) * Y[perm]\n\n        if weight is None:\n            return X, Y\n        else:\n            weight = coeffs.view(-1) * weight + (1 - coeffs.view(-1)) * weight[perm]\n            return X, Y, weight\n\n        \n        \nclass Net(nn.Module):\n    def __init__(self, cfg):\n        super(Net, self).__init__()\n\n        self.cfg = cfg\n\n        self.n_classes = cfg.n_classes\n\n        self.mel_spec = ta.transforms.MelSpectrogram(\n            sample_rate=cfg.sample_rate,\n            n_fft=cfg.window_size,\n            win_length=cfg.window_size,\n            hop_length=cfg.hop_size,\n            f_min=cfg.fmin,\n            f_max=cfg.fmax,\n            pad=0,\n            n_mels=cfg.mel_bins,\n            power=cfg.power,\n            normalized=False,\n        )\n\n        self.amplitude_to_db = ta.transforms.AmplitudeToDB(top_db=cfg.top_db)\n        self.wav2img = torch.nn.Sequential(self.mel_spec, self.amplitude_to_db)\n\n        self.backbone = timm.create_model(\n            cfg.backbone,\n            pretrained=cfg.pretrained,\n            num_classes=0,\n            global_pool=\"\",\n            in_chans=cfg.in_chans,\n            drop_path_rate=0.1\n        )\n\n        if \"efficientnet\" in cfg.backbone:\n            backbone_out = self.backbone.num_features\n        else:\n            backbone_out = self.backbone.feature_info[-1][\"num_chs\"]\n\n        self.global_pool = GeM()\n\n        self.head = nn.Linear(backbone_out, self.n_classes)\n\n        if cfg.pretrained_weights is not None:\n            sd = torch.load(cfg.pretrained_weights, map_location=\"cpu\")[\"model\"]\n            sd = {k.replace(\"module.\", \"\"): v for k, v in sd.items()}\n            self.load_state_dict(sd, strict=True)\n            print(\"weights loaded from\", cfg.pretrained_weights)\n        self.loss_fn = nn.BCEWithLogitsLoss(reduction=\"none\")\n\n        self.mixup = Mixup(mix_beta=cfg.mix_beta)\n\n        self.factor = int(cfg.wav_crop_len / 5.0)\n\n    def forward(self, batch):\n\n        if not self.training:\n            x = batch[\"input\"]\n            x = x / x.abs().amax(keepdim=True) # Normalize\n            bs, parts, time = x.shape\n            x = x.reshape(parts, time)\n        else:\n            x = batch[\"input\"]\n            y = batch[\"target\"]\n            bs, time = x.shape\n            x = x.reshape(bs * self.factor, time // self.factor)\n\n        with autocast(enabled=False):\n            x = self.wav2img(x)  # (bs, mel, time)\n            if self.cfg.mel_norm:\n                x = (x + 80) / 80\n\n        x = x.permute(0, 2, 1)\n        x = x[:, None, :, :]\n\n        weight = batch[\"weight\"]\n\n        if self.training:\n            b, c, t, f = x.shape\n            x = x.permute(0, 2, 1, 3)\n            x = x.reshape(b // self.factor, self.factor * t, c, f)\n\n            if self.cfg.mixup:\n                x, y, weight = self.mixup(x, y, weight)\n            if self.cfg.mixup2:\n                x, y, weight = self.mixup(x, y, weight)\n\n            x = x.reshape(b, t, c, f)\n            x = x.permute(0, 2, 1, 3)\n\n        x = self.backbone(x)\n\n        if self.training:\n            b, c, t, f = x.shape\n            x = x.permute(0, 2, 1, 3)\n            x = x.reshape(b // self.factor, self.factor * t, c, f)\n            x = x.permute(0, 2, 1, 3)\n        x = self.global_pool(x)\n        x = x[:, :, 0, 0]\n        logits = self.head(x)\n\n        return {\"logits\": logits.sigmoid(), \"logits_raw\": logits}\n","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:24.756137Z","iopub.execute_input":"2022-05-24T13:29:24.756486Z","iopub.status.idle":"2022-05-24T13:29:24.787066Z","shell.execute_reply.started":"2022-05-24T13:29:24.756456Z","shell.execute_reply":"2022-05-24T13:29:24.786396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MSDNet(nn.Module):\n    def __init__(self, cfg):\n        super(MSDNet, self).__init__()\n\n        self.cfg = cfg\n\n        self.n_classes = cfg.n_classes\n\n        self.mel_spec = ta.transforms.MelSpectrogram(\n            sample_rate=cfg.sample_rate,\n            n_fft=cfg.window_size,\n            win_length=cfg.window_size,\n            hop_length=cfg.hop_size,\n            f_min=cfg.fmin,\n            f_max=cfg.fmax,\n            pad=0,\n            n_mels=cfg.mel_bins,\n            power=cfg.power,\n            normalized=False,\n        )\n\n        self.amplitude_to_db = ta.transforms.AmplitudeToDB(top_db=cfg.top_db)\n        self.wav2img = torch.nn.Sequential(self.mel_spec, self.amplitude_to_db)\n\n        self.backbone = timm.create_model(\n            cfg.backbone,\n            pretrained=cfg.pretrained,\n            num_classes=0,\n            global_pool=\"\",\n            in_chans=cfg.in_chans,\n            drop_path_rate=0.1\n        )\n\n        if \"efficientnet\" in cfg.backbone:\n            backbone_out = self.backbone.num_features\n        else:\n            backbone_out = self.backbone.feature_info[-1][\"num_chs\"]\n\n        self.global_pool = GeM()\n\n#         self.head = nn.Linear(backbone_out, self.n_classes)\n\n        if cfg.pretrained_weights is not None:\n            sd = torch.load(cfg.pretrained_weights, map_location=\"cpu\")[\"model\"]\n            sd = {k.replace(\"module.\", \"\"): v for k, v in sd.items()}\n            self.load_state_dict(sd, strict=True)\n            print(\"weights loaded from\", cfg.pretrained_weights)\n        self.loss_fn = nn.BCEWithLogitsLoss(reduction=\"none\")\n\n        self.mixup = Mixup(mix_beta=cfg.mix_beta)\n\n        self.factor = int(cfg.wav_crop_len / 5.0)\n        self.big_dropout = nn.Dropout(p=0.5)\n        hidden_dims = 512\n        self.classifier = nn.Sequential(\n            nn.Linear(backbone_out, hidden_dims),\n            nn.ReLU(),\n            nn.Dropout(p=0.2),\n            nn.Linear(hidden_dims, hidden_dims),\n            nn.ReLU(),\n            nn.Dropout(p=0.2),\n            nn.Linear(hidden_dims, self.n_classes),\n        )\n\n    def forward(self, batch):\n\n        if not self.training:\n            x = batch[\"input\"]\n            x = x / x.abs().amax(keepdim=True) # Normalize\n            bs, parts, time = x.shape\n            x = x.reshape(parts, time)\n        else:\n            x = batch[\"input\"]\n            y = batch[\"target\"]\n            bs, time = x.shape\n            x = x.reshape(bs * self.factor, time // self.factor)\n\n        with autocast(enabled=False):\n            x = self.wav2img(x)  # (bs, mel, time)\n            if self.cfg.mel_norm:\n                x = (x + 80) / 80\n\n        x = x.permute(0, 2, 1)\n        x = x[:, None, :, :]\n\n        weight = batch[\"weight\"]\n\n        x = self.backbone(x)\n\n        x = self.global_pool(x)\n        x = x[:, :, 0, 0]\n#         logits = self.head(x)\n        logits = torch.mean(torch.stack([self.classifier(self.big_dropout(x)) for _ in range(5)], dim=0), dim=0)\n\n\n        return {\"logits\": logits.sigmoid(), \"logits_raw\": logits}","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:24.841084Z","iopub.execute_input":"2022-05-24T13:29:24.841461Z","iopub.status.idle":"2022-05-24T13:29:24.859124Z","shell.execute_reply.started":"2022-05-24T13:29:24.841432Z","shell.execute_reply":"2022-05-24T13:29:24.858428Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class BinaryNet(nn.Module):\n    def __init__(self, cfg):\n        super(BinaryNet, self).__init__()\n\n        self.cfg = cfg\n\n        self.n_classes = cfg.n_classes\n\n        self.mel_spec = ta.transforms.MelSpectrogram(\n            sample_rate=cfg.sample_rate,\n            n_fft=cfg.window_size,\n            win_length=cfg.window_size,\n            hop_length=cfg.hop_size,\n            f_min=cfg.fmin,\n            f_max=cfg.fmax,\n            pad=0,\n            n_mels=cfg.mel_bins,\n            power=cfg.power,\n            normalized=False,\n        )\n\n        self.amplitude_to_db = ta.transforms.AmplitudeToDB(top_db=cfg.top_db)\n        self.wav2img = torch.nn.Sequential(self.mel_spec, self.amplitude_to_db)\n\n        self.backbone = timm.create_model(\n            cfg.backbone,\n            pretrained=cfg.pretrained,\n            num_classes=0,\n            global_pool=\"\",\n            in_chans=cfg.in_chans,\n        )\n\n        if \"efficientnet\" in cfg.backbone:\n            backbone_out = self.backbone.num_features\n        else:\n            backbone_out = self.backbone.feature_info[-1][\"num_chs\"]\n\n        self.global_pool = GeM()\n\n        self.head = nn.Linear(backbone_out, self.n_classes)\n        self.bn0 = nn.InstanceNorm2d(1)\n        self.loss_fn = nn.BCEWithLogitsLoss(reduction=\"none\")\n\n        self.mixup = Mixup(mix_beta=cfg.mix_beta)\n        self.att = nn.Sequential(nn.Linear(backbone_out, 512), nn.ReLU(), nn.Linear(512, 1))\n\n        if cfg.pretrained_weights is not None:\n            sd = torch.load(cfg.pretrained_weights, map_location=\"cpu\")[\"model\"]\n            sd = {k.replace(\"module.\", \"\"): v for k, v in sd.items()}\n            self.load_state_dict(sd, strict=True)\n            print(\"weights loaded from\", cfg.pretrained_weights)\n\n    def forward(self, batch):\n\n        if self.training:\n            x = batch[\"input\"]\n            y = batch[\"target\"]\n            bs, time = x.shape\n\n        else:\n            x = batch[\"input\"]\n            bs, parts, time = x.shape\n            x = x.reshape(parts, time)\n            # y = batch[\"target\"]\n            # y = y[0]\n\n        with autocast(enabled=False):\n            x = self.wav2img(x)  # (8, 256, 1876)\n            if self.cfg.mel_norm:\n                x = (x + 80) / 80\n\n        x = x.permute(0, 2, 1)\n        x = x[:, None, :, :]\n        x = self.bn0(x)\n\n        weight = batch[\"weight\"]\n\n        if self.training:\n            if np.random.random() <= self.cfg.mixup:\n                x, y, weight = self.mixup(x, y, weight)\n            if np.random.random() <= self.cfg.mixup2:\n                x, y, weight = self.mixup(x, y, weight)\n\n        x = self.backbone(x)  # (8, 512, 59, 8)\n        x = x.mean(3)  # pool freq\n        x = x.permute(0, 2, 1)  # bs, time, feats\n\n        att_weights = torch.softmax(self.att(x), dim=1)\n        x2 = (x * att_weights).sum(1)\n\n        logits = self.head(x2)  # (batch_size, classes)\n\n        return {\"logits\": logits.sigmoid()}","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:24.971598Z","iopub.execute_input":"2022-05-24T13:29:24.971879Z","iopub.status.idle":"2022-05-24T13:29:24.990372Z","shell.execute_reply.started":"2022-05-24T13:29:24.971850Z","shell.execute_reply":"2022-05-24T13:29:24.989557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_state_dict(sd_fp):\n    sd = torch.load(sd_fp, map_location=\"cpu\")['model']\n    sd = {k.replace(\"module.\", \"\"):v for k,v in sd.items()}\n    return sd\n\nfrom scipy.stats.mstats import gmean","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:25.067893Z","iopub.execute_input":"2022-05-24T13:29:25.068080Z","iopub.status.idle":"2022-05-24T13:29:25.073888Z","shell.execute_reply.started":"2022-05-24T13:29:25.068057Z","shell.execute_reply":"2022-05-24T13:29:25.073071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import math\n# wv, sr = librosa.load(\"../input/birdclef-2022/test_soundscapes/soundscape_453028782.ogg\")\n# list(range(1, math.ceil(((len(wv)) / sr) / 5)+1))","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:25.164864Z","iopub.execute_input":"2022-05-24T13:29:25.165161Z","iopub.status.idle":"2022-05-24T13:29:25.168732Z","shell.execute_reply.started":"2022-05-24T13:29:25.165132Z","shell.execute_reply":"2022-05-24T13:29:25.167797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import json\n\nTEST_AUDIO_PATH = '../input/birdclef-2022/test_soundscapes/'\n\nwith open('../input/birdclef-2022/scored_birds.json') as fp:\n    SCORED_BIRDS = json.load(fp)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:25.299494Z","iopub.execute_input":"2022-05-24T13:29:25.299778Z","iopub.status.idle":"2022-05-24T13:29:25.304704Z","shell.execute_reply.started":"2022-05-24T13:29:25.299750Z","shell.execute_reply":"2022-05-24T13:29:25.303929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_df_test_from_path():\n    files = sorted(os.listdir(TEST_AUDIO_PATH))\n    data = []\n    for f in files:\n        wv, sr = librosa.load(TEST_AUDIO_PATH + f)\n        n_chunks = math.ceil(len(wv) / sr / 5)\n        filename = f\n        row_prefix = f[:-4]\n        bird = SCORED_BIRDS[0]\n        for chunk in range(1, n_chunks + 1):\n            #for bird in SCORED_BIRDS:\n            #row_id = f\"{f[:-4]}_{bird}_{chunk*5}\"\n            \n            ending_second = chunk*5\n            data.append((filename, row_prefix, ending_second, [bird]))\n            \n    return  pd.DataFrame(data, columns=['filename', 'row_prefix', 'ending_second', 'birds'])\n        \ntest_df = create_df_test_from_path()","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:25.397232Z","iopub.execute_input":"2022-05-24T13:29:25.397677Z","iopub.status.idle":"2022-05-24T13:29:27.023232Z","shell.execute_reply.started":"2022-05-24T13:29:25.397649Z","shell.execute_reply":"2022-05-24T13:29:27.022317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(test_df.shape)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:27.025161Z","iopub.execute_input":"2022-05-24T13:29:27.025520Z","iopub.status.idle":"2022-05-24T13:29:27.042929Z","shell.execute_reply.started":"2022-05-24T13:29:27.025477Z","shell.execute_reply":"2022-05-24T13:29:27.042195Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.tail()","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:27.044150Z","iopub.execute_input":"2022-05-24T13:29:27.045724Z","iopub.status.idle":"2022-05-24T13:29:27.056237Z","shell.execute_reply.started":"2022-05-24T13:29:27.045686Z","shell.execute_reply":"2022-05-24T13:29:27.055584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"N_CORES = 2\ncfg.batch_size = 1\n\naug = None\ntest_ds = CustomDataset(test_df, cfg, aug, mode=\"val\")\ntest_dl = DataLoader(test_ds, shuffle=False, batch_size = cfg.batch_size, num_workers = N_CORES, pin_memory=True)\n\ntest_ds[0]","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:27.058122Z","iopub.execute_input":"2022-05-24T13:29:27.058524Z","iopub.status.idle":"2022-05-24T13:29:27.129400Z","shell.execute_reply.started":"2022-05-24T13:29:27.058488Z","shell.execute_reply":"2022-05-24T13:29:27.128527Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DEVICE = \"cuda\" if torch.cuda.is_available() else 'cpu'","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:27.130827Z","iopub.execute_input":"2022-05-24T13:29:27.131102Z","iopub.status.idle":"2022-05-24T13:29:27.135855Z","shell.execute_reply.started":"2022-05-24T13:29:27.131065Z","shell.execute_reply":"2022-05-24T13:29:27.134818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# bird classification models\ncfg.backbone = \"eca_nfnet_l0\"\nstate_dict = \"../input/bird22-clf-models/eca_nfnet_l0_0.7092.pth\"\n\nnet1 = Net(cfg).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nnet1.load_state_dict(sd, strict=True)\n\n\ncfg.backbone = \"tf_efficientnetv2_s_in21k\"\nstate_dict = \"../input/bird22-clf-models/effv2s_best_score_seed123_0.6936.pth\"\n\nnet2 = Net(cfg).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nnet2.load_state_dict(sd, strict=True)\n\n\ncfg.backbone = \"eca_nfnet_l0\"\nstate_dict = \"../input/bird2022-models3/allfold_last_seed8864_0.81120.pth\"\n\nnet3 = MSDNet(cfg).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nnet3.load_state_dict(sd, strict=True)\n\n\ncfg.backbone = \"resnet34\"\nstate_dict = \"../input/bird22-clf-models/resnet34_0.6859.pth\"\n\nnet4 = Net(cfg).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nnet4.load_state_dict(sd, strict=True)\n\n\ncfg.backbone = \"convnext_tiny\"\nstate_dict = \"../input/bird2022-models3/convnext_tiny_fold2_best_score_seed323_0.6707.pth\"\n\nnet5 = MSDNet(cfg).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nnet5.load_state_dict(sd, strict=True)\n\n\n# MSD Models\ncfg.backbone = \"eca_nfnet_l0\"\nstate_dict = \"../input/bird2020models2/ecal0_msd_fold2_seed64_0.7744.pth\"\n\nnet6 = MSDNet(cfg).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nnet6.load_state_dict(sd, strict=True)\n\n\n\nr34_cfg = copy(cfg)\n\nr34_cfg.backbone = \"resnet34\"\nr34_cfg.window_size = 2048\nr34_cfg.hop_size = 512\nr34_cfg.fmin = 16\nr34_cfg.fmax = 16386\nr34_cfg.mel_bins = 256\n\nstate_dict = \"../input/bird2020models2/r34_fold3_best_score_seed123_0.4884.pth\"\nnet7 = MSDNet(r34_cfg).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nnet7.load_state_dict(sd, strict=True)\n\n\ncfg.backbone = \"eca_nfnet_l0\"\nstate_dict = \"../input/bird2020models2/ecal0_fold4_seed64_0.5013.pth\"\n\nnet8 = MSDNet(cfg).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nnet8.load_state_dict(sd, strict=True)\n\n\ncfg.backbone = \"tf_efficientnetv2_s_in21k\"\nstate_dict = \"../input/bird2022-models3/effv2s_msd_fold2_best_score_seed42_0.7339.pth\"\n\nnet9 = MSDNet(cfg).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nnet9.load_state_dict(sd, strict=True)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:27.137423Z","iopub.execute_input":"2022-05-24T13:29:27.137692Z","iopub.status.idle":"2022-05-24T13:29:32.952201Z","shell.execute_reply.started":"2022-05-24T13:29:27.137655Z","shell.execute_reply":"2022-05-24T13:29:32.951489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# binary classificaton model\ncfg_bin = copy(cfg)\ncfg_bin.window_size = 2048\ncfg_bin.hop_size = 512\ncfg_bin.sample_rate = 32000\ncfg_bin.fmin = 16\ncfg_bin.fmax = 16386\ncfg_bin.power = 2\ncfg_bin.mel_bins = 256\ncfg_bin.top_db = 80.0\ncfg_bin.backbone = \"tf_efficientnet_b0_ns\"\ncfg_bin.birds = np.array([\"bird\"])\ncfg_bin.n_classes = len(cfg_bin.birds)\n\nstate_dict = \"../input/bird2020models2/binary_checkpoint_last_seed122615.pth\"\n\nbin_net1 = BinaryNet(cfg_bin).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nbin_net1.load_state_dict(sd, strict=True)\n\n\nstate_dict = \"../input/2ndplacebirdclef2021-models/pp_binary_ext3_1/checkpoint_last_seed594730.pth\"\n\nbin_net2 = BinaryNet(cfg_bin).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nbin_net2.load_state_dict(sd, strict=True)\n\n\n\n\ncfg_bin.backbone = \"seresnext26t_32x4d\"\nstate_dict = \"../input/2ndplacebirdclef2021-models/pp_binary_ext3_2/checkpoint_last_seed660619.pth\"\nbin_net3 = BinaryNet(cfg_bin).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nbin_net3.load_state_dict(sd, strict=True)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:32.953772Z","iopub.execute_input":"2022-05-24T13:29:32.954287Z","iopub.status.idle":"2022-05-24T13:29:33.889536Z","shell.execute_reply.started":"2022-05-24T13:29:32.954232Z","shell.execute_reply":"2022-05-24T13:29:33.888759Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# list(net1.global_pool.parameters()), list(bin_net.global_pool.parameters())","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:33.891221Z","iopub.execute_input":"2022-05-24T13:29:33.891749Z","iopub.status.idle":"2022-05-24T13:29:33.896758Z","shell.execute_reply.started":"2022-05-24T13:29:33.891706Z","shell.execute_reply":"2022-05-24T13:29:33.895729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def flatten(l):\n    return [item for sublist in l for item in sublist]","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:33.899852Z","iopub.execute_input":"2022-05-24T13:29:33.900154Z","iopub.status.idle":"2022-05-24T13:29:33.907033Z","shell.execute_reply.started":"2022-05-24T13:29:33.900114Z","shell.execute_reply":"2022-05-24T13:29:33.906259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with torch.no_grad():\n    preds1 = []\n    bin_preds = []\n    for batch in tqdm(test_dl):\n        batch = batch_to_device(batch, DEVICE)\n        with torch.cuda.amp.autocast():\n            out1 = net1(batch)['logits']\n            out2 = net2(batch)['logits']\n            out3 = net3(batch)['logits']\n            out4 = net4(batch)['logits']\n            out5 = net5(batch)['logits']\n            out6 = net6(batch)['logits']\n            out7 = net7(batch)['logits']\n            out8 = net8(batch)['logits']\n            out9 = net9(batch)['logits']\n\n            out = out1*0.15+out2*0.15+out3*0.15+out4*0.05+out5*0.1+out6*0.1+out7*0.15+out8*0.1+out9*0.05\n            preds1 += [out.cpu().numpy()]\n            \n            bin_out1 = bin_net1(batch)[\"logits\"]\n            bin_out2 = bin_net2(batch)[\"logits\"]\n            bin_out3 = bin_net3(batch)[\"logits\"]\n            \n            bin_out = (bin_out1+bin_out2+bin_out3)/3\n            bin_preds += [bin_out.cpu().numpy()]\n\npreds1 = np.vstack(preds1).astype(np.float32)\nbin_preds = np.vstack(bin_preds)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:33.908592Z","iopub.execute_input":"2022-05-24T13:29:33.908973Z","iopub.status.idle":"2022-05-24T13:29:34.544352Z","shell.execute_reply.started":"2022-05-24T13:29:33.908931Z","shell.execute_reply":"2022-05-24T13:29:34.543523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # preds1 = preds1 * (1 + (bin_preds * 0.8))\n# bin_preds\npreds1 = preds1 * (1 + (bin_preds * 0.1))","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:34.546040Z","iopub.execute_input":"2022-05-24T13:29:34.546330Z","iopub.status.idle":"2022-05-24T13:29:34.551091Z","shell.execute_reply.started":"2022-05-24T13:29:34.546257Z","shell.execute_reply":"2022-05-24T13:29:34.549989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# thresh = np.percentile(preds1.ravel(), 92)\n# thresh","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:34.552507Z","iopub.execute_input":"2022-05-24T13:29:34.552898Z","iopub.status.idle":"2022-05-24T13:29:34.560919Z","shell.execute_reply.started":"2022-05-24T13:29:34.552861Z","shell.execute_reply":"2022-05-24T13:29:34.560160Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_preds = pd.DataFrame(preds1, columns=test_ds.bird2id.keys())[SCORED_BIRDS]\ndf_preds.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:34.563788Z","iopub.execute_input":"2022-05-24T13:29:34.563980Z","iopub.status.idle":"2022-05-24T13:29:34.591017Z","shell.execute_reply.started":"2022-05-24T13:29:34.563958Z","shell.execute_reply":"2022-05-24T13:29:34.590212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# thresh_o = pd.Series(np.percentile(df_preds.values, 90, axis=0), index=df_preds.columns)\n# thresh_o","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:34.593982Z","iopub.execute_input":"2022-05-24T13:29:34.594174Z","iopub.status.idle":"2022-05-24T13:29:34.600760Z","shell.execute_reply.started":"2022-05-24T13:29:34.594151Z","shell.execute_reply":"2022-05-24T13:29:34.599852Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_preds[\"binary_pred\"] = bin_preds\n\n# binary classifierはcall\ndf_preds[\"binary_call\"] = df_preds[\"binary_pred\"] > 0.7","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:34.601977Z","iopub.execute_input":"2022-05-24T13:29:34.603110Z","iopub.status.idle":"2022-05-24T13:29:34.611281Z","shell.execute_reply.started":"2022-05-24T13:29:34.603075Z","shell.execute_reply":"2022-05-24T13:29:34.610537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = test_df.join(df_preds).drop(['birds'], axis=1).reset_index()","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:34.612458Z","iopub.execute_input":"2022-05-24T13:29:34.612730Z","iopub.status.idle":"2022-05-24T13:29:34.623703Z","shell.execute_reply.started":"2022-05-24T13:29:34.612696Z","shell.execute_reply":"2022-05-24T13:29:34.622960Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_mean_score(df):\n    z0 = df[SCORED_BIRDS]\n    z1 = df.groupby(\"row_prefix\")[SCORED_BIRDS].shift(1).bfill()\n    z2 = df.groupby(\"row_prefix\")[SCORED_BIRDS].shift(-1).ffill()\n    z3 = df.groupby(\"row_prefix\")[SCORED_BIRDS].shift(2).bfill()\n    z4 = df.groupby(\"row_prefix\")[SCORED_BIRDS].shift(-2).ffill()\n    \n    z_ave = np.average([z0,z1,z2,z3,z4], axis=0, weights=[7,1.2,1.2, 0.3, 0.3])\n    df[SCORED_BIRDS] = z_ave\n    return df\n\ntest_df = make_mean_score(test_df)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:34.625282Z","iopub.execute_input":"2022-05-24T13:29:34.625744Z","iopub.status.idle":"2022-05-24T13:29:34.652561Z","shell.execute_reply.started":"2022-05-24T13:29:34.625708Z","shell.execute_reply":"2022-05-24T13:29:34.651898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"thresh = pd.Series(np.percentile(test_df[SCORED_BIRDS].values, 90, axis=0), index=test_df[SCORED_BIRDS].columns)\nthresh","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:34.653832Z","iopub.execute_input":"2022-05-24T13:29:34.654073Z","iopub.status.idle":"2022-05-24T13:29:34.664743Z","shell.execute_reply.started":"2022-05-24T13:29:34.654041Z","shell.execute_reply":"2022-05-24T13:29:34.663873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.melt(test_df, id_vars=['filename', 'row_prefix', 'ending_second', 'binary_call'], value_vars=SCORED_BIRDS, var_name=\"bird\", value_name=\"proba\")\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:34.666223Z","iopub.execute_input":"2022-05-24T13:29:34.666570Z","iopub.status.idle":"2022-05-24T13:29:34.683894Z","shell.execute_reply.started":"2022-05-24T13:29:34.666537Z","shell.execute_reply":"2022-05-24T13:29:34.683128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df['row_id'] = test_df['row_prefix'] + \"_\" + test_df['bird'] + \"_\" + test_df['ending_second'].astype(str)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:34.685046Z","iopub.execute_input":"2022-05-24T13:29:34.685344Z","iopub.status.idle":"2022-05-24T13:29:34.699123Z","shell.execute_reply.started":"2022-05-24T13:29:34.685311Z","shell.execute_reply":"2022-05-24T13:29:34.698323Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# test_df['target'] = test_df['proba'] > thresh\nbirdwise_thresh = test_df.bird.replace(thresh)\ntest_df[\"target\"] = test_df[\"proba\"] > birdwise_thresh\n\n# binaryでcall判定された行は閾値を緩和\n# test_df.loc[test_df[\"binary_call\"], 'target'] = \\\n#     test_df.loc[test_df[\"binary_call\"], 'proba'] > (birdwise_thresh[test_df[\"binary_call\"]] * 0.68)\n\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:39.767019Z","iopub.execute_input":"2022-05-24T13:29:39.767316Z","iopub.status.idle":"2022-05-24T13:29:39.785793Z","shell.execute_reply.started":"2022-05-24T13:29:39.767275Z","shell.execute_reply":"2022-05-24T13:29:39.784810Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = test_df[['row_id', 'target']]\nsub.to_csv(\"submission.csv\", index=False)\nsub.head()","metadata":{"execution":{"iopub.status.busy":"2022-05-24T13:29:40.554538Z","iopub.execute_input":"2022-05-24T13:29:40.554801Z","iopub.status.idle":"2022-05-24T13:29:40.569491Z","shell.execute_reply.started":"2022-05-24T13:29:40.554772Z","shell.execute_reply":"2022-05-24T13:29:40.568657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2022-05-21T11:38:29.783451Z","iopub.execute_input":"2022-05-21T11:38:29.783719Z","iopub.status.idle":"2022-05-21T11:38:29.787713Z","shell.execute_reply.started":"2022-05-21T11:38:29.783662Z","shell.execute_reply":"2022-05-21T11:38:29.786871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}