{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nimport os.path as op\nimport pandas as pd\nimport numpy as np\nimport gc\nfrom librosa.feature import melspectrogram\nimport librosa.display\nimport librosa\nfrom tqdm.notebook import tqdm\nfrom joblib import Parallel, delayed\nimport cv2\nimport time\nfrom keras.preprocessing.sequence import pad_sequences\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"INPUT_ROOT = \"../input\"\nRAW_DATA = op.join(INPUT_ROOT, \"birdsong-recognition\")\nTRAIN_AUDIO_DIR = op.join(RAW_DATA, \"train_audio\")\nTEST_AUDIO_DIR = op.join(INPUT_ROOT, \"birdcall-check\", \"test_audio\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_csv = pd.read_csv(op.join(RAW_DATA, \"train.csv\"))\ntest_csv = pd.read_csv(op.join(INPUT_ROOT, \"birdcall-check\", \"test.csv\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Train .csv dataset has %d rows and %d columns' % train_csv.shape, end=\"\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('There are %d unique bird species in the dataset' % train_csv['ebird_code'].nunique(), end=\"\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_csv.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_csv.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Parameters"},{"metadata":{"trusted":true},"cell_type":"code","source":"class Params():\n    sr = 44100\n    n_mels = 128\n    fmin = 20\n    fmax = 16000\n    chunk_duration = 5\n    chunk_size = chunk_duration*sr\n    img_size = None\n\nclasses = train_csv['ebird_code'].unique()\nnum_classes = train_csv['ebird_code'].nunique()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Dataset"},{"metadata":{"trusted":true},"cell_type":"code","source":"def mono_to_color(X: np.ndarray, mean=None, std=None, norm_max=None, norm_min=None, eps=1e-6):\n    \"\"\"\n    Code from https://www.kaggle.com/daisukelab/creating-fat2019-preprocessed-data\n    \"\"\"\n    # Stack X as [X,X,X]\n    X = np.stack([X, X, X], axis=-1)\n\n    # Standardize\n    mean = mean or X.mean()\n    X = X - mean\n    std = std or X.std()\n    Xstd = X / (std + eps)\n    _min, _max = Xstd.min(), Xstd.max()\n    norm_max = norm_max or _max\n    norm_min = norm_min or _min\n    if (_max - _min) > eps:\n        # Normalize to [0, 255]\n        V = Xstd\n        V[V < norm_min] = norm_min\n        V[V > norm_max] = norm_max\n        V = 255 * (V - norm_min) / (norm_max - norm_min)\n        V = V.astype(np.uint8)\n    else:\n        # Just zero\n        V = np.zeros_like(Xstd, dtype=np.uint8)\n    return V","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def save_train(df, path, parameters):\n    Images = []\n    for index in range(len(df)):\n        file_name = df.filename[index]\n        ebird_code = df.ebird_code[index]\n\n        y, _ = librosa.load(path + ebird_code + '/' + file_name, sr=parameters.sr)\n        \n        length = y.shape[0]\n        if length>0: \n            y, sr = librosa.effects.trim(y)\n\n        if length >= CHUNK_SIZE:\n            y = y[0:+CHUNK_SIZE]\n        else:\n            #y = pad_sequences(y.T.flatten().reshape(1, -1), maxlen=CHUNK_SIZE, dtype=\"float32\").reshape(-1)\n            y = np.pad(y, (CHUNK_SIZE - length, 0), 'constant')\n    \n        spectrogram = librosa.feature.melspectrogram(y)\n        spectrogram = librosa.power_to_db(spectrogram).astype(np.float32)\n        \n        image = mono_to_color(spectrogram)\n        height, width, _ = image.shape\n        image = cv2.resize(image, (int(width * self.img_size / height), self.img_size))\n        image = image/255.0\n        image = np.moveaxis(image, 2, 0).astype(np.float32)\n        Images.append(image)\n        \n    with open(\"preprocessed/mels_train.pkl\", 'wb') as f:\n        pickle.dump(Images, f, pickle.HIGHEST_PROTOCOL)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"parameters = Params()\nsave_train(train_csv, TRAIN_AUDIO_DIR, parameters)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def load_pkl(filename):\n#     with open(filename, 'rb') as f:\n#         return pickle.load(f)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class TestDataset(data.Dataset):\n    def __init__(self, df, clip, parameters):\n        self.clip = clip.astype(np.float32)\n        self.parameters = parameters\n        \n        if df['site'].values[0] == \"site_3\":\n            n_samples = len(clip) // parameters.chunk_size\n            self.df = pd.DataFrame(data={'site': ['site_3'] * n_samples,\n                                         'row_id': [f'site_3_{audio_id[0]}_{int(s)}' for s in seconds],\n                                         'seconds': [i * parameters.chunk_duration for i in range(1, n_samples + 1)],\n                                         'audio_id': [df['audio_id'].values[0]] * n_samples\n                                        })\n        else:\n            self.df = df\n            \n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx):\n        \n        end_seconds = int(self.df['seconds'][idx])\n        start_seconds = int(end_seconds - parameters.chunk_duration)\n\n        start_index = self.parameters.sr * start_seconds\n        end_index = self.parameters.sr * end_seconds\n\n        y = self.clip[start_index:end_index].astype(np.float32)\n\n        melspec = librosa.feature.melspectrogram(y, sr=SR, **self.melspectrogram_parameters)\n        melspec = librosa.power_to_db(melspec).astype(np.float32)\n        \n        spectrogram = librosa.feature.melspectrogram(\n            y,\n            sr=self.parameters.sr,\n            n_mels=self.parameters.n_mels,\n            fmin=self.parameters.fmin,\n            fmax=self.parameters.fmax\n        )\n        spectrogram = librosa.power_to_db(spectrogram).astype(np.float32)\n        \n        image = mono_to_color(spectrogram)\n        height, width, _ = image.shape\n        image = cv2.resize(image, (int(width * self.img_size / height), self.img_size))\n        image = image/255.0\n        image = np.moveaxis(image, 2, 0).astype(np.float32)\n        \n        return image","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}