{"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":"# Libraries","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport matplotlib.pyplot as plt\nimport soundfile as sf\nimport librosa\n\nfrom sklearn.model_selection import train_test_split\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Path","metadata":{}},{"cell_type":"code","source":"path = '/kaggle/input/birdclef-2021/'\nos.listdir(path)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Functions\nWe define some helper functions.","metadata":{}},{"cell_type":"code","source":"def read_ogg_file(full_path):\n    \"\"\" Read ogg audio file and return numpay array and samplerate\"\"\"\n    data, samplerate = sf.read(full_path)\n    return data, samplerate\n\nfrom skimage.transform import resize\nimport numpy as np\n\ndef spec_to_image(spec):    \n    spec = resize(spec, (224, 400))\n    eps=1e-6\n    mean = spec.mean()\n    std = spec.std()\n    spec_norm = (spec - mean) / (std + eps)\n    spec_min, spec_max = spec_norm.min(), spec_norm.max()\n    spec_scaled = 255 * (spec_norm - spec_min) / (spec_max - spec_min)\n    spec_scaled = spec_scaled.astype(np.uint8)\n    spec_scaled = np.asarray(spec_scaled)\n    return spec_scaled","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load Data","metadata":{}},{"cell_type":"code","source":"import pickle\n\nwith open ('../input/birdclef-2021-pretrained-model/labels.pkl', 'rb') as fp:\n    labels = pickle.load(fp)\n\nprint('Number of unique bird labels:', len(labels))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We encode the labels and write them into a data frame:","metadata":{}},{"cell_type":"markdown","source":"# Parameter\nBased on the EDA we define some parameters:","metadata":{}},{"cell_type":"code","source":"import torch\n\ndata_lenght = 160000\naudio_lenght = 5\nbatch_size = 4\nnum_labels = len(labels)\n\nif torch.cuda.is_available():\n    device=torch.device('cuda:0')\nelse:\n    device=torch.device('cpu')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Define Model","metadata":{}},{"cell_type":"code","source":"import librosa\nfrom torch.utils.data import Dataset, DataLoader\n\nclass AudioData(Dataset):\n    def __init__(self, path, list_IDs, df, data_type):\n        self.data_type = data_type\n        self.path = path\n        self.df = df\n        self.data = []\n        self.row_ids = []\n        \n        for i, ID in enumerate(list_IDs):\n            prefix = str(self.df.loc[ID, 'audio_id'])+'_'+self.df.loc[ID, 'site']\n            file_list = [s for s in os.listdir(self.path) if prefix in s]\n            if len(file_list) == 0:\n                # Dummy for missing test audio files\n                audio_file_fft = np.zeros((data_lenght//2))\n                spectrogram = librosa.feature.melspectrogram(audio_file_fft)\n                spec_db=librosa.power_to_db(spectrogram,top_db=80)\n            else:\n                file = file_list[0]#[s for s in os.listdir(self.path) if prefix in s][0]\n                audio_file, audio_sr = read_ogg_file(self.path+file)\n                audio_file = audio_file[int((self.df.loc[ID, 'seconds']-5)/audio_lenght)*data_lenght:int(self.df.loc[ID, 'seconds']/audio_lenght)*data_lenght]\n                audio_file_fft = np.abs(np.fft.fft(audio_file)[: len(audio_file)//2])\n#                 # scale data\n#                 audio_file_fft = (audio_file_fft-audio_file_fft.mean())/audio_file_fft.std()\n            \n                spectrogram = librosa.feature.melspectrogram(audio_file_fft, sr=audio_sr)\n                spec_db=librosa.power_to_db(spectrogram,top_db=80)\n            \n            img = spec_to_image(spec_db)\n            mel_spec = np.stack((img, img, img))\n\n            row_id = str(self.df.loc[ID, 'row_id'])\n            \n            self.data.append(mel_spec)\n            self.row_ids.append(row_id)\n            \n#             if data_type == \"train\" and len(file_list) > 0:\n#                 #agmentaion\n        \n    def __len__(self):\n        return len(self.data)\n    \n    def __getitem__(self, idx):\n        return self.data[idx], self.row_ids[idx]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!mkdir -p /root/.cache/torch/hub/checkpoints/\n!cp ../input/pretrained-pytorch-models/resnet50-19c8e357.pth /root/.cache/torch/hub/checkpoints/","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torchvision.models import resnet50\nfrom torch import nn\n\nclass BirdCLEFModel(nn.Module):\n    def __init__(self, n_classes):\n        super().__init__()\n        resnet = resnet50(pretrained=True)\n        resnet.fc = nn.Sequential(\n            nn.Dropout(p=0.2),\n            nn.Linear(in_features=resnet.fc.in_features, out_features=n_classes)\n        )\n        self.base_model = resnet\n        self.sigm = nn.Sigmoid()\n\n    def forward(self, x):\n        return self.sigm(self.base_model(x))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predict Test Data","metadata":{}},{"cell_type":"code","source":"model = BirdCLEFModel(num_labels)\nmodel.load_state_dict(torch.load(\"../input/birdclef-2021-pretrained-model/20epoch_mseloss.pt\"))\nmodel.to(device)\nmodel.eval()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def prediction(test_audios, _dir):\n    warnings.filterwarnings(\"ignore\")\n    prediction_dfs = []\n    for audio_path in test_audios:\n        seconds = []\n        audio_ids= []\n        sites = []\n        row_ids = []\n        for second in range(5, 605, 5):\n            audio_id = audio_path.name.split(\"_\")[0]\n            site = audio_path.name.split(\"_\")[1]\n            row_id = \"_\".join(audio_path.name.split(\"_\")[:2]) + f\"_{second}\"\n            seconds.append(second)\n            audio_ids.append(audio_id)\n            sites.append(site)\n            row_ids.append(row_id)\n\n        test_df = pd.DataFrame({\n            \"row_id\": row_ids,\n            \"audio_id\": audio_ids,\n            \"site\": sites,\n            \"seconds\": seconds\n        })\n        \n        list_IDs_test = list(test_df.index)\n        test_data = AudioData(_dir, list_IDs_test, test_df, \"test\")\n        test_loader = DataLoader(test_data, batch_size=1, shuffle=True)\n        \n        rows = []\n        birds = []\n        for ind, data in enumerate(test_loader):\n            x, row_id = data\n            x = x.to(device, dtype=torch.float32)\n            y_hat = model(x)\n            predicted = y_hat.cpu().detach().numpy()\n            predicted = np.round(predicted)\n\n            types = []\n\n            for col in range(len(predicted[0])):\n                if predicted[0][col] == 1.:\n                    types.append(labels[col])\n\n            \n            if len(types) > 1 and 'nocall' in types:\n                types.remove('nocall')\n            elif len(types) == 0:\n                types.append('nocall')\n\n            string = \" \".join(types)\n\n            rows.append(row_id[0])\n            birds.append(string)\n\n        prediction_df = pd.DataFrame(list(zip(rows, birds)), columns =['row_id', 'birds'])\n        prediction_dfs.append(prediction_df)\n\n    print(len(prediction_dfs))\n    df = pd.concat(prediction_dfs, axis=0, sort=False).reset_index(drop=True)\n    return df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pathlib import Path\nTEST = (len(list(Path(\"../input/birdclef-2021/test_soundscapes/\").glob(\"*.ogg\"))) != 0)\nif TEST:\n    data_dir = \"../input/birdclef-2021/test_soundscapes/\"\nelse:\n    data_dir = \"../input/birdclef-2021/train_soundscapes/\"\n\nDATADIR = Path(data_dir)\nall_audios = list(DATADIR.glob(\"*.ogg\"))\nsubmission = prediction(all_audios, data_dir)\nsubmission.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}