{"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":"markdown","source":"# Let's Think of a Better Split Method","metadata":{"papermill":{"duration":0.018531,"end_time":"2021-04-27T16:16:17.44056","exception":false,"start_time":"2021-04-27T16:16:17.422029","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import numpy as np\nimport librosa as lb\nimport librosa.display as lbd\nimport soundfile as sf\nfrom  soundfile import SoundFile\nimport pandas as pd\nfrom  IPython.display import Audio\nfrom pathlib import Path\n\nfrom matplotlib import pyplot as plt\n\nfrom tqdm.notebook import tqdm\nimport joblib, json, re\n\nfrom  sklearn.model_selection  import StratifiedKFold\ntqdm.pandas()","metadata":{"id":"2dt7oG43VAqc","papermill":{"duration":2.637633,"end_time":"2021-04-27T16:16:20.164867","exception":false,"start_time":"2021-04-27T16:16:17.527234","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-18T10:41:36.941036Z","iopub.execute_input":"2023-04-18T10:41:36.941538Z","iopub.status.idle":"2023-04-18T10:41:38.544570Z","shell.execute_reply.started":"2023-04-18T10:41:36.941490Z","shell.execute_reply":"2023-04-18T10:41:38.542605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv('../input/birdclef-2023/train_metadata.csv')\ndf['secondary_labels'] = df['secondary_labels'].apply(lambda x: re.findall(r\"'(\\w+)'\", x))\ndf['len_sec_labels'] = df['secondary_labels'].map(len)\n","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:41:38.547601Z","iopub.execute_input":"2023-04-18T10:41:38.548250Z","iopub.status.idle":"2023-04-18T10:41:38.759600Z","shell.execute_reply.started":"2023-04-18T10:41:38.548196Z","shell.execute_reply":"2023-04-18T10:41:38.758554Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[df.len_sec_labels>0].sample(3)","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:41:38.761694Z","iopub.execute_input":"2023-04-18T10:41:38.762759Z","iopub.status.idle":"2023-04-18T10:41:38.812945Z","shell.execute_reply.started":"2023-04-18T10:41:38.762698Z","shell.execute_reply":"2023-04-18T10:41:38.811548Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.primary_label.value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:41:38.817114Z","iopub.execute_input":"2023-04-18T10:41:38.817693Z","iopub.status.idle":"2023-04-18T10:41:38.835778Z","shell.execute_reply.started":"2023-04-18T10:41:38.817634Z","shell.execute_reply":"2023-04-18T10:41:38.834165Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Something has to be done for Birds with <= 1 samples.","metadata":{}},{"cell_type":"markdown","source":"## Also the fact that we have to perform inference in 2 hours w/ CPU, I think best solution is just to have single split rather than using multiple folds.","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nimport pandas as pd\n\ndef birds_stratified_split(df, target_col, test_size=0.2):\n    class_counts = df[target_col].value_counts()\n    low_count_classes = class_counts[class_counts < 2].index.tolist() ### Birds with single counts\n\n    df['train'] = df[target_col].isin(low_count_classes)\n\n    train_df, val_df = train_test_split(df[~df['train']], test_size=test_size, stratify=df[~df['train']][target_col], random_state=42)\n\n    train_df = pd.concat([train_df, df[df['train']]], axis=0).reset_index(drop=True)\n\n    # Remove the 'valid' column\n    train_df.drop('train', axis=1, inplace=True)\n    val_df.drop('train', axis=1, inplace=True)\n\n    return train_df, val_df","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:41:38.837862Z","iopub.execute_input":"2023-04-18T10:41:38.839167Z","iopub.status.idle":"2023-04-18T10:41:38.850942Z","shell.execute_reply.started":"2023-04-18T10:41:38.839118Z","shell.execute_reply":"2023-04-18T10:41:38.849344Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df, valid_df = birds_stratified_split(df, 'primary_label', 0.2)","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:41:38.854270Z","iopub.execute_input":"2023-04-18T10:41:38.855250Z","iopub.status.idle":"2023-04-18T10:41:38.942752Z","shell.execute_reply.started":"2023-04-18T10:41:38.855203Z","shell.execute_reply":"2023-04-18T10:41:38.941303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.primary_label.value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:41:38.944285Z","iopub.execute_input":"2023-04-18T10:41:38.944774Z","iopub.status.idle":"2023-04-18T10:41:38.957834Z","shell.execute_reply.started":"2023-04-18T10:41:38.944725Z","shell.execute_reply":"2023-04-18T10:41:38.956519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.primary_label.value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:41:38.959369Z","iopub.execute_input":"2023-04-18T10:41:38.959798Z","iopub.status.idle":"2023-04-18T10:41:38.977002Z","shell.execute_reply.started":"2023-04-18T10:41:38.959758Z","shell.execute_reply":"2023-04-18T10:41:38.975397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_df.primary_label.value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:41:38.978834Z","iopub.execute_input":"2023-04-18T10:41:38.979517Z","iopub.status.idle":"2023-04-18T10:41:38.994360Z","shell.execute_reply.started":"2023-04-18T10:41:38.979455Z","shell.execute_reply":"2023-04-18T10:41:38.992410Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Config:\n    sampling_rate = 32000\n    img_weight = 256\n    duration = 5 \n    fmin = 0\n    fmax = None\n    audios_path = Path(\"/kaggle/input/birdclef-2023/train_audio\")\n    out_dir_train = Path(\"specs/train\") \n    \n    out_dir_valid = Path(\"specs/valid\") \n","metadata":{"papermill":{"duration":0.027531,"end_time":"2021-04-27T16:16:20.271347","exception":false,"start_time":"2021-04-27T16:16:20.243816","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-18T10:41:39.000189Z","iopub.execute_input":"2023-04-18T10:41:39.000982Z","iopub.status.idle":"2023-04-18T10:41:39.007726Z","shell.execute_reply.started":"2023-04-18T10:41:39.000933Z","shell.execute_reply":"2023-04-18T10:41:39.006381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Config.out_dir_train.mkdir(exist_ok=True, parents=True)\nConfig.out_dir_valid.mkdir(exist_ok=True, parents=True)","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:41:39.009208Z","iopub.execute_input":"2023-04-18T10:41:39.009868Z","iopub.status.idle":"2023-04-18T10:41:39.021881Z","shell.execute_reply.started":"2023-04-18T10:41:39.009826Z","shell.execute_reply":"2023-04-18T10:41:39.019350Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_audio_info(filepath):\n    \"\"\"Get some properties from  an audio file\"\"\"\n    with SoundFile(filepath) as f:\n        sr = f.samplerate\n        frames = f.frames\n        duration = float(frames)/sr\n    return {\"frames\": frames, \"sr\": sr, \"duration\": duration}","metadata":{"papermill":{"duration":0.026875,"end_time":"2021-04-27T16:16:20.351194","exception":false,"start_time":"2021-04-27T16:16:20.324319","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-18T10:41:39.025031Z","iopub.execute_input":"2023-04-18T10:41:39.027826Z","iopub.status.idle":"2023-04-18T10:41:39.035206Z","shell.execute_reply.started":"2023-04-18T10:41:39.027762Z","shell.execute_reply":"2023-04-18T10:41:39.034153Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def add_path_df(df):\n    \n    df[\"path\"] = [str(Config.audios_path/filename) for filename in df.filename]\n    df = df.reset_index(drop=True)\n    pool = joblib.Parallel(2)\n    mapper = joblib.delayed(get_audio_info)\n    tasks = [mapper(filepath) for filepath in df.path]\n    df2 =  pd.DataFrame(pool(tqdm(tasks))).reset_index(drop=True)\n    df = pd.concat([df,df2], axis=1).reset_index(drop=True)\n\n    return df","metadata":{"id":"Kmh6xx5_NCjJ","outputId":"ad61f09f-6f0e-4204-c658-21112e051785","papermill":{"duration":0.031496,"end_time":"2021-04-27T16:16:20.401055","exception":false,"start_time":"2021-04-27T16:16:20.369559","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-18T10:41:39.036849Z","iopub.execute_input":"2023-04-18T10:41:39.037701Z","iopub.status.idle":"2023-04-18T10:41:39.052363Z","shell.execute_reply.started":"2023-04-18T10:41:39.037643Z","shell.execute_reply":"2023-04-18T10:41:39.050739Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tqdm.pandas()\n","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:41:39.054143Z","iopub.execute_input":"2023-04-18T10:41:39.055210Z","iopub.status.idle":"2023-04-18T10:41:39.066295Z","shell.execute_reply.started":"2023-04-18T10:41:39.055147Z","shell.execute_reply":"2023-04-18T10:41:39.064627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = add_path_df(train_df)","metadata":{"papermill":{"duration":0.017674,"end_time":"2021-04-27T16:16:20.436943","exception":false,"start_time":"2021-04-27T16:16:20.419269","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-18T10:41:39.068009Z","iopub.execute_input":"2023-04-18T10:41:39.068406Z","iopub.status.idle":"2023-04-18T10:43:19.456471Z","shell.execute_reply.started":"2023-04-18T10:41:39.068367Z","shell.execute_reply":"2023-04-18T10:43:19.454755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_df = add_path_df(valid_df)","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:43:19.458736Z","iopub.execute_input":"2023-04-18T10:43:19.459186Z","iopub.status.idle":"2023-04-18T10:43:43.857094Z","shell.execute_reply.started":"2023-04-18T10:43:19.459136Z","shell.execute_reply":"2023-04-18T10:43:43.856039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df[\"duration\"].describe()","metadata":{"papermill":{"duration":0.257618,"end_time":"2021-04-27T16:18:04.144335","exception":false,"start_time":"2021-04-27T16:18:03.886717","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-18T10:43:43.858864Z","iopub.execute_input":"2023-04-18T10:43:43.859959Z","iopub.status.idle":"2023-04-18T10:43:43.874530Z","shell.execute_reply.started":"2023-04-18T10:43:43.859914Z","shell.execute_reply":"2023-04-18T10:43:43.873234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def compute_melspec(y, sr, n_mels, hop_length, fmin, fmax):\n    \"\"\"\n    Computes a mel-spectrogram and puts it at decibel scale\n    Arguments:\n        y {np array} -- signal\n        params {AudioParams} -- Parameters to use for the spectrogram. Expected to have the attributes sr, n_mels, f_min, f_max\n    Returns:\n        np array -- Mel-spectrogram\n    \"\"\"\n    melspec = lb.feature.melspectrogram(\n        y=y, sr=sr, n_mels=n_mels, fmin=fmin, fmax=fmax,\n        hop_length=hop_length\n    )\n\n    melspec = lb.power_to_db(melspec).astype(np.float32)\n    return melspec","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:43:43.875997Z","iopub.execute_input":"2023-04-18T10:43:43.876785Z","iopub.status.idle":"2023-04-18T10:43:43.883271Z","shell.execute_reply.started":"2023-04-18T10:43:43.876742Z","shell.execute_reply":"2023-04-18T10:43:43.882041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def mono_to_color(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    \n    _min, _max = X.min(), X.max()\n\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\n    return V\n\ndef crop_or_pad(y, length, is_train=True, start=None):\n    if len(y) < length:\n        y = np.concatenate([y, np.zeros(length - len(y))])\n        \n        n_repeats = length // len(y)\n        epsilon = length % len(y)\n        \n        y = np.concatenate([y]*n_repeats + [y[:epsilon]])\n        \n    elif len(y) > length:\n        if not is_train:\n            start = start or 0\n        else:\n            start = start or np.random.randint(len(y) - length)\n\n        y = y[start:start + length]\n\n    return y","metadata":{"id":"-Nlw4E5UVAqi","papermill":{"duration":0.036932,"end_time":"2021-04-27T16:18:04.507902","exception":false,"start_time":"2021-04-27T16:18:04.47097","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-18T10:43:43.885063Z","iopub.execute_input":"2023-04-18T10:43:43.885465Z","iopub.status.idle":"2023-04-18T10:43:43.900326Z","shell.execute_reply.started":"2023-04-18T10:43:43.885405Z","shell.execute_reply":"2023-04-18T10:43:43.898969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class AudioToImage:\n    def __init__(self, sr=Config.sampling_rate, n_mels=128, img_weight=Config.img_weight ,fmin=Config.fmin, fmax=Config.fmax, duration=Config.duration, step=None, res_type=\"kaiser_fast\", resample=True, train = True):\n\n        self.sr = sr\n        self.n_mels = n_mels\n        self.fmin = fmin\n        self.fmax = fmax or self.sr//2\n        self.hop_length = int(sr * duration / (img_weight - 1))\n\n        self.duration = duration\n        self.audio_length = self.duration*self.sr\n        self.step = step or self.audio_length\n        \n        self.res_type = res_type\n        self.resample = resample\n\n        self.train = train\n    def audio_to_image(self, audio):\n        melspec = compute_melspec(audio, self.sr, self.n_mels, self.hop_length ,self.fmin, self.fmax ) \n        image = mono_to_color(melspec)\n        print(image.shape)\n#         compute_melspec(y, sr, n_mels, fmin, fmax)\n        return image\n\n    def __call__(self, row, save=True):\n\n      audio, orig_sr = sf.read(row.path, dtype=\"float32\")\n\n      if self.resample and orig_sr != self.sr:\n        audio = lb.resample(audio, orig_sr, self.sr, res_type=self.res_type)\n        \n      audios = [audio[i:i+self.audio_length] for i in range(0, max(1, len(audio) - self.audio_length + 1), self.step)]\n      audios[-1] = crop_or_pad(audios[-1] , length=self.audio_length)\n      images = [self.audio_to_image(audio) for audio in audios]\n      images = np.stack(images)\n      print(images.shape)\n      if save:\n        if self.train:\n            path = Config.out_dir_train/f\"{row.filename}.npy\"\n        else:\n            path = Config.out_dir_valid/f\"{row.filename}.npy\"\n            \n        path.parent.mkdir(exist_ok=True, parents=True)\n        np.save(str(path), images)\n      else:\n        return  row.filename, images","metadata":{"papermill":{"duration":0.039542,"end_time":"2021-04-27T16:18:04.570629","exception":false,"start_time":"2021-04-27T16:18:04.531087","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-18T10:45:16.061911Z","iopub.execute_input":"2023-04-18T10:45:16.062386Z","iopub.status.idle":"2023-04-18T10:45:16.080582Z","shell.execute_reply.started":"2023-04-18T10:45:16.062337Z","shell.execute_reply":"2023-04-18T10:45:16.079218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tqdm.pandas()","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:44:09.500737Z","iopub.execute_input":"2023-04-18T10:44:09.501147Z","iopub.status.idle":"2023-04-18T10:44:09.507852Z","shell.execute_reply.started":"2023-04-18T10:44:09.501111Z","shell.execute_reply":"2023-04-18T10:44:09.506533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_audios_as_images(df, train = True):\n    pool = joblib.Parallel(2)\n    \n    converter = AudioToImage(step=int(Config.duration*0.666*Config.sampling_rate),train=train)\n    mapper = joblib.delayed(converter)\n    tasks = [mapper(row) for row in df.itertuples(False)]\n    pool(tqdm(tasks))","metadata":{"papermill":{"duration":0.032362,"end_time":"2021-04-27T16:18:04.626619","exception":false,"start_time":"2021-04-27T16:18:04.594257","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-18T10:45:18.419558Z","iopub.execute_input":"2023-04-18T10:45:18.419986Z","iopub.status.idle":"2023-04-18T10:45:18.429191Z","shell.execute_reply.started":"2023-04-18T10:45:18.419949Z","shell.execute_reply":"2023-04-18T10:45:18.427154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"get_audios_as_images(train_df, train = True)\n","metadata":{"papermill":{"duration":4117.309995,"end_time":"2021-04-27T17:26:41.959921","exception":false,"start_time":"2021-04-27T16:18:04.649926","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-18T10:45:18.799519Z","iopub.execute_input":"2023-04-18T10:45:18.800718Z","iopub.status.idle":"2023-04-18T10:46:25.709542Z","shell.execute_reply.started":"2023-04-18T10:45:18.800669Z","shell.execute_reply":"2023-04-18T10:46:25.707401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"get_audios_as_images(valid_df, train = False)","metadata":{"execution":{"iopub.status.busy":"2023-04-18T10:44:00.820484Z","iopub.status.idle":"2023-04-18T10:44:00.821922Z","shell.execute_reply.started":"2023-04-18T10:44:00.821583Z","shell.execute_reply":"2023-04-18T10:44:00.821622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#","metadata":{"papermill":{"duration":0.027772,"end_time":"2021-04-27T17:26:42.374518","exception":false,"start_time":"2021-04-27T17:26:42.346746","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-18T10:44:00.823513Z","iopub.status.idle":"2023-04-18T10:44:00.824143Z","shell.execute_reply.started":"2023-04-18T10:44:00.823814Z","shell.execute_reply":"2023-04-18T10:44:00.823847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}