{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceType":"competition","sourceId":91844,"databundleVersionId":11361821},{"sourceType":"datasetVersion","sourceId":12414515,"datasetId":7829559,"databundleVersionId":12981685},{"sourceType":"modelInstanceVersion","sourceId":3729,"databundleVersionId":5092434,"modelInstanceId":2656,"modelId":312}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport librosa\n\nimport torch\nimport torch.nn as nn\nimport os\nimport random\nfrom matplotlib import pyplot as plt\nimport seaborn as sns\nfrom ast import literal_eval\nimport timm\nimport glob\nfrom joblib import Parallel, delayed\n\nimport pandas.api.types\n\nimport sklearn.metrics\nfrom sklearn.model_selection import StratifiedKFold\nfrom tqdm import tqdm\nimport gc\n\nfrom warnings import filterwarnings\nfilterwarnings(\"ignore\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-07-09T01:28:29.875509Z","iopub.execute_input":"2025-07-09T01:28:29.875783Z","iopub.status.idle":"2025-07-09T01:28:29.88095Z","shell.execute_reply.started":"2025-07-09T01:28:29.875764Z","shell.execute_reply":"2025-07-09T01:28:29.880215Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Config","metadata":{}},{"cell_type":"code","source":"class Config:\n    train_dir = \"/kaggle/input/birdclef-2025/train_audio\"\n    seed =42\n    train_csv = \"/kaggle/input/birdclef-2025/train.csv\"\n    sample_submission_csv = \"/kaggle/input/birdclef-2025/sample_submission.csv\"\n    train_soundscapes = \"/kaggle/input/birdclef-2025/train_soundscapes\"\n    test_soundscapes = \"/kaggle/input/birdclef-2025/test_soundscapes\"\n    test_soundscapes = \"/kaggle/input/birdclef-2025/test_audio\"\n\n    sr = int(32e3)\n    num_classes = 206\n    n_fft = 1024\n    hop_length = 500\n\n    n_mels = 128\n    fmin = 50\n    fmax = 15000\n    power = 2\n    image_shape = (128, 640, 1)\n    submission_mode = len(glob.glob(\"/kaggle/input/birdclef-2025/test_soundscapes/*.ogg\")) > 0","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-09T01:16:04.093078Z","iopub.execute_input":"2025-07-09T01:16:04.093406Z","iopub.status.idle":"2025-07-09T01:16:04.103753Z","shell.execute_reply.started":"2025-07-09T01:16:04.093382Z","shell.execute_reply":"2025-07-09T01:16:04.103078Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if Config.submission_mode: sound_dir = glob.glob(Config.test_soundscapes + \"/*.ogg\")\nelse: sound_dir = glob.glob(Config.train_soundscapes + \"/*.ogg\")[:5]\n\nsound_dir\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-09T01:16:06.604235Z","iopub.execute_input":"2025-07-09T01:16:06.60451Z","iopub.status.idle":"2025-07-09T01:16:06.779245Z","shell.execute_reply.started":"2025-07-09T01:16:06.604489Z","shell.execute_reply":"2025-07-09T01:16:06.778635Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def set_seed(seed: int = 42):\n    random.seed(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n\n    if torch.cuda.is_available():\n        torch.cuda.manual_seed(seed)\n        torch.cuda.manual_seed_all(seed)\n\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n\n    print(f\"[INFO] Set Seed: {seed}\")\n\nset_seed()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-09T01:16:25.625198Z","iopub.execute_input":"2025-07-09T01:16:25.625505Z","iopub.status.idle":"2025-07-09T01:16:25.632766Z","shell.execute_reply.started":"2025-07-09T01:16:25.625482Z","shell.execute_reply":"2025-07-09T01:16:25.632047Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%time\ndef process(audio_path):\n    filename = audio_path.split(\"/\")[-1].split(\".\")[0]\n    data, _ = librosa.load(audio_path, sr= Config.sr)\n\n    data = data * 1024 #scaling\n\n    chunk_duration = 5\n    min_len = chunk_duration * Config.sr\n\n    local_mapper = {}\n\n    for i in range(0, len(data), min_len):\n        #making row ids\n        t = i // Config.sr\n        row_id = f\"{filename}_{t + chunk_duration}\"\n\n        chunk_5s = data[i:i +min_len]\n        chunk_10s = np.tile(chunk_5s, 2)\n\n        chunk_10s = chunk_10s.reshape(-1, len(chunk_10s))\n\n\n        #converting to mel spectogra\n        mel_sp = librosa.feature.melspectrogram(\n            y = chunk_10s,\n            sr = Config.sr,\n            fmin = Config.fmin,\n            fmax = Config.fmax,\n            power = Config.power,\n            n_mels = Config.n_mels,\n            n_fft = Config.n_fft,\n            hop_length = Config.hop_length\n            \n        )\n\n        mel_sp = librosa.power_to_db(mel_sp, ref = 1)\n        \n        #Normalizing the feature values\n        eps = 1e-12\n        mel_sp = (mel_sp - mel_sp.min())/ (mel_sp.max() - mel_sp.min() + eps)\n        mel_sp = mel_sp[:, :,:640]\n        local_mapper[row_id] = mel_sp\n    return local_mapper\n\n#Loading audio files\nall_mappers = Parallel(\n    n_jobs = -1,\n    backend = \"loky\",\n    \n)(delayed(process)(filepath) for filepath in sound_dir)\n\n\n#creating complete mapping\nglobal_mapper ={}\nfor mapper in all_mappers: global_mapper.update(mapper)\n\nprint(f\"[INFO] Loaded all audio files, total_items: {len(global_mapper)}\")\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-09T01:29:35.097239Z","iopub.execute_input":"2025-07-09T01:29:35.097532Z","iopub.status.idle":"2025-07-09T01:29:35.810597Z","shell.execute_reply.started":"2025-07-09T01:29:35.097511Z","shell.execute_reply":"2025-07-09T01:29:35.809864Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"global_mapper.keys()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-09T01:30:24.564914Z","iopub.execute_input":"2025-07-09T01:30:24.565308Z","iopub.status.idle":"2025-07-09T01:30:24.570489Z","shell.execute_reply.started":"2025-07-09T01:30:24.565277Z","shell.execute_reply":"2025-07-09T01:30:24.56968Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Model pool","metadata":{}},{"cell_type":"code","source":"%%time\n\nmodels = [\n    \"/kaggle/input/effnet-b0-epochs-5-birdclef-2025/fold_0_epoch_4_effnetB0_val_auc_0.9472870763789322_val_loss_7.524325902379999.pth\",\n    \"/kaggle/input/effnet-b0-epochs-5-birdclef-2025/fold_1_epoch_4_effnetB0_val_auc_0.9447145925611731_val_loss_7.717746867454492.pth\",\n    \"/kaggle/input/effnet-b0-epochs-5-birdclef-2025/fold_2_epoch_4_effnetB0_val_auc_0.9358180214457962_val_loss_7.354451903910845.pth\"\n]\n\ndevice = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n\nclass Model(nn.Module):\n    def __init__(self, model_name: str):\n        super().__init__()\n        \n        self.base_model = timm.create_model(\n            model_name = model_name,\n            num_classes = Config.num_classes,\n            pretrained = False,\n            in_chans = 1\n        )\n    def forward(self, x):\n        #making prediction\n        y = self.base_model(x)\n        return y\n\nmodels_pool =[]\nfor model_path in models:\n    model = Model(model_name = \"tf_efficientnet_b0\")\n    model.load_state_dict(torch.load(model_path, map_location = device))\n    model.eval()\n    model.to(device)\n    models_pool.append(model)\n\nprint(\"[INFO] Loaded all models\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-09T01:45:05.428819Z","iopub.execute_input":"2025-07-09T01:45:05.429098Z","iopub.status.idle":"2025-07-09T01:45:07.205252Z","shell.execute_reply.started":"2025-07-09T01:45:05.429077Z","shell.execute_reply":"2025-07-09T01:45:07.204584Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Inference","metadata":{}},{"cell_type":"code","source":"class TestDataset(torch.utils.data.Dataset):\n    def __init__(self,mapper):\n        self.mapper = mapper\n        self.ids = list(slef.mapper.keys())\n\n    def __len__(self):return len(slef.mapper)\n    def __getitem__(self, idx): return self.ids[idx], self.mapper[self.ids[idx]]\n\ntest_loader = torch.utils.data.DataLoader(\n    test_ds := TestDataset(global_mapper),\n    batch_size = 16,\n    num_workers = 2,\n    shuffle = False,\n    drop_last = False\n    \n)\n\n# To capture the model prediction per row id \npred_mapper = {}\n\nfor (row_ids, mels) in test_loader:\n    mels_t = torch.sensor(mels).to(device)\n\n    model_preds =[]\n\n    with torch.no_grad():\n        for model in models_pool:\n            outputs = model(mels_t)\n\n            probs = torch.sigmoid(outputs).detach().cpu().numpy().squeeze()\n            model_preds.append(probs) # prediction of every model on current batch\n            \n\n    \n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}