{"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,"sourceType":"competition"},{"sourceId":227579048,"sourceType":"kernelVersion"}],"dockerImageVersionId":30918,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nimport os\nimport timm\nimport librosa\nimport numpy as np\nimport pandas as pd\n\n# import random\n# import albumentations as A\n# # import audiomentations as Audio\n# from albumentations.pytorch import ToTensorV2\n\nimport gc\nimport dataclasses\nfrom concurrent.futures import ThreadPoolExecutor","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:29.390216Z","iopub.execute_input":"2025-03-15T01:08:29.390499Z","iopub.status.idle":"2025-03-15T01:08:39.622048Z","shell.execute_reply.started":"2025-03-15T01:08:29.390475Z","shell.execute_reply":"2025-03-15T01:08:39.621037Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_data_path = \"/kaggle/input/birdclef-2025/test_soundscapes\"\nsubmission_path = \"/kaggle/input/birdclef-2025/sample_submission.csv\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:39.623132Z","iopub.execute_input":"2025-03-15T01:08:39.623576Z","iopub.status.idle":"2025-03-15T01:08:39.627923Z","shell.execute_reply.started":"2025-03-15T01:08:39.623552Z","shell.execute_reply":"2025-03-15T01:08:39.627001Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transform = None\naudio_transform = None","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:39.629597Z","iopub.execute_input":"2025-03-15T01:08:39.629810Z","iopub.status.idle":"2025-03-15T01:08:39.656258Z","shell.execute_reply.started":"2025-03-15T01:08:39.629792Z","shell.execute_reply":"2025-03-15T01:08:39.655278Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"@dataclasses.dataclass\nclass AudioParam:\n    SR: int=32_000\n    NFFT: int=2048\n    NMEL: int=128\n    FMAX: int=16_000\n    FMIN: int=20\n    HOP_LENGTH: int=NFFT // 4\n\naudio_param = AudioParam()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:39.657499Z","iopub.execute_input":"2025-03-15T01:08:39.657789Z","iopub.status.idle":"2025-03-15T01:08:39.677807Z","shell.execute_reply.started":"2025-03-15T01:08:39.657767Z","shell.execute_reply":"2025-03-15T01:08:39.676951Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sub_csv = pd.read_csv(submission_path)\nidx2cls = sub_csv.columns.drop(\"row_id\").tolist()\ncls2idx = {c: i for i, c in enumerate(idx2cls)}","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:39.678622Z","iopub.execute_input":"2025-03-15T01:08:39.678879Z","iopub.status.idle":"2025-03-15T01:08:39.721321Z","shell.execute_reply.started":"2025-03-15T01:08:39.678855Z","shell.execute_reply":"2025-03-15T01:08:39.720604Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"DEBUG = False\nfile_names = [os.path.join(test_data_path, fp) for fp in os.listdir(test_data_path) if fp.endswith(\".ogg\")]\nif len(file_names) == 0:\n    file_names = [\n        \"/kaggle/input/birdclef-2025/train_soundscapes/H02_20230420_074000.ogg\",\n        \"/kaggle/input/birdclef-2025/train_soundscapes/H02_20230420_112000.ogg\",\n        \"/kaggle/input/birdclef-2025/train_soundscapes/H02_20230420_164000.ogg\",\n    ]\n    DEBUG = True","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:39.722077Z","iopub.execute_input":"2025-03-15T01:08:39.722329Z","iopub.status.idle":"2025-03-15T01:08:39.731379Z","shell.execute_reply.started":"2025-03-15T01:08:39.722308Z","shell.execute_reply":"2025-03-15T01:08:39.730381Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class EfficientNetV2(nn.Module):\n    def __init__(self, num_classes=1, pretrained=False, dropout=.0):\n        super().__init__()\n        self.backbone = timm.create_model(\n            \"timm/tf_efficientnetv2_m.in21k\",\n            in_chans=1,\n            pretrained=pretrained,\n            features_only=True,\n            drop_rate=dropout,\n            drop_path_rate=dropout,\n        )\n\n        self.head = nn.Sequential(\n            nn.Conv2d(512, num_classes, 1),\n            nn.AdaptiveAvgPool2d(1),\n            nn.Flatten(1),\n        )\n\n    def forward(self, x):\n        x = self.backbone(x)[-1]\n        x = self.head(x)\n\n        return x","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:39.732225Z","iopub.execute_input":"2025-03-15T01:08:39.732491Z","iopub.status.idle":"2025-03-15T01:08:39.748740Z","shell.execute_reply.started":"2025-03-15T01:08:39.732464Z","shell.execute_reply":"2025-03-15T01:08:39.747531Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class EfficientNetB3(nn.Module):\n    def __init__(self, num_classes=1):\n        super().__init__()\n        self.backbone = timm.create_model(\n            \"efficientnet_b3.ra2_in1k\",\n            pretrained=False, \n            features_only=True, \n        )\n        self.backbone.conv_stem = nn.Conv2d(1, 40, 3, stride=2, padding=1, bias=False)\n        self.head = nn.Sequential(\n            nn.Conv2d(384, num_classes, 1),\n            nn.AdaptiveAvgPool2d(1),\n            nn.Flatten(1),\n        )\n\n    def forward(self, x):\n        x = self.backbone(x)[-1]\n        x = self.head(x)\n\n        return x","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:39.750949Z","iopub.execute_input":"2025-03-15T01:08:39.751303Z","iopub.status.idle":"2025-03-15T01:08:39.768352Z","shell.execute_reply.started":"2025-03-15T01:08:39.751281Z","shell.execute_reply":"2025-03-15T01:08:39.767206Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# model = EfficientNetB3(len(idx2cls))\n# model.load_state_dict(\n#     torch.load(\n#         \"/kaggle/input/birdclef-2025-base-trainer/EfficientB3_last\",\n#         map_location=\"cpu\",\n#         weights_only=True,\n#     )\n# )\n\nmodel = EfficientNetV2(len(idx2cls))\nmodel.load_state_dict(\n    torch.load(\n        \"/kaggle/input/birdclef-2025-base-trainer/EfficientV2_last\",\n        map_location=\"cpu\",\n        weights_only=True,\n    )\n)\n\nmodel.eval();","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:39.769327Z","iopub.execute_input":"2025-03-15T01:08:39.769528Z","iopub.status.idle":"2025-03-15T01:08:42.948522Z","shell.execute_reply.started":"2025-03-15T01:08:39.769511Z","shell.execute_reply":"2025-03-15T01:08:42.947466Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def pipeline(x):\n    mels = librosa.feature.melspectrogram(\n        y=x,\n        sr=audio_param.SR,\n        n_fft=audio_param.NFFT,\n        n_mels=audio_param.NMEL,\n        fmax=audio_param.FMAX,\n        fmin=audio_param.FMIN,\n        hop_length=audio_param.HOP_LENGTH,\n    )\n\n    # db_map = pcen(mels).astype(np.float32)\n\n    db_map = librosa.power_to_db(mels, ref=np.max)\n    db_map = (db_map + 80) / 80\n\n    return db_map[:, None]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:42.949600Z","iopub.execute_input":"2025-03-15T01:08:42.949966Z","iopub.status.idle":"2025-03-15T01:08:42.955316Z","shell.execute_reply.started":"2025-03-15T01:08:42.949933Z","shell.execute_reply":"2025-03-15T01:08:42.954225Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"@torch.no_grad()\ndef predict(fp):\n    x, _ = librosa.load(fp, sr=audio_param.SR)\n    x = x.reshape(-1, audio_param.SR*5)\n    if audio_transform is not None:\n        x = audio_transform(sample=x, sample_rate=audio_param.SR)\n\n    x = pipeline(x)\n\n    if transform is not None:\n        x = transform(image=x)[\"image\"]\n\n    x = torch.from_numpy(x)\n\n    out = model(x).sigmoid().detach().numpy()\n    fp_name = os.path.basename(fp).split(\".\")[0]\n    row_id = [f\"{fp_name}_{(i+1)*5}\" for i in range(0, out.shape[0])]\n\n    return out, row_id","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:42.956153Z","iopub.execute_input":"2025-03-15T01:08:42.956500Z","iopub.status.idle":"2025-03-15T01:08:42.974500Z","shell.execute_reply.started":"2025-03-15T01:08:42.956472Z","shell.execute_reply":"2025-03-15T01:08:42.973625Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"row_id = []\nmatrix = []\nwith ThreadPoolExecutor(max_workers=4) as executor:\n    for out, rid in executor.map(predict, file_names):\n        row_id += rid\n        matrix.append(out)\nmatrix = np.concatenate(matrix)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:42.975271Z","iopub.execute_input":"2025-03-15T01:08:42.975463Z","iopub.status.idle":"2025-03-15T01:08:58.343353Z","shell.execute_reply.started":"2025-03-15T01:08:42.975447Z","shell.execute_reply":"2025-03-15T01:08:58.342397Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"matrix = np.concatenate([np.array(row_id).reshape(-1, 1), matrix], axis=1)\nsub_csv = pd.DataFrame(matrix, columns=[\"row_id\", *idx2cls])\nsub_csv.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:58.344228Z","iopub.execute_input":"2025-03-15T01:08:58.344805Z","iopub.status.idle":"2025-03-15T01:08:58.361705Z","shell.execute_reply.started":"2025-03-15T01:08:58.344775Z","shell.execute_reply":"2025-03-15T01:08:58.360559Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sub_csv.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T01:08:58.362454Z","iopub.execute_input":"2025-03-15T01:08:58.362741Z","iopub.status.idle":"2025-03-15T01:08:58.435251Z","shell.execute_reply.started":"2025-03-15T01:08:58.362715Z","shell.execute_reply":"2025-03-15T01:08:58.434221Z"}},"outputs":[],"execution_count":null}]}