{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.11.11","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":12075157,"sourceType":"datasetVersion","datasetId":7601011},{"sourceId":235777618,"sourceType":"kernelVersion"}],"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false},"papermill":{"default_parameters":{},"duration":27.447062,"end_time":"2025-03-12T14:13:11.647927","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2025-03-12T14:12:44.200865","version":"2.6.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!python -m pip install --no-index --find-links=../input/openvino-wheels -r ../input/openvino-wheels/requirements.txt -q","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:47:09.426849Z","iopub.execute_input":"2025-06-06T01:47:09.427604Z","iopub.status.idle":"2025-06-06T01:47:13.748017Z","shell.execute_reply.started":"2025-06-06T01:47:09.427571Z","shell.execute_reply":"2025-06-06T01:47:13.746728Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport gc\nimport time\nimport numpy as np\nimport pandas as pd\nimport torch\nimport torch.nn.functional as F\nimport torchaudio\nimport torchaudio.transforms as AT\nfrom contextlib import contextmanager\nimport concurrent.futures\nimport openvino.runtime as ov","metadata":{"papermill":{"duration":12.984639,"end_time":"2025-03-12T14:13:00.145177","exception":false,"start_time":"2025-03-12T14:12:47.160538","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:47:13.75096Z","iopub.execute_input":"2025-06-06T01:47:13.751336Z","iopub.status.idle":"2025-06-06T01:47:13.758091Z","shell.execute_reply.started":"2025-06-06T01:47:13.751292Z","shell.execute_reply":"2025-06-06T01:47:13.757149Z"}},"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":{"papermill":{"duration":0.105385,"end_time":"2025-03-12T14:13:00.253425","exception":false,"start_time":"2025-03-12T14:13:00.14804","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:47:13.760046Z","iopub.execute_input":"2025-06-06T01:47:13.76043Z","iopub.status.idle":"2025-06-06T01:47:13.798864Z","shell.execute_reply.started":"2025-06-06T01:47:13.7604Z","shell.execute_reply":"2025-06-06T01:47:13.797835Z"}},"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=2048\nwin_length=2048\nhop_length=768\nf_min=50\nf_max=15000\nn_mels=192\n\nst_time = [2.5, 7.5, 12.5, 17.5, 22.5, 27.5, 32.5, 37.5, 42.5, 47.5, 52.5]\ned_time = [7.5, 12.5, 17.5, 22.5, 27.5, 32.5, 37.5, 42.5, 47.5, 52.5, 57.5]\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)\n\n\ndef normalize_std(spec, eps=1e-6):\n    mean = torch.mean(spec)\n    std = torch.std(spec)\n    return torch.where(std == 0, spec-mean, (spec - mean) / (std+eps))\n\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    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+1e-6)\n        melspec = normalize_std(melspec)\n        melspec = torch.unsqueeze(melspec, dim=0)\n        PREDS.append(melspec)\n    PREDS2 = []\n    for i in range(11):   \n        waveform2 = waveform[:,int(st_time[i]*sample_rate):int(ed_time[i]*sample_rate)]\n        melspec = mel_spectrogram(waveform2)\n        melspec = torch.log(melspec+1e-6)\n        melspec = normalize_std(melspec)\n        melspec = torch.unsqueeze(melspec, dim=0)\n        PREDS2.append(melspec)\n    return torch.vstack(PREDS), torch.vstack(PREDS2)","metadata":{"papermill":{"duration":0.144235,"end_time":"2025-03-12T14:13:00.400505","exception":false,"start_time":"2025-03-12T14:13:00.25627","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:47:13.799751Z","iopub.execute_input":"2025-06-06T01:47:13.799991Z","iopub.status.idle":"2025-06-06T01:47:13.820432Z","shell.execute_reply.started":"2025-06-06T01:47:13.799972Z","shell.execute_reply":"2025-06-06T01:47:13.819557Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"core = ov.Core()\n\nov_config = {\n    \"PERFORMANCE_HINT\": \"THROUGHPUT\",\n}\n\ncompiled_models = []\nfor i in range(13):\n    openvino_model = core.read_model(model=f'/kaggle/input/birdclef2025-noir-models-ov/model_{i}.xml')\n    compiled_model = core.compile_model(openvino_model, device_name=\"AUTO\", config=ov_config)\n    compiled_models.append(compiled_model)\n\ncompiled_models2 = []\nfor i in range(13):\n    openvino_model = core.read_model(model=f'/kaggle/input/birdclef2025-noir-models-ov/model2_{i}.xml')\n    compiled_model = core.compile_model(openvino_model, device_name=\"AUTO\", config=ov_config)\n    compiled_models2.append(compiled_model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:47:13.823293Z","iopub.execute_input":"2025-06-06T01:47:13.823817Z","iopub.status.idle":"2025-06-06T01:47:55.660707Z","shell.execute_reply.started":"2025-06-06T01:47:13.823778Z","shell.execute_reply":"2025-06-06T01:47:55.658937Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"alpha = 0.5\n\ndef pred_ov(afile):\n    global compiled_models\n    global compiled_models2\n    global pred\n    path = test_audio_dir + afile + '.ogg'\n    sig, sig2 = audio_to_mel(path)\n    input_tensor = ov.Tensor(array=sig.numpy(), shared_memory=True)\n    input_tensor2 = ov.Tensor(array=sig2.numpy(), shared_memory=True)\n\n    outputs = []\n    infer_requests = []\n    for cmodel in compiled_models:\n        infer_request = cmodel.create_infer_request()        \n        infer_request.set_input_tensor(input_tensor)\n        infer_request.start_async() \n        infer_requests.append(infer_request)\n    for infer_request in infer_requests:\n        infer_request.wait()\n        output = infer_request.get_output_tensor() \n        output_buffer = output.data\n        outputs.append(output_buffer)\n    outputs = np.stack(outputs, axis=0)\n    outputs = torch.sigmoid(torch.from_numpy(outputs)) \n    outputs = outputs.mean(dim=0).numpy()\n\n    outputs2 = []\n    infer_requests2 = []\n    for cmodel in compiled_models2:\n        infer_request = cmodel.create_infer_request()        \n        infer_request.set_input_tensor(input_tensor2)\n        infer_request.start_async() \n        infer_requests2.append(infer_request)\n    for infer_request in infer_requests2:\n        infer_request.wait()\n        output = infer_request.get_output_tensor() \n        output_buffer = output.data\n        outputs2.append(output_buffer)\n    outputs2 = np.stack(outputs2, axis=0)\n    outputs2 = torch.sigmoid(torch.from_numpy(outputs2)) \n    outputs2 = outputs2.mean(dim=0).numpy()\n\n    outputs[0,:] = alpha * outputs[0,:] + (1-alpha) * (outputs[0,:] + outputs2[0,:]) * 0.5\n    outputs[11,:] = alpha * outputs[11,:] + (1-alpha) * (outputs[11,:] + outputs2[10,:]) * 0.5\n    for i in range(10):\n        outputs[i+1,:] = alpha * outputs[i+1,:] + (1-alpha) * (outputs2[i,:] + outputs2[i+1,:]) * 0.5\n\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    return outputs","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:47:55.663014Z","iopub.execute_input":"2025-06-06T01:47:55.663513Z","iopub.status.idle":"2025-06-06T01:47:55.678509Z","shell.execute_reply.started":"2025-06-06T01:47:55.663489Z","shell.execute_reply":"2025-06-06T01:47:55.677303Z"}},"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=8) as executor:\n    _ = list(executor.map(pred_ov, file_list))\nend_t = time.time()\n\nif debug == True:\n    print(700*(end_t - start)/60/debug_num)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T01:47:55.679437Z","iopub.execute_input":"2025-06-06T01:47:55.679742Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"results = pd.DataFrame(pred, columns = ['row_id'] + class_labels) \ndisplay(results.head())\nresults.to_csv(\"submission.csv\", index=False)   ","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sub = pd.read_csv('submission.csv')\ncols = sub.columns[1:]\ngroups = sub['row_id'].str.rsplit('_', n=1).str[0]\ngroups = groups.values\nfor group in np.unique(groups):\n    sub_group = sub[group == groups]\n    predictions = sub_group[cols].values\n    new_predictions = predictions.copy()\n    for i in range(1, predictions.shape[0]-1):\n        new_predictions[i] = (predictions[i-1] * 0.1) + (predictions[i] * 0.8) + (predictions[i+1] * 0.1)\n    new_predictions[0] = (predictions[0] * 0.9) + (predictions[1] * 0.1)\n    new_predictions[-1] = (predictions[-1] * 0.9) + (predictions[-2] * 0.1)\n    sub_group[cols] = new_predictions\n    sub[group == groups] = sub_group\nsub.to_csv(\"submission.csv\", index=False)\n\n\nif debug:\n    results = pd.read_csv('submission.csv')\n    display(results)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if debug == True:\n    import matplotlib.pyplot as plt\n    \n    sample_rate = 32000\n    n_fft=1024\n    win_length=1024\n    hop_length=512\n    f_min=50\n    f_max=16000\n    n_mels=128\n    \n    mel_spectrogram_debug = 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    )\n\n    \n    def audio_to_mel_debug(filepath=None):\n        waveform, sample_rate = torchaudio.load(filepath,backend=\"soundfile\")\n        len_wav = waveform.shape[1]\n        waveform = waveform / torch.max(torch.abs(waveform))\n        melspec = mel_spectrogram_debug(waveform)\n        melspec = 10*torch.log10(melspec)\n        return melspec\n\n    \n    def plot_results(results, file_name):\n        path = test_audio_dir + file_name + \".ogg\"\n        specgram = audio_to_mel_debug(path)\n        fig, axes = plt.subplots(2, 1, figsize=(10, 8))\n        axes[0].set_title(file_name)\n        im = axes[0].imshow((specgram[0]), origin=\"lower\", aspect=\"auto\")\n        axes[0].set_ylabel(\"mel bin\")\n        axes[0].set_xlabel(\"frame\")\n        fig.colorbar(im, ax=axes[0])\n        heatmap = axes[1].pcolor(results[results[\"row_id\"].str.contains(file_name)].iloc[:12,1:].values.T, edgecolors='k', linewidths=0.1, vmin=0, vmax=1, cmap='Blues')\n        fig.colorbar(heatmap, ax=axes[1])\n        axes[1].set_xticks(np.arange(0, 12, 1))\n        axes[1].set_xticklabels(np.arange(0,60,5))\n        axes[1].set_ylabel(\"sec\")\n        axes[1].set_xlabel(\"species\")\n        fig.tight_layout()\n        fig.show()\n\n    \n    for file_name in file_list:\n        plot_results(results, file_name)","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}