{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.12"},"kaggle":{"accelerator":"none","dataSources":[{"sourceType":"competition","sourceId":91844,"databundleVersionId":11361821},{"sourceType":"datasetVersion","sourceId":11007574,"datasetId":6852834,"databundleVersionId":11388047},{"sourceType":"kernelVersion","sourceId":227215399}],"dockerImageVersionId":30918,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false},"papermill":{"default_parameters":{},"duration":29.711705,"end_time":"2025-03-12T13:10:48.026302","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2025-03-12T13:10:18.314597","version":"2.6.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"* Training Notebook [here.](https://www.kaggle.com/code/myso1987/birdclef2025-2-train-baseline-5s)\n* Dataset Creation [here](https://www.kaggle.com/code/myso1987/birdclef2025-1-crop-audio-5s)","metadata":{}},{"cell_type":"code","source":"import os\nimport gc\nimport time\nimport pandas as pd\nimport torch\nimport torch.nn as nn\nfrom torchvision import models\nimport torchaudio\nimport torchaudio.transforms as AT\nfrom contextlib import contextmanager\nimport concurrent.futures","metadata":{"execution":{"iopub.status.busy":"2025-03-18T23:11:03.137064Z","iopub.execute_input":"2025-03-18T23:11:03.137432Z","iopub.status.idle":"2025-03-18T23:11:12.961963Z","shell.execute_reply.started":"2025-03-18T23:11:03.137370Z","shell.execute_reply":"2025-03-18T23:11:12.960899Z"},"papermill":{"duration":12.967807,"end_time":"2025-03-12T13:10:34.467910","exception":false,"start_time":"2025-03-12T13:10:21.500103","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_audio_dir = '../input/birdclef-2025/test_soundscapes/'\nfile_list = [f for f in sorted(os.listdir(test_audio_dir))]\nfile_list = [file.split('.')[0] for file in file_list if file.endswith('.ogg')]\n\ndebug = False\nif len(file_list) == 0:\n    debug = True\n    debug_st_num = 5\n    debug_num = 8\n    test_audio_dir = '../input/birdclef-2025/train_soundscapes/'\n    file_list = [f for f in sorted(os.listdir(test_audio_dir))]\n    file_list = [file.split('.')[0] for file in file_list if file.endswith('.ogg')]\n    file_list = file_list[debug_st_num:debug_st_num+debug_num]\n\nprint('Debug mode:', debug)\nprint('Number of test soundscapes:', len(file_list))","metadata":{"execution":{"iopub.status.busy":"2025-03-18T23:11:12.962956Z","iopub.execute_input":"2025-03-18T23:11:12.963475Z","iopub.status.idle":"2025-03-18T23:11:13.092931Z","shell.execute_reply.started":"2025-03-18T23:11:12.963444Z","shell.execute_reply":"2025-03-18T23:11:13.091820Z"},"papermill":{"duration":0.104002,"end_time":"2025-03-12T13:10:34.575366","exception":false,"start_time":"2025-03-12T13:10:34.471364","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"wav_sec = 5\nsample_rate = 32000\nmin_segment = sample_rate*wav_sec\n\nclass_labels = sorted(os.listdir('../input/birdclef-2025/train_audio/'))\n\nn_fft=1024\nwin_length=1024\nhop_length=512\nf_min=20\nf_max=15000\nn_mels=128\n\nmel_spectrogram = AT.MelSpectrogram(\n    sample_rate=sample_rate,\n    n_fft=n_fft,\n    win_length=win_length,\n    hop_length=hop_length,\n    center=True,\n    f_min=f_min,\n    f_max=f_max,\n    pad_mode=\"reflect\",\n    power=2.0,\n    norm='slaney',\n    n_mels=n_mels,\n    mel_scale=\"htk\",\n    # normalized=True\n)\n\ndef normalize_std(spec, eps=1e-23):\n    mean = torch.mean(spec)\n    std = torch.std(spec)\n    return torch.where(std == 0, spec-mean, (spec - mean) / (std+eps))\n\ndef audio_to_mel(filepath=None):\n    waveform, sample_rate = torchaudio.load(filepath,backend=\"soundfile\")\n    len_wav = waveform.shape[1]\n    waveform = waveform[0,:].reshape(1, len_wav) # stereo->mono mono->mono\n    waveform = waveform / torch.max(torch.abs(waveform))\n    waveform = waveform + 1.5849e-05*(torch.rand(1, len_wav)-0.5) \n    PREDS = []\n    for i in range(12):\n        waveform2 = waveform[:,i*sample_rate*5:i*sample_rate*5+sample_rate*5]\n        melspec = mel_spectrogram(waveform2)\n        melspec = torch.log(melspec)\n        melspec = normalize_std(melspec)\n        melspec = torch.unsqueeze(melspec, dim=0)\n        \n        PREDS.append(melspec)\n    return torch.vstack(PREDS)","metadata":{"execution":{"iopub.status.busy":"2025-03-18T23:11:13.093988Z","iopub.execute_input":"2025-03-18T23:11:13.094335Z","iopub.status.idle":"2025-03-18T23:11:13.222228Z","shell.execute_reply.started":"2025-03-18T23:11:13.094306Z","shell.execute_reply":"2025-03-18T23:11:13.221033Z"},"papermill":{"duration":0.124095,"end_time":"2025-03-12T13:10:34.702541","exception":false,"start_time":"2025-03-12T13:10:34.578446","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class Model_resnet34(nn.Module):\n    def __init__(self, pretrained=False):\n        super().__init__()\n\n        # Use timm\n        model = models.resnet34(pretrained=pretrained)\n\n        num_ftrs = model.fc.in_features\n        model.fc = nn.Linear(num_ftrs, len(class_labels))\n        self.model = model\n\n    def forward(self, x):\n        x = torch.cat((x,x,x),1)\n        x = self.model(x)\n        return x\n\nmodel = Model_resnet34(pretrained=False)\nmodel.load_state_dict(torch.load('/kaggle/input/birdclef-2025-models/baseline.pth', weights_only=True, map_location=torch.device('cpu')))\nmodel.eval();","metadata":{"execution":{"iopub.status.busy":"2025-03-18T23:11:13.224143Z","iopub.execute_input":"2025-03-18T23:11:13.224474Z","iopub.status.idle":"2025-03-18T23:11:15.157936Z","shell.execute_reply.started":"2025-03-18T23:11:13.224443Z","shell.execute_reply":"2025-03-18T23:11:15.156806Z"},"papermill":{"duration":1.849403,"end_time":"2025-03-12T13:10:36.555055","exception":false,"start_time":"2025-03-12T13:10:34.705652","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def prediction(afile):    \n    global pred\n    path = test_audio_dir + afile + '.ogg'\n    with torch.inference_mode():\n        sig = audio_to_mel(path)\n        print()\n        outputs = model(sig)\n        outputs = torch.sigmoid(outputs).detach().cpu().numpy()\n        chunks = [[] for i in range(12)]\n        for i in range(len(chunks)):        \n            chunk_end_time = (i + 1) * 5\n            row_id = afile + '_' + str(chunk_end_time)\n            pred['row_id'].append(row_id)\n            bird_no = 0\n            for bird in class_labels:         \n                pred[bird].append(outputs[i,bird_no])\n                bird_no += 1\n        gc.collect()","metadata":{"execution":{"iopub.status.busy":"2025-03-18T23:11:15.159094Z","iopub.execute_input":"2025-03-18T23:11:15.159470Z","iopub.status.idle":"2025-03-18T23:11:15.166354Z","shell.execute_reply.started":"2025-03-18T23:11:15.159439Z","shell.execute_reply":"2025-03-18T23:11:15.165003Z"},"papermill":{"duration":0.012347,"end_time":"2025-03-12T13:10:36.570713","exception":false,"start_time":"2025-03-12T13:10:36.558366","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred = {'row_id': []}\nfor species_code in class_labels:\n    pred[species_code] = []\n    \nstart = time.time()\nwith concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:\n    _ = list(executor.map(prediction, file_list))\nend_t = time.time()\n\nif debug == True:\n    print(700*(end_t - start)/60/debug_num)","metadata":{"execution":{"iopub.status.busy":"2025-03-18T23:11:15.167285Z","iopub.execute_input":"2025-03-18T23:11:15.167593Z","iopub.status.idle":"2025-03-18T23:11:22.485552Z","shell.execute_reply.started":"2025-03-18T23:11:15.167554Z","shell.execute_reply":"2025-03-18T23:11:22.484338Z"},"papermill":{"duration":8.10507,"end_time":"2025-03-12T13:10:44.678845","exception":false,"start_time":"2025-03-12T13:10:36.573775","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"results = pd.DataFrame(pred, columns = ['row_id'] + class_labels) \n    \nresults.to_csv(\"submission.csv\", index=False)    \n\nif debug:\n    display(results.head())","metadata":{"execution":{"iopub.status.busy":"2025-03-18T23:11:22.486688Z","iopub.execute_input":"2025-03-18T23:11:22.487101Z","iopub.status.idle":"2025-03-18T23:11:22.585078Z","shell.execute_reply.started":"2025-03-18T23:11:22.487060Z","shell.execute_reply":"2025-03-18T23:11:22.584069Z"},"papermill":{"duration":0.119152,"end_time":"2025-03-12T13:10:44.801270","exception":false,"start_time":"2025-03-12T13:10:44.682118","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null}]}