{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"!pip install soundfile","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install efficientnet_pytorch","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install torchcontrib","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%cd ../input/fmixpytorch/FMix-master\nfrom fmix import sample_and_apply\n%cd /kaggle/working","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%cd ../input/cpythongit/cpython-master\nfrom Lib import copy\n%cd /kaggle/working","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np                                                             \nimport soundfile as sf\nimport matplotlib.pyplot as plt\nimport torch\nimport torchaudio\nfrom torchvision import transforms\nfrom torch.utils.data import Dataset\nfrom sklearn import model_selection\nfrom PIL import Image\nimport albumentations\nfrom torch.utils.data import DataLoader\nimport efficientnet_pytorch\nimport torch.nn.functional as F\nfrom torchcontrib.optim import SWA\nimport gc\nimport torch.nn as nn\nfrom sklearn.metrics import label_ranking_average_precision_score\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# checking if cuda is available\nfrom torch import device as device_\n\ndevice = device_(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"filename = '../input/rfcx-species-audio-detection/train/06c44d203.flac'\n\nwaveform, sample_rate = sf.read(filename , start = int((2880000/60) * 1.28), stop = int((2880000/60) * 2.0213) )\n\nwaveform = torch.from_numpy(waveform)\n\nwaveform = torch.reshape(waveform, (1, waveform.shape[0]))\n\nspecgram = torchaudio.transforms.Spectrogram()(waveform)\n\nspecgram = specgram.repeat(3, 1, 1)\n\nprint(\"Shape of spectrogram: {}\".format(specgram.size()))\n\nplt.figure()\nplt.imshow(specgram.log2()[0,:,:].numpy(), cmap='bwr')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv(\"../input/rfcx-species-audio-detection/train_tp.csv\")\ndf.species_id.value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df['species_id'].nunique()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df[\"kfold\"] = -1    \ndf = df.sample(frac=1).reset_index(drop=True)\ny = df.species_id.values\nkf = model_selection.StratifiedKFold(n_splits=5)\n\nfor f, (t_, v_) in enumerate(kf.split(X=df, y=y)):\n    df.loc[v_, 'kfold'] = f\ndf.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fold = 0\ndf_train = df[df.kfold != fold].reset_index(drop=True)\ndf_valid = df[df.kfold == fold].reset_index(drop=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class audio_classification(Dataset):\n    def __init__(self, ids, recording_id, t_min, t_max, species_id, is_valid = 0):\n        self.ids = ids\n        self.recording_id = recording_id\n        self.t_min = t_min\n        self.t_max = t_max\n        self.species_id = species_id\n        self.is_valid = is_valid\n        if self.is_valid == 1:\n            self.aug = albumentations.Compose([\n               albumentations.Resize(256 , 256, always_apply = True)\n            ])\n        else:                  # transfoms for training images \n            self.aug = albumentations.Compose([\n                albumentations.Resize(256 , 256, always_apply = True) ,\n                albumentations.ShiftScaleRotate(shift_limit = 0.0625,\n                                                scale_limit = 0.1 ,\n                                                rotate_limit = 5,\n                                                p = 0.9)\n            ])\n        \n    def __len__(self):\n        return len(self.ids)\n    \n    def __getitem__(self, index):\n        filename = \"../input/rfcx-species-audio-detection/train/\"+ self.recording_id[index] +\".flac\"\n        waveform , _ = sf.read(filename , start = int((2880000/60) * self.t_min[index]), stop = int((2880000/60) * self.t_max[index]) )\n        \n        waveform = torch.from_numpy(waveform)\n\n        waveform = torch.reshape(waveform, (1, waveform.shape[0]))\n\n        specgram = torchaudio.transforms.Spectrogram()(waveform)\n\n        specgram = specgram.repeat(3, 1, 1)\n        \n        specgram = np.transpose(specgram.numpy(), (1,2,0))\n        \n        specgram = self.aug(image = specgram)['image']\n        \n        specgram = np.transpose(specgram, (2,0,1)).astype(np.float32)\n        \n        return {\n            'specgram' : torch.tensor(specgram, dtype = torch.float) ,\n            'label' : torch.tensor(np.eye(24, dtype='float64')[int(self.species_id[index])])\n        }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data = audio_classification(ids = [i for i in range(len(df_train))], \n                                  recording_id = df_train['recording_id'],\n                                  t_min = df_train['t_min'],\n                                  t_max = df_train['t_max'],\n                                  species_id = df_train['species_id'])\n\nval_data = audio_classification(ids = [i for i in range(len(df_valid))], \n                                recording_id = df_valid['recording_id'],\n                                t_min = df_valid['t_min'],\n                                t_max = df_valid['t_max'],\n                                species_id = df_valid['species_id'],\n                                is_valid = 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"idx = 1\n\nprint(val_data[idx]['label'])\n\nimg = val_data[idx]['specgram']\nplt.figure()\nplt.imshow(img.log2()[0,:,:].numpy(), cmap='bwr')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TRAIN_BATCH_SIZE = 8\n\ntraining_dataloader = DataLoader(train_data,\n                        num_workers= 4,\n                        batch_size= TRAIN_BATCH_SIZE,\n                        shuffle=True,\n                        drop_last=True\n                       )\n\nval_dataloader = DataLoader(val_data,\n                        num_workers= 4,\n                        batch_size= TRAIN_BATCH_SIZE,\n                        shuffle=False,\n                        drop_last=False\n                       )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class EfficientNet_b5(nn.Module):\n    def __init__(self):\n        super(EfficientNet_b5, self).__init__()\n        self.model = efficientnet_pytorch.EfficientNet.from_pretrained('efficientnet-b5')\n        self.dropout = nn.Dropout(0.1)\n        self.final_layer = nn.Linear(2048 , 24)\n        \n    def forward(self, image_inputs):\n        batch_size, _, _, _ = image_inputs.shape\n    \n        x = self.model.extract_features(image_inputs)\n        x = self.model._avg_pooling(x)\n        x = F.adaptive_avg_pool2d(x, 1).reshape(batch_size, -1)\n        outputs = self.final_layer(self.dropout(x))\n\n        return outputs\n    \nmodel = EfficientNet_b5()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"EPOCHS = 6\nnum_train_steps = int(len(train_data) / TRAIN_BATCH_SIZE / EPOCHS)\n\n# printing the no of training steps for each epoch of our training dataloader  \nprint(f'num_train_steps = {num_train_steps}')\n\nmodel = model.to(device)\n\nbase_optimizer = torch.optim.Adadelta(model.parameters(), lr = 1e-3 * 0.95)\n\noptimizer = SWA(base_optimizer, swa_start=5, swa_freq=5, swa_lr=0.05)\n\nloss_fn = torch.nn.BCEWithLogitsLoss()\n\nscheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience = 3, verbose = True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# defining the training loop\ndef train_loop_fn(data_loader, model, optimizer, device, scheduler=None):\n    running_loss = 0.0\n    all_targets = 0\n    all_predictions = 0\n    \n    model.train()\n    \n    alpha, decay_power = 1.0, 3.0\n    \n    for batch_index,dataset in enumerate(data_loader):\n        image = dataset[\"specgram\"]\n        label = dataset[\"label\"]\n        \n        image, perm, lambda_value = sample_and_apply(image, alpha, decay_power, (256, 256))\n        \n        image = image.to(device, dtype=torch.float)\n        label = label.to(device, dtype=torch.float)\n        \n        optimizer.zero_grad()\n\n        outputs = model(image)\n        \n        y_true = label.detach().cpu().numpy()\n        y_pred = outputs.detach().cpu().numpy()\n        \n        loss = loss_fn(outputs, label) * lambda_value + loss_fn(outputs, label[perm]) * (1 - lambda_value)\n\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n        \n        if batch_index > 0:\n            all_targets = np.concatenate((all_targets, y_true), axis=0)\n            all_predictions = np.concatenate((all_predictions, y_pred), axis=0)\n        else:\n            all_targets = y_true\n            all_predictions = y_pred\n        \n        del image, label\n        gc.collect()\n        torch.cuda.empty_cache()\n            \n    train_loss = running_loss / float(len(train_data))\n    train_label_ranking_average_precision_score = label_ranking_average_precision_score(all_targets, all_predictions)\n    \n    scheduler.step(train_loss)\n    \n    return train_loss, train_label_ranking_average_precision_score","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def eval_loop_fn(data_loader, model, device):\n    running_loss = 0.0\n    all_targets = 0\n    all_predictions = 0\n    \n    model.eval()\n    \n    for batch_index,dataset in enumerate(data_loader):\n        image = dataset[\"specgram\"]\n        label = dataset[\"label\"]\n        \n        image = image.to(device, dtype=torch.float)\n        label = label.to(device, dtype=torch.float)\n\n        outputs = model(image)\n        \n        y_true = label.detach().cpu().numpy()\n        y_pred = outputs.detach().cpu().numpy()\n        \n        loss = loss_fn(label, outputs)\n        \n        running_loss += loss.item()\n        \n        if batch_index > 0:\n            all_targets = np.concatenate((all_targets, y_true), axis=0)\n            all_predictions = np.concatenate((all_predictions, y_pred), axis=0)\n        else:\n            all_targets = y_true\n            all_predictions = y_pred\n        \n        del image, label\n        gc.collect()\n        torch.cuda.empty_cache()\n    \n    valid_loss = running_loss / float(len(val_data))\n    valid_label_ranking_average_precision_score = label_ranking_average_precision_score(all_targets, all_predictions)\n    \n    return valid_loss , valid_label_ranking_average_precision_score","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def _run():\n    no_of_folds = 5\n    for i in range(no_of_folds):\n        a_string = \"*\" * 20\n\n        print(a_string, \" FOLD NUMBER \", i, a_string)\n        \n        df_train = df[df.kfold != i].reset_index(drop=True)\n        df_valid = df[df.kfold == i].reset_index(drop=True)\n        \n        all_accuracies = []\n        \n        for epoch in range(EPOCHS):\n            print(f\"Epoch --> {epoch+1} / {EPOCHS}\")\n            print(f\"-------------------------------\")\n\n            train_loss, train_label_ranking_average_precision_score = train_loop_fn(training_dataloader, model, optimizer, device, scheduler)\n            print('training Loss: {:.4f} & training Validation Label Ranking Average Precision Score : {:.2f}%'.format(train_loss, train_label_ranking_average_precision_score*100))\n\n            valid_loss , valid_label_ranking_average_precision_score = eval_loop_fn(val_dataloader, model, device)\n            print('validation Loss: {:.4f} & Validation Label Ranking Average Precision Score : {:.2f}%'.format(valid_loss , valid_label_ranking_average_precision_score*100))\n            \n            all_accuracies.append(valid_label_ranking_average_precision_score)\n        print('\\n')\n        \n        if i < 1:\n            best_accuracy = max(all_accuracies)\n            best_model = copy.deepcopy(model)\n        else:\n            if best_accuracy > max(all_accuracies):\n                continue\n            else:\n                best_accuracy = max(all_accuracies)\n                best_model = copy.deepcopy(model)\n        \n        optimizer.swap_swa_sgd()\n    \n    torch.save(best_model.state_dict(),'./Audio_Classsification_GPU_CutMix_EfficientNet-B5_FOLD.pt')\n    print()\n    print(\"The highest accuracy we got among all the folds is {:.2f}%\".format(best_accuracy*100))\n    \n    return best_model\n        \nif __name__ == \"__main__\":\n    best_model = _run()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_submission = pd.read_csv(\"../input/rfcx-species-audio-detection/sample_submission.csv\")\nsample_submission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class audio_test_set_classification(Dataset):\n    def __init__(self, ids, recording_id):\n        self.ids = ids\n        self.recording_id = recording_id\n        self.aug = albumentations.Compose([\n               albumentations.Resize(256 , 256, always_apply = True),\n               albumentations.ShiftScaleRotate(shift_limit = 0.0625,\n                                                scale_limit = 0.1 ,\n                                                rotate_limit = 5,\n                                                p = 0.9)\n            ])\n        \n    def __len__(self):\n        return len(self.ids)\n    \n    def __getitem__(self, index):\n        filename = \"../input/rfcx-species-audio-detection/test/\"+ self.recording_id[index] +\".flac\"\n        \n        waveform , _ = sf.read(filename)\n        \n        waveform = torch.from_numpy(waveform)\n\n        waveform = torch.reshape(waveform, (1, waveform.shape[0]))\n\n        specgram = torchaudio.transforms.Spectrogram()(waveform)\n\n        specgram = specgram.repeat(3, 1, 1)\n        \n        specgram = np.transpose(specgram.numpy(), (1,2,0))\n        \n        specgram = self.aug(image = specgram)['image']\n        \n        specgram = np.transpose(specgram, (2,0,1)).astype(np.float32)\n        \n        return {\n            'recording_id' : self.recording_id[index],\n            'specgram' : torch.tensor(specgram, dtype = torch.float)\n        }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_data = audio_test_set_classification(ids = [i for i in range(len(sample_submission))], recording_id = sample_submission['recording_id'])\n\ntest_dataloader = DataLoader(test_data,\n                        num_workers=4,\n                        batch_size=8,\n                        drop_last=False\n                       )\nidx = 111 \nprint(test_data[idx]['recording_id'],\".flac\")\nimg = test_data[idx]['specgram']\nplt.figure()\nplt.imshow(img.log2()[0,:,:].numpy(), cmap='bwr')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# test time augmentation for running  inference 5 times\nbest_model.eval()\n\nfinal_preds = None\n\nfor batch_index,dataset in enumerate(test_dataloader):\n    recording_id = dataset[\"recording_id\"]\n    specgram = dataset[\"specgram\"]\n\n    specgram = specgram.to(device, dtype=torch.float)\n\n    with torch.no_grad():\n        for i in range(5):\n            preds = best_model(specgram)\n            preds = preds.detach().cpu().numpy()\n            if i > 0:\n                temp = np.add(preds, temp)\n            else:\n                temp = preds\n\n    temp = temp/5\n    if batch_index > 0:\n        final_preds = np.concatenate((final_preds, temp), axis=0)\n    else:\n        final_preds = preds      ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"final_preds.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_submission.iloc[:,1:] = final_preds","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_submission.to_csv(\"submission.csv\", index=False)","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}