{"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":"# Import Libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport random\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport soundfile as sf\n\nimport torchaudio\nfrom torchaudio import transforms\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\n\nfrom tqdm import tqdm\nfrom collections import defaultdict\n\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-02-20T15:01:01.268856Z","iopub.execute_input":"2022-02-20T15:01:01.269345Z","iopub.status.idle":"2022-02-20T15:01:03.459126Z","shell.execute_reply.started":"2022-02-20T15:01:01.269259Z","shell.execute_reply":"2022-02-20T15:01:03.458262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load Data","metadata":{}},{"cell_type":"code","source":"root_dir = '../input/birdclef-2022'\ntrain_df = pd.read_csv(root_dir + '/train_metadata.csv')\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:03.460942Z","iopub.execute_input":"2022-02-20T15:01:03.461647Z","iopub.status.idle":"2022-02-20T15:01:03.598230Z","shell.execute_reply.started":"2022-02-20T15:01:03.461606Z","shell.execute_reply":"2022-02-20T15:01:03.597454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Quick EDA and Data Pre-processing","metadata":{}},{"cell_type":"code","source":"train_df.shape","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:03.599421Z","iopub.execute_input":"2022-02-20T15:01:03.601240Z","iopub.status.idle":"2022-02-20T15:01:03.607515Z","shell.execute_reply.started":"2022-02-20T15:01:03.601196Z","shell.execute_reply":"2022-02-20T15:01:03.606612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.describe()","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:03.609914Z","iopub.execute_input":"2022-02-20T15:01:03.610263Z","iopub.status.idle":"2022-02-20T15:01:03.646499Z","shell.execute_reply.started":"2022-02-20T15:01:03.610218Z","shell.execute_reply":"2022-02-20T15:01:03.645660Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.info()","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:03.647948Z","iopub.execute_input":"2022-02-20T15:01:03.648201Z","iopub.status.idle":"2022-02-20T15:01:03.677896Z","shell.execute_reply.started":"2022-02-20T15:01:03.648167Z","shell.execute_reply":"2022-02-20T15:01:03.677179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Looks like no null values are there.","metadata":{}},{"cell_type":"code","source":"# For this baseline notebook, we would consider following columns \ncolumns_of_interest = ['primary_label', 'rating', 'filename']\ntrain_df = train_df[columns_of_interest]\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:04.713606Z","iopub.execute_input":"2022-02-20T15:01:04.714187Z","iopub.status.idle":"2022-02-20T15:01:04.727525Z","shell.execute_reply.started":"2022-02-20T15:01:04.714149Z","shell.execute_reply":"2022-02-20T15:01:04.726577Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f, ax = plt.subplots(figsize=(20,8))\nsns.countplot(x='rating', data=train_df, ax=ax)","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:05.682084Z","iopub.execute_input":"2022-02-20T15:01:05.682969Z","iopub.status.idle":"2022-02-20T15:01:06.088410Z","shell.execute_reply.started":"2022-02-20T15:01:05.682924Z","shell.execute_reply":"2022-02-20T15:01:06.087629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"we will consider only those audio files whose rating >= 3.0","metadata":{}},{"cell_type":"code","source":"train_df = train_df[train_df.rating >= 3.0]","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:07.936682Z","iopub.execute_input":"2022-02-20T15:01:07.937291Z","iopub.status.idle":"2022-02-20T15:01:07.942592Z","shell.execute_reply.started":"2022-02-20T15:01:07.937257Z","shell.execute_reply":"2022-02-20T15:01:07.941945Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = train_df.reset_index(drop=True)\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:08.086172Z","iopub.execute_input":"2022-02-20T15:01:08.086871Z","iopub.status.idle":"2022-02-20T15:01:08.100658Z","shell.execute_reply.started":"2022-02-20T15:01:08.086831Z","shell.execute_reply":"2022-02-20T15:01:08.099680Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = train_df.primary_label.unique().tolist()","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:09.172544Z","iopub.execute_input":"2022-02-20T15:01:09.172824Z","iopub.status.idle":"2022-02-20T15:01:09.180527Z","shell.execute_reply.started":"2022-02-20T15:01:09.172793Z","shell.execute_reply":"2022-02-20T15:01:09.179848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label2id = {labels[i]: i for i in range(len(labels))}","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:09.340171Z","iopub.execute_input":"2022-02-20T15:01:09.340647Z","iopub.status.idle":"2022-02-20T15:01:09.344534Z","shell.execute_reply.started":"2022-02-20T15:01:09.340612Z","shell.execute_reply":"2022-02-20T15:01:09.343864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels[0], label2id['afrsil1']","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:09.504309Z","iopub.execute_input":"2022-02-20T15:01:09.504981Z","iopub.status.idle":"2022-02-20T15:01:09.509770Z","shell.execute_reply.started":"2022-02-20T15:01:09.504946Z","shell.execute_reply":"2022-02-20T15:01:09.509164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_audio_dir = '../input/birdclef-2022/train_audio'","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:10.519205Z","iopub.execute_input":"2022-02-20T15:01:10.519518Z","iopub.status.idle":"2022-02-20T15:01:10.525921Z","shell.execute_reply.started":"2022-02-20T15:01:10.519479Z","shell.execute_reply":"2022-02-20T15:01:10.525276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in tqdm(range(len(train_df))):\n    filename = train_df.loc[i,'filename']\n    sig, sr = torchaudio.load(os.path.join(train_audio_dir, filename))\n    train_df.loc[i, 'num_channels'] = sig.shape[0]  # number of audio channels (mono/stereo)\n    train_df.loc[i, 'signal_len'] = sig.shape[1]  # signal length\n    train_df.loc[i, 'sampling_rate'] = sr","metadata":{"execution":{"iopub.status.busy":"2022-02-20T07:44:55.566423Z","iopub.execute_input":"2022-02-20T07:44:55.566925Z","iopub.status.idle":"2022-02-20T08:09:22.803732Z","shell.execute_reply.started":"2022-02-20T07:44:55.566883Z","shell.execute_reply":"2022-02-20T08:09:22.802556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df['num_channels'] = train_df['num_channels'].astype('int64')\ntrain_df['signal_len'] = train_df['signal_len'].astype('int64')\ntrain_df['sampling_rate'] = train_df['sampling_rate'].astype('int64')\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-20T08:09:22.805609Z","iopub.execute_input":"2022-02-20T08:09:22.805921Z","iopub.status.idle":"2022-02-20T08:09:22.831761Z","shell.execute_reply.started":"2022-02-20T08:09:22.805885Z","shell.execute_reply":"2022-02-20T08:09:22.830448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.sampling_rate.unique()","metadata":{"execution":{"iopub.status.busy":"2022-02-20T08:09:22.833179Z","iopub.execute_input":"2022-02-20T08:09:22.83345Z","iopub.status.idle":"2022-02-20T08:09:22.842381Z","shell.execute_reply.started":"2022-02-20T08:09:22.833406Z","shell.execute_reply":"2022-02-20T08:09:22.841478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"we have unqiue sampling rate i.e., 32 KHz\n\nFor a 1 second video, the array size will be 32000","metadata":{}},{"cell_type":"code","source":"sns.countplot(train_df.num_channels)","metadata":{"execution":{"iopub.status.busy":"2022-02-20T08:09:22.843972Z","iopub.execute_input":"2022-02-20T08:09:22.845269Z","iopub.status.idle":"2022-02-20T08:09:23.064839Z","shell.execute_reply.started":"2022-02-20T08:09:22.845179Z","shell.execute_reply":"2022-02-20T08:09:23.063594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"There are more number of two channel audios. So we will convert mono (1 channel ) audio to stereo (2 channel) audio by replication.","metadata":{}},{"cell_type":"code","source":"def MonoToStereo(aud, num_channel=2):\n    sig, sr = aud\n    if sig.shape[0] == num_channel:\n        return aud\n    else:\n        stereo_sig = torch.cat([sig, sig])\n    \n    return (stereo_sig, sr)","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:15.611954Z","iopub.execute_input":"2022-02-20T15:01:15.612211Z","iopub.status.idle":"2022-02-20T15:01:15.616829Z","shell.execute_reply.started":"2022-02-20T15:01:15.612184Z","shell.execute_reply":"2022-02-20T15:01:15.616160Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.signal_len.min(), train_df.signal_len.max()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f, ax = plt.subplots(figsize=(15,8))\nsns.distplot(train_df.signal_len, ax=ax)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"we need to have signal length to be of same size. So we will either pad the signal or truncate the signal.","metadata":{}},{"cell_type":"code","source":"# Let's consider the length of all videos to be 10 seconds (A hyperparam - to be tuned)\nmax_len_ms = 10000 # 10k milliseconds ~ 10 seconds\n\ndef pad_signal(aud, max_len_ms):\n    sig, sr = aud\n    num_channels, sig_len = sig.shape\n    max_len = sr // 1000 * max_len_ms\n    \n    if sig_len > max_len:\n        sig = sig[:, :max_len]\n    elif sig_len < max_len:\n        # padding both sides of the signal\n        pad_begin_len = random.randint(0, max_len - sig_len)\n        pad_end_len = max_len - sig_len - pad_begin_len\n        \n        # pad with zeros\n        pad_begin = torch.zeros((num_channels, pad_begin_len))\n        pad_end = torch.zeros((num_channels, pad_end_len))\n        \n        sig = torch.cat((pad_begin, sig, pad_end), 1)\n    \n    return (sig, sr)","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:17.676711Z","iopub.execute_input":"2022-02-20T15:01:17.677273Z","iopub.status.idle":"2022-02-20T15:01:17.683721Z","shell.execute_reply.started":"2022-02-20T15:01:17.677238Z","shell.execute_reply":"2022-02-20T15:01:17.683023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Data Augmentation on raw audio: Time shift\ndef time_shift(aud, shift_limit):\n    sig, sr = aud\n    _, sig_len = sig.shape\n    shift_amt = int(random.random() * shift_limit * sig_len)\n    return (sig.roll(shift_amt), sr)","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:17.823690Z","iopub.execute_input":"2022-02-20T15:01:17.824214Z","iopub.status.idle":"2022-02-20T15:01:17.828516Z","shell.execute_reply.started":"2022-02-20T15:01:17.824179Z","shell.execute_reply":"2022-02-20T15:01:17.827864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Convert augmented audio to Mel Spectrogram\ndef mel_spec(aud, n_mels=64, n_fft=1024, hop_len=None):\n    sig, sr = aud\n    top_db = 80\n    \n    spec = transforms.MelSpectrogram(sr, n_fft=n_fft, hop_length=hop_len, n_mels=n_mels)(sig)\n    # shape of spec: (channels, n_mels, time)\n    \n    # Convert to decibels\n    spec = transforms.AmplitudeToDB(top_db=top_db)(spec)\n    return spec","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:18.041298Z","iopub.execute_input":"2022-02-20T15:01:18.041659Z","iopub.status.idle":"2022-02-20T15:01:18.048319Z","shell.execute_reply.started":"2022-02-20T15:01:18.041624Z","shell.execute_reply":"2022-02-20T15:01:18.047497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Data augmentation on mel spectrogram: Time and Frequency Masking\ndef spectro_augment(spec, max_mask_pct=0.1, n_freq_masks=1, n_time_masks=1):\n    _, n_mels, n_steps = spec.shape\n    mask_value = spec.mean()\n    aug_spec = spec\n    \n    freq_mask_param = max_mask_pct * n_mels\n    for _ in range(n_freq_masks):\n        aug_spec = transforms.FrequencyMasking(freq_mask_param)(aug_spec, mask_value)\n        \n    time_mask_param = max_mask_pct * n_steps\n    for _ in range(n_time_masks):\n        aug_spec = transforms.TimeMasking(time_mask_param)(aug_spec, mask_value)\n        \n    return aug_spec","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:18.450304Z","iopub.execute_input":"2022-02-20T15:01:18.450543Z","iopub.status.idle":"2022-02-20T15:01:18.456834Z","shell.execute_reply.started":"2022-02-20T15:01:18.450516Z","shell.execute_reply":"2022-02-20T15:01:18.455817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Preprocessing on one signal sample","metadata":{}},{"cell_type":"code","source":"idx = random.randint(0, len(train_df))\nfilename = train_df.loc[idx,'filename']\nsig, sr = torchaudio.load(os.path.join(train_audio_dir, filename))\naudio_sample = (sig, sr)\n\n# mono to stereo (if mono)\naudio = MonoToStereo(audio_sample)\n\n# Pad or Truncate\naudio = pad_signal(audio, max_len_ms)\n\n# Augment on raw audio\naudio = time_shift(audio, shift_limit=0.4)\n\n# Convert to Mel Spectrogram\nspec = mel_spec(audio)\n\n# Augment on mel spec\naug_spec = spectro_augment(spec)\naug_spec.shape","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:18.818530Z","iopub.execute_input":"2022-02-20T15:01:18.819137Z","iopub.status.idle":"2022-02-20T15:01:19.037433Z","shell.execute_reply.started":"2022-02-20T15:01:18.819089Z","shell.execute_reply":"2022-02-20T15:01:19.036758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"aug_spec_np = aug_spec.permute(1,2,0).numpy()\nf, ax = plt.subplots(figsize=(15,8))\nplt.imshow(aug_spec_np[:, :, 0])\nplt.show()\nf, ax = plt.subplots(figsize=(15,8))\nplt.imshow(aug_spec_np[:, :, 1])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:19.430353Z","iopub.execute_input":"2022-02-20T15:01:19.430728Z","iopub.status.idle":"2022-02-20T15:01:19.854075Z","shell.execute_reply.started":"2022-02-20T15:01:19.430691Z","shell.execute_reply":"2022-02-20T15:01:19.853417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Building Custom Dataset","metadata":{}},{"cell_type":"code","source":"class CustomDataset(Dataset):\n    def __init__(self, audio_dir, df, max_len_ms=10000, shift_limit=0.4):\n        self.train_audio_dir = audio_dir\n        self.train_df = df\n        self.max_len_ms = max_len_ms\n        self.shift_limit = shift_limit\n        \n    def __len__(self):\n        return len(self.train_df)\n\n    def __getitem__(self, index):\n        filename = self.train_df.loc[index, 'filename']\n        label = self.train_df.loc[index, 'primary_label']\n        \n        sig, sr = torchaudio.load(os.path.join(self.train_audio_dir, filename))\n        audio = (sig, sr)\n        \n        ##################        \n        # process signal #\n        ##################\n        \n        # mono to stereo (if mono)\n        audio = MonoToStereo(audio)\n\n        # Pad or Truncate\n        audio = pad_signal(audio, self.max_len_ms)\n\n        # Augment raw audio\n        audio = time_shift(audio, shift_limit=self.shift_limit)\n\n        # Convert to Mel Spectrogram\n        spec = mel_spec(audio)\n\n        # Augment mel spec\n        aug_spec = spectro_augment(spec)\n        \n        return aug_spec, torch.tensor(label2id[label])","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:20.347153Z","iopub.execute_input":"2022-02-20T15:01:20.347957Z","iopub.status.idle":"2022-02-20T15:01:20.356612Z","shell.execute_reply.started":"2022-02-20T15:01:20.347910Z","shell.execute_reply":"2022-02-20T15:01:20.355748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_audio_dir = '../input/birdclef-2022/train_audio'\nmax_len_ms = 10000\nshift_limit = 0.4\ndataset = CustomDataset(train_audio_dir, train_df, max_len_ms, shift_limit)","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:20.883929Z","iopub.execute_input":"2022-02-20T15:01:20.884182Z","iopub.status.idle":"2022-02-20T15:01:20.888381Z","shell.execute_reply.started":"2022-02-20T15:01:20.884155Z","shell.execute_reply":"2022-02-20T15:01:20.887709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_size = int(0.8 * len(dataset))\nval_size = len(dataset) - train_size\ntrain_dataset, val_dataset = torch.utils.data.random_split(dataset, [train_size, val_size])","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:01:22.316985Z","iopub.execute_input":"2022-02-20T15:01:22.317254Z","iopub.status.idle":"2022-02-20T15:01:22.324127Z","shell.execute_reply.started":"2022-02-20T15:01:22.317226Z","shell.execute_reply":"2022-02-20T15:01:22.323333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 32\ntrain_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=BATCH_SIZE, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:20:54.989184Z","iopub.execute_input":"2022-02-20T15:20:54.989502Z","iopub.status.idle":"2022-02-20T15:20:54.995794Z","shell.execute_reply.started":"2022-02-20T15:20:54.989464Z","shell.execute_reply":"2022-02-20T15:20:54.994641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inputs, targets = next(iter(train_loader))\ninputs.shape, targets.shape","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:20:55.127086Z","iopub.execute_input":"2022-02-20T15:20:55.127399Z","iopub.status.idle":"2022-02-20T15:20:57.406313Z","shell.execute_reply.started":"2022-02-20T15:20:55.127370Z","shell.execute_reply":"2022-02-20T15:20:57.405612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Cool!!","metadata":{}},{"cell_type":"markdown","source":"Let's build model architecture.","metadata":{}},{"cell_type":"markdown","source":"# Model Building","metadata":{}},{"cell_type":"code","source":"class CNN(nn.Module):\n    def __init__(self, num_classes):\n        super(CNN, self).__init__()\n        self.conv1 = nn.Conv2d(2,8,3,1,1,bias=False)\n        self.bn1 = nn.BatchNorm2d(8)\n        self.conv2 = nn.Conv2d(8,16,3,1,1,bias=False)\n        self.bn2 = nn.BatchNorm2d(16)\n        self.conv3 = nn.Conv2d(16,32,3,1,1,bias=False)\n        self.bn3 = nn.BatchNorm2d(32)\n        \n        self.fc1 = nn.Linear(19968, 1000)\n        self.fc2 = nn.Linear(1000, num_classes)\n        \n        self.pool = nn.MaxPool2d(2,2)\n        self.relu = nn.ReLU()\n        self.dropout = nn.Dropout(p=0.5)\n        \n    def forward(self, x):\n        x = self.pool(self.relu(self.bn1(self.conv1(x))))\n        x = self.pool(self.relu(self.bn2(self.conv2(x))))\n        x = self.pool(self.relu(self.bn3(self.conv3(x))))\n        \n        x = x.reshape(x.shape[0], -1)\n        x = self.dropout(x)\n        x = self.relu(self.fc1(x))\n        x = self.fc2(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:20:58.769344Z","iopub.execute_input":"2022-02-20T15:20:58.769599Z","iopub.status.idle":"2022-02-20T15:20:58.780362Z","shell.execute_reply.started":"2022-02-20T15:20:58.769572Z","shell.execute_reply":"2022-02-20T15:20:58.779687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = CNN(num_classes=len(labels))\noutput = model(inputs)\noutput.shape","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:20:58.990969Z","iopub.execute_input":"2022-02-20T15:20:58.991256Z","iopub.status.idle":"2022-02-20T15:20:59.488624Z","shell.execute_reply.started":"2022-02-20T15:20:58.991230Z","shell.execute_reply":"2022-02-20T15:20:59.487934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LERANING_RATE = 1e-4\n\n# Defining loss and optimizer\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=LERANING_RATE)","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:20:59.490114Z","iopub.execute_input":"2022-02-20T15:20:59.490431Z","iopub.status.idle":"2022-02-20T15:20:59.495061Z","shell.execute_reply.started":"2022-02-20T15:20:59.490394Z","shell.execute_reply":"2022-02-20T15:20:59.494237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model Training","metadata":{}},{"cell_type":"code","source":"def train_epoch(model, data_loader, device, criterion, optimizer):\n    model.train()\n\n    losses = []\n    correct = 0\n    total = 0\n\n    for batch_idx, (x, y) in enumerate(tqdm(data_loader)):\n        x = x.to(device) \n        y = y.to(device) \n\n        output = model(x)\n\n        loss = criterion(output, y)\n\n        losses.append(loss.item())\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        _, preds = torch.max(output, dim=1)\n        correct += (preds.cpu() == y.cpu()).sum().item()\n        total += preds.size(0)\n\n    acc = (correct * 1.0) / total\n\n    return acc, np.mean(losses)","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:21:00.780447Z","iopub.execute_input":"2022-02-20T15:21:00.781255Z","iopub.status.idle":"2022-02-20T15:21:00.789239Z","shell.execute_reply.started":"2022-02-20T15:21:00.781210Z","shell.execute_reply":"2022-02-20T15:21:00.788611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def val_epoch(model, data_loader, device, criterion):\n    model.eval()\n\n    losses = []\n    correct = 0\n    total = 0\n    with torch.no_grad():\n        for batch_idx, (x, y) in enumerate(tqdm(data_loader)):\n            x = x.to(device) \n            y = y.to(device) \n\n            output = model(x)\n\n            loss = criterion(output, y)\n\n            losses.append(loss.item())\n\n            _, preds = torch.max(output, dim=1)\n            correct += (preds.cpu() == y.cpu()).sum().item()\n            total += preds.size(0)\n\n    acc = (correct * 1.0) / total\n\n    return acc, np.mean(losses)","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:21:04.109281Z","iopub.execute_input":"2022-02-20T15:21:04.110105Z","iopub.status.idle":"2022-02-20T15:21:04.117726Z","shell.execute_reply.started":"2022-02-20T15:21:04.110061Z","shell.execute_reply":"2022-02-20T15:21:04.116902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(model, epochs, device, train_loader, val_loader, criterion, optimizer):\n    history = defaultdict(list)\n\n    best_val_acc = 0\n\n    for epoch in range(epochs):\n        print(f'Epoch: {epoch + 1}/{epochs}')\n        print('-' * 10)\n        print('Training')\n        train_acc, train_loss = train_epoch(model, train_loader, device, criterion, optimizer)\n        print('\\nValidating')\n        val_acc, val_loss = val_epoch(model, val_loader, device, criterion)\n\n        print(f'\\nTrain Loss: {train_loss}\\tTrain Acc: {train_acc}')\n        print(f'Val Loss: {val_loss}\\tVal Acc: {val_acc}')\n\n        history['train_loss'].append(train_loss)\n        history['train_acc'].append(train_acc)\n        history['val_loss'].append(val_loss)\n        history['val_acc'].append(val_acc)\n\n        if val_acc > best_val_acc:\n            best_val_acc = val_acc\n            torch.save(model.state_dict(), 'best_model.pth.tar')\n\n    return history","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:21:06.564980Z","iopub.execute_input":"2022-02-20T15:21:06.565505Z","iopub.status.idle":"2022-02-20T15:21:06.573255Z","shell.execute_reply.started":"2022-02-20T15:21:06.565469Z","shell.execute_reply":"2022-02-20T15:21:06.572167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EPOCHS = 10\nDEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:21:06.848028Z","iopub.execute_input":"2022-02-20T15:21:06.848603Z","iopub.status.idle":"2022-02-20T15:21:06.852562Z","shell.execute_reply.started":"2022-02-20T15:21:06.848568Z","shell.execute_reply":"2022-02-20T15:21:06.851914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = CNN(num_classes=len(labels)).to(DEVICE)\nhistory = train(model, EPOCHS, DEVICE, train_loader, val_loader, criterion, optimizer)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model Testing","metadata":{}},{"cell_type":"code","source":"model.load_state_dict(torch.load('best_model.pth.tar'))","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:49:58.442189Z","iopub.execute_input":"2022-02-20T15:49:58.442443Z","iopub.status.idle":"2022-02-20T15:49:58.521183Z","shell.execute_reply.started":"2022-02-20T15:49:58.442416Z","shell.execute_reply":"2022-02-20T15:49:58.520364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.read_csv(root_dir + '/test.csv')\nsample_sub_df = pd.read_csv(root_dir + '/sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:50:01.022548Z","iopub.execute_input":"2022-02-20T15:50:01.022820Z","iopub.status.idle":"2022-02-20T15:50:01.040295Z","shell.execute_reply.started":"2022-02-20T15:50:01.022770Z","shell.execute_reply":"2022-02-20T15:50:01.039569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:50:03.063686Z","iopub.execute_input":"2022-02-20T15:50:03.064522Z","iopub.status.idle":"2022-02-20T15:50:03.074447Z","shell.execute_reply.started":"2022-02-20T15:50:03.064486Z","shell.execute_reply":"2022-02-20T15:50:03.073797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_sub_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:50:03.255700Z","iopub.execute_input":"2022-02-20T15:50:03.256218Z","iopub.status.idle":"2022-02-20T15:50:03.263761Z","shell.execute_reply.started":"2022-02-20T15:50:03.256185Z","shell.execute_reply":"2022-02-20T15:50:03.263140Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_audio_dir = '../input/birdclef-2022/test_soundscapes'\nfor idx in tqdm(range(len(test_df))):\n    audio_id = test_df.loc[idx, 'file_id']\n    true_label = test_df.loc[idx, 'bird']\n    end_time = test_df.loc[idx, 'end_time']\n    \n    path = os.path.join(test_audio_dir, audio_id, '.ogg')\n\n    if os.path.isfile(path):\n        sig, sr = torchaudio.load(file_pth)\n        \n        rows = sig.shape[1] // (32000 *5)\n        sig = sig.reshape(rows, -1)\n\n        row_id = end_time // 5\n\n        sig = sig[row_id-1].reshape(1,-1)\n\n        audio = MonoToStereo((sig, sr))\n        audio = pad_signal(audio, 10000)\n        audio = time_shift(audio, shift_limit=0.4)\n        spec = mel_spec(audio)\n        aug_spec = spectro_augment(spec)\n        aug_spec = aug_spec.unsqueeze(0)\n        output = model(aug_spec)\n\n        _, pred = torch.max(output, dim=1)\n        if labels[pred] == true_label:\n            sample_sub_df.loc[idx, 'target'] = True\n        else:\n            sample_sub_df.loc[idx, 'target'] = False\n        \n    else:\n        pred = True if random.randint(0,1) else False\n        sample_sub_df.loc[idx, 'target'] = pred\n        continue","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:50:05.588935Z","iopub.execute_input":"2022-02-20T15:50:05.589459Z","iopub.status.idle":"2022-02-20T15:50:05.608577Z","shell.execute_reply.started":"2022-02-20T15:50:05.589423Z","shell.execute_reply":"2022-02-20T15:50:05.607835Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Make submission","metadata":{}},{"cell_type":"code","source":"sample_sub_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:50:07.408319Z","iopub.execute_input":"2022-02-20T15:50:07.408625Z","iopub.status.idle":"2022-02-20T15:50:07.422048Z","shell.execute_reply.started":"2022-02-20T15:50:07.408592Z","shell.execute_reply":"2022-02-20T15:50:07.420153Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_sub_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:50:07.741057Z","iopub.execute_input":"2022-02-20T15:50:07.741272Z","iopub.status.idle":"2022-02-20T15:50:07.750618Z","shell.execute_reply.started":"2022-02-20T15:50:07.741247Z","shell.execute_reply":"2022-02-20T15:50:07.749924Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Done!')","metadata":{"execution":{"iopub.status.busy":"2022-02-20T15:50:08.379739Z","iopub.execute_input":"2022-02-20T15:50:08.380283Z","iopub.status.idle":"2022-02-20T15:50:08.385172Z","shell.execute_reply.started":"2022-02-20T15:50:08.380246Z","shell.execute_reply":"2022-02-20T15:50:08.383800Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}