{"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":"import random\nimport librosa\nimport librosa.display as display\nimport numpy as np\nimport soundfile as sf\nimport torch\nimport torch.utils.data as data\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom IPython.display import Audio\nimport os\nfrom pathlib import Path\nfrom typing import Optional, List\n\ndef set_seed(seed: int = 42):\n    random.seed(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)  # type: ignore\n    torch.backends.cudnn.deterministic = True  # type: ignore\n    torch.backends.cudnn.benchmark = True  # type: ignore\n    \nset_seed(1213)\nROOT = Path(\"..\")\nTRAIN_AUDIO_ROOT = Path(\"../input/birdclef-2022/train_audio\")","metadata":{"_kg_hide-input":true,"scrolled":true,"execution":{"iopub.status.busy":"2022-05-11T02:36:54.351123Z","iopub.execute_input":"2022-05-11T02:36:54.351512Z","iopub.status.idle":"2022-05-11T02:36:54.364125Z","shell.execute_reply.started":"2022-05-11T02:36:54.351476Z","shell.execute_reply":"2022-05-11T02:36:54.362636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Read csv & make list","metadata":{}},{"cell_type":"code","source":"train_metadata_df = pd.read_csv(\"../input/birdclef-2022/train_metadata.csv\")\nlabel_dic = {v:i for i, v in enumerate(train_metadata_df[\"primary_label\"].unique())}\nn_labels = len(label_dic)\n\ntrain_list = train_metadata_df[[\"primary_label\", \"filename\"]].values.tolist()","metadata":{"execution":{"iopub.status.busy":"2022-05-11T02:32:40.049125Z","iopub.execute_input":"2022-05-11T02:32:40.049443Z","iopub.status.idle":"2022-05-11T02:32:40.186106Z","shell.execute_reply.started":"2022-05-11T02:32:40.049411Z","shell.execute_reply":"2022-05-11T02:32:40.184699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Install audiomentations & acoustics\n## Reference\n+ [audiomentations](https://github.com/iver56/audiomentations)\n+ [acoustics](https://github.com/python-acoustics/python-acoustics)","metadata":{}},{"cell_type":"code","source":"pip install audiomentations","metadata":{"execution":{"iopub.status.busy":"2022-05-11T02:32:40.187763Z","iopub.execute_input":"2022-05-11T02:32:40.188156Z","iopub.status.idle":"2022-05-11T02:32:49.802105Z","shell.execute_reply.started":"2022-05-11T02:32:40.188121Z","shell.execute_reply":"2022-05-11T02:32:49.800933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install acoustics","metadata":{"execution":{"iopub.status.busy":"2022-05-11T02:32:49.803976Z","iopub.execute_input":"2022-05-11T02:32:49.804348Z","iopub.status.idle":"2022-05-11T02:32:59.786164Z","shell.execute_reply.started":"2022-05-11T02:32:49.804302Z","shell.execute_reply":"2022-05-11T02:32:59.785154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Make pink & brown noise","metadata":{}},{"cell_type":"code","source":"SR = 32000","metadata":{"execution":{"iopub.status.busy":"2022-05-11T02:33:44.104223Z","iopub.execute_input":"2022-05-11T02:33:44.104867Z","iopub.status.idle":"2022-05-11T02:33:44.108561Z","shell.execute_reply.started":"2022-05-11T02:33:44.104803Z","shell.execute_reply":"2022-05-11T02:33:44.107718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# I make pink & brown noise before training.\n# And I load these noise with random position in training.\n# Speed-up is possible by making noise before traing.\n\nimport acoustics\nbrown_noise = acoustics.generator.brown(120*SR)\npink_noise = acoustics.generator.pink(120*SR)\n\n# define directories\nif not os.path.exists('../noise'):\n    os.mkdir('../noise')\nnoise_dir = ROOT / 'noise'\n\nsf.write(noise_dir / \"brown_noise.wav\", brown_noise, samplerate=SR)\nsf.write(noise_dir / \"pink_noise.wav\", pink_noise, samplerate=SR)","metadata":{"execution":{"iopub.status.busy":"2022-05-11T02:36:23.333776Z","iopub.execute_input":"2022-05-11T02:36:23.334201Z","iopub.status.idle":"2022-05-11T02:36:24.407460Z","shell.execute_reply.started":"2022-05-11T02:36:23.334165Z","shell.execute_reply":"2022-05-11T02:36:24.406533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset","metadata":{}},{"cell_type":"code","source":"# if you use mixing other audio dataset, you can write this.\n# I saved other audio dataset as as npy, because numpy is faster than reading audio data.\n\n#noise_np = np.load(\"***.npy\")","metadata":{"execution":{"iopub.status.busy":"2022-05-11T02:33:00.154155Z","iopub.status.idle":"2022-05-11T02:33:00.154629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_melspec(y):\n    melspec = librosa.power_to_db(librosa.feature.melspectrogram(y, sr=SR, n_mels=128))\n    librosa.display.specshow(melspec, sr=SR, x_axis=\"time\", y_axis=\"mel\")\n    plt.colorbar()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-11T02:36:26.974768Z","iopub.execute_input":"2022-05-11T02:36:26.975200Z","iopub.status.idle":"2022-05-11T02:36:26.982296Z","shell.execute_reply.started":"2022-05-11T02:36:26.975146Z","shell.execute_reply":"2022-05-11T02:36:26.981266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PERIOD = 5\nLENGTH = 3\n\nfrom audiomentations import Compose, AddGaussianNoise\nfrom audiomentations import AddGaussianSNR, Gain\nfrom audiomentations import AddShortNoises, AddBackgroundNoise\n\naugmenter = Compose([AddGaussianNoise(min_amplitude=0.001, max_amplitude=0.015, p=0.5),\n                     AddGaussianSNR(p=0.5),\n                     Gain(min_gain_in_db=-12, max_gain_in_db=12, p=0.5),\n                     AddBackgroundNoise(sounds_path=noise_dir, min_snr_in_db=3, max_snr_in_db=30, p=0.5),\n                     AddShortNoises(noise_dir)\n                    ])\n\nclass Dataset(data.Dataset):\n    def __init__(\n            self,\n            file_list: List[List[str]],\n            phase):\n        self.file_list = file_list  # list of list: [file_path, ebird_code]\n        self.phase = phase\n\n    def __len__(self):\n        return len(self.file_list)\n    \n    def __getitem__(self, idx: int):\n        target, wav_path = self.file_list[idx]\n        \n        y, sr = sf.read(TRAIN_AUDIO_ROOT / wav_path)\n        if len(y.shape) == 2: # stereo to mono\n            y = np.mean(y, axis=-1)\n            \n        # load 3 sec\n        y = y[:SR*LENGTH]\n        \n        # time shift\n        y_new = np.zeros(PERIOD*sr) # 5sec\n        if self.phase == \"train\": \n            begin_no = torch.randint(0, PERIOD*sr-LENGTH*SR, (1,)).detach().cpu().numpy()[0]\n        else: # validation\n            begin_no = 0\n        y_new[begin_no: begin_no + LENGTH*SR] = y\n        y = y_new.astype(np.float32)\n        \n        # label smoothing\n        labels = (0.1/n_labels) * np.ones(n_labels, dtype=\"f\")\n        labels[label_dic[target]] = 0.9        \n\n        # add noise \n        if self.phase == \"train\":\n            y = augmenter(samples=y, sample_rate=SR).astype(np.float32)\n            \n            # If you use mixing other audio dataset, you can below\n            #noise = noise_np[torch.randint(0, len(noise_np),(1,))] # random load\n            #y = 0.9*y + 0.1*noise[:SR*PERIOD]\n            y = y.astype(np.float32)\n\n        return {\"waveform\": y, \"targets\": labels}\n    \ntrain_dataset = Dataset(train_list, phase=\"val\")\nOutput = train_dataset.__getitem__(0)\n\nplt.plot(Output[\"targets\"])\nplt.title(\"Label\")\nplt.show()\n\nprint(\"Original sound\")\nshow_melspec(Output[\"waveform\"])\nAudio(Output[\"waveform\"], rate=SR)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-05-11T02:38:34.372468Z","iopub.execute_input":"2022-05-11T02:38:34.373127Z","iopub.status.idle":"2022-05-11T02:38:34.844737Z","shell.execute_reply.started":"2022-05-11T02:38:34.373066Z","shell.execute_reply":"2022-05-11T02:38:34.843646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = Dataset(train_list, phase=\"train\")\nOutput = train_dataset.__getitem__(0)\n\nprint(\"Sound with augmentation\")\nshow_melspec(Output[\"waveform\"])\nAudio(Output[\"waveform\"], rate=SR)","metadata":{"execution":{"iopub.status.busy":"2022-05-11T02:42:23.321470Z","iopub.execute_input":"2022-05-11T02:42:23.321918Z","iopub.status.idle":"2022-05-11T02:42:23.643650Z","shell.execute_reply.started":"2022-05-11T02:42:23.321883Z","shell.execute_reply":"2022-05-11T02:42:23.642711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}