{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"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,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":389681,"sourceType":"modelInstanceVersion","isSourceIdPinned":false,"modelInstanceId":320996,"modelId":341603}],"dockerImageVersionId":31012,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nfrom pathlib import Path","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T05:40:11.520491Z","iopub.execute_input":"2025-05-13T05:40:11.520899Z","iopub.status.idle":"2025-05-13T05:40:11.525896Z","shell.execute_reply.started":"2025-05-13T05:40:11.52087Z","shell.execute_reply":"2025-05-13T05:40:11.524863Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nTEST_DIR = \"/kaggle/input/birdclef-2025/test_soundscapes\"   # Thay bằng đường dẫn thực tế\n\ntest_files = list(Path(TEST_DIR).glob('*.ogg'))\n\n\"\"\"\ntest_files = []\n\nfor filename in os.listdir(TEST_DIR):\n    # Lọc chỉ các file kết thúc bằng .ogg (không phân biệt hoa thường)\n    if filename.lower().endswith(\".ogg\"):\n        test_files.append(filename)\n        # print(full_path)       # Nếu bạn cần đường dẫn đầy đủ\n\"\"\"\n\ntest_files","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T05:40:11.717317Z","iopub.execute_input":"2025-05-13T05:40:11.718293Z","iopub.status.idle":"2025-05-13T05:40:11.727262Z","shell.execute_reply.started":"2025-05-13T05:40:11.718255Z","shell.execute_reply":"2025-05-13T05:40:11.726307Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ids = []\nfor fname in test_files:\n    root = fname.rsplit(\".\", 1)[0]\n    id_str = root.split(\"_\")[-1]\n    ids.append(id_str)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T05:38:20.435871Z","iopub.execute_input":"2025-05-13T05:38:20.436226Z","iopub.status.idle":"2025-05-13T05:38:20.450945Z","shell.execute_reply.started":"2025-05-13T05:38:20.436201Z","shell.execute_reply":"2025-05-13T05:38:20.449652Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_info = pd.DataFrame()\ntest_info[\"filename\"] = test_files\ntest_info[\"id\"] = ids\ntest_info","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T05:37:41.898326Z","iopub.status.idle":"2025-05-13T05:37:41.898618Z","shell.execute_reply.started":"2025-05-13T05:37:41.898482Z","shell.execute_reply":"2025-05-13T05:37:41.898496Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd, numpy as np, librosa\nfrom pathlib import Path\nfrom tqdm.auto import tqdm\n\nSR        = 32000        # sample-rate đích\nSEG_SEC = 5\n\nN_MELS = 128;  N_FFT = 1024;  HOP = 320              # PCEN\n# ─── Hàm PCEN ────────────────────────────────────────\ndef waveform_to_pcen(wav_np: np.ndarray) -> np.ndarray:\n    S = librosa.feature.melspectrogram(\n            y          = wav_np,\n            sr         = SR,\n            n_fft      = N_FFT,\n            hop_length = HOP,\n            n_mels     = N_MELS,\n            fmin       = 50,\n            fmax       = 12_000,\n            power      = 2.0)\n    pcen = librosa.pcen(S, sr=SR, hop_length=HOP,\n                        gain=0.98, bias=2.0, power=0.5,\n                        time_constant=0.4)\n    return pcen.astype(np.float32)                   # (128, 501)\n\n# ─── Lấy đúng 1 lát 5 s (từ 1 s đến 6 s) mỗi file ───\nrows = []\n\nfor _, r in tqdm(test_info.iterrows(), total=len(test_info)):\n    wav, _ = librosa.load(TEST_DIR + \"/\" + r[\"filename\"], sr=SR, mono=True)\n\n    for k in range(12):\n        START_SEC = k * 5\n        END_SEC = START_SEC + SEG_SEC\n        START_SAM = START_SEC * SR\n        END_SAM   = END_SEC * SR   \n\n        seg = wav[START_SAM : END_SAM]                   # slice 1-6 s (160 000 mẫu)\n        pcen = waveform_to_pcen(seg)                     # (128, 501)\n    \n        rows.append({\n            \"row_id\"        : f\"soundscape_{r['id']}_{END_SEC}\",  \n            \"pcen\"        : pcen\n        })","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T05:37:41.899612Z","iopub.status.idle":"2025-05-13T05:37:41.899918Z","shell.execute_reply.started":"2025-05-13T05:37:41.899784Z","shell.execute_reply":"2025-05-13T05:37:41.899798Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_data = pd.DataFrame(rows, columns=[\"row_id\", \"pcen\"])\ntest_data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T05:37:41.900971Z","iopub.status.idle":"2025-05-13T05:37:41.901278Z","shell.execute_reply.started":"2025-05-13T05:37:41.901146Z","shell.execute_reply":"2025-05-13T05:37:41.901159Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.models import load_model\nmodel = load_model(\"/kaggle/input/birdclef1/tensorflow2/default/1/pcen_cnn.h5\", compile=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T05:37:41.90224Z","iopub.status.idle":"2025-05-13T05:37:41.902505Z","shell.execute_reply.started":"2025-05-13T05:37:41.902376Z","shell.execute_reply":"2025-05-13T05:37:41.902394Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\n\n# 1) Stack toàn bộ dữ liệu đầu vào thành một mảng 4-D\n#    từ list of (128,501) → array X shape (N,128,501,1)\nX = np.stack([pcen[..., np.newaxis] for pcen in test_data[\"pcen\"]], axis=0)\n\n# 2) Gọi predict một lần cho toàn bộ hoặc chia nhỏ theo batch_size\n#    (có thể điều chỉnh batch_size cho phù hợp bộ nhớ/GPU)\nall_preds = model.predict(X, batch_size=32)  # shape (N,206)\n\n# 3) Gán ngược lại vào DataFrame\ntest_data[\"pred\"] = list(all_preds)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T05:37:41.905065Z","iopub.status.idle":"2025-05-13T05:37:41.905394Z","shell.execute_reply.started":"2025-05-13T05:37:41.905255Z","shell.execute_reply":"2025-05-13T05:37:41.90527Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T05:37:41.906837Z","iopub.status.idle":"2025-05-13T05:37:41.907245Z","shell.execute_reply.started":"2025-05-13T05:37:41.907023Z","shell.execute_reply":"2025-05-13T05:37:41.907071Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\n\n# 1. Đọc sample_submission để lấy danh sách cột (header)\nsample = pd.read_csv(\"/kaggle/input/birdclef-2025/sample_submission.csv\")\ncols = sample.columns.tolist()  \n# cols[0] == \"row_id\", cols[1:] là tên 206 lớp\n\n# 2. Xây DataFrame mới từ df[\"pred\"]\n#    - df[\"pred\"] là series các mảng (206,)\n#    - np.vstack sẽ tạo array shape (N,206)\npred_array = np.vstack(test_data[\"pred\"].values)  \n\n# 3. Tạo DataFrame kết quả\nsubmission = pd.DataFrame(pred_array, columns=cols[1:], index=test_data.index)\nsubmission.insert(0, \"row_id\", test_data[\"row_id\"].values)  # chèn cột row_id lên đầu\n\n# 4. Ghi ra CSV\nsubmission.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-13T05:37:41.908538Z","iopub.status.idle":"2025-05-13T05:37:41.909034Z","shell.execute_reply.started":"2025-05-13T05:37:41.908892Z","shell.execute_reply":"2025-05-13T05:37:41.908908Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}