{"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":"# BirdCLEF 2022 : Final Submission\nIn this notebook we will predict using the trained data.\n\nThis is the last one of the 3 notebooks which uses all the finding and the trained models to predict over the test set.\n\nNote : This will be used as a prediction notebook.\n\nSo, the conditions should be met are -\n1. RT <= 9hrs.\n2. Internet Access : Disabled.\n3. Usage of public data : Enabled.","metadata":{}},{"cell_type":"markdown","source":"# Libraries","metadata":{}},{"cell_type":"code","source":"# Libraries for basic data loading and manipulation\nimport os\nimport json\nimport pandas as pd\n\nimport torch\nimport torch.nn as nn\nimport torchaudio\nfrom torchaudio.transforms import MelSpectrogram\nfrom torchvision.transforms import Resize\nfrom torch.utils.data import Dataset, DataLoader\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"execution":{"iopub.status.busy":"2022-03-02T19:29:24.261802Z","iopub.execute_input":"2022-03-02T19:29:24.262415Z","iopub.status.idle":"2022-03-02T19:29:26.095178Z","shell.execute_reply.started":"2022-03-02T19:29:24.262324Z","shell.execute_reply":"2022-03-02T19:29:26.093892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Datapaths","metadata":{}},{"cell_type":"code","source":"test_dir = \"../input/birdclef-2022/test_soundscapes\"\ntest_base_path = \"../input/birdclef-2022/test.csv\"\nclass_dict_base_path = \"../input/birdclef-2022-saved-weights-and-misc/class_dict.json\"\nbest_acc_mode_base_path = \"../input/birdclef-2022-saved-weights-and-misc/birdclef2022-best_accuracy_model.pt\"\nbest_loss_model_base_path = \"../input/birdclef-2022-saved-weights-and-misc/birdclef2022-best_loss_model.pt\"","metadata":{"execution":{"iopub.status.busy":"2022-03-02T19:29:26.591496Z","iopub.execute_input":"2022-03-02T19:29:26.591805Z","iopub.status.idle":"2022-03-02T19:29:26.597147Z","shell.execute_reply.started":"2022-03-02T19:29:26.591772Z","shell.execute_reply":"2022-03-02T19:29:26.596189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Loading test dataframe","metadata":{}},{"cell_type":"code","source":"test_df = pd.read_csv(test_base_path)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-02T19:29:26.989171Z","iopub.execute_input":"2022-03-02T19:29:26.989666Z","iopub.status.idle":"2022-03-02T19:29:27.022796Z","shell.execute_reply.started":"2022-03-02T19:29:26.989622Z","shell.execute_reply":"2022-03-02T19:29:27.022098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Loading class labels which will be needed to prepare predictions.","metadata":{}},{"cell_type":"code","source":"class_labels = json.load(open(class_dict_base_path, \"r\"))\nnum_classes = len(class_labels.keys())\nprint(\"Number of class : {}\".format(num_classes))","metadata":{"execution":{"iopub.status.busy":"2022-03-02T19:29:27.375835Z","iopub.execute_input":"2022-03-02T19:29:27.376336Z","iopub.status.idle":"2022-03-02T19:29:27.391396Z","shell.execute_reply.started":"2022-03-02T19:29:27.376294Z","shell.execute_reply":"2022-03-02T19:29:27.390650Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Fixing the device","metadata":{}},{"cell_type":"code","source":"device = \"cuda:0\" if torch.cuda.is_available() else \"cpu\"\ndevice","metadata":{"execution":{"iopub.status.busy":"2022-03-02T19:29:27.810731Z","iopub.execute_input":"2022-03-02T19:29:27.811196Z","iopub.status.idle":"2022-03-02T19:29:27.817961Z","shell.execute_reply.started":"2022-03-02T19:29:27.811154Z","shell.execute_reply":"2022-03-02T19:29:27.817171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Convolution shape updating function\ndef conv_shape(shape, kernel_size, stride, padding):\n    H, W = shape[0], shape[1]\n    H = ((H - kernel_size + 2*padding) // stride) + 1\n    W = ((W - kernel_size + 2*padding) // stride) + 1\n    return H, W","metadata":{"execution":{"iopub.status.busy":"2022-03-02T19:29:28.012554Z","iopub.execute_input":"2022-03-02T19:29:28.012974Z","iopub.status.idle":"2022-03-02T19:29:28.018693Z","shell.execute_reply.started":"2022-03-02T19:29:28.012940Z","shell.execute_reply":"2022-03-02T19:29:28.018132Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Neural Network :\n\nThe neural network class is needed to prepare the skeleton on which we will add the pretrined weights.","metadata":{}},{"cell_type":"code","source":"class Conv(nn.Module):\n    \n    def __init__(self, \n                   in_channels,\n                   out_channels,\n                   kernel_size,\n                   stride=(1,1),\n                   padding=(0,0),\n                   momentum=0.15):\n        super(Conv, self).__init__()\n        self.conv_block = nn.Sequential(\n            nn.BatchNorm2d(in_channels, momentum = momentum),\n            nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding),\n            nn.ReLU()\n        )\n        \n    def forward(self, x):\n        return self.conv_block(x)\n\n\nclass CLEFNetwork(nn.Module):\n    \n    def __init__(self,\n                 num_classes,\n                 in_channels = 1,\n                 H = 128,\n                 W = 128,\n                 num_downs = 3):\n        super(CLEFNetwork, self).__init__()\n        \n        self.num_C = num_classes\n        self.num_downs = num_downs\n        self.in_channels = in_channels\n        self.C = 8\n        self.H, self.W = self.calc_HW(H, W)\n        self.in_conv_block = Conv(self.in_channels, self.C, 7, (2, 2))\n        self.conv_block = nn.ModuleList(\n                [\n                    Conv(self.C * 2**i, self.C * 2**(i+1), 3, (2, 2))\n                    for i in range(self.num_downs-1)\n                ]\n        )\n        self.fc_block = nn.Sequential(\n                nn.Linear(self.H * self.W * self.C * 2**(self.num_downs - 1), 1024),\n                nn.Linear(1024, 1024),\n                nn.Linear(1024, self.num_C)\n        )\n        \n    def calc_HW(self, H, W):\n        H, W = conv_shape((H, W), 7, 2, 0)\n        for num_down in range(self.num_downs - 1):\n            H, W = conv_shape((H, W), 3, 2, 0)\n        return H, W\n        \n        \n    def forward(self, x):\n        x = self.in_conv_block(x)\n        for block in self.conv_block:\n            x = block(x)\n        x = x.view(x.shape[0], -1)\n        x = self.fc_block(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-03-02T19:29:28.437202Z","iopub.execute_input":"2022-03-02T19:29:28.437844Z","iopub.status.idle":"2022-03-02T19:29:28.457935Z","shell.execute_reply.started":"2022-03-02T19:29:28.437798Z","shell.execute_reply":"2022-03-02T19:29:28.457139Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Calling the Netwrok class and updating pretrained weights","metadata":{}},{"cell_type":"code","source":"best_model = CLEFNetwork(num_classes)\ncheckpoint = torch.load(best_loss_model_base_path, map_location = torch.device(device))\nbest_model.load_state_dict(checkpoint[\"model\"])\nprint(best_model)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T19:29:28.800284Z","iopub.execute_input":"2022-03-02T19:29:28.801094Z","iopub.status.idle":"2022-03-02T19:29:30.590831Z","shell.execute_reply.started":"2022-03-02T19:29:28.801062Z","shell.execute_reply":"2022-03-02T19:29:30.590185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction Dataset Generation","metadata":{}},{"cell_type":"code","source":"class CLEFPredDataset(Dataset):\n    \n    def __init__(self,\n                data_dir,\n                meta_df,\n                transform = None\n                ):\n        super(CLEFPredDataset, self).__init__()\n        self.data_dir = data_dir\n        self.meta_df = meta_df\n        self.transform = transform\n        \n    def __len__(self):\n        return len(self.meta_df)\n    \n    def __getitem__(self, index):\n        path = self.meta_df.loc[index, \"file_id\"]\n        path = f\"{os.path.join(self.data_dir, path)}.ogg\"\n        time = self.meta_df.loc[index, \"end_time\"]\n        mono_audio = self.load_audio(path, time)\n        mono_audio = mono_audio.unsqueeze(dim=0)\n        return mono_audio\n        \n    def load_audio(self, path, time):\n        audio, sample_rate = torchaudio.load(path)\n        audio = audio[:, (time-5)*sample_rate: time*sample_rate]\n        if self.transform != None:\n            for aug in self.transform:\n                audio = aug(audio)\n        return audio[0,:]","metadata":{"execution":{"iopub.status.busy":"2022-03-02T19:29:30.592029Z","iopub.execute_input":"2022-03-02T19:29:30.592317Z","iopub.status.idle":"2022-03-02T19:29:30.602129Z","shell.execute_reply.started":"2022-03-02T19:29:30.592287Z","shell.execute_reply":"2022-03-02T19:29:30.601410Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### adding transformations to equalize the data.","metadata":{}},{"cell_type":"code","source":"augm = [\n    MelSpectrogram(n_mels = 128),\n    Resize((128, 128))\n]\naugm","metadata":{"execution":{"iopub.status.busy":"2022-03-02T19:29:30.603555Z","iopub.execute_input":"2022-03-02T19:29:30.603787Z","iopub.status.idle":"2022-03-02T19:29:30.670002Z","shell.execute_reply.started":"2022-03-02T19:29:30.603759Z","shell.execute_reply":"2022-03-02T19:29:30.669325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = CLEFPredDataset(test_dir, test_df, transform = augm)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T19:29:30.671990Z","iopub.execute_input":"2022-03-02T19:29:30.672258Z","iopub.status.idle":"2022-03-02T19:29:30.676090Z","shell.execute_reply.started":"2022-03-02T19:29:30.672223Z","shell.execute_reply":"2022-03-02T19:29:30.675448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Preparing a sample submission file just to save the notebook and submit for the competition.\n### Note : When the notebook will be submitted the below cells will be working and the genuine output file will be produced.","metadata":{}},{"cell_type":"code","source":"test = test_df.copy()\ntest[\"target\"] = [False for _ in range(len(test))]\nimp_features = [\"row_id\", \"target\"]\ntest = test[imp_features]\ntest.to_csv(\"submission.csv\", index = False)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T19:29:30.677096Z","iopub.execute_input":"2022-03-02T19:29:30.677458Z","iopub.status.idle":"2022-03-02T19:29:30.697819Z","shell.execute_reply.started":"2022-03-02T19:29:30.677431Z","shell.execute_reply":"2022-03-02T19:29:30.697109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction :","metadata":{}},{"cell_type":"code","source":"if device == \"cuda:0\":\n    best_model = best_model.cuda()\nBATCH_SIZE = 64\ntest_dl = DataLoader(dataset, batch_size = BATCH_SIZE, shuffle = False)\nprediction = []\nwith torch.no_grad():\n    for index, patch in enumerate(test_dl):\n        dev_patch = patch.to(device)\n        output = best_model(dev_patch)\n        if device == \"cuda:0\":\n            output = torch.argmax(output, dim=1).cpu().tolist()\n        else:\n            output = torch.argmax(output, dim=1).tolist()\n        prediction += output\ntest_df[\"target\"] = prediction\ntest_df[\"target\"] = test_df[\"target\"].apply(lambda x : class_labels[str(x)])\ntest_df[\"target\"] = test_df[\"bird\"] == test_df[\"target\"]\nimp_features = [\"row_id\", \"target\"]\ntest_df = test_df[imp_features]\ntest_df.to_csv(\"submission.csv\", index = False)","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Thanks for visiting :)\n# Do UPVOTE if you like it :)\n\n### Follow me on [kaggle](https://www.kaggle.com/sagnik1511) , [GitHub](https://www.github.com/sagnik1511) and on [LinkedIn](https://www.linkedin.com/in/sagnik1511)","metadata":{}}]}