{"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":"gpu","dataSources":[{"sourceId":25954,"databundleVersionId":2091745,"sourceType":"competition"},{"sourceId":1297722,"sourceType":"datasetVersion","datasetId":750498},{"sourceId":2130303,"sourceType":"datasetVersion","datasetId":1278322}],"dockerImageVersionId":30840,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import cv2\nimport re\nimport torch\nimport time\n\nimport numpy as np\nimport librosa as lb\nimport soundfile as sf\nimport pandas as pd\n\nfrom pathlib import Path\nfrom torch.utils.data import Dataset, DataLoader\nfrom tqdm.notebook import tqdm\n\ntry:\n    import resnest\nexcept ModuleNotFoundError:\n    import shutil\n    shutil.copytree('../input/resnest50-fast-package/resnest-0.0.6b20200701/resnest', 'resnet', dirs_exist_ok=True) \n    !pip install \"./resnet\"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-01-28T22:44:28.669715Z","iopub.execute_input":"2025-01-28T22:44:28.670079Z","iopub.status.idle":"2025-01-28T22:44:37.084406Z","shell.execute_reply.started":"2025-01-28T22:44:28.670053Z","shell.execute_reply":"2025-01-28T22:44:37.082546Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_root = Path(\"../input/birdclef-2021/test_soundscapes\")\ntrain_data = Path(\"../input/birdclef-2021/train_soundscapes\")\n# for submission\nif len(list(test_root.glob(\"*.ogg\"))):\n    train_data = test_root\n\ndata = pd.DataFrame(\n     [(path.stem, *path.stem.split(\"_\"), path) for path in Path(train_data).glob(\"*.ogg\")],\n    columns = [\"filename\", \"id\", \"site\", \"date\", \"filepath\"]\n)\nprint(data.shape)\ndata.head()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def melspectrogram(y, params):\n    result = lb.feature.melspectrogram(y=y, sr=params['sr'], n_mels=params['n_mels'], fmin=params['fmin'], fmax=params['fmax'])\n    result = lb.power_to_db(result).astype(np.float32)\n    return result\n\ndef colorize(X, eps=1e-6, mean=None, std=None):\n    mean = mean or X.mean()\n    std = std or X.std()\n    X = (X - mean) / (std + eps)\n    _min, _max = X.min(), X.max()\n    if (_max - _min) > eps:\n        V = np.clip(X, _min, _max)\n        V = 255 * (V - _min) / (_max - _min)\n        V = V.astype(np.uint8)\n    else:\n        V = np.zeros_like(X, dtype=np.uint8)\n    return V\n\ndef normalize(image):\n    image = image.astype(\"float32\", copy=False) / 255.0\n    image = np.stack([image, image, image])\n    return image\n\nclass CustomDataset(Dataset):\n    def __init__(self, data, sr=32000, n_mels=128, fmin=0, fmax=None, duration=5, step=None, res_type=\"kaiser_fast\", resample=True):\n        self.data = data\n        self.params = {\n            'sr': sr,\n            'n_mels': n_mels,\n            'fmin': fmin,\n            'fmax': fmax or sr // 2\n        }\n        self.duration = duration\n        self.audio_length = duration * sr\n        self.step = step or self.audio_length\n        self.res_type = res_type\n        self.resample = resample\n    \n    def __len__(self):\n        return len(self.data)\n    \n    def audio_to_image(self, audio):\n        melspec = melspectrogram(audio, self.params)\n        image = normalize(colorize(melspec))\n        \n        return image\n    \n    def __getitem__(self, idx):\n        audio, orig_sr = sf.read(self.data.loc[idx, \"filepath\"], dtype=\"float32\")\n\n        if self.resample and orig_sr != self.params['sr']:\n            audio = lb.resample(audio, orig_sr, self.params['sr'], res_type=self.res_type)\n          \n        audios = []\n        for i in range(self.audio_length, len(audio) + self.step, self.step):\n            start = max(0, i - self.audio_length)\n            end = start + self.audio_length\n            audios.append(audio[start:end])\n            \n        if len(audios[-1]) < self.audio_length:\n            audios = audios[:-1]\n            \n        images = [self.audio_to_image(audio) for audio in audios]\n        images = np.stack(images)\n        return images","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_data = CustomDataset(data=data)\n\ntest_item = test_data[1]\nprint(test_item.shape)\nfrom matplotlib import pyplot as plt\ntest_images = [np.einsum('kij->ijk', img) for img in test_item]\n\nfig, axs = plt.subplots(4, 4, figsize=(18, 9))\nfor i in range(16):\n    axs[int(i / 4), i % 4].imshow(test_images[i + 1])\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train = pd.read_csv(\"../input/birdclef-2021/train_metadata.csv\")\n\nid_by_label = {label: label_id for label_id,label in enumerate(sorted(df_train[\"primary_label\"].unique()))}\nlabel_by_id = {val: key for key,val in id_by_label.items()}\nnum_classes = len(label_by_id.keys())\nprint(id_by_label)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"checkpoint_path = Path(\"../input/kkiller-birdclef-models-public/birdclef_resnest50_fold0_epoch_10_f1_val_06471_20210417161101.pth\")\nfrom resnest.torch import resnest50\nDEVICE = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\nnet = resnest50(pretrained=False)\nnet.fc = torch.nn.Linear(net.fc.in_features, num_classes)\ndummy_device = torch.device(\"cpu\")\nd = torch.load(checkpoint_path, map_location=dummy_device)\nfor key in list(d.keys()):\n    d[key.replace(\"model.\", \"\")] = d.pop(key)\nnet.load_state_dict(d)\nnet = net.to(DEVICE)\nnet = net.eval()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"@torch.no_grad()\ndef get_thresh_preds(out, thresh=0.15):\n    o = (-out).argsort(1)\n    npreds = (out > thresh).sum(1)\n    preds = []\n    for oo, npred in zip(o, npreds):\n        preds.append(oo[:npred].cpu().numpy().tolist())\n    return preds\n\ndef get_bird_names(preds):\n    bird_names = []\n    for pred in preds:\n        if not pred:\n            bird_names.append(\"nocall\")\n        else:\n            bird_names.append(\" \".join([label_by_id[bird_id] for bird_id in pred]))\n    return bird_names\n\nxb = torch.from_numpy(test_data[3]).to(DEVICE)\no = net(xb)\npred = get_bird_names(get_thresh_preds(o))\nout = ''\nfor idx, elem in enumerate(pred):\n    if elem != 'nocall':\n        out += 'found ' + elem + ' at ' + str(idx * 5) + '-' + str(idx * 5 + 5) + ' sec of audio\\n'\nprint(out)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def predict(net, test_data):\n    preds = []\n    with torch.no_grad():\n        for idx in  tqdm(list(range(len(test_data)))):\n            xb = torch.from_numpy(test_data[idx]).to(DEVICE)\n            pred = 0.\n            o = net(xb)\n            pred = torch.sigmoid(o)\n            pred = get_bird_names(get_thresh_preds(pred))\n            preds.append(pred)\n    return preds\n\npreds = predict(net, test_data)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def preds_as_df(data, preds):\n    sub = {\n        \"row_id\": [],\n        \"birds\": [],\n    }\n    \n    for row, pred in zip(data.itertuples(False), preds):\n        row_id = [f\"{row.id}_{row.site}_{5*i}\" for i in range(1, len(pred)+1)]\n        sub[\"birds\"] += pred\n        sub[\"row_id\"] += row_id\n    sub = pd.DataFrame(sub)\n    sample_sub = pd.read_csv(\"../input/birdclef-2021/sample_submission.csv\", usecols=[\"row_id\"])\n    sub = sample_sub.merge(sub, on=\"row_id\", how=\"left\")\n    sub[\"birds\"] = sub[\"birds\"].fillna(\"nocall\")\n    return sub","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sub = preds_as_df(data, preds)\nprint(sub)\nsub.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}