{"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/torchaudio-0.8.1-cp37-cp37m-manylinux1_x86_64.whl ../input/birds-inference-pip-wheels/torch-1.8.1-cp37-cp37m-manylinux1_x86_64.whl\n!pip install ../input/birds-inference-pip-wheels/timm-0.4.8.zip --no-index --no-deps\n#!pip install ../input/birdclef21trainmeta/timm-0.4.9_23052021/pytorch-image-models-master --no-index --no-deps\n!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-04-16T20:43:43.581636Z","iopub.execute_input":"2022-04-16T20:43:43.582264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import timm\ntimm.__version__","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\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\n","metadata":{"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":{"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 = 2048\ncfg.hop_size = 512\ncfg.sample_rate = 32000\ncfg.fmin = 16\ncfg.fmax = 16386\ncfg.power = 2\ncfg.mel_bins = 256\ncfg.top_db = 80.0\n\n# img model\ncfg.backbone = \"resnet18\"\ncfg.pretrained = True\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 = False\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 = 64\ncfg.batch_size_val = 64\ncfg.backbone = \"resnet34\"\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":{"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":{"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        self.aug_audio = cfg.train_aug\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            label = row[[f\"t{i}\" for i in range(self.cfg.n_classes)]].values\n            wav_len = None\n            # Este es mi \"entrada\" a que un audio dure mucho\n            parts = label.shape[0]\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        if self.mode == \"train\":\n            if self.aug_audio:\n                wav = self.aug_audio(samples=wav, sample_rate=self.cfg.sample_rate)\n        else:\n            if self.cfg.val_aug:\n                wav = self.cfg.val_aug(samples=wav, sample_rate=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            \"target\": torch.tensor(label.astype(np.float32)),\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":{"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        )\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            bs, parts, time = x.shape\n            x = x.reshape(parts, time)\n            y = batch[\"target\"]\n            y = y[0]\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        loss = self.loss_fn(logits, y)\n        loss = (loss.mean(dim=1) * weight) / weight.sum()\n        loss = loss.sum()\n\n        return {\"loss\": loss, \"logits\": logits.sigmoid(), \"logits_raw\": logits, \"target\": y}\n","metadata":{"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":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wv, sr = librosa.load(\"../input/birdclef-2022/test_soundscapes/soundscape_453028782.ogg\")","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:30:56.41498Z","iopub.execute_input":"2022-03-02T00:30:56.41538Z","iopub.status.idle":"2022-03-02T00:30:58.846511Z","shell.execute_reply.started":"2022-03-02T00:30:56.415347Z","shell.execute_reply":"2022-03-02T00:30:58.845667Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import math\nlist(range(1, math.ceil(((len(wv)) / sr) / 5)+1))","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:30:58.847941Z","iopub.execute_input":"2022-03-02T00:30:58.848268Z","iopub.status.idle":"2022-03-02T00:30:58.857596Z","shell.execute_reply.started":"2022-03-02T00:30:58.848211Z","shell.execute_reply":"2022-03-02T00:30:58.856888Z"},"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-03-02T00:30:58.858996Z","iopub.execute_input":"2022-03-02T00:30:58.859961Z","iopub.status.idle":"2022-03-02T00:30:58.872209Z","shell.execute_reply.started":"2022-03-02T00:30:58.859921Z","shell.execute_reply":"2022-03-02T00:30:58.871503Z"},"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-03-02T00:30:58.873414Z","iopub.execute_input":"2022-03-02T00:30:58.873848Z","iopub.status.idle":"2022-03-02T00:31:00.502554Z","shell.execute_reply.started":"2022-03-02T00:30:58.873807Z","shell.execute_reply":"2022-03-02T00:31:00.501832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(test_df.shape)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:31:00.504151Z","iopub.execute_input":"2022-03-02T00:31:00.504391Z","iopub.status.idle":"2022-03-02T00:31:00.52119Z","shell.execute_reply.started":"2022-03-02T00:31:00.504358Z","shell.execute_reply":"2022-03-02T00:31:00.520392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.tail()","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:31:00.522496Z","iopub.execute_input":"2022-03-02T00:31:00.522752Z","iopub.status.idle":"2022-03-02T00:31:00.536155Z","shell.execute_reply.started":"2022-03-02T00:31:00.52272Z","shell.execute_reply":"2022-03-02T00:31:00.535358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"N_CORES = 4\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)\n\ntest_ds[0]","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:31:00.537335Z","iopub.execute_input":"2022-03-02T00:31:00.537593Z","iopub.status.idle":"2022-03-02T00:31:00.707654Z","shell.execute_reply.started":"2022-03-02T00:31:00.53756Z","shell.execute_reply":"2022-03-02T00:31:00.706865Z"},"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-03-02T00:31:00.708935Z","iopub.execute_input":"2022-03-02T00:31:00.709823Z","iopub.status.idle":"2022-03-02T00:31:00.713861Z","shell.execute_reply.started":"2022-03-02T00:31:00.70978Z","shell.execute_reply":"2022-03-02T00:31:00.713091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#state_dict = \"../input/mel-gem-resnet-from-2021-2nd-place/first_model/checkpoint_last_seed123.pth\"\n#state_dict = \"../input/mel-gem-resnet/first_model/checkpoint_last_seed123.pth\"\nstate_dict = \"../input/mel-gem-resnet-from-2021-2nd-place/first_model/checkpoint_last_seed123.pth\"\ncfg.backbone = \"resnet34\"\nnet = Net(cfg).eval().to(DEVICE)\nsd = get_state_dict(state_dict)\nprint(\"loading dict\")\nnet.load_state_dict(sd, strict=True)\n","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:31:00.715183Z","iopub.execute_input":"2022-03-02T00:31:00.716072Z","iopub.status.idle":"2022-03-02T00:31:06.777335Z","shell.execute_reply.started":"2022-03-02T00:31:00.716014Z","shell.execute_reply":"2022-03-02T00:31:06.776591Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"list(net.global_pool.parameters())","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:31:06.778773Z","iopub.execute_input":"2022-03-02T00:31:06.779277Z","iopub.status.idle":"2022-03-02T00:31:06.790569Z","shell.execute_reply.started":"2022-03-02T00:31:06.779239Z","shell.execute_reply":"2022-03-02T00:31:06.789643Z"},"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-03-02T00:31:06.791927Z","iopub.execute_input":"2022-03-02T00:31:06.792212Z","iopub.status.idle":"2022-03-02T00:31:06.797975Z","shell.execute_reply.started":"2022-03-02T00:31:06.792168Z","shell.execute_reply":"2022-03-02T00:31:06.797111Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with torch.no_grad():\n    preds = []\n    for batch in tqdm(test_dl):\n        batch = batch_to_device(batch, DEVICE)\n        with torch.cuda.amp.autocast():\n            out = net(batch)['logits']\n            preds += [out.cpu().numpy()]","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:31:06.799304Z","iopub.execute_input":"2022-03-02T00:31:06.799557Z","iopub.status.idle":"2022-03-02T00:31:08.006425Z","shell.execute_reply.started":"2022-03-02T00:31:06.799524Z","shell.execute_reply":"2022-03-02T00:31:08.0056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#test_df = create_df_test_from_path()","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:31:08.009791Z","iopub.execute_input":"2022-03-02T00:31:08.010576Z","iopub.status.idle":"2022-03-02T00:31:08.016301Z","shell.execute_reply.started":"2022-03-02T00:31:08.01054Z","shell.execute_reply":"2022-03-02T00:31:08.015584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_preds = pd.DataFrame(np.vstack(preds), columns=test_ds.bird2id.keys())[SCORED_BIRDS]\ndf_preds.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:31:08.018363Z","iopub.execute_input":"2022-03-02T00:31:08.019786Z","iopub.status.idle":"2022-03-02T00:31:08.065625Z","shell.execute_reply.started":"2022-03-02T00:31:08.01975Z","shell.execute_reply":"2022-03-02T00:31:08.064849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = test_df.join(df_preds).drop(['birds'], axis=1).reset_index()\ntest_df = pd.melt(test_df, id_vars=['filename', 'row_prefix', 'ending_second'], value_vars=SCORED_BIRDS, var_name=\"bird\", value_name=\"proba\")\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:31:08.069209Z","iopub.execute_input":"2022-03-02T00:31:08.071475Z","iopub.status.idle":"2022-03-02T00:31:08.107462Z","shell.execute_reply.started":"2022-03-02T00:31:08.071441Z","shell.execute_reply":"2022-03-02T00:31:08.106846Z"},"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-03-02T00:31:08.111012Z","iopub.execute_input":"2022-03-02T00:31:08.113413Z","iopub.status.idle":"2022-03-02T00:31:08.133929Z","shell.execute_reply.started":"2022-03-02T00:31:08.113378Z","shell.execute_reply":"2022-03-02T00:31:08.133304Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df['target'] = test_df['proba'] > 0.012\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-02T00:36:56.843997Z","iopub.execute_input":"2022-03-02T00:36:56.844602Z","iopub.status.idle":"2022-03-02T00:36:56.859963Z","shell.execute_reply.started":"2022-03-02T00:36:56.844563Z","shell.execute_reply":"2022-03-02T00:36:56.859077Z"},"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-02-28T07:37:03.076743Z","iopub.execute_input":"2022-02-28T07:37:03.079333Z","iopub.status.idle":"2022-02-28T07:37:03.099121Z","shell.execute_reply.started":"2022-02-28T07:37:03.079254Z","shell.execute_reply":"2022-02-28T07:37:03.098016Z"},"trusted":true},"execution_count":null,"outputs":[]}]}