{"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":"from fastai.vision.all import *\nimport librosa","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From https://www.kaggle.com/kneroma/clean-fast-simple-bird-identifier-inference getting file locations and labels in case of train:","metadata":{}},{"cell_type":"code","source":"NUM_CLASSES = 397\nSR = 32_000\nDURATION = 5\nTHRESH = 0.25\nTEST_AUDIO_ROOT = Path(\"../input/birdclef-2021/test_soundscapes\")\nSAMPLE_SUB_PATH = \"../input/birdclef-2021/sample_submission.csv\"\nTARGET_PATH = None\nif not len(list(TEST_AUDIO_ROOT.glob(\"*.ogg\"))):\n    TEST_AUDIO_ROOT = Path(\"../input/birdclef-2021/train_soundscapes\")\n    SAMPLE_SUB_PATH = None\n    # SAMPLE_SUB_PATH = \"../input/birdclef-2021/sample_submission.csv\"\n    TARGET_PATH = Path(\"../input/birdclef-2021/train_soundscape_labels.csv\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = pd.DataFrame(\n     [(path.stem, *path.stem.split(\"_\"), path) for path in Path(TEST_AUDIO_ROOT).glob(\"*.ogg\")],\n    columns = [\"filename\", \"id\", \"site\", \"date\", \"filepath\"]\n)\nprint(data.shape)\ndata.head()","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv(\"../input/birdclef-2021/train_metadata.csv\")\n\nLABEL_IDS = {label: label_id for label_id,label in enumerate(sorted(df_train[\"primary_label\"].unique()))}\nINV_LABEL_IDS = {val: key for key,val in LABEL_IDS.items()}\ndf_train.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"row_ids = []\nfilenames = []\nfor fn, sid, site, date, filepath in data.values:\n    y, sr = librosa.load(filepath, sr=32000)\n    n_clips = len(y)/(32000*5)\n    for c in range(int(n_clips)):\n        row_ids.append('_'.join(fn.split('_')[:-1]) + '_' + str(5*(c+1)))\n        filenames.append(filepath)\nsubmission_df = pd.DataFrame({\n    'row_id':row_ids,\n    'birds':['nocall' for _ in row_ids],\n    'fn':filenames,\n    'start_time':[int(r.split('_')[-1])-5 for r in row_ids]\n})\nprint(submission_df.shape)\nsubmission_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Making Preds\n\nBla bla threshold etc","metadata":{}},{"cell_type":"code","source":"def chunk_to_spec(chunk, SPEC_HEIGHT=64,SPEC_WIDTH=256, rate=32000, FMIN=200, FMAX=12500):\n    mel_spec = librosa.feature.melspectrogram(y=chunk, \n                                              sr=32000, \n                                              n_fft=1024, \n                                              hop_length=int(32000 * 5 / (SPEC_WIDTH - 1)), \n                                              n_mels=SPEC_HEIGHT, \n                                              fmin=FMIN, \n                                              fmax=FMAX)\n    mel_spec_db = librosa.power_to_db(mel_spec, ref=np.max)\n    return mel_spec_db\n\nclass TitledImage(fastuple):\n    def show(self, ctx=None, **kwargs): show_titled_image(self, ctx=ctx, **kwargs)\n\nclass ClipTransform(ItemTransform):\n\n    def __init__(self, df):\n        self.df=df\n        self.vocab,self.o2i = uniqueify(df['label'], sort=True, bidir=True)\n        \n    def encodes(self, i, from_np=False):\n        row_id, birds, fn, start_time, label = self.df.iloc[i].values\n        y, sr = librosa.load(fn, sr=32000, offset=start_time, duration=5)\n        spec = chunk_to_spec(y,SPEC_HEIGHT=112,SPEC_WIDTH=224)\n        spec -= np.min(spec) \n        spec /= 80 # np.max(spec) # Normalize\n        spec =  torch.unsqueeze(tensor(spec), 0)\n        spec = torch.cat([spec, spec, spec]) # Stack three channels to simulate RGB if using a pretrained model\n        return spec, self.o2i[label]\n    \n    def decodes(self, x):\n        return TitledImage(x[0],self.vocab[x[1]])\n\n\ndf_small = submission_df\ndf_small['label'] = 'LABEL'\nclip_tfm = ClipTransform(df_small)\n\n# Not using either of these apart from making the dataloaders so can ignore the obvious issues\ntrain =  df_small.sample(frac=0.1)\nvalid =  df_small.sample(frac=0.1)\ntrain_idx, valid_idx = list(train.index), list(valid.index)\nprint('train and val size', len(train_idx), len(valid_idx))\ntrain_tl= TfmdLists(train_idx, clip_tfm)\nvalid_tl= TfmdLists(valid_idx, clip_tfm)\ndls = DataLoaders.from_dsets(train_tl, valid_tl, bs=16)\ndls = dls.cuda()\ntest_dl = dls.test_dl(df_small.index)\nxb, yb = dls.one_batch()\nprint(xb.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn = load_learner('../input/baseline-model/baseline_3e.pkl')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = learn.get_preds(dl=test_dl)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds[0].shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bird_names = df_train.primary_label.unique()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_calls = []\nthresh = 0.45\nfor p in preds[0]:\n    calls = []\n    for i, prob in enumerate(p):\n        if prob > thresh:\n            calls.append(bird_names[i])\n    if len(calls)==0:\n        calls.append('nocall')\n    pred_calls.append(calls)\nsub = submission_df[['row_id', 'birds']].copy()\nsub['birds'] = [' '.join(calls) for calls in pred_calls]\nsub.sample(10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_metrics(s_true, s_pred):\n    s_true = set(s_true.split())\n    s_pred = set(s_pred.split())\n    n, n_true, n_pred = len(s_true.intersection(s_pred)), len(s_true), len(s_pred)\n    \n    prec = n/n_pred\n    rec = n/n_true\n    f1 = 2*prec*rec/(prec + rec) if prec + rec else 0\n    \n    return {\"f1\": f1, \"prec\": prec, \"rec\": rec, \"n_true\": n_true, \"n_pred\": n_pred, \"n\": n}\nif TARGET_PATH:\n    sub_target = pd.read_csv(TARGET_PATH)\n    sub_target = sub_target.merge(sub, how=\"left\", on=\"row_id\")\n    \n    print(sub_target[\"birds_x\"].notnull().sum(), sub_target[\"birds_x\"].notnull().sum())\n    assert sub_target[\"birds_x\"].notnull().all()\n    assert sub_target[\"birds_y\"].notnull().all()\n    \n    df_metrics = pd.DataFrame([get_metrics(s_true, s_pred) for s_true, s_pred in zip(sub_target.birds_x, sub_target.birds_y)])\n    \n    print(df_metrics.mean())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# sub_target[sub_target.birds_y != \"nocall\"]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Exploring the threshold - anything between 0.15 and 0.6 does about the same, peaking around 0.4 in this case.\n# for thresh in range(5, 95, 5):\n#     pred_calls = []\n#     thresh = thresh/100.0\n#     for p in preds[0]:\n#         calls = []\n#         for i, prob in enumerate(p):\n#             if prob > thresh:\n#                 calls.append(bird_names[i])\n#         if len(calls)==0:\n#             calls.append('nocall')\n#         pred_calls.append(calls)\n#     sub = submission_df[['row_id', 'birds']].copy()\n#     sub['birds'] = [' '.join(calls) for calls in pred_calls]\n    \n#     sub_target = pd.read_csv(TARGET_PATH)\n#     sub_target = sub_target.merge(sub, how=\"left\", on=\"row_id\")\n    \n#     print(sub_target[\"birds_x\"].notnull().sum(), sub_target[\"birds_x\"].notnull().sum())\n#     assert sub_target[\"birds_x\"].notnull().all()\n#     assert sub_target[\"birds_y\"].notnull().all()\n    \n#     df_metrics = pd.DataFrame([get_metrics(s_true, s_pred) for s_true, s_pred in zip(sub_target.birds_x, sub_target.birds_y)])\n    \n#     print(df_metrics.mean())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}