{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":91844,"databundleVersionId":11361821,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":1462550,"sourceType":"datasetVersion","datasetId":857643},{"sourceId":3729,"sourceType":"modelInstanceVersion","isSourceIdPinned":false,"modelInstanceId":2656,"modelId":312}],"dockerImageVersionId":30918,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n\nimport librosa\nimport glob\n\nimport torch\nimport torch.nn as nn\nimport albumentations\n\nimport os\nimport random\nfrom joblib import Parallel, delayed\nimport json\nfrom matplotlib import pyplot as plt\nimport seaborn as sns\nimport timm\n\nimport pandas.api.types\nimport sklearn.metrics\n\nfrom tqdm import tqdm\nimport gc\n\nfrom sklearn.model_selection import StratifiedKFold\n\nfrom ast import literal_eval\n\nimport torch.nn.functional as F\n\nfrom warnings import filterwarnings\nfilterwarnings('ignore')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:14:06.864132Z","iopub.execute_input":"2025-03-25T12:14:06.864580Z","iopub.status.idle":"2025-03-25T12:14:44.776427Z","shell.execute_reply.started":"2025-03-25T12:14:06.864544Z","shell.execute_reply":"2025-03-25T12:14:44.775360Z"}},"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    \n    train_soundscapes = \"/kaggle/input/birdclef-2025/train_soundscapes\"\n    test_soundscapes = \"/kaggle/input/birdclef-2025/test_soundscapes\"\n    test_audio = \"/kaggle/input/birdclef-2025/test_audio\"\n    sample_submission_csv = \"/kaggle/input/birdclef-2025/sample_submission.csv\"\n    sr = int(32e3)\n    n_fft = 1024\n    hop_length = 500\n    n_mels = 128\n    fmin = 50\n    fmax = 16000\n    power = 2\n    num_classes = 206\n    image_shape = (128, 648, 1)\n    submission_mode = len(glob.glob(\"/kaggle/input/birdclef-2025/test_soundscapes/*.ogg\")) > 0\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:14:44.777844Z","iopub.execute_input":"2025-03-25T12:14:44.778107Z","iopub.status.idle":"2025-03-25T12:14:44.783969Z","shell.execute_reply.started":"2025-03-25T12:14:44.778085Z","shell.execute_reply":"2025-03-25T12:14:44.783128Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def set_seed(seed:int=Config.seed) -> None:\n    random.seed(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    if torch.cuda.is_available():\n        torch.cuda.manual_seed(seed)\n        torch.cuda.manual_seed_all(seed)\n    torch.backends.cudnn.determistic = True\n    torch.backends.cudnn.benchmark = False\n    print(f'[info] Set Seeds:{seed}')\n\nset_seed()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:14:44.785862Z","iopub.execute_input":"2025-03-25T12:14:44.786122Z","iopub.status.idle":"2025-03-25T12:14:44.809190Z","shell.execute_reply.started":"2025-03-25T12:14:44.786100Z","shell.execute_reply":"2025-03-25T12:14:44.808068Z"}},"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","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:14:44.810543Z","iopub.execute_input":"2025-03-25T12:14:44.810831Z","iopub.status.idle":"2025-03-25T12:14:44.850428Z","shell.execute_reply.started":"2025-03-25T12:14:44.810805Z","shell.execute_reply":"2025-03-25T12:14:44.849496Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def process(audio_path):\n    filename = audio_path.split(\"/\")[-1].split(\".\")[0]\n    data, _ = librosa.load(audio_path, sr = Config.sr)\n    data = data *1024\n    local_mapper={}\n\n    #Dividing the  data into 5sec chunks\n    chunk_duration =  5\n    min_len = chunk_duration * Config.sr\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        chunk_5s = data[i:i+min_len]\n        chunk_10s= np.tile(chunk_5s, 2)\n        chunk_10s = chunk_10s.reshape(-1, len(chunk_10s))\n\n    # Converting to mel spectrogram\n        mel_sp = librosa.feature.melspectrogram(\n            y= chunk_10s,\n            sr= Config.sr,\n            fmin = Config.fmin,\n            power= Config.power,\n            n_mels = Config.n_mels,\n            n_fft = Config.n_fft,\n            hop_length = Config.hop_length\n        )\n        mel_sp = librosa.power_to_db(mel_sp, ref=1)\n    \n        \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 the audio files\nall_mappers = Parallel(\n    n_jobs = -1,\n    backend = 'loky')(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 sudio files, total_items:{len(global_mapper)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:14:44.851412Z","iopub.execute_input":"2025-03-25T12:14:44.851719Z","iopub.status.idle":"2025-03-25T12:14:48.605163Z","shell.execute_reply.started":"2025-03-25T12:14:44.851693Z","shell.execute_reply":"2025-03-25T12:14:48.603960Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for key, val in global_mapper.items(): \n    print(key)\n    print(val)\n    break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:14:48.606469Z","iopub.execute_input":"2025-03-25T12:14:48.606871Z","iopub.status.idle":"2025-03-25T12:14:48.613880Z","shell.execute_reply.started":"2025-03-25T12:14:48.606828Z","shell.execute_reply":"2025-03-25T12:14:48.612892Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%time\n\nmodels = [\n    \"/kaggle/input/effnet-b0-512-3200-spectro-1-mixup-2-avg-bg-bird/classifier_timm_tf_efficientnet_b0_512_32000_spectro_1_mixup_2_avg_bg_bird/lightning_logs/version_fold0/_ckpt_epoch_18.ckpt\",\n    \"/kaggle/input/effnet-b0-512-3200-spectro-1-mixup-2-avg-bg-bird/classifier_timm_tf_efficientnet_b0_512_32000_spectro_1_mixup_2_avg_bg_bird/lightning_logs/version_fold0/_ckpt_epoch_32.ckpt\",\n    \"/kaggle/input/effnet-b0-512-3200-spectro-1-mixup-2-avg-bg-bird/classifier_timm_tf_efficientnet_b0_512_32000_spectro_1_mixup_2_avg_bg_bird/lightning_logs/version_fold0/_ckpt_epoch_25.ckpt\"\n]\n\n# Device setup\ndevice = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n\n# Model class\nclass Model(nn.Module):\n    def __init__(self, model_name: str):\n        super().__init__()\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    \n    def forward(self, x):\n        return self.base_model(x)\nmodels_pool = []\n\nfor model_path in models:\n    model = Model(model_name=\"tf_efficientnet_b0\")\n    checkpoint = torch.load(model_path, map_location=device)\n    state_dict = checkpoint['state_dict'] if 'state_dict' in checkpoint else checkpoint\n    new_state_dict = {}\n    for k, v in state_dict.items():\n        new_key = k.replace(\"model.\", \"\").replace(\"base_model.\", \"\")\n        new_state_dict[new_key] = v\n\n\n    model.load_state_dict(new_state_dict, strict=False)\n\n    model.eval().to(device)\n    models_pool.append(model)\n\nprint(\"[INFO] Loaded all the models successfully!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:14:48.614954Z","iopub.execute_input":"2025-03-25T12:14:48.615241Z","iopub.status.idle":"2025-03-25T12:14:50.407479Z","shell.execute_reply.started":"2025-03-25T12:14:48.615209Z","shell.execute_reply":"2025-03-25T12:14:50.406589Z"}},"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(self.mapper.keys())\n    def __len__(self): return len(self.mapper)\n    def __getitem__(self, idx): return self.ids[idx], self.mapper[self.ids[idx]]\n\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# to capture the model prediction per row id\n\npred_mapper = {}\n\n\nfor (row_ids, mels) in test_loader:\n    mels_t = torch.tensor(mels).to(device)\n\n    model_preds = []\n\n    with torch.no_grad():\n        for model in models_pool:\n            output = model(mels_t)\n\n            probs = torch.sigmoid(output).detach().cpu().numpy().squeeze()\n            model_preds.append(probs) #prediction of every model on current batch\n\n    # Avg the model predictions\n    mel_preds = np.mean (model_preds, axis = 0)\n\n    for idx, row_id in enumerate(row_ids):\n        pred_mapper[row_id] = mel_preds[idx]\n\n    del mels_t\n\nlen(global_mapper), len(pred_mapper.keys())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:14:50.410729Z","iopub.execute_input":"2025-03-25T12:14:50.411252Z","iopub.status.idle":"2025-03-25T12:15:05.699540Z","shell.execute_reply.started":"2025-03-25T12:14:50.411221Z","shell.execute_reply":"2025-03-25T12:15:05.698267Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# #Creating submission df\n# columns = pd.read_csv(Config.sample_submission_csv).columns\n# sub_df = pd.DataFrame(columns = columns[1:], data = list(pred_mapper.values()))\n# sub_df['row_id'] = list(pred_mapper.keys())\n# sub_df = sub_df[[sub_df.columns[-1]]+ [*sub_df.columns[:-1].tolist()]]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:15:05.701312Z","iopub.execute_input":"2025-03-25T12:15:05.701665Z","iopub.status.idle":"2025-03-25T12:15:05.705304Z","shell.execute_reply.started":"2025-03-25T12:15:05.701635Z","shell.execute_reply":"2025-03-25T12:15:05.704423Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_submission_path = '/kaggle/input/birdclef-2025/sample_submission.csv'\n\nprint(f\"Looking for: {sample_submission_path}\")\nprint(f\"Files in /kaggle/input/birdclef-2025: {os.listdir('/kaggle/input/birdclef-2025')}\")\n\ncolumns = pd.read_csv(sample_submission_path).columns\nspecies_columns = columns[1:]\n\nsub_df = pd.DataFrame(data=list(pred_mapper.values()), columns=species_columns)\nsub_df['row_id'] = list(pred_mapper.keys())\n\nsub_df = sub_df[['row_id'] + species_columns.tolist()]\n\nsub_df.to_csv('/kaggle/working/submission.csv', index=False)\nprint(\"[INFO] Submission file saved successfully at /kaggle/working/submission.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:15:05.706257Z","iopub.execute_input":"2025-03-25T12:15:05.706547Z","iopub.status.idle":"2025-03-25T12:15:05.766611Z","shell.execute_reply.started":"2025-03-25T12:15:05.706521Z","shell.execute_reply":"2025-03-25T12:15:05.765588Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_sub = pd.read_csv('/kaggle/input/birdclef-2025/sample_submission.csv')\nprint(\"Sample submission shape:\", sample_sub.shape)\n\nprint(\"Your submission shape:\", sub_df.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:15:05.767598Z","iopub.execute_input":"2025-03-25T12:15:05.767919Z","iopub.status.idle":"2025-03-25T12:15:05.780119Z","shell.execute_reply.started":"2025-03-25T12:15:05.767892Z","shell.execute_reply":"2025-03-25T12:15:05.779277Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_row_ids = pd.read_csv('/kaggle/input/birdclef-2025/sample_submission.csv')['row_id'].tolist()\nyour_row_ids = sub_df['row_id'].tolist()\n\nmissing = set(sample_row_ids) - set(your_row_ids)\nextra = set(your_row_ids) - set(sample_row_ids)\n\nprint(\"Missing row_ids:\", missing)\nprint(\"Extra row_ids:\", extra)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:15:05.781096Z","iopub.execute_input":"2025-03-25T12:15:05.781417Z","iopub.status.idle":"2025-03-25T12:15:05.802005Z","shell.execute_reply.started":"2025-03-25T12:15:05.781368Z","shell.execute_reply":"2025-03-25T12:15:05.801163Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions = sub_df.iloc[:, 1:].values\nprint(\"Min prediction value:\", predictions.min())\nprint(\"Max prediction value:\", predictions.max())\nprint(\"Any NaN values?\", np.isnan(predictions).any())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:15:05.802902Z","iopub.execute_input":"2025-03-25T12:15:05.803210Z","iopub.status.idle":"2025-03-25T12:15:05.810275Z","shell.execute_reply.started":"2025-03-25T12:15:05.803184Z","shell.execute_reply":"2025-03-25T12:15:05.809278Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(sub_df.dtypes)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:15:05.811445Z","iopub.execute_input":"2025-03-25T12:15:05.811799Z","iopub.status.idle":"2025-03-25T12:15:05.829643Z","shell.execute_reply.started":"2025-03-25T12:15:05.811760Z","shell.execute_reply":"2025-03-25T12:15:05.828700Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sub_df.to_csv('/kaggle/working/submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:15:05.830543Z","iopub.execute_input":"2025-03-25T12:15:05.831016Z","iopub.status.idle":"2025-03-25T12:15:05.862952Z","shell.execute_reply.started":"2025-03-25T12:15:05.830979Z","shell.execute_reply":"2025-03-25T12:15:05.861514Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(sub_df.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:15:05.863896Z","iopub.execute_input":"2025-03-25T12:15:05.864187Z","iopub.status.idle":"2025-03-25T12:15:05.880852Z","shell.execute_reply.started":"2025-03-25T12:15:05.864159Z","shell.execute_reply":"2025-03-25T12:15:05.879826Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(pd.read_csv('/kaggle/input/birdclef-2025/sample_submission.csv').head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:15:05.881897Z","iopub.execute_input":"2025-03-25T12:15:05.882170Z","iopub.status.idle":"2025-03-25T12:15:05.901408Z","shell.execute_reply.started":"2025-03-25T12:15:05.882137Z","shell.execute_reply":"2025-03-25T12:15:05.900576Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sub_df.to_csv('/kaggle/working/submission.csv', index=False)\nprint(\"[INFO] Submission file saved successfully at /kaggle/working/submission.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-25T12:15:05.902230Z","iopub.execute_input":"2025-03-25T12:15:05.902558Z","iopub.status.idle":"2025-03-25T12:15:05.921583Z","shell.execute_reply.started":"2025-03-25T12:15:05.902531Z","shell.execute_reply":"2025-03-25T12:15:05.920592Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}