{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"## setup\n## TODO: move all under bird2022wheels\n!pip install ../input/birds-inference-pip-wheels/torchaudio-0.8.1-cp37-cp37m-manylinux1_x86_64.whl ../input/birds-inference-pip-wheels/torch-1.8.1-cp37-cp37m-manylinux1_x86_64.whl\n!pip install ../input/birds-inference-pip-wheels/audiomentations-0.16.0-py3-none-any.whl --no-index --no-deps\n!pip install ../input/birds-inference-pip-wheels/torchlibrosa-0.0.9-py3-none-any.whl --no-index --no-deps\n!pip install ../input/birds2022wheels/nnAudio-0.3.1-py3-none-any.whl\n!cp -r ../input/timmlatest ../working/timmlatest\n!pip install -U ../working/timmlatest\n!rm -rf ../working/timmlatest","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-05-24T14:10:55.860828Z","iopub.execute_input":"2022-05-24T14:10:55.861177Z","iopub.status.idle":"2022-05-24T14:13:12.585607Z","shell.execute_reply.started":"2022-05-24T14:10:55.861095Z","shell.execute_reply":"2022-05-24T14:13:12.584683Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## https://github.com/Selimonder/birdclef2022/\nimport os, sys, glob, math\n\nos.environ[\"MKL_NUM_THREADS\"] = \"1\"\nos.environ[\"OMP_NUM_THREADS\"] = \"1\"\n\ngithub_folder = \"/kaggle/input/birdclef2022-dev/birdclef2022-cls_exp/birdclef2022-cls_exp/\"\nsys.path.append(github_folder)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:12.587550Z","iopub.execute_input":"2022-05-24T14:13:12.587822Z","iopub.status.idle":"2022-05-24T14:13:12.594722Z","shell.execute_reply.started":"2022-05-24T14:13:12.587783Z","shell.execute_reply":"2022-05-24T14:13:12.593653Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nimport gc\nimport torch\nimport librosa\nimport argparse, warnings\n\nimport numpy as np\nimport pandas as pd\nimport IPython.display as ipd\n\nimport zoo\nfrom training.config import load_config\nfrom training.datasets import BirdDatasetOOF\n\n\ncv2.ocl.setUseOpenCL(False)\ncv2.setNumThreads(0)\n\nfrom tqdm import tqdm\nfrom torch.utils.data import DataLoader\n\nwarnings.simplefilter(\"ignore\")","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:12.595854Z","iopub.execute_input":"2022-05-24T14:13:12.596215Z","iopub.status.idle":"2022-05-24T14:13:20.881232Z","shell.execute_reply.started":"2022-05-24T14:13:12.596179Z","shell.execute_reply":"2022-05-24T14:13:20.880388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## models","metadata":{}},{"cell_type":"code","source":"def load_model(conf_path: str, weights_path: str, prefix: str, suffix: str, fold: int, to_device: bool = True):\n    conf = load_config(conf_path)\n    conf['encoder_params']['pretrained'] = False\n    \n    snapshot_name = \"{}{}_{}_{}_{}\".format(prefix, conf[\"network\"], conf[\"encoder_params\"][\"encoder\"], fold, suffix)\n    weights_path = os.path.join(weights_path, snapshot_name)\n    print(weights_path)\n    model = zoo.__dict__[conf[\"network\"]](**conf[\"encoder_params\"])\n    model = torch.nn.DataParallel(model).cuda()\n    print(\"=> loading checkpoint '{}''\".format(weights_path))\n    checkpoint = torch.load(weights_path, map_location=\"cpu\")\n    print(\"epoch\", checkpoint[\"epoch\"])\n    model.load_state_dict(checkpoint[\"state_dict\"])\n    model.eval()\n    if to_device: model.cuda()\n    return model\n\nmodels = []\n\n## best only for now\nsuffixes = [\"lb\"]#, \"f1_score\" \"last\"]\nfolds    = 5\n\nfor i in range(folds):\n    for sx in suffixes:\n        try:\n            model = load_model(conf_path    = f\"{github_folder}/configs/cls_nf0_v3.json\",\n                               weights_path = \"/kaggle/input/nfnet-baseline-bs16\",\n                               prefix       = \"baseline_submit_bs16\",\n                               suffix       = sx,\n                               fold         = i)\n            models.append(model)\n        except Exception as e:\n            print(f\"model not found\", e)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:20.883922Z","iopub.execute_input":"2022-05-24T14:13:20.884362Z","iopub.status.idle":"2022-05-24T14:13:32.375853Z","shell.execute_reply.started":"2022-05-24T14:13:20.884310Z","shell.execute_reply":"2022-05-24T14:13:32.375072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(models)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:32.377170Z","iopub.execute_input":"2022-05-24T14:13:32.377594Z","iopub.status.idle":"2022-05-24T14:13:32.387006Z","shell.execute_reply.started":"2022-05-24T14:13:32.377555Z","shell.execute_reply":"2022-05-24T14:13:32.386083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## infer","metadata":{}},{"cell_type":"code","source":"\ndef prepare_clip(fpath, frame_length, sample_rate):\n    \"\"\"\n    Prepare audio clip for inference\n    \"\"\"\n    infer_frame_length = frame_length\n    batch = {\"wav_tensors\": [], \"end_times\": []}\n    \n    waveform, sample_rate = librosa.load(fpath, sr=sample_rate, mono=True)\n    n_parts = math.ceil(len(waveform) / int(infer_frame_length * sample_rate))\n    \n    for seg_idx in range(n_parts): \n        end_time = (seg_idx + 1) * frame_length\n        seg_wav  = waveform[(end_time*sample_rate)-(sample_rate*frame_length):end_time*sample_rate]\n        \n        wav_tensor = torch.from_numpy(seg_wav)\n        \n        if len(wav_tensor) == frame_length * sample_rate:\n            batch[\"wav_tensors\"].append(wav_tensor.unsqueeze(0))\n        elif len(wav_tensor) < frame_length * sample_rate:\n            wav_tensor = torch.nn.functional.pad(wav_tensor, (0, (frame_length * sample_rate) - len(wav_tensor)))\n            batch[\"wav_tensors\"].append(wav_tensor.unsqueeze(0))\n        elif len(wav_tensor) > frame_length * sample_rate:\n            wav_tensor = wav_tensor[:(frame_length * sample_rate)]\n            batch[\"wav_tensors\"].append(wav_tensor.unsqueeze(0))\n            \n        batch[\"end_times\"].append(end_time)\n    batch[\"wav_tensors\"] = torch.stack(batch[\"wav_tensors\"]).cuda()\n    return batch, n_parts, len(waveform)\n\n@torch.no_grad()\ndef predict_clip(models, batch, n_parts, frame_length):\n    preds = np.zeros([len(models), n_parts, 21])\n    for m_idx, model in enumerate(models):\n        with torch.cuda.amp.autocast():\n            preds[m_idx] = model(batch[\"wav_tensors\"], is_test=True)[\"logit\"].sigmoid().cpu().numpy()\n    return preds.max(0) ## max by model    \n    ","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:32.388379Z","iopub.execute_input":"2022-05-24T14:13:32.388811Z","iopub.status.idle":"2022-05-24T14:13:32.402406Z","shell.execute_reply.started":"2022-05-24T14:13:32.388775Z","shell.execute_reply":"2022-05-24T14:13:32.401437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(models)","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:32.403764Z","iopub.execute_input":"2022-05-24T14:13:32.404572Z","iopub.status.idle":"2022-05-24T14:13:32.416178Z","shell.execute_reply.started":"2022-05-24T14:13:32.404534Z","shell.execute_reply":"2022-05-24T14:13:32.415384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\n@torch.no_grad()\ndef generate_preds():\n    debug = False\n    preds        = []\n    test_files   = sorted(glob.glob(\"/kaggle/input/birdclef-2022/test_soundscapes/*.ogg\")) \n    sample_rate  = 32000\n    \n    scored_birds = np.array(['akiapo', 'aniani', 'apapan', 'barpet', 'crehon', 'elepai', 'ercfra',\n                              'hawama', 'hawcre', 'hawgoo', 'hawhaw', 'hawpet1', 'houfin', 'iiwi',\n                              'jabwar', 'maupar', 'omao', 'puaioh', 'skylar', 'warwhe1', 'yefcan'])\n\n    frame_length = 5\n    infer_frame_length = 5\n\n    for fpath in test_files:\n        file_id = os.path.basename(fpath).replace(\".ogg\", \"\")\n        batch, n_parts, len_waveform = prepare_clip(fpath, frame_length, sample_rate)\n        clip_preds = predict_clip(models, batch, n_parts, frame_length)\n        preds.append(clip_preds)\n        \n        ## switch to infer frame length\n        n_parts_sub = math.ceil(len_waveform / int(infer_frame_length * sample_rate))\n        clip_preds = np.array_split(clip_preds, n_parts_sub, axis=0)\n        \n                \n    prob_array = np.array(preds)\n    \n    scored_bird_name2idx = {}\n    for i, x in enumerate(scored_birds):\n        scored_bird_name2idx[x] = i\n\n    return prob_array, scored_bird_name2idx\n\nprob_array, scored_bird_name2idx = generate_preds()\n# del models\n# gc.collect()\n# torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:32.417515Z","iopub.execute_input":"2022-05-24T14:13:32.418268Z","iopub.status.idle":"2022-05-24T14:13:32.749422Z","shell.execute_reply.started":"2022-05-24T14:13:32.418232Z","shell.execute_reply":"2022-05-24T14:13:32.748544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prob_array.shape","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:32.750951Z","iopub.execute_input":"2022-05-24T14:13:32.757597Z","iopub.status.idle":"2022-05-24T14:13:32.766148Z","shell.execute_reply.started":"2022-05-24T14:13:32.757553Z","shell.execute_reply":"2022-05-24T14:13:32.765119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"----","metadata":{}},{"cell_type":"code","source":"%cd /kaggle/input/birdnetgit","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:32.769519Z","iopub.execute_input":"2022-05-24T14:13:32.772592Z","iopub.status.idle":"2022-05-24T14:13:32.782637Z","shell.execute_reply.started":"2022-05-24T14:13:32.772550Z","shell.execute_reply":"2022-05-24T14:13:32.781596Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport sys\nimport json\nimport math\nimport glob\nimport librosa\nimport operator\nimport argparse\nimport datetime\nimport traceback\n\nfrom multiprocessing import Pool, freeze_support\n\nimport numpy as np\n\nimport config as cfg\nimport audio\nimport model\nfrom analyze import *\n\nimport pandas as pd\nimport numpy as np","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:32.786900Z","iopub.execute_input":"2022-05-24T14:13:32.787325Z","iopub.status.idle":"2022-05-24T14:13:32.821590Z","shell.execute_reply.started":"2022-05-24T14:13:32.787288Z","shell.execute_reply":"2022-05-24T14:13:32.820757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv(\"../birdclef-2022/eBird_Taxonomy_v2021.csv\")\ns2id = lambda x: df[(df['PRIMARY_COM_NAME'] == x)].SPECIES_CODE.tolist()[0]\n\ncfg.MODEL_PATH = '/kaggle/input/birdnetgit/checkpoints/V2.1/BirdNET_GLOBAL_2K_V2.1_Model_FP32.tflite'\ncfg.MDATA_MODEL_PATH = '/kaggle/input/birdnetgit/checkpoints/V2.1/BirdNET_GLOBAL_2K_V2.1_MData_Model_FP32.tflite'\ncfg.LABELS_FILE = '/kaggle/input/birdnetgit/checkpoints/V2.1/BirdNET_GLOBAL_2K_V2.1_Labels.txt'\ncfg.TRANSLATED_LABELS_PATH = '/kaggle/input/birdnetgit/labels/V2.1'\n\ncfg.SIG_LENGTH = 5\ncfg.SIG_OVERLAP = 0 \ncfg.SIG_MINLEN = 5 \n\n# Load eBird codes, labels\n\ndef loadCodes(CODEC_FILE):\n\n    with open(CODEC_FILE, 'r') as cfile:\n        codes = json.load(cfile)\n\n    return codes\n\ncfg.CODES = loadCodes(\"./eBird_taxonomy_codes_2021E.json\")\ndef loadLabels(labels_file):\n\n    labels = []\n    with open(labels_file, 'r') as lfile:\n        for line in lfile.readlines():\n            labels.append(line.replace('\\n', ''))    \n\n    return labels\n\ndef prepare_clip(fpath):\n    \"\"\"\n    Prepare audio clip for inference\n    \"\"\"\n    sample_rate = cfg.SAMPLE_RATE\n    frame_length = cfg.SIG_LENGTH\n    infer_frame_length = frame_length\n    \n    sample_rate = 48000\n    chunks = []\n    \n    waveform, sample_rate = librosa.load(fpath, sr=sample_rate, mono=True, res_type='kaiser_fast')\n    n_parts = math.ceil(len(waveform) / int(infer_frame_length * sample_rate))\n    \n    for seg_idx in range(n_parts): \n        end_time = (seg_idx + 1) * frame_length\n        chunk  = waveform[(end_time*sample_rate)-(sample_rate*frame_length):end_time*sample_rate]\n                \n        if len(chunk) == frame_length * sample_rate:\n            chunks.append(chunk)\n        elif len(chunk) < frame_length * sample_rate:\n            chunk = np.pad(chunk, (0, (frame_length * sample_rate) - len(chunk)))\n            chunks.append(chunk)\n        elif len(chunk) > frame_length * sample_rate:\n            chunk = chunk[:(frame_length * sample_rate)]\n            chunks.append(chunk)\n            \n    return chunks\n\n\nscored_birds = np.array(['akiapo', 'aniani', 'apapan', 'barpet', 'crehon', 'elepai', 'ercfra',\n                          'hawama', 'hawcre', 'hawgoo', 'hawhaw', 'hawpet1', 'houfin', 'iiwi',\n                          'jabwar', 'maupar', 'omao', 'puaioh', 'skylar', 'warwhe1', 'yefcan'])\n\ncfg.LABELS = loadLabels(cfg.LABELS_FILE)\n\nmodel.loadModel()\n\n","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:32.822884Z","iopub.execute_input":"2022-05-24T14:13:32.823123Z","iopub.status.idle":"2022-05-24T14:13:33.159976Z","shell.execute_reply.started":"2022-05-24T14:13:32.823089Z","shell.execute_reply":"2022-05-24T14:13:33.159152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bird_dict = {}\nfor i, lb in enumerate(cfg.LABELS):\n    try:\n        lbb = s2id(lb.split(\"_\")[-1])\n        if lbb in scored_birds:\n            bird_dict[lbb] = i\n    except Exception as e:\n        continue\n    \nbird_dict[\"aniani\"] = 0\n\nsorted_bd = dict(sorted(bird_dict.items(), key=lambda item: item[0]))\nget_idx = list(sorted_bd.values())","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:33.163048Z","iopub.execute_input":"2022-05-24T14:13:33.163249Z","iopub.status.idle":"2022-05-24T14:13:39.251863Z","shell.execute_reply.started":"2022-05-24T14:13:33.163224Z","shell.execute_reply":"2022-05-24T14:13:39.251114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def predict_single(test_path)\n\ndef generate_preds_bn():\n    test_files   = sorted(glob.glob(\"/kaggle/input/birdclef-2022/test_soundscapes/*.ogg\"))\n    \n    preds = []\n    file_ids = []\n    \n    for fpath in test_files:\n        chunks = prepare_clip(fpath)\n        pred = predict(chunks)[:, get_idx]\n        preds.append(pred)\n        file_id = os.path.basename(fpath).replace(\".ogg\", \"\")\n        file_ids.append(file_id)\n        \n    preds = np.array(preds)\n    return preds, file_ids\n        ","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:39.254121Z","iopub.execute_input":"2022-05-24T14:13:39.254652Z","iopub.status.idle":"2022-05-24T14:13:39.260825Z","shell.execute_reply.started":"2022-05-24T14:13:39.254614Z","shell.execute_reply":"2022-05-24T14:13:39.260077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\npreds_bn, file_ids = generate_preds_bn()\n","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:39.262182Z","iopub.execute_input":"2022-05-24T14:13:39.262441Z","iopub.status.idle":"2022-05-24T14:13:42.737214Z","shell.execute_reply.started":"2022-05-24T14:13:39.262408Z","shell.execute_reply":"2022-05-24T14:13:42.736470Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds_bn[:, :, 1] = prob_array[:, :, 1]","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:42.738715Z","iopub.execute_input":"2022-05-24T14:13:42.738977Z","iopub.status.idle":"2022-05-24T14:13:42.744061Z","shell.execute_reply.started":"2022-05-24T14:13:42.738941Z","shell.execute_reply":"2022-05-24T14:13:42.743219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## fix aniani\navg_preds = (3 * preds_bn + prob_array) / 4\n\navg_preds.shape","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:42.745718Z","iopub.execute_input":"2022-05-24T14:13:42.745982Z","iopub.status.idle":"2022-05-24T14:13:42.756170Z","shell.execute_reply.started":"2022-05-24T14:13:42.745948Z","shell.execute_reply":"2022-05-24T14:13:42.755485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission   = []\ninfer_frame_length = 5\nthreshold = 0.1\n\nfor clip_preds, file_id in zip(avg_preds, file_ids):\n    for frame_idx, pred in enumerate(clip_preds):\n        end_time = (frame_idx + 1) * infer_frame_length\n        for bi, bird in enumerate(scored_birds):\n            submission.append({\n                \"row_id\": f\"{file_id}_{bird}_{end_time}\",\n                \"target\": pred[bi] > threshold,\n            })","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:42.759093Z","iopub.execute_input":"2022-05-24T14:13:42.759345Z","iopub.status.idle":"2022-05-24T14:13:42.768552Z","shell.execute_reply.started":"2022-05-24T14:13:42.759312Z","shell.execute_reply":"2022-05-24T14:13:42.767782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd /kaggle/working","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:42.771602Z","iopub.execute_input":"2022-05-24T14:13:42.771824Z","iopub.status.idle":"2022-05-24T14:13:42.779582Z","shell.execute_reply.started":"2022-05-24T14:13:42.771795Z","shell.execute_reply":"2022-05-24T14:13:42.778633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission = pd.DataFrame(submission).set_index(\"row_id\")\ndf_submission.to_csv(\"submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:42.781156Z","iopub.execute_input":"2022-05-24T14:13:42.781520Z","iopub.status.idle":"2022-05-24T14:13:42.798020Z","shell.execute_reply.started":"2022-05-24T14:13:42.781486Z","shell.execute_reply":"2022-05-24T14:13:42.797300Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"\"\"\ntotal rows : {len(df_submission)}\nactivated  : {len(df_submission[(df_submission.target==True)])}\n\"\"\")\n\ndf_submission[(df_submission.target==True)].head()","metadata":{"execution":{"iopub.status.busy":"2022-05-24T14:13:42.799394Z","iopub.execute_input":"2022-05-24T14:13:42.799656Z","iopub.status.idle":"2022-05-24T14:13:42.816970Z","shell.execute_reply.started":"2022-05-24T14:13:42.799622Z","shell.execute_reply":"2022-05-24T14:13:42.816302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}